我正在编写一个小工具,该工具应该能够检查关注的任意过程,并检查其静态链接的任何功能是否 trampolined 。(蹦床的一个示例可能是Microsoft绕行过程中的操作。)
为此,我可以解析目标过程的PE标头,并在其中所有导入功能中检索其所有导入的DLL。然后,我可以比较磁盘上的DLL和目标过程内存中加载的DLL之间的以下内容:
a。每个导入功能的Import Address Table
中的条目。
b。每个函数机器代码的第一个字节。
,如果以上任何一个不匹配,这肯定意味着将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部分中,此外,如果不是函数,则该部分将不会执行权限。因此,您可以使用这两个特征来过滤。