怎麼樣儘可能地分析出一個 dll 文件的有用信息?
本質上來說dll和exe的區別不大,都是可執行文件,只是沒有直接執行的入口,要通過其他進程來調用而已,所以和exe的分析方法是一樣的,動態或者靜態反編譯,有殼脫殼。
題外話:其實Windows下可以用Rundll32.exe直接運行dll的:
Rundll32.exe DLLname,Functionname [Arguments]
比如:
Rundll32.Exe User32.dll LockWorkStation
上面這條命令是調用User32.dll的LockWorkStation函數鎖定桌面
Windows的命令行也是很強大的好不好?
沙盒動態分析行為
基本上和分析可執行文件一樣。有殼先脫殼,常見的殼,可以網上找找看脫殼機,不過很多脫殼機都內嵌病毒,使用的時候要小心。殼不常見,那就只能自己分析,手動脫殼,脫殼簡單的簡單死,麻煩的麻煩死,有時候生不如死,就不展開了。
dll有可能是託管的,那就操起.NET Reflector或ILSpy反編譯一下,幸運的話,代碼就基本出來能看了,不幸運的,代碼是混淆過的,生不如死,容我離開一會。回來發現不懂IL啊,改不動,裝上reflexi插件,改的飛起。這時才想起來,我只是想提取個圖標和圖片而已,找到資源區,導出搞定。
dll是原生的,對了,提取資源的話,ResHack足以。不行,我要破解,我想提取演算法,那就找出江湖流傳已久的免費神器odbg,發現耍不來,找來找去,還是上古神器IDA靠譜,可惜要錢,錢我給的起,奈何老婆不讓給,怒而破解之,!@#$%^,卒~~~。被救醒後,只能退而求其次,弄個已破的老版本耍耍,沒想到中了CryptLocker,積累的代碼,下載的書籍,包括1T的愛情動作片,全部轉化為別人的資產,要求bitcoin贖取,¥¥……¥,悲傷過度,¥¥¥¥,卒~~~。
上段為演繹的真實情節,總之傷心往事太多,樓主引以為鑒。
有了IDA,就好說了,靜態反編譯,看看導出表,查查導入表,瀏覽下字元串表,尋找各種線索。如果是C++編譯的代碼,裝個掃描RTTI的插件,如果編譯時有開RTTI的話,可以找到很多類層次結構信息,慢慢的觀察彙編,找些資料學習編譯鏈接的知識,找出代碼到彙編的常用pattern,反過來從彙編推回代碼,然後從代碼的意圖推測出函數的功用,做好標註,回頭再按自己的思路優化重整代碼,儘管沒辦法完全恢復代碼原樣。遇到沒辦法理解反推的地方,就用頂樓的方法,或自己寫個簡單的exe,LoadLibrary,GetProcAddress動態調試下,當中又會碰到很多奇葩的難題,各種反調試措施呀,等等,想辦法解決或繞過它們。就這樣,日復一日,年復一年,慢慢的,慢慢的,把所有函數都標註出來,當然最後的結果就是~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~,卒。
1、一般我會先看導入表和字元串表,根據這兩個大致可以猜到這個程序的大部分功能比如導入表裡有send、recv、sendto之類的函數,那多半會有網路操作;CreateProcess和CreatePipe、ReadFile、WriteFile同時出現,可能會反彈shell等等,字元串表也是同理。當然這個方法並不準確,完全可以不通過導入表,並且加密字元串來調用各種API,所以一般還要結合下面的步驟一起
2、看導出表
DllMain函數和ServiceMain函數是入口函數,dll被載入時就會自動調用的(ServiceMain是服務的入口函數)其他的導出函數分析完Dll的導出函數基本上就可以確定出一個DLL的功能了,但是同樣可以不通過導出表去調用Dll中的函數,能不能調用一個函數的關鍵在於能不能找到這個函數的地址,導出表的作用就是幫助調用者找到內部函數的地址,所以完全可以自己實現一個方法去找內部函數的地址,比如我在一個函數頭N個位元組設計一個標記,調用時通過找這個標記就可以得到要調用的函數地址。3、動態調試這個就不解釋了你們沒聽說過火眼嘛
- 輸入/輸出表,研究一下函數名、參數、引用的其他dll;
- 寫個loader測試一下,研究返回值;
- API HOOK;
- IDA+OD;
用depends軟體可以看到裡面的函數
推薦閱讀: