流放一文。 對Asprotect v1.1的手動脫殼的一點分析 (9千字)

看雪資料發表於2000-10-27

對Asprotect v1.1的手動脫殼的一點分析

【宣告】
我寫文章以交流為主,希望大家在轉載時能保持文章的完整性。

【前言】
由於r!sc已經寫出了脫殼機rAD.exe,所以寫此文實在沒有多大意思。看此文說實話還不如去看rAD.exe的原始碼更有意義。

樣例檔案:    Asprotect.exe    (Asprotect v1.1的主程式)
加殼方式:    Asprotect v1.1
目標:        手動脫殼
作者:        ljttt
寫作日期:    2000-10-13

1、首先,啟動PEEditor,開啟Asprotect.exe檔案,得到對我們有用的資訊。
Image Base        : 400000
Size of Image    : 9E000

2、Ctrl-D進入SoftICE,下斷點
bpint 3

3、單擊break'n'enter,單擊Run,將中斷在第一條指令處,此時我們按照提示輸入如下指令
eb eip 60
這樣,就修改了入口的程式碼由 CC 改為 60。這樣螢幕顯示如下:
015F:0048F001  60                  PUSHAD                            <--第一條指令處
015F:0048F002  E9D9040000          JMP      0048F4E0
015F:0048F007  2BD4                SUB      EDX,ESP
015F:0048F009  ED                  IN        EAX,DX
015F:0048F00A  AC                  LODSB

4、跟蹤一段,我們可以到達如下地方:
015F:0048F58A  81EE02000000        SUB      ESI,00000002
015F:0048F590  81DB91D657C9        SBB      EBX,C957D691
015F:0048F596  0FBFEB              MOVSX    EBP,BX
015F:0048F599  81FFE6C50868        CMP      EDI,6808C5E6
015F:0048F59F  0F8588FFFFFF        JNZ      0048F52D
015F:0048F5A5  BA4166DFBC          MOV      EDX,BCDF6641
015F:0048F5AA  E928FFFFFF          JMP      0048F4D7                <--此處將跳走
從跟蹤的情況來看,我覺得這裡應該說用到了"花指令"和"變形引擎"兩種技術。原來我設想的"變形引擎"會出現在加殼軟體中,看來現在"如願"了。這也說明加殼軟體在不斷地提高反跟蹤的技術。看來我也得多下苦功了。不然,以後只有用用別人寫的脫殼機的份了。

5、繼續跟蹤到如下一段時:
015F:00C260DD  8BC8                MOV      ECX,EAX
015F:00C260DF  8DBD452A4400        LEA      EDI,[EBP+00442A45]
015F:00C260E5  8BB575294400        MOV      ESI,[EBP+00442975]
015F:00C260EB  F3A4                REPZ MOVSB                        <--此處是SMC技術的運用。將修改後面的程式碼。
015F:00C260ED  8B8575294400        MOV      EAX,[EBP+00442975]        <--這裡的程式碼將被修改
015F:00C260F3  6800800000          PUSH      00008000
015F:00C260F8  6A00                PUSH      00
015F:00C260FA  50                  PUSH      EAX
015F:00C260FB  FF957D294400        CALL      [EBP+0044297D]
015F:00C26101  8D0E                LEA      ECX,[ESI]
015F:00C26103  85512C              TEST      [ECX+2C],EDX
015F:00C26106  44                  INC      ESP
015F:00C26107  07                  POP      ES
015F:00C26108  50                  PUSH      EAX
015F:00C26109  C3                  RET

這是執行REPZ MOVSB指令以後的程式碼
015F:00C260E5  8BB575294400        MOV      ESI,[EBP+00442975]
015F:00C260EB  F3A4                REPZ MOVSB
015F:00C260ED  8B8575294400        MOV      EAX,[EBP+00442975]        <--這是修改後的程式碼
015F:00C260F3  6800800000          PUSH      00008000
015F:00C260F8  6A00                PUSH      00
015F:00C260FA  50                  PUSH      EAX
015F:00C260FB  FF957D294400        CALL      [EBP+0044297D]
015F:00C26101  8D85512C4400        LEA      EAX,[EBP+00442C51]
015F:00C26107  50                  PUSH      EAX
015F:00C26108  C3                  RET

6、繼續跟蹤到如下:
015F:00C265B8  5B                  POP      EBX
015F:00C265B9  0BDB                OR        EBX,EBX
015F:00C265BB  8985112F4400        MOV      [EBP+00442F11],EAX
015F:00C265C1  61                  POPAD
015F:00C265C2  7508                JNZ      00C265CC
015F:00C265C4  B801000000          MOV      EAX,00000001
015F:00C265C9  C20C00              RET      000C
015F:00C265CC  689C0EC200          PUSH      00C20E9C                <--這個00C20E9C的地址也是程式用SMC的方式得到的
015F:00C265D1  C3                  RET                                <--我們將到此處

7、在 RET 指令後將到如下一段程式碼處:
015F:00C20E9C  55                  PUSH      EBP
015F:00C20E9D  8BEC                MOV      EBP,ESP
015F:00C20E9F  83C4F4              ADD      ESP,-0C
015F:00C20EA2  E88922FFFF          CALL      00C13130
015F:00C20EA7  0F855F2FFFFF        JNZ      00C13E0C
015F:00C20EAD  E81634FFFF          CALL      00C142C8
015F:00C20EB2  E8917BFFFF          CALL      00C18A48
015F:00C20EB7  E86489FFFF          CALL      00C19820
015F:00C20EBC  E8BFACFFFF          CALL      00C1BB80
015F:00C20EC1  E8462FFFFF          CALL      00C13E0C                <--在這裡,我們要按F8進入,否則程式將執行完畢
015F:00C20EC6  8BE5                MOV      ESP,EBP
015F:00C20EC8  5D                  POP      EBP
015F:00C20EC9  C20C00              RET      000C

8、在 CALL 00C13E0C 處我們按 F8 鍵進入,此時我們不需要再繼續直線跟蹤下去了。因為如果你看了rAD.exe的原始碼說明就知道,這不過是在DLL中的程式段中,由於DLL的入口函式部分沒有什麼實際意義。所以繼續直線跟蹤下去,只會花費我們大把大把的時間,這是有幾種方法繼續跟蹤,看過rAD.exe的原始碼後,就可以知道我們可以如下方式設斷點。首先搜尋特徵程式碼,然後在特徵程式碼處設斷點繼續跟蹤。

第一種:
s eip l ffffffff 51,89,14,24,8B,F8,B2,01
如果搜尋到的地址為 <Address>,則可以設斷點
bpx <Address>-4

第二種:
s eip l ffffffff 81,C4,04,F0,FF,FF,50,81
如果搜尋到的地址為 <Address>,則可以設斷點
bpx <Address>

第三種:
s eip l ffffffff 55,8B,EC,83,C4,F8,53,56,57,8B,F9,89
如果搜尋到的地址為 <Address>,則可以設斷點
bpx <Address>

我一般設第二種方式的斷點,以後的跟蹤注意一旦出現 RET 指令時,首先檢視一下堆疊中的內容,如果是將跳轉到 FindClose 中時,則向下翻頁找到 RET 語句處設斷點,然後按F5鍵繼續,(不要直接按F7,這樣無效)。直到如下程式碼:
015F:00C205B3  E860CEFFFF          CALL      00C1D418            <--此處可以按F10帶過
015F:00C205B8  E801000000          CALL      00C205BE            <--此處只是一個跳轉指令的作用,必須按F8鍵,否則程式將直接執行
015F:00C205BD  8183C404310424E80100ADD      DWORD PTR [EBX+043104C4],0001E824
015F:00C205C7  0000                ADD      [EAX],AL
015F:00C205C9  6883C4048B          PUSH      8B04C483
015F:00C205CE  051420C200          ADD      EAX,00C22014
015F:00C205D3  E802000000          CALL      00C205DA            <--同理
015F:00C205D8  E86883C404          CALL      05868945            <--同理
015F:00C205DD  010424              ADD      [ESP],EAX
015F:00C205E0  C3                  RET

