在嘗試學習分析的過程中,判斷結論不一定准確,只是一些我自己的思考和探索。敬請批評指正!
1. IDA使用
(1)搜索、下載並執行IDA Pro,對可執行程序lab05-01.dll進行裝載,分別以圖形模式和文本模式查看程序的反匯編結果
-
運行IDA Pro,打開Lab05-01.dll,以圖形化界面顯示:
-
直接定位到DLLMain開始的位置上。用空格鍵可以切換到文本模式查看:
(2)查看程序中的所有函數
程序中的所有函數包括:導入函數、導出函數、在中間過程中使用的函數。
-
我們可以從Import窗口查看導入函數,Export窗口查看導出函數,Function Window查看程序中所有函數:
(3) 查看程序中的所有字符串:
-
打開字符串strings視圖:
-
這里就可以看到所有的字符串:
(4)查看某個函數調用其它函數的情況
-
隨便在左側函數欄找一個函數,雙擊到達這個函數所在位置.text節10011F40:
-
使用圖形化工具查看:
-
Function calls
顯示所有的函數調用; -
Xrefs to
查看哪些函數調用了這個函數: -
Xrefs from
查看這個函數調用了那些函數: -
User Xrefs chart
可以讓用戶選擇顯示內容:- Cross references to:顯示被那些函數調用,相當於Xrefs to
- Cross references from:顯示調用那些函數,相當於Xrefs from
- Recursive:遞歸顯示, 若取消則僅顯示上下直接調用函數
- Follow only current direction:僅當前函數,若取消就變成了顯示全部的函數調用
- Recursion depth:顯示調用的深度
- Externals:是否忽略外部Windows API函數
- Data:是否忽略數據
- From Library Functions:是否忽略庫函數內部的交叉參考
- To Library functions:是否忽略外部的交叉參考
- Print Comment:是否對外部函數打印注釋
-
2. 使用IDA對lab05-01.dll進行分析
(1)DLLMain的地址是?
-
一打開lab05-01.dll程序,自動停到入口地址DLLMain的位置:
-
可以看到DLLMain的地址是在.text節1000D02E的位置
(2)調用了gethostbyname的函數有?
-
打開導入表:
-
通過ALT+T調出查找gethostbyname:
-
然后被定位到:
-
雙擊該項,跳轉到其定位的地址100163CC的位置上:
-
使用IDAPro的交叉引用功能,在上述位置用快捷鍵Ctrl+X打開交叉引用窗口:
-
p是gethostbyname被調用的引用,經過觀察可得,在5個不同的位置調用了gethostbyname。
(3)分析地址為0x10001757處對gethostbyname的調用,確定DNS請求的目標。
-
使用快捷鍵G快速定位到0x10001757:
-
這里是一段匯編代碼,call指令調用gethostbyname:
-
這一段里面,首先在eax中壓入偏移,雙擊off_10019040可以查看:
-
這里可以通過IDA的自動注釋功能看到部分內容,雙擊aThisIsRdoPics查看完整的內容:
- 這里就是這個偏移指向的字符串“[This is RDO]pics.praticalmalwareanalysis.com”。
-
接着,eax加上了0Dh,我們通過hex界面可能看得更直觀,右擊aThisIsRdoPics選擇在新的十六進制視圖打開:
-
光標放在網址最前位置,可以在下方看到相對偏移,除去中括號中內容的網址部分開始位置的偏移就是0Dh:
-
然后將這個指向這個URL的eax壓入棧,調用gethostbyname函數。
(4)字符串“\cmd.exe /c”出現在內存中的什么位置?分析引用“\cmd.exe /c”的代碼所在區域可能完成的作用。
-
在字符串視圖查找字符串“\cmd.exe /c”:
-
雙擊打開:
-
可以看到位置是xdoors_d:10095B34。通過雙擊字符串后面注釋中的上箭頭或Ctrl+C查看交叉引用找到其引用:
-
定位到:
-
匯編學的不好,在這里看匯編代碼也實在是費勁,為了大體判斷這一部分的功能,我采用圖形化界面,直接雙擊藍色無條件跳轉指向線、綠色條件跳轉指向線查看代碼的流程。
-
可以看到一些有用的信息:
call ds:GetCurrentDirectoryA:是一個系統參數,在一個緩沖區中裝載當前目錄。 call ds:GetLocalTime:獲取本地時間。
-
字符串位置:
-
雙擊查看:
-
獲得關鍵信息:“Shell Session”會話
call ds:CreatePipe:創建匿名管道的同時返回兩個句柄:管道讀句柄和管道寫句柄。 call ds:GetStartupInfoA:獲取進程起始信息。 call ds:recv:套接字接收函數 call ds:closesocket:關閉套接字。
-
-
綜合來看,這一部分可能完成的作用是使用套接字的一個遠程會話。
(5)函數sub_10004E79調用了哪些函數?其中的API函數有哪些?根據API函數信息猜測該函數的作用,並嘗試對該函數進行重命名。
-
在左側函數欄查找到sub_10004E79,雙擊查看:
-
使用圖形化工具查看這個函數調用了那些函數:
-
函數sub_10004E79調用了直接調用了四個函數,間接調用了四個函數。
-
API函數有:
GetSystemDefaultLangID:取得系統的默認語言ID Sprintf:把格式化的數據寫入某個字符串中
-
C語言庫函數有:
Send:向一個已經連接的socket發送數據 Strlen:檢測字符串實際長度 Malloc:向系統申請分配指定個字節的內存空間 Free:釋放指向的存儲空間
-
-
猜測這個函數應該是獲取了系統語言並打印出來,可以在左側函數欄右擊函數編輯:
-
重命名函數,方便進一步研究:
-
更改后可以看到函數名都已經被修改了:
(6)在0x10001701處是一個對socket的調用,它的三個參數分別是什么?結合MSDN中socket幫助和IDA中的命名符號常量,你認為這三個參數實際分別是什么?
-
首先到達0x10001701處,看到其三個參數分別為:2,1,6:
-
可以使用hex-ray反匯編C語言偽代碼看得更清楚:
-
在MSDN中查找socket function:
-
可以找到我們需要的參數:
-
AF
-
Type
-
protocol
-
-
Socket函數中的三個參數分別為:
2:AF_INET使用IPv4協議 1:SOCK_STREAM使用流式Socket 6:IPPROTO_TCP使用tcp協議
-
可以右擊更改為對應的名稱方便理解:
-
這個標志實際上是一個枚舉型變量:
-
更改后效果:
4. 實踐小結
-
有同學遇到了這樣一個問題來問我:在Function window中搜索后面某一題中調用的函數沒有找到,在Import中搜索到了,這個Function Window不應該包含這個程序里所有的函數嗎,為什么會找不到一個確實被調用了的函數呢?
-
我看了一下,確實是這樣,打開其它程序,同樣不顯示導入函數:
-
查看Function Window中的標志F,因為標志F表示可能是導入函數,也可能是自己寫的函數,沒有看到有該標志的,可能是因為IDA版本問題或者是本身導入函數就不算在程序中寫的函數?
-
IDA Pro功能實在是太強大了,在這么短的時間內只做到了根據問題粗略的使用,《惡意代碼分析實戰》用了一章的篇幅講這個強大的反匯編器,讀完了之后感覺有很多可拓展的使用方法(有些插件需要付費才能下載,免費版的功能和上面說的不大一樣),還需要一定時間的學習。
-
在做這次實踐的過程中,我一直在想如何在沒有這些問題的提示下使用IDAPro對一個惡意代碼進行高級靜態分析。匯編和反匯編很重要,對程序及工具交互能力的利用也很重要。在接下來的學習過程中需要逐步解決這個問題。