C語言空函數分析

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

首先在VC6裏面寫一個空函數Fun();3d

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

接着F5開始運行這個程序
ip

程序停在了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函數執行完畢

相關文章
相關標籤/搜索