對PECompact加殼的DLL脫殼的一點分析 (7千字)

看雪資料發表於2000-08-17

對PECompact加殼的DLL脫殼的一點分析

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

【前言】
目前,我對DLL的脫殼的瞭解也不多,相信有些地方會和對EXE的脫殼大致相同。現在我知道的主要不同是必須要在DLL的空間開始跟蹤。否則從EXE開始跟蹤,那還不把人累死。另外 ProcDump 和 PEditor 之類的工具好象還無法自動修復DLL的import table。唉,又是手動,什麼時候有個DLL的脫殼機出現呢? ou,別看我!我程式設計的水平三流,寫不出那些好東東。

樣例檔案:    dlcsp32.dll    (DynaDoc Reader v3.01所帶動態連結庫檔案,這個程式就是看.wdl電子圖書檔案的那個)
加殼方式:    PECompact v1.41b1加殼
檢測工具:    和尚頭上的蝨子-----明擺著的嘛
除錯工具:    SoftICE v4.05,PEditor v1.5,Hex WorkShop 2.10
目標:        脫殼
作者:        ljttt
寫作日期:    2000-08-16

1、首先當然要分析基本資訊了。用PEditor開啟動態連結庫檔案,得到如下資訊
Entry Point:    00024000
Image Base:    10000000
Size of Image:    00029000

Section        Virtual Size    Virtual Offset
pec1        00020000    00001000
pec2        00003000    00021000
.pec        00004000    00024000
.rsrc        00001000    00028000

再來看看import table和export table的情況,export table沒有改變。問我怎麼知道?有未加殼的DLL嘛。西西。

2、現在我們要想辦法在動態連結庫的入口點 10024000 處中斷,當然方法很多了,這裡介紹兩種辦法。

①、第一種方法
一、首先,用PEditor開啟DLL檔案,然後單擊 FLC 按鈕(這個功能是幫你計算Virtual Address轉換為 Offset的)
輸入 10024000 ,單擊 DO! 按鈕,得到 Offset[hex] 為 B000。
二、然後,用Hex WorkShop開啟DLL檔案,定位到 B000,記下此處位元組的值 EB。
三、然後,用PEditor開啟Dlview32.EXE(主程式檔案)。單擊 break'n enter 按鈕(這個功能是幫你在程式的某個地址空間設下int 3中斷),在 Virtual Address 中輸入 10024000。
四、Ctrl-D中斷進入SoftICE,設斷點 bpint 3。
五、F5回到Windows,單擊break'n enter視窗中 RUN 按鈕。這樣我們將在動態連結庫的第一條指令處中斷。

②、第二種方法
一、同第一種方法
二、同第一種方法
三、然後,用Hex WorkShop把 B000 處的位元組 EB 改為 CC。
四、同第一種方法
五、執行程式。這樣我們也可以在動態連結庫的第一條指令處中斷。

這裡,我用第一種方法。我們現在中斷在第一條指令處。但是還不能繼續跟蹤。要把 CC (即int 3指令)改為原來程式的程式碼。

(簡稱說明: EP: Entry Point,    OEP: Orginal Entry Point,    RVA: Relative Virtual Address )

程式碼視窗顯示如下:
015F:10024000  CC                  INT      3            <---中斷在此,這就是我們要改回的位元組
015F:10024001  06                  PUSH      ES
015F:10024002  6810DE0000          PUSH      0000DE10        <---有點奇怪哦? DE10 不是我們要找的 OEP 嗎 ,怎麼在這裡就出現了?難道不用找了?
015F:10024007  C3                  RET
015F:10024008  9C                  PUSHFD
015F:10024009  60                  PUSHAD
015F:1002400A  E802000000          CALL      10024011
015F:1002400F  33C0                XOR      EAX,EAX
015F:10024011  8BC4                MOV      EAX,ESP
015F:10024013  83C004              ADD      EAX,04

下指令
eb eip EB        (修改當然 IP 所在地址的位元組為 EB)

好,程式碼顯示成原來的模樣了。
015F:10024000  EB06                JMP      10024008        <---程式碼復原後
015F:10024002  6810DE0000          PUSH      0000DE10        <---奇怪?
015F:10024007  C3                  RET
==> 10024008  9C                  PUSHFD
015F:10024009  60                  PUSHAD
015F:1002400A  E802000000          CALL      10024011
015F:1002400F  33C0                XOR      EAX,EAX
015F:10024011  8BC4                MOV      EAX,ESP
015F:10024013  83C004              ADD      EAX,04

3、這樣程式碼就復原了。不過你發現一點問題沒有? DLL的 OEP 怎麼會在這裡就出現了? 好奇怪?!先不管它,設個斷點留著看看。設斷點
bpx 10024002

