C語言空函數分析


實驗環境:WIN7虛擬機
軟件:VC6

首先在VC6里面寫一個空函數Fun();

F7編譯運行一下,沒有出錯,接着在函數處使用F9下斷點,使程序運行到Fun函數時停下。

接着F5開始運行這個程序

程序停在了Fun函數處,反匯編進去進行逆向分析


可以看到程序停在Fun函數的入口處,這里的call就是Fun函數的入口,F11跟進去進行分析。

原始堆棧圖是這樣的。

0040D408 call @ILT+5(_Fun) (0040100a)

F11,跟進這個call進行分析,進入函數之后編譯器會將跳出函數之后下一個要執行的地址壓入堆棧,即將0040D40D壓入堆棧,同時esp-4,esp變成0012FEF8,這時的堆棧是這樣的:

跟進來之后是一個jmp,F11直接跳轉。

現在進到函數里面了

00401010 push ebp

首先將ebp壓棧,就是將[ebp]壓入堆棧,即將0012FF48壓入堆棧,然后esp的位置向上提升一個變為0012FEF4。

查看檢查寄存器進行驗證:

00401011 mov ebp,esp

將esp的值賦給ebp,也就是將0012FEF4賦給ebp,這時的堆棧圖是這樣的

查看寄存器驗證,這里可以看到esp和ebp的值相等,說明上面那個堆棧圖沒有問題

00401013 sub esp,40h

將esp減去40h,也就是將esp的位置提升到0012FEB4位置,這一步的作用是提升堆棧,這時的堆棧圖是這樣的

查看寄存器進行驗證,看到esp的值為0012FEB4

00401016 push ebx

接着將ebx壓棧,查看棧頂可以看到ebx被壓入堆棧,同時esp的位置向上提升。


此時的堆棧是這樣的:

00401017 push esi

將esi的值壓入堆棧,此時的堆棧是這樣的


查看寄存器進行驗證:

00401018 push edi

接着將edi的值壓入堆棧,此時的堆棧是這樣的


查看寄存器驗證:

00401019 lea edi,[ebp-40h]

將[ebp-40h]的地址存入edi中,也就是將0012FEB4存入edi。

查看寄存器驗證,可以看到0012FEB4被存入edi中

0040101C mov ecx,10h

將10h存入ecx中,也就是將00000010存入ecx,查看寄存器驗證:

00401021 mov eax,0CCCCCCCCh

將CCCCCCCC存入eax中,查看寄存器驗證:

00401026 rep stos dword ptr [edi]

將eax的中的值存儲到[edi]對應地址的內存中,並重復ecx次,也就是將CCCCCCCC存入地址0012FEB4對應的內存中,並重復10h次,rep每執行一次,[edi]會相應的加4(向下填充數值),ecx會相應的減4(減少執行次數)。

此時的堆棧是這樣的:


查看寄存器驗證一下,發現從0012FEF4到0012FEB4全部被填充為CCCCCCCC。

00401028 pop edi

將edi出棧,也就是將esp當前對應的值0012FF48賦給edi,同時esp加4變成0012FEAC,此時的堆棧


查看寄存器驗證:

00401029 pop esi

將esi出棧,也就是將esp當前對應的值00000000賦給edi,同時esp加4變成0012FEB0,此時的堆棧


查看寄存器驗證:

0040102A pop ebx

將ebx出棧,也就是將esp當前對應的值7FFDD000賦給ebx,同時esp加4變成0012FEB4,此時的堆棧


查看寄存器驗證一下:

0040102B mov esp,ebp

將ebp的值賦給esp,這里的作用相當於降低堆棧,此時的堆棧是這樣的


查看寄存器進行驗證,esp的值和ebp的值相等

0040102D pop ebp

將ebp出棧,也就是將esp當前對應的值0012FF48賦給ebx,這時ebx又回到了一開始所在的位置,同時esp加4變成0012FEF8,此時的堆棧是這樣的


查看寄存器驗證一下

0040102E C3 ret

相當於pop eip,即將當前esp對應的值放入eip中,也就是將0040D40D放入eip中,同時ESP+4,esp變為0012FEFC,此時的堆棧是這樣的


查看寄存器驗證一下,至此堆棧恢復平衡,Fun函數執行完畢


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM