我正在编写一个小工具,它应该能够检查感兴趣的任意进程并检查它的任何静态链接函数是否被蹦床。(蹦床的一个例子可能是Microsoft Detours对流程所做的事情。)
为此,我解析目标进程的PE 标头并检索其所有导入的 DLL,其中包含所有导入的函数。然后我可以比较磁盘上的 DLL 和目标进程内存中加载的 DLL:
A.Import Address Table
每个导入函数的条目。
B. 每个函数机器码的前 N 个字节。
如果以上任何一项不匹配,这肯定意味着 atrampoline
已应用于特定函数(或 WinAPI。)
这很好用,除了目标进程可以导入全局变量而不是函数的情况。例如_acmdln
是这样的全局变量。您仍然可以在其中找到msvcrt.dll
并使用它:
//I'm not sure why you'd want to do it this way,
//but it will give you the current command line.
//So just to prove the concept ...
HMODULE hMod = ::GetModuleHandle(L"msvcrt.dll");
char* pVar = (char*)::GetProcAddress(hMod, "_acmdln");
char* pCmdLine = pVar ? *(char**)pVar : NULL;
因此,这对我的蹦床检查工具意味着我需要区分导入函数 (WinAPI) 和全局变量。知道怎么做吗?
PS。如果我不这样做,我上面描述的算法将比较全局变量的“代码字节”,就像它是一个函数一样,它只是一个指向肯定会不同的命令行的指针,然后标记它作为蹦床功能。
PS2。不完全是我的代码,但可以在此处找到类似的解析 PE 标头的方法。(搜索用于DumpImports
提取 DLL 导入的函数。)