我一直在搞乱汇编语言中的 PE 文件结构。我很确定我已经正确地进入了导入部分。我将此用作参考,其中每个框等于 4 个字节:
+-------------------------+-------------------------+
| RVA to a list of | DATE/TIME |
| pointer to APIs names | | IMPORT DATA DIRECTORY
+-------------------------+-------------------------+ #1
| .DLL address (unused) | RVA to .DLL name |
+-------------------------+-------------------------+
|RVA to API address list |
+-------------------------+
奥利德。注意右边eax的值(00402048),然后看高亮的调用指令的值是跳转到(00402000)。
我试图从(RVA 到 API 地址列表)调用第一个函数,即ExitProcess ,但是当我尝试对该地址发出调用时,它导致我的程序崩溃。当我用 Ollydbg 调试它时,我发现发出调用 ExitProcess时的地址与我在列表中找到的地址不同。在 Ollydbg 中,我发现的地址指向 <&KERNEL32.ExitProcess>,而调用 ExitProcess指向 <JMP.&KERNEL32.ExitProcess>。我在某处读到过某种 jmp 存根。就是这样吗?我应该如何调用“RVA 到 API 地址列表”中的函数?
我知道这可能令人困惑。如果您需要更多说明,请告诉我。
这是代码:
extern printf
extern ExitProcess
global _start
section .code
_start:
mov eax, [imagebase]
mov esi, eax
add eax, 3ch
mov eax, DWORD [eax]
add eax, esi; PE header pointer in eax
add eax, 128; 24 for PE Optional Header offset and then 104 for import RVA
mov ebx, DWORD [eax]
add ebx, DWORD [imagebase]; ebx now has import section offset
mov eax, DWORD [ebx+16]
add eax, DWORD [imagebase]; has array offset
mov ecx, ExitProcess
push 0
call ecx
;call eax
;jmp ecx
;call ExitProcess
imagebase: db 0,0,64,0; 0x00400000; This is right