这种简单粗糙的日志对我来说已经够用了。若希望以更友好的形式显示参数信息,就必须有一些数据文件来描述各 API 函数的调用方式、返回值类型、参数个数等内容。比如这样:
int LoadLibraryA([in] char *lpLibFileName);
int LoadLibraryW([in] wchar *lpLibFileName);
void *GetProcAddress([in] int hModule, [in] char *lpProcName);
int GetModuleFileNameA([in] int hModule, [out] char *lpFilename, [in] int nSize);
int GetModuleFileNameW([in] int hModule, [out] wchar *lpFilename, [in] int nSize);
编写一个简单的词法解析模块直接解析 VC 自带的 .h 文件,对使用者来说就更省事了。经过参数类型解析后的输出信息会好看很多:
------------------------------------------------------
004099F2 -> GetModuleFileNameA(
int hModule: 0 (unsigned = 0 / hex = 0),
char*lpFilename: [0012F824] = "",
int nSize: 260 (unsigned = 260 / hex = 104),
13 << results
int hModule: 0 (unsigned = 0 / hex = 0),
char*lpFilename: [0012F824] = "e: rojan.exe" in stack of Thread,
int nSize: 260 (unsigned = 260 / hex = 104)
);
------------------------------------------------------
00409A06 -> CopyFileA(
char*lpExistingFileName: [0012F824] = "e: rojan.exe" in stack of Thread,
char* lpNewFileName: [0012F71C] = "C:WINDOWSsystem32 rojan.exe" in stack of Thread,
int bFailIfExists: 0 (unsigned = 0 / hex = 0),
1 << results
char*lpExistingFileName: [0012F824] = "",
char* lpNewFileName: [0012F71C] = "",
int bFailIfExists: 0 (unsigned = 0 / hex = 0)
);
------------------------------------------------------
00409A9A -> OpenSCManagerA(
char* lpMachineName: [00000000] = (null),
char*lpDatabaseName: [00000000] = (null),
int dwDesiredAccess: 983103 (unsigned = 983103 / hex = F003F),
1374656 << results
char* lpMachineName: [00000000] = "",
char*lpDatabaseName: [00000000] = "",
int dwDesiredAccess: 983103 (unsigned = 983103 / hex = F003F)
);
------------------------------------------------------
00409AD5 -> CreateServiceA(
inthSCManager: 1374656 (unsigned = 1374656 / hex = 14F9C0),
char* lpServiceName: [0042008C] = "trojan" in main image (.data),
char* lpDisplayName: [004200C0] = "Back door for testing" in main image (.data),
int dwDesiredAccess: 983551 (unsigned = 983551 / hex = F01FF),
int dwServiceType: 288 (unsigned = 288 / hex = 120),
int dwStartType: 2 (unsigned = 2 / hex = 2),
intdwErrorControl: 1 (unsigned = 1 / hex = 1),
char*lpBinaryPathName: [0012F71C] = "C:WINDOWSsystem32 rojan.exe -start" in stack of Thread,
char*lpLoadOrderGroup: [00000000] = (null),
int*lpdwTagId: 00000000,
char*lpDependencies: [004201C4] = "" in main image (.data),
char*lpServiceStartName: [00000000] = (null),
char*lpPassword: [00000000] = (null),
1370392 << results
inthSCManager: 1374656 (unsigned = 1374656 / hex = 14F9C0),
char* lpServiceName: [0042008C] = "",
char* lpDisplayName: [004200C0] = "",
int dwDesiredAccess: 983551 (unsigned = 983551 / hex = F01FF),
int dwServiceType: 288 (unsigned = 288 / hex = 120),
int dwStartType: 2 (unsigned = 2 / hex = 2),
intdwErrorControl: 1 (unsigned = 1 / hex = 1),
char*lpBinaryPathName: [0012F71C] = "",
char*lpLoadOrderGroup: [00000000] = "",
int*lpdwTagId: 00000000,
char*lpDependencies: [004201C4] = "",
char*lpServiceStartName: [00000000] = "",
char*lpPassword: [00000000] = ""
);
......
dumbug 是一个开源的 API TRACING 工具,但被设计为仅对 trace 文件中定义的 API 调用进行跟踪。要想通过原始的 dumbug 获得完整 API 调用序列,工作量一点也不比 API HOOKING 方式小。而且就分析木马程序来说,我们并不需要记录 kernel32.dll 等系统链接库内部的 API 调用序列,所以还应根据 EXE 和 DLL 的入口地址、代码段长度进行过滤,最大限度减少冗余信息。在 dumbug 中,只要为 Tracer 对象的 ActivateTraces() 方法添加一些代码,并在其他地方也做相应的小修改,就可以输出上面的结果了。
上一篇 北京奥运会虚假信息邮件病毒成恶意攻击源头
下一篇 网络安全友情链接
阅读推荐
相关文章