我正在写一个小工具,它应该能够检查一个感兴趣的任意进程,并检查它的静态链接函数是否有任何一个是 蹦床. (安 蹦床的例子 可能是 微软绕道 对一个进程的影响)。)
为此,我解析了 PE头 的目标进程,并检索其所有导入的DLLs和其中的所有导入函数,然后我可以比较磁盘上的DLLs和目标进程内存中加载的DLLs。那么我可以将磁盘上的DLL和目标进程内存中加载的DLL进行以下比较。
A. 中的条目。Import Address Table
对于每个导入的函数。
B. 每个函数的机器代码的前N个字节。
如果以上任何一项不匹配,这将很肯定地意味着一个 trampoline
被应用到一个特定的函数(或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导入。)
全局变量将在.data部分而不是.text部分,此外,如果不是函数,该部分将没有执行权限。 因此你可以利用这两个特点来进行过滤。