1
我一直在使用匯編語言中的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 |
+-------------------------+
Ollydbg的。注意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
該問題的屏幕截圖將有所幫助。 – 2012-07-23 18:41:09
直接使用導入表條目調用一個函數應該不會引起問題。我懷疑你的調用函數中的某個地方必須返回而不用恢復寄存器,堆棧或除外處理程序。您可以在程序入口點使用'CALL DWORD PTR [EAX]'進行測試。其中'EAX'是'ExitProcess'的導入表項的地址。 – Jay 2012-07-24 03:10:18
其實現在我只是試着將ExitProcess的地址移到ecx然後調用ecx。用ollydbg看,我仍然得到了我在函數指針列表中所做的相同地址,但它不起作用。它唯一的工作是當我「調用ExitProcess」時。我也嘗試跳轉到ecx。那也行不通。 – 2012-07-24 03:23:35