對程序調用API變形的一點認識

.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函數的入口了

發佈了11 篇原創文章 · 獲贊 3 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章