脫殼筆記-手工脫FSG壓縮殼

殼:一段保護軟件不被非法修改或反編譯的程序,它會在附加在我們的代碼之前,獲得運行的權利,然後對程序進行修改。實現對軟件的保護與壓縮。

一、進行FSG壓縮後的產生的效果

1、進行FSG壓縮前後的效果圖
FSG
FSG壓縮前爲34KB,壓縮後爲9KB。此時不用懷疑,這兩個程序都能都正常運行。

2、使用PEID查殼
這裏寫圖片描述
這裏寫圖片描述
可以看到,TestFSG使用的是FSG v2.0進行的壓縮

3、使用OD對比查看模塊間的調用(右鍵->查找->所有模塊間的調用)
這裏寫圖片描述
這裏寫圖片描述
進行FSG的壓縮之後,我們看不到模塊之間的調用了

4、使用LoadPE查看TestFSG.exe的輸入表
這裏寫圖片描述
此時輸入表中只有兩個API,它們就是FSG殼運行時所需要使用到的兩個API。
FSG殼通過LoadLibrayA加載原始程序所需要使用的動態鏈接庫,然後通過GetProcAddress獲取原始程序所需要調用的API的地址,將原始的輸入表還原到程序。
根據這樣就實現了加載程序時對輸入表的動態還原,所以我們第3點中看不到模塊間的調用的原因。

既然FSG殼將我們的API進行了“隱藏”,那麼我們要進行的脫殼就是要實現API的還原。

二、手工脫FSG殼

1、使用OD加載TestFSG
這裏寫圖片描述
此時程序先運行的是FSG這個殼的代碼,這段代碼主要用於將原始的代碼、數據進行解壓還原的操作。
解壓完成後,程序就會跑到我們原始的程序上運行。
此時我們就可以將原始程序dump(轉儲)下來,再進行一些修復,就完成了FSG的手動脫殼。

2、使用F8單步運行,如果遇到call直接往下運行,如果遇到往前面運行的jmp語句,直接點擊jmp的下一條語句,按F4(運行到指定位置)往下運行。直到跑到該彙編指令處:
這裏寫圖片描述
jnz語句用於最終判斷FSG殼是否解壓完成。如果沒有解壓完成,就跳轉到004001D4的指令繼續解壓(循環解壓);如果解壓完成,繼續往下執行0040001D1的jmp指令,使得程序跳轉到原始程序的入口點運行。

3、在jmp處下斷點(F2),F9運行到jmp處
這裏寫圖片描述
在jmp處F7(單步步入)執行後,就跳轉到了我們原是程序的入口點
這裏寫圖片描述
此時並不能看到彙編代碼,我們右鍵->分析->分析代碼,此時就能顯示了

4、使用LoadPE進行dump解壓後的內存中的程序(注:如果無法在進程中找到使用OD打開的應用程序,使用管理員權限再運行下LoadPE)
這裏寫圖片描述
右鍵->完整轉存(dump full)
轉存後的可執行文件:dumped.exe
這裏寫圖片描述

雙擊dumped.exe,此時並不能正常運行!
這裏寫圖片描述
這是正常情況,因爲殼通常都會修改IAT(關於IAT的理解)。於是乎,程序雖然經過FSG的解壓,進入到了程序的入口點,但是FSG殼在還原的時候,並沒有完全的還原IAT(導入函數地址表)。
甚至其它的一些殼不會進行還原IAT,它僅僅是實現了一個自己能夠識別的IAT,然後再程序運行的過程中,它自身進行動態的還原。

5、使用ImpREC選擇脫殼的程序查看輸入表函數信息(注:如果沒有找到脫殼程序的話,同樣使用管理員權限運行即可)
這裏寫圖片描述
1)選擇我們的脫殼進程TestFSG.exe(它這裏自動轉換成了小寫testfsg.exe,不用介意)
2)填寫我們OEP(程序入口點)的RVA值。
獲取的方法一:手動計算,前面我們通過OD已經跳轉到了OEP,地址爲0040102D,00400000爲基址,102D爲OEP的RVA值。
獲取的方法二:在OEP指令右鍵->用OllyDump脫殼調試進程->獲取EIP作爲OEP
這裏寫圖片描述
3)點擊“自動查找IAT”,再點擊“獲取輸入表”,此時就能獲取到輸入表的函數信息了
4)點擊“轉儲到文件”轉儲到先前的dumped.exe文件,會新形成一個dumped_.exe文件
這裏寫圖片描述

到此,程序依舊不能運行,因爲ImpREC僅僅幫我們修復了IAT中的一個dll,並沒有完全的還原IAT

6、手動修復導入表(就是輸入表)中的導入函數表信息(IAT Import address table)
1)在ImpREC獲取一個導入函數的RVA值,在OD的內存地址窗口中跳轉到RVA值
這裏寫圖片描述
此時取第一個函數的RVA值:00009000
前面我們知道程序加載到內存中的基址爲:00400000
所以函數在內存中地址爲:00400000+00009000=00409000

2)在內存中”Ctrl+G”跳轉到00409000地址處,再”右鍵->長型->地址”,就可顯示出調用的API名字
這裏寫圖片描述
首先我們得知道:每個Dll的導入函數地址表中根據0字節結尾!因爲它們本身就是一個數組實現的。
而FSG雖然在應用程序加載的時候進行的動態還原,但是它並沒有使得每個導入函數地址表中以0結尾,而我們要做的就是將不以0結尾了,使用二進制0填充

3)往下拉取到一個Dll的導入函數列表(IAT)末尾處
這裏寫圖片描述
使用0填充後效果
這裏寫圖片描述

4)然後將每個Dll的IAT末尾不爲0的,都使用0字節填充,直到到導入表中的最後一個dll的IAT結束(通常爲許多0字節結束的地方爲結束位置,你也可以在結束的位置繼續往下拉取,自行判斷是否爲結束)
這裏寫圖片描述
至此,對IAT的修復已經完成。
記錄最後結束爲止的RVA值:9170
減去起始位置的RVA值,得出IAT的大小:9170-9000=170

5)再使用ImpREC手動填寫IAT的起始RVA(9000),以及IAT的大小170,再進行轉儲dumped.exe就OK了
這裏寫圖片描述
注:如果有顯示無效的的輸入表函數信息,直接右鍵->刪除指針後再轉儲即可

本文難免有所錯誤,如有問題歡迎留言

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章