首页
社区
课程
招聘
[原创]记一次简单的代码还原--实时监控系统日志
发表于: 2017-9-25 17:18 4259

[原创]记一次简单的代码还原--实时监控系统日志

2017-9-25 17:18
4259
逆windows日志小工具
查看导入函数发现OpenEventLogW,就拖到IDA,查看交叉引用,立马定位到关键函数,F5以下,一开始看关键函数很清晰,但是后面发现一些字符串相关的解析的还是有问题,中间删删补补,还查了一些其他的资料,终于完成了
下面是代码
// GetEventLog.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <strsafe.h>
#include <locale.h>
#define MAX_RECORD_BUFFER_SIZE  0x10000 
#define MAX_TIMESTAMP_LEN       23 + 1

 
void GetTimestamp(const DWORD Time , WCHAR DisplayString[])
{
	ULONGLONG ullTimeStamp = 0;
	ULONGLONG SecsTo1970 = 116444736000000000;
	SYSTEMTIME st;
	FILETIME ft , ftLocal;

	ullTimeStamp = Int32x32To64(Time , 10000000) + SecsTo1970;
	ft.dwHighDateTime = (DWORD)((ullTimeStamp >> 32) & 0xFFFFFFFF);
	ft.dwLowDateTime = (DWORD)(ullTimeStamp & 0xFFFFFFFF);

	FileTimeToLocalFileTime(&ft , &ftLocal);
	FileTimeToSystemTime(&ftLocal , &st);
	StringCchPrintf(DisplayString , MAX_TIMESTAMP_LEN , L"%d/%d/%d %.2d:%.2d:%.2d" ,
					st.wMonth , st.wDay , st.wYear , st.wHour , st.wMinute , st.wSecond);
}


int main()
{
	// 创建事件对象
	HANDLE hEvent = CreateEventW(0 , 1 , 0 , 0);
	HANDLE hEventLog = OpenEventLogW(0 , L"Applicattion Error");
	 
	DWORD OldestRecord;
	DWORD NumberOfRecords;
	// 使一个应用程序在事件写入指定的事件日志时接收通知。当事件写入日志时,指定的事件对象被设置为信号状态。
	// 将事件对象和产生日志"绑定"在一起
	NotifyChangeEventLog(hEventLog , hEvent);
	DWORD newLog;
	
	PEVENTLOGRECORD pBuf = (PEVENTLOGRECORD)malloc(MAX_RECORD_BUFFER_SIZE);
	DWORD pnBytesRead;
	DWORD pnMinNumberOfBytesNeeded;
	 
	 
	while (1)
	{
		// 捕获日志[通过事件对象获取捕获信号]
		while (1)
		{
			// 等待日志事件
			WaitForSingleObject(hEvent , -1);
			OldestRecord = 0;
			NumberOfRecords = 0;
			if(GetOldestEventLogRecord(hEventLog , &OldestRecord))
			{
				if(GetNumberOfEventLogRecords(hEventLog , &NumberOfRecords))
					break;
			}
			
			ResetEvent(hEvent);
		}
		
		newLog = NumberOfRecords - 1 + OldestRecord;

		// 读取日志
		if(!ReadEventLogW(hEventLog , 6 , newLog , pBuf , 0x38 , &pnBytesRead , &pnMinNumberOfBytesNeeded) && GetLastError() == 122)
		{
			// 如果读取错误,可能是之前申请的内存小了,这里重新申请
			pBuf = (PEVENTLOGRECORD)realloc(pBuf , pnMinNumberOfBytesNeeded);
			if(!pBuf)
			{
				printf("内存错误");
				TerminateProcess(NULL , 0);
			}
			// 重新申请完之后,继续读取
			if(!ReadEventLogW(hEventLog , 6 , newLog , pBuf , pnMinNumberOfBytesNeeded , &pnBytesRead , &pnMinNumberOfBytesNeeded))
			{
				printf("内存错误");
				TerminateProcess(NULL , 0);
			}
		}

		if (pBuf->EventType == 1)
		{
			CHAR ppColumn[ 8 ][ 25 ] = {
				"应用程序名:    ",
				"应用程序版本:  ",
				"应用程序时间戳:",
				"故障模块名称:  ",
				"故障模块版本:  ",
				"故障模块时间戳:",
				"异常代码:      ",
				"异常偏移:      "
			};

			// WCHAR SourceName []
			// WCHAR Computername []
			// SID UserSid
			// WCHAR Strings []
			// BYTE Data []
			// CHAR Pad []
			// DWORD Length;
			 
			WCHAR *pDataBuf;
			PWCHAR lpString[ 8 ];// 字符串指针数组.用于保存各信息的首地址
			DWORD dwDataStrLength;
			DWORD RecordBuf
				= (DWORD)pBuf + pBuf->StringOffset;
			NumberOfRecords = 0;
			if (pBuf->NumStrings > 0)
			{
				for (int i = 0; i < 8; i++)
				{
					// 定位到该条数据的首地址[注意是宽字符]
					pDataBuf = (WCHAR *)(RecordBuf + 2 * NumberOfRecords);
					lpString[ i ] = pDataBuf;
					// 计算字符串长度
					dwDataStrLength = lstrlenW(pDataBuf) + 1;
					// 计算下条数据的偏移
					NumberOfRecords = dwDataStrLength + NumberOfRecords;
				}
				
			}

			// 打印标题
			setlocale(LC_CTYPE , "");
			wprintf(L"%s\n", L"**************** 15PB Event Catcher ^-^ by 树梢之上****************");

			// 转化时间
			WCHAR TimeStamp[ MAX_TIMESTAMP_LEN ];
			GetTimestamp(pBuf->TimeGenerated , TimeStamp);
			wprintf(L"%s\n", TimeStamp);

			HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
			SetConsoleTextAttribute(hConsole , 7);


			for (int i = 0; i < 8; i++)
			{
				SetConsoleTextAttribute(hConsole , 7);
				// 打印标题
				printf("%-20s" , ppColumn[ i ]);
				CHAR MultiByteStr[ 1040 ];
				memset(MultiByteStr , 0 , 1040);
				// 求长度
				DWORD v17 = lstrlenW((LPCWSTR)lpString[ i ]);
				// 宽字符转窄
				WideCharToMultiByte(0 , 0 , (LPCWSTR)lpString[ i ] , v17 , MultiByteStr , 1040 , 0 , 0);
				// 设置字符颜色
				if(i >= 6 || i == 3)
				{
					SetConsoleTextAttribute(hConsole , 0xA);
				}
				// 打印数据
				printf("%s\n" , MultiByteStr);
				 
			}

		}
	}
}




[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2019-4-12 10:07 被树梢之上编辑 ,原因:
收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 181
活跃值: (621)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
15PB
2017-9-26 08:46
0
雪    币: 35
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
2017-9-26 10:20
0
雪    币: 115
活跃值: (23)
能力值: (RANK:20 )
在线值:
发帖
回帖
粉丝
4
一天就打广告
2017-9-27 09:46
0
游客
登录 | 注册 方可回帖
返回
//