9、當我們在 RET 指令執行後,(此時將看到兩個CALL呼叫,在第二個處要按F8進入)將離最後的目標不遠了,所以可以小心地按F8繼續。
015F:00C1F845  5D                  POP      EBP
015F:00C1F846  8B65FC              MOV      ESP,[EBP-04]
015F:00C1F849  8B45F8              MOV      EAX,[EBP-08]
015F:00C1F84C  8944241C            MOV      [ESP+1C],EAX
015F:00C1F850  61                  POPAD
015F:00C1F851  50                  PUSH      EAX
015F:00C1F852  6863F8C100          PUSH      00C1F863
015F:00C1F857  687BF8C100          PUSH      00C1F87B
015F:00C1F85C  E8F7FEFFFF          CALL      00C1F758
015F:00C1F861  50                  PUSH      EAX
015F:00C1F862  C3                  RET                            <--此處,我跟蹤的情況,將跳轉到00C1F878處
015F:00C1F863  5B                  POP      EBX
015F:00C1F864  6A10                PUSH      10
015F:00C1F866  E8DDFEFFFF          CALL      00C1F748
015F:00C1F86B  50                  PUSH      EAX
015F:00C1F86C  E8CFFEFFFF          CALL      00C1F740
015F:00C1F871  50                  PUSH      EAX
015F:00C1F872  6A00                PUSH      00
015F:00C1F874  E8D7FEFFFF          CALL      00C1F750
015F:00C1F879  53                  PUSH      EBX
015F:00C1F87A  50                  PUSH      EAX
015F:00C1F87B  C3                  RET                            <--這是我們要跟蹤的最後的一條指令了,Yeah![ESP]=OEP=4574F4。
015F:00C1F87C  90                  NOP
015F:00C1F87D  6845F8C100          PUSH      00C1F845
015F:00C1F882  C3                  RET                            <--此處,將向上跳轉到00C1F845處

10、在 00C1F87B 處我們下指令,儲存記憶體映象
/dump 400000 9E000 c:\temp\dump.exe

11、現在開始修補工作,用 PEEditor 開啟dump.exe檔案,選擇dumpfixer,即修改RS=VS等等。

12、執行我寫的小工具ITOOLS。先選擇"修補檔案頭"和"寫入程式空間"兩項,然後開啟Asprotect.exe檔案,ITOOLS將建立程式,此時直到程式執行出現在工作列中時(最好再等一會兒),單擊確定按鈕,ITOOLS將開始修補PE頭和轉換ThunkData,然後彈出對話方塊警告,此時如果轉換正確,(即沒有出現Error字眼)選擇確定,最後你還需要單擊一下Asprotect程式中的開啟選單一下,如果沒有出現錯誤,則你可以啟動Imp_List進行Import Table的Rebuild工作。此時我們可以得到完整的Import Table檔案Import0.bin。

13、用Hex WorkShop開啟dump.exe和Import0.bin,將Import0.bin中內容替換到dump.exe中的 5F000 處。(這個值可以由Address.txt得知)然後儲存。

14、用 PEEditor 修改Export Table的RVA=0,Size=0,Import Table的RVA=5F000,Size=(大於0即可)。Basereloce的RVA=0,Size=0,Tls Table的RVA=63000(此值也可以不改),Size不變。儲存。

15、執行程式,發現出現錯誤提示在地址C1C4A8,透過查詢dump.exe檔案,可以知道其在5D5BC和5D5A0兩處有此值,看來還有問題,重新執行Asprotect。如果我們前面所設的斷點沒有下 bd * 禁止的話,又一次將依次中斷在這些斷點上,我們下指令
d C1C4A8
可以看到顯示的內容為 408DC3。0K!得到了我們想要的值。回到Windows中,修改其中兩處的值為 408DC3。重新執行,依然出錯。這次地址很奇怪。看了半天,我終於想明白 5D5BC 和 5D5A0 儲存的內容應該是指向內容為 408DC3 的指標。這好辦。我把 5D5BC 和 5D5A0 兩處的值修改為 5D5A4 ,把 5D5A4 的內容修改為 408DC3。再次執行。OK!終於成功。好辛苦。還是rAD.exe好!到底是大師的作品。呵呵!

【後記】
這裡寫得一點新意都沒有。浪費了時間!再也不寫這種沒什麼意思的文章了。僅有的一點作用可能就是在rAD.exe不起作用的時候,而且你有大把大把的時間脫殼的時候............這是什麼邏輯!......:-& (口吐白沫,暈倒在地)

相關文章