一、工具及殼介紹
- 使用工具:Ollydbg、PEID、ImportREC、LoadPE、010 Editor
- 查看待脫殼程序
- 查看AsPack殼特有的區段信息
- 小結:根據鏈接器版本推斷待脫殼程序應該是VS 2013編寫
二、脫殼
1、ESP定律脫殼
- 使用OD加載程序,發現pushad指令,判斷程序已加殼,這里可以采用ESP定律脫殼
- 單步過pushad處指令后,在esp處下硬件斷點
- 讓程序運行起來,程序中斷的地方即為popad的地方,單步幾次之后,一般就能找到原始OEP
- 單步幾次后發現CALL和JMP組合
- 使用回車進入CALL后發現VS 2013 程序特有的幾個函數,確認到達OEP處
-
查看此時模塊基址(exe的基址)
注意:本次為11000000(每次重啟系統有可能不相同)
-
在原始OEP處dump文件,使用OD插件OllyDump
修改起始地址為基址,入口地址為原始OEP地址並取消重建輸入表選項
- 轉儲文件后,使用導入表修復工具(ImportREC)對導入表進行修復
-
轉儲文件后運行脫殼程序
發現程序無法運行,並且導入表修復沒有問題,那基本可以確定是隨機基址的問題
- 使用010 Editor找到特征(40 81)修改隨即機制的標記位,在運行程序
2、單步跟蹤脫殼
- AsPack加殼之后的OEP處就存在花指令
- 1117007處的代碼第一個字節永遠不會執行的指令,將其填充成nop指令可去除干擾
- 重新加載待脫殼程序,當我們單步跟蹤時,遇到的函數時GetModuleHandleA,而且我們發現參數是kernel32.dll,調用此函數獲取的信息時kernel32.dll的基地址
- 有了kernel32的基地址之后就可以獲取這個模塊的其他任意函數,接下來調用的應該是GetProcAddress
- 繼續單步跟蹤,發現第三個函數調用
- 在這里VirtualAlloc函數的出現,一般與解壓解密代碼有一定的關聯,繼續跟蹤
- 發現又有一個VirtualAlloc函數的調用,繼續跟蹤分析。發現一個函數調用,查看內部調用發現很繁瑣,只能分析一下參數,分析之后發現這個函數大有文章。
- 分析參數發現4個參數與我們想要找的解壓代碼函數很相似,有申請的內存地址,有代碼段的大小(代碼段大小的識別第一看數值大小,第二看調用完之后的情況,由於之前已經分析過,所以代碼段大小非常容易確定),單步不過這個函數,分析緩沖區,發現190000中果然是解壓的代碼
- 這個函數暫時不需要往里面跟蹤,繼續單步往下分析。能夠看到有一段代碼在尋找E8或E9,然后修復E8或E9后面的值,也就是說整個代碼段CALL和JMP都將會被修復
- 觀察修復后的值和未修復的值,發現修復后的值是原先的代碼,而未修復的值是經過轉換的,這個值看起來是為了迎合壓縮算法而進行的轉換,分析到這,不需要在深入進行分析,總結一下,到目前為止我們分析的代碼中最有價值的就是代碼進行了解壓,對代碼進行了修正
- 經過修正代碼的循環,繼續往下跟蹤,可以發現將解壓的代碼拷貝到原始代碼段的代碼。
- 拷貝完之后,申請的內存就沒有用了,所以單步跟蹤發現釋放內存的函數
- 繼續單步跟蹤,發現一個向上的跳轉
- 單步一下這段代碼發現原來是在循環解壓代碼、數據等各區段
- 繼續跟蹤,代碼訪問了重定位的區段,分析之后發現是在重定位代碼
- 其中有一行代碼時清除重定位信息的,正是有了這行代碼,我們脫殼之后,隨機基址才無法支持,所以在脫殼時,應該將這行代碼nop掉。
- 重定位代碼之后,繼續單步跟蹤分析,發現有這樣的一組調用。
- 修復IAT的時候才會有這樣一組操作,繼續往下分析
- 找到了填充IAT的地方,到此為止shell部分的代碼基本上分析的差不多了,我們可以查看一下代碼段及數據段。
- 代碼段已經恢復
- IAT函數調用也都恢復
- 接着繼續跟蹤,最后就是修改各區段的內存屬性,填充原始OEP地址,跳轉到原始OEP
- 最終跳轉到原始OEP處,然后進行dump,修改等操作就可以了
3、基址重定位的修復
- 在單步跟蹤時我們注意到了有重定位相關的代碼,並發現有對重定位表清除的操作
- 我們能識別出內存中重定位表的信息,只要大片以3開頭的word數據,一般都是基址重定位信息,基址的RVA是16000
- 在清除重定位信息的地方下斷點,觀察寄存器的值和寄存器指向的內容
- 可以看出是在清除重定位表中的數據,確定之后可以將其nop掉
- 之后需要分析出基址重定位的總大小,查看內存之后發現最大應該是0xC72
- 總結一下,基址重定位表的RVA是16000,大小是0xC72,將dump出的程序,使用LoadPE對數據目錄表中基址重定位項進行修改
- 完成修改,進行測試運行,程序完美支持隨機基址