如何为已编译模块中的导入函数生成调用指令

时间:2016-11-09 23:59:25

标签: windows assembly import module

我不确定我是否正确地表达了问题,但基本上我想知道从另一个库调用导入函数时如何生成调用指令。

例如

GetModuleFileName(...)

编译为

call 0x4D0000

其中0x4D0000是导入函数的动态地址。

Windows如何设置这些调用,是否可以绕过它并设置自定义地址。

1 个答案:

答案 0 :(得分:1)

call语句中使用的地址不是动态的。它是一个相对地址,在链接时固定,就像调用任何其他函数一样。那是因为调用实际上是存根,而存根执行间接跳转到实际函数。间接跳转使用引用导入表中位置的内存操作数。当Windows加载可执行文件(或DLL)时,它会使用可执行文件或DLL在其链接的任何DLL中使用的所有函数的地址更新导入表。

所以如果一个可执行的调用指令是这样的:

    call _GetModuleFileNameA@12

然后在同一个可执行文件中的其他地方就像这样:

_GetModuleFileNameA@12:
    jmp  [__imp__GetModuleFileNameA@12]

在导入表的某个地方有一个这样的定义:

__imp__GetModuleFileNameA@12:
    DD    ?

Windows在加载可执行文件(或DLL)时在导入表中设置__imp_GetModuleFileName@12的值。虽然在加载可执行文件(或DLL)后更改值并不太难,但是你可以做的事情并没有太多改变。请注意,导入表可能位于只读部分,这意味着您可能需要更改虚拟内存保护才能执行此操作。