.386
.Model Flat, StdCall
Option Casemap :None
Include windows.inc
Include user32.inc
Include kernel32.inc
IncludeLib user32.lib
IncludeLib kernel32.lib
.DATA
szDllKernel db 'user32.dll',0
szMessageBox db 'MessageBoxA',0
.DATA?
lpMessageBox dd ?
.CODE
START:
invoke GetModuleHandle,addr szDllKernel
mov ebx,eax
invoke GetProcAddress,ebx,offset szMessageBox
mov lpMessageBox,eax
push MB_OK
push 0
push 0
push 0
mov EAX,offset _END
push EAX
jmp lpMessageBox
_END:
invoke ExitProcess,0
END START
看出點什麼了嗎?我把CALL變成了PUSH和JMP兩個指令
瞭解調用過程的人都知道CALL指令就是先把下一條指令地址壓棧然後在用JMP跳轉到函數入口處,那我們的解決辦法就出來了,我們可以自己完成這個調用動作,先把下一條指令壓棧
.CODE
START:
invoke GetModuleHandle,addr szDllKernel
mov ebx,eax
invoke GetProcAddress,ebx,offset szMessageBox
mov lpMessageBox,eax
push MB_OK
push 0
push 0
push 0
mov EAX,offset _END
push EAX
;添加的代碼開始
mov edi,edi
push ebp
mov ebp,esp
add lpMessageBox,5
;添加的代碼結束
jmp lpMessageBox
_END:
invoke ExitProcess,0
END START
把目標API的前幾行代碼在自己程序裏實現,然後在跳轉到API函數中去繼續運行。比如我是把MessageBox的前3行代碼在自己的程序裏實現,然後在條到MessageBox的第4行裏繼續運行。
這樣跳轉到目標入口地址就不是API函數的入口了