压缩与脱壳-脱壳高级篇 上
2007-01-12 20:11:51 来源:WEB开发网可以推测出,当我们运行这个可执行程序时,PE 文件的引导部分试图从 FirstThunk 部分获得输入函数的名字。但是,正象你注意到的,这部分根本没有包含函数名字符串的 RVA,但是函数地址的 RVA 在内存中。
我们需要怎么做
--------------
现在,为了让这个可执行文件运行,我们需要重建 FirstThunk 部分的内容,让它们指向我们在输入表第三部分看到的函数名字符串。这不是一项很困难的任务,但是,我们需要知道哪个IAT 对应哪个函数,而函数字符串和 FirstThunk 内容并不采用同样的存储方法。所以,对于每
一个 IAT,我们需要验证它对应的是哪个函数名(事实上,根据 IMAGE_IMPORT_DESCRIPTOR.Name DWord 我们已经有了 DLL 名称,这些并没有被改变)。
如何验证每一个函数
------------------
正向我们上面所见到的,在内存中,每一个被破坏的 IAT 都有一个函数地址的 RVA。这些地址并没有被破坏,所以,我们只要重新找回指向错误 IAT 的函数地址,把它们指向函数名字符串。
为此,在 Kernel32.dll 中有一个非常有用的 API:GetProcAddress。它允许你得到给定函数的地址。这里是它的描述:
GetProcAddress(
HMODULE hModule, // DLL 模块的句柄
LPCSTR lpProcName // 函数名
);
所以,对于每一个被破坏的 IAT,在 GetProcAddress 返回我们寻找的函数地址之前,只需要分析包含在输入表第三部分的所有函数名。
- hModule 参数是 DLL 模块的句柄(也就是说,模块映象在内存中的基址),我们可以通过 GetModuleHandleA API 得到:
HMODULE GetModuleHandle(
LPCTSTR lpModuleName // 返回模块名地址句柄
);
(lpModuleName 只需要指向我们从 IMAGE_IMPORT_DESCRIPTOR.Name 部分得到的 DLL 文件名字符串)
更多精彩
赞助商链接