这个问题遵循这个问题。
我使用导入表、ILT、IAT和提示/名称表管理.idata部分的创建。当我使用PE文件检查工具,比如PE-熊,一切看起来都很好,并且在.text节的反汇编视图中,PE能够找到“调用”指令所引用的函数的名称。
下面是屏幕截图:

但遗憾的是,当我试图执行二进制文件时,它不能工作,调试器x64dbg (它也有32位版本)找不到函数。因此,我怀疑PE装载机没有正确地纠正我的IAT,因为我不明白的原因。x64dbg也未能显示我的"Hello“字符串,但在本例中应该是因为我暂时还没有填充.reloc部分。
我还需要填写.reloc部分吗?
这里是一个调试会话的捕获,第一次“调用”指令崩溃。

下面是一个带有Visual生成的类似exe的捕获,在本例中,x32dbg能够指示由“调用”指令引用的函数名。

PS:我开始学习ASM,所以我可能会忽略一些东西,比如设置CPU标志或其他任何东西。我给IAT的RVA以“呼叫”指令。
发布于 2022-08-21 10:57:47
只有在所选的 (0x00400000)地址上没有空闲内存时,Windows才会使用来自ImageBase (0x00400000)部分的基重定位。这可能发生在加载DLL时,而不是加载简单的HelloWorld.exe时。每次加载程序为您的可执行文件创建一个新进程时,所有32位地址空间都是空闲的,不需要重新定位任何内容。
您将CALL GetStdHandle组装为CALL DWORD PTR [0x00404038],您期望0x00404038上的内存包含DWORD到DLL函数的入口点?这不是加载程序的工作方式,也不是调试器查找函数的方式。
你应该调用一个间接的接近JMP的指令,从IAT跳转到DWORD。在这种情况下,加载程序不需要收集和重新定位所有导入函数的零散调用。相反,它只在ILT中行走,每次导入就进行一次迁移,并将最后的VA存储到IAT。然后,您可以在IAT中看到地址来自地址空间的上半部分,例如0x7F******或kernel32.dll的首选加载地址,如负载-时间动态链接中所描述的。
ILT、IAT和提示/名称并不是手工构建的.idata部分中唯一的基本组件,参见ImportCreate作为示例。
https://stackoverflow.com/questions/73430166
复制相似问题