c程式的啟動過程的反組譯碼分析

來源:互聯網
上載者:User

標籤:局部變數   程式碼分析   編譯器   控制台   c語言   

0x01  工具準備

1.最簡c代碼一隻,

int main(){

return 0;}

2.ollydbg

3.VC++6.0

4.GCC(mingw)

0x02  程式碼分析

int main()

{

return 0;

}

在gcc下,添加-nostdlib編譯選項,即連結器不連結標準庫,會提示以下錯誤資訊:

 

D:\Backup\我的文件\src>gcc main.c -nostdlib-o main.exe

C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccmSU3wr.o:main.c:(.text+0x9): undefined re

ference to `__main‘

collect2.exe: error: ld returned 1 exit status

 

關於-nostdlib編譯選項,只有命令列指定的項才傳遞給連結器。標準開機檔案和庫都不會傳遞給連結器。該選項隱式開啟選項-nostartfiles 和-nodefaultlibs。該選項也可以寫作--no-standard-libraries。

在gcc執行彙編之後,在連結部分,當只開啟選項-nostartfiles時,結果正常,未出現錯誤資訊。而在-nodefaultlibs選項中,提示很多錯誤資訊。

說明main函數,依賴了一些系統標準庫檔案,在連結的時候,需要到了一些函數,例如pre_cpp_init、check_managed_app、pre_c_init、_tmainCRTStartup、_InterlockedCompareExchangePointer、duplicate_ppstrings、WinMainCRTStartup、mainCRTStartup、_mingw_prepare_except_fr_msvcr80_and_higher….

彙編裡面的_main就是C語言裡面的main,是因為彙編器和C編譯器對符號的命名差一個底線。

連結器會在系統標準庫檔案,類似於/lib/crt2.o的檔案中,尋找_start符號,然後在_start中執行建立堆對象,棧,開啟系統預先提供的裝置,將argv,argc參數傳入main函數,然後調用main函數。

0x03  vc main函數反組譯碼分析

1:    int main()

2:    {

00401010   push        ebp   //在堆棧上儲存EBP

00401011   mov         ebp,esp //將堆棧當前位置給EBP,以在堆棧結構中儲存值時的參考點

00401013   sub         esp,40h //分配空間

00401016   push        ebx  //儲存資料區段值

00401017   push        esi //源地址指標

00401018   push        edi //目的地址指標

00401019   lea         edi,[ebp-40h] //裝入有效地址,用來得到局部變數和函數參數的指標。這裡[ebp-40h]就是基地址再向下位移40h,就是前面說的為本地變數留出的空間的起始地址;將這個值裝載入edi寄存器,從而得到局部變數的地址

0040101C   mov         ecx,10h //在ecx寄存器儲存10h

00401021   mov         eax,0CCCCCCCCh

00401026   rep stos    dword ptr [edi] //初始化局部變數空間,ds:[edi]

3:        return 0;

00401028   xor         eax,eax

4:    }

0040102A   pop         edi //恢複所有寄存器的值

0040102B   pop         esi

0040102C   pop         ebx

0040102D   mov         esp,ebp //恢複堆棧

0040102F   pop         ebp

00401030   ret //返回到源EIP地址

 

Vc查看調用棧,可以看到在main函數之前,系統還啟動了mainCRTStartup函數,這個函數是控制台環境下多位元組編碼的啟動函數。在kernel32.dll中地址7c816fd7處調用了mainCRTStartup函數。

main() line 2

mainCRTStartup() line 206 + 25 bytes

KERNEL32! 7c816fd7()

0x04 ollydbg反組譯碼分析


Od載入,。


堆棧視窗。


通過堆棧,可以看到kelnel32調用了入口函數(mainCRTStartup),對於od來說,main函數並不是Entry point,而是mainCRTStartup函數。

一直單步,單步到00401146處,od分析為調用GetVersion函數,擷取當前運行平台的版本號碼,因為是控制台程式,所以擷取版本號碼為ms-dos的版本資訊。

繼續單步,單步到0040119E處,單步進入,可以看到有HeapCreate申請堆空間函數,大小由傳遞的參數決定,並且該call裡有HeapDestroy銷毀堆函數。因此0040119E為初始化堆空間,。


在004011C0處,od分析為GetCommandLineA函數,擷取命令列參數資訊的首地址。

進入下面的那個call後,可以看到GetEnvironmentStringsW和GetEnvironmentStrings函數,擷取環境變數的首地址,。以Unicode編碼形式返回到寄存器和堆棧中,最後採用WideCharToMultiByte函數將Unicode字串到一個多位元組字串, 

並且後續有參數分析的一些函數,環境變數資訊分析,從而得到main函數所需的參數,然後在00402D4B位置,將參數傳到main函數中,從而執行main函數中的內容。

0x05 後記

最近在閱讀《c++反組譯碼與逆向分析技術揭秘》,在閱讀到第三章認識啟動函數,找到使用者入口時,得知main函數之前系統要做一些準備工作,再加上上學期學的C語言程式入口函數不是main函數,而是_start函數,這不禁引發了一些思考,到底編譯器在編譯和系統執行程式的時候發生了什麼,因此想以執行個體進行一定的分析。在思考的過程中,有些涉及到了編譯器的知識,包括它如何工作的,彙編之後又是如何連結的,這一部分內容不太熟悉,這一方面得掌握編譯原理的知識,還得學習編譯器的相關內容。那些東西還沒學,因此不免有一些缺憾。瞭解反組譯碼的一些內容,可以更深層次的理解相對底層的一些東西,包括棧,堆和寄存器的資料交換。另外並未使用到神器IDA,利用IDA會更好地靜態分析一些函數。


c程式的啟動過程的反組譯碼分析

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.