
前言
每個人在除錯中快速查找所需代碼時都有不同的方法,但是最基本最常用的有下面幾種,
學習這4種方法前我們需要思考一個問題,我們知道,運行HelloWorld.exe程式會彈出一個訊息框,顯示“Hello
World!”資訊,固然是因為我們撰寫了代碼,可在這種情形下,只要運行一下程式,不論是誰都能輕松意識到這一點,如果你熟悉win32 api的開發,看到彈出的訊息框就會想到,這是呼叫MessageBox()
API的結果,應用程式的功能非常明確,只要運行一下程式,就能大致推測出其內部結構,不過前提是你已經具備了開發和分析代碼的經驗,
一、代碼執行法
我們需要查找的是main()函式中呼叫MessageBox()函式的代碼,在除錯器中除錯HelloWorld.exe(F8)時,main()函式的MessageBox()函式在某個時刻就會被呼叫執行,彈出訊息對話框,顯示“Hello World!”這條資訊,
上面就是代碼執行法的基本原理,當程式功能非常明確時,我們可以逐條執行指令來查找需要查找的位置,但是代碼執行法僅適用于被除錯的代碼量不大、且程式功能明確的情況,倘若被除錯的代碼量很大且比較復雜時,此種方法就不再適用了,下面使用代碼執行法來查找代碼中的main()函式,從“大本營”(40104F)開始,按F8鍵逐行執行命令,在某個時刻彈出訊息對話框,顯示“Hello World!”資訊,按Ctrl+F2鍵再次載入待除錯的可執行檔案并重新除錯,不斷按F8鍵,某個時刻一定會彈出訊息對話框,彈出訊息對話框時呼叫的函式即為main()函式,如圖2-20所示,地址401144處有一條函式呼叫指令“CALL00401000”,被呼叫的函式地址為401000,按F7鍵(Step Into)進入被呼叫的函式,可以發現該函式就是我們要查找的main()函式,


如上圖,地址40100E處有一條呼叫MessageBox() API的陳述句,401002與401007處分別有一條PUSH陳述句,他把訊息對話框的標題與顯示字串(Title = “www.reversecore.com”, Text = “Hello World!”)保存到堆疊(Stack)中,并作為引數傳遞給MessageBox W()函式,
這樣我們就準確的查找到了main()函式,
win32應用程式中,API函式的引數是通過堆疊傳遞的,VC++中默認字串是使用Unicode碼表示的,并且,處理字串的API函式也全部變更為Unicode系列函式,
二、字串檢索法
右鍵選單-search for-all referenced text strings
OllyDbg初次載入待除錯的程式時,都會先經歷一個預分析程序,此程序中會查看行程記憶體,程式中參考的字串和呼叫的API都會被摘錄出來,整理到另外的一個串列中,這樣的串列對除錯時相當有用的,使用all referenced text strings命令會彈出一個視窗,其中列出了程式代碼參考的字串,

地址401007處有一條PUSH 004092A0命令,該命令中參考的004092A0處即是字串“Hello World!”,雙擊字串,游標定位到main()函式中呼叫MessageBox W()函式的代碼處,
在OllyDbg的value視窗,然后按Ctrl+G命令,可以進一步查看位于記憶體4092A0地址處的字串,首先使用滑鼠單擊value視窗,然后按Ctrl+G快捷鍵,打開Enter expression to follow in Dump視窗,(如果你的資料視窗不是這樣的,右鍵單機選擇HEX)

ascii前兩行即使“Hello World!”字串,它是以unicode碼形式表示的,并且字串的后面被填充上了NULL值(記住這塊null值的區域,我們以后還會再講的),
VC++中,static字串會被默認保存為Unicode碼形式,static字串是指在程式內部被硬編碼的字串,
上圖我們還需要注意的是4092A0這個地址,它與我們之前看到的代碼區域地址比如401XXX是不一樣的,在HelloWorld行程中,409XXX地址空間被用來保存程式使用的資料,大家要清楚一點:代碼和資料所在的區域是彼此分開的,
我們后面會慢慢學習代碼和資料在檔案里是怎么保存,以及怎么加載到記憶體的,這些是windows PE檔案格式的相關內容,我們暫時先不管他,
三、API檢索法
3.1在呼叫代碼中設定斷點
右鍵單擊-search for-all intermodular calls
windows 編程中,如果想讓顯示幕顯示內容,則需要使用win32API向OS請求顯示輸出,換句話說,應用程式向顯示幕輸出內容時,需要在程式內部呼叫win32 API,認真觀察一個程式的功能后,我們能夠大致推測出它在運行時呼叫的WIN32 API,則會為程式調式帶來極大便利,以HelloWorld.exe為例,它在運行時會彈出一個訊息視窗,由此我們可以推斷出該程式呼叫了user_32.MessageBox W() API,(敏感詞所以加了下劃線)
在OllyDbg的預分析中,不僅可以分析出程式中使用的字串,還可以摘錄出程式運行時呼叫的API函式串列,如果只想查看程式代碼中呼叫了哪些API函式,可以直接使用all intermodular calls命令,如下圖視窗列出了程式中呼叫的所有API,

