序
在玩cm时,为了了解程序流程,使用了apilogger记录API的调用情况。
保存的日志中,有很多系统DLL的内部API调用,这是我不关心的。
我只关心cm调用了什么API.
写了测试程序,对apilogger产生的总日志做处理,将cm调用API的日志另存成一个小日志,用来分析程序流程. 写完后,效果还不错,18W行的日志变为了4W行.
对于apilogger产生的总日志, 行中包含.exe字样,就是cm的日志。
也可以对EIP的记录进行判断, e.g. 0x004xxxxx, 就是cm的日志。
测试程序
// log_extractor.cpp : Defines the entry point for the console application.
// code on vs2010
#define _CRT_SECURE_NO_WARNINGS
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <tchar.h>
#include <atlbase.h>
bool log_process(const char* psz_log_file_name, const char* psz_log_file_out_name);
int _tmain(int argc, _TCHAR* argv[])
{
USES_CONVERSION;
bool b_rc = false;
do {
if (argc < 3) {
printf("must take TWO parameter\n");
printf("parameter1 is log file path name\n");
printf("parameter2 is log output file path name\n");
printf("e.g. log_extractor.exe d:\\cm_api_log.txt d:\\log_out.txt\n");
break;
}
b_rc = log_process(W2A(argv[1]), W2A(argv[2]));
printf("%s = log_process(%s)\n", (b_rc ? "true" : "false"), W2A(argv[1]));
if (b_rc) {
printf("please see %s\n", W2A(argv[2]));
}
} while (0);
system("pause");
return 0;
}
bool log_process(const char* psz_log_file_name, const char* psz_log_file_out_name)
{
FILE* pfile = NULL;
FILE* pfile_out = NULL;
bool b_rc = false;
char szBuf[1024] = {'\0'};
int iLen = 0;
do {
if (NULL == psz_log_file_name) {
break;
}
if (NULL == psz_log_file_out_name) {
break;
}
pfile_out = fopen(psz_log_file_out_name, "w+");
if (NULL == pfile_out) {
break;
}
pfile = fopen(psz_log_file_name, "r");
if (NULL == pfile) {
break;
}
memset(szBuf, 0, sizeof(szBuf));
while(NULL != fgets(szBuf, sizeof(szBuf), pfile)) {
iLen = strlen(szBuf);
if (NULL != strstr(szBuf, ".exe")) {
szBuf[iLen - 1] = '\r';
szBuf[iLen] = '\n';
printf("%d : %s", iLen, szBuf);
fwrite(szBuf, sizeof(char), strlen(szBuf), pfile_out);
}
memset(szBuf, 0, sizeof(szBuf));
}
b_rc = true;
} while (0);
if (NULL != pfile) {
fclose(pfile);
pfile = NULL;
}
if (NULL != pfile_out) {
fclose(pfile_out);
pfile_out = NULL;
}
return b_rc;
}