4、設斷點
bpx loadlibrarya do "dd esp->4"        (老一套了)

5、按 F5 繼續,又中斷在我們新設的斷點。我們來看一下資料視窗

顯示如下:
015F:1002041A 4E52454B  32334C45  6C6C642E  00000000      KERNEL32.dll....
015F:1002042A 656C6552  44657361  00000043  44746547      ReleaseDC...GetD
015F:1002043A 53550043  32335245  6C6C642E  00000000      C.USER32.dll....
015F:1002044A 656C6544  624F6574  7463656A  00000000      DeleteObject....

哦,這裡看來就是我們要找的import table的一部分了。

6、繼續搜尋,下指令
s 30:10000000 l ffffffff 1A,04,02,00    (這裡就不多說了,和《脫殼----對用Petite2.2加殼的程式進行手動脫殼的一點分析》一文中所說的情況相同,所以搜尋方法也一樣了。以後幾步同理)
搜尋結果顯示如下:
Pattern found at 0030:1002000C (0002000C)   

7、下指令
dd 1002000C-C

資料視窗顯示如下:
0030:10020000 000200DC  00000000  00000000  0002041A      ................
0030:10020010 00020270  000201D8  00000000  00000000      p...............
0030:10020020 0002043C  0002036C  00020050  00000000      <...l...P.......

8、這樣到了import table的起始處了。現在開始儲存import table。
/dump 10020000 1000 c:\temp\dump.bin    (1000 的長度是根據 00 位元組的位置來確定的)

9、下指令 BD 2 禁止 bpx loadlibrarya 中斷,繼續跟蹤。到如下

015F:10025335  51                  PUSH      ECX
015F:10025336  53                  PUSH      EBX
015F:10025337  6A00                PUSH      00
015F:10025339  FFD0                CALL      EAX
015F:1002533B  FFA55E854000        JMP      [EBP+0040855E]
015F:10025341  8BB54E854000        MOV      ESI,[EBP+0040854E]
015F:10025347  8BBD52854000        MOV      EDI,[EBP+00408552]
015F:1002534D  E82E0C0000          CALL      10025F80
015F:10025352  61                  POPAD
015F:10025353  9D                  POPFD
015F:10025354  50                  PUSH      EAX
015F:10025355  6810DE0010          PUSH      1000DE10            <--- 1000DE10 - 10000000 = DE10 就是 OEP 了
015F:1002535A  C20400              RET      0004            <--- 這裡就要到回到真正的入口處了,在此停下。儲存映象

10、記下 OEP 為 DE10。下指令儲存整個DLL記憶體映象。
/dump 10000000 29000 c:\temp\dump.dll

11、按 F5 繼續,沒有中斷在我們在步驟 3 處設下中斷。關閉主程式時,中斷。正好在此處中斷。
顯示如下:
015F:10024000  EB06                JMP      10024008
015F:10024002  6810DE0000          PUSH      1000DE10        <---開始中斷時的 0000DE10 這時已經變成 1000DE10 了。
015F:10024007  C3                  RET
==> 10024008  9C                  PUSHFD
015F:10024009  60                  PUSHAD
015F:1002400A  E802000000          CALL      10024011
015F:1002400F  33C0                XOR      EAX,EAX
015F:10024011  8BC4                MOV      EAX,ESP
015F:10024013  83C004              ADD      EAX,04

看來此處的幾條指令的用處PECompact是別有用意安排的,可能是為了方便去解除安裝動態連結庫吧。

12、開始修補工作。用PEditor開啟dump.dll檔案,選擇sections,右鍵開啟選單,選擇dumpfixer。OK!一次完成所有Section的RVA、Size的轉換工作。再修改Entry Point為 DE10,單擊apply changes儲存,選擇directory,修改其中的Import Table的RVA為 20000,Size為1000。單擊儲存。

13、用Hex WorkShop開啟dump.dll和dump.bin,定位dump.dll位置到 20000,選擇 1000 個位元組。刪除。
選擇dump.bin的 1000 個位元組,複製到dump.dll中。儲存。

14、測試。OK,收工。

【後記】
本來我想用UPX加殼DLL來實驗的。當然是想先找個"軟柿子"捏。沒想到,發現它加殼的DLL在import table做了手腳。這些天我正窩火,還有一個Asprotect加殼的Awave Audio v7.0的import table始終還原不出來。想不到又碰上這種問題,讓我頭暈眼花了好一陣子,(現在我看見import table的問題就有這毛病......烙下病根了)於是我一腳把UPX踢開,改為分析PECompact加殼DLL來實驗,西西,這回簡單。怎麼樣,我寫的東東價錢公道,水分又足,咬一口新鮮水靈,大家快來買呀...........不好,打假別動隊來了,趕緊溜 .......

相關文章