可以看到呼叫MessageBox W()的代碼,該函式位于40100E地址處,他是user_32.MessageBox W() API,雙擊它,游標就會定位到呼叫它的地址處(40100E),觀察一個程式的行為特征,若能事先推測出代碼中使用的API,則使用上述方法能夠幫助我們快速查找到需要的部分,
對于程式中呼叫的API,OllyDbg如何準確摘錄出他們的名稱呢?首先,他不是通過查看源代碼來摘取的,如果想要了解其中的原理,我們需要理解PE檔案格式的IAT(Import
Address Table,匯入地址表)結構,我們會在后面的文章中提到這些內容,
3.2在API代碼中設定斷點
滑鼠右鍵選單-search for - name in all calls
OllyDbg并不能為所有可執行檔案都列出API函式呼叫串列,使用壓縮器、保護器工具對可執行檔案進行壓碩訓保護之后,檔案結構就會改變,此時OllyDbg就無法列出API呼叫串列了(甚至連除錯都會變得十分困難),
壓縮器(Run time Packer,運行時壓縮器)
壓縮器是一個實用壓縮工具,能夠壓縮可執行檔案的代碼、資料、資源等,與普通壓縮不同,它壓縮后的檔案本身就是一個可執行檔案,
保護器
保護器不僅具有壓縮功能,還添加了反除錯、反模擬、反轉儲等功能,能夠有效保護行程,如果想仔細分析保護器,我們還需要具有更高級的逆向知識,
這種情況下,DLL代碼庫被加載到行程記憶體后,我們可以直接向DLL代碼庫添加斷點,API是作業系統對用戶應用程式提供的一系列函式,他們實作于C:\Windows\system32檔案夾中的 *.dll檔案(如kernel32.dll、user_32.dll、gdi32.dll、advapi32.dll、ws2_32.dll等)內部,簡單的說,我們撰寫的應用程式執行某種操作時(如各種I/O操作),必須使用OS提供的API向OS提出請求,然后與被呼叫API對應的系統DLL檔案就會被加載到應用程式的行程記憶體,
在OllyDbg選單中選擇 View-Memory選單(Alt+M),打開記憶體映射視窗,如下圖,記憶體映射視窗中顯示了一部分HelloWorld.exe行程記憶體,在圖底部可以看到user_32庫被加載到了記憶體,

使用OllyDbg中的Name in all modules命令可以列出被加載的DLL檔案中提供的所有API,使用Name in all moudules命令打開All names視窗,單機Name欄目按名稱排序,通過鍵盤敲出MessageBox W后,游標會自動定位到MessageBox W上,

USER_32模塊中有一個Export型別的MessageBoxW函式(不同環境下函式地址不同),雙擊MessageBoxW函式后就會顯示其代碼,它實作于USER_32.dll庫中,如圖

觀察MessageBoxW函式的地址空間可以發現,它與HelloWorld.exe使用的地址空間完全不同,在函式起始地址上按F2鍵,設定好斷點后按F9繼續執行,

如果HelloWorld.exe應用程式中呼叫了MessageBoxW() API,則除錯時程式運行到該處就會暫停,
與預測的一樣,程式執行到MessageBoxW代碼的斷點處就停了下來,此時暫存器視窗中的ESP值為19FF18

它是行程堆疊的地址,在右下角的堆疊視窗中可以看到更詳細的資訊

我們會在后面的教程中詳細說明函式呼叫以及站動作原理,現在可以暫時忽略
如上圖,ESP值的12FF18處對應一個回傳地址401014,HelloWorld.exe的main()函式呼叫完MessageBoxW函式后,程式執行流將回傳到該地址處,按Ctrl+F9快捷鍵使程式運行到MessageBoxW函式的RETN命令處,然后按F7鍵也可以回傳到401014地址處,地址401014的上方就是地址40100E,它正是呼叫MessageBoxW函式的地方,

以上是我所掌握的幾種方法,大家還有其他的思路嗎?
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/404059.html
標籤:其他
上一篇:哆啦安全服務介紹
下一篇:“哆啦生活服務商城“上線通知
