脫殼----對用Petite2.2加殼的程式進行手動脫殼的一點分析
(以後如未特別說明,這裡所說的脫殼均是指對用Petite2.2加殼的程式而言)
前言:這幾天一直在對Petite2.2做試驗。總結一下這幾天的一點經驗,希望對大家對Petite2.2加殼的程式進行手動脫殼時有一點幫助。一般按照以下方法可以簡化跟蹤的過程,也節省一點大家手動脫殼的時間。(當然大家如果手頭上有對此的自動脫殼的工具的話,就不在此列了。可惜現在我手頭上還沒有。也沒有編寫這類脫殼程式的經驗,不知道如何下手。希望以後我能對此知其一二
:-) )這裡能簡化的一點步驟就是不需要重建import table,(以下可以看到原因)。看到r!sc的文章對Petite.exe(注意是加殼程式本身)脫殼時,需要自己構造一個import
table(我沒有構造import table的經驗,想來這是一件很花工夫的事情),這很讓人以為Petite加殼的程式也需要這樣做。實際上情況比想象的好
:-)。這也是我寫篇文章的動機所在。
以下用Petite2.2加殼Notepad.exe(M$自帶的記事本程式)來說明一下。
目標檔案: Notepad.exe (用Level 4級壓縮方式加殼)
加殼方式: Petite 2.2
所用工具: SoftICE v4.0, ProcDump v1.6.2, ICEDump v6.0.15
作者: ljttt
1、首先,當然少不了用ProcDump來分析一下對我們有用的檔案資訊。
Entry Point: 0000D042
Size of image: 0000E000
Image Base: 00400000
2、用SoftICE的Loader載入加殼程式。
3、設斷點
bpx loadlibrarya do "dd esp->4"
4、F5執行程式,將中斷在我們所設斷點上。觀察資料視窗。可以看到將要被程式載入的的動態連結庫的名字字串。如下:
0030:00400800 4C454853 2E32334C 006C6C64 4E52454B
SHELL32.dll.KERN
0030:00400810 32334C45 6C6C642E 45535500 2E323352
EL32.dll.USER32.
0030:00400820 006C6C64 33494447 6C642E32 6F63006C
dll.GDI32.dll.co
0030:00400830 676C646D 642E3233 41006C6C 50415644
mdlg32.dll.ADVAP
0030:00400840 2E323349 006C6C64 00000000 00000000
I32.dll.........
0030:00400850 00000000 00000000 00000000 00000000
................
但是這裡不是image_import_descriptors的部分。大多數時候我們看到的記憶體地址為400800,(這是在PE頭的空間內),從我跟蹤的幾個程式的情況分析,還原始碼總是把要載入的連結庫名字複製到此,而沒有破壞真正的image_import_descriptors,因此我們要找到真正的import
table的入口地址。
5、下指令。向後搜尋字串
s 30:400850 l ffffffff 'SHELL32.dll'
搜尋結果如下:
Pattern found at 0030:0040D382 (0000CB32)
6、下指令。搜尋import table部分
s 30:400000 l ffffffff 82,D3,00,00
搜尋結果如下:
Pattern found at 0030:0040D234 (0000D234)
7、我們來看看真正的import table的入口,下指令
dd 40d234-c
顯示如下:
0030:0040D228 00000000 356C813B 7FCE0000 0000D382
....;.l5.......
0030:0040D238 0000D2D4 00000000 355A749D BFF70000
.........tZ5....
0030:0040D248 0000D38E 0000D2C0 00000000 356C8139
............9.l5
0030:0040D258 BFF50000 0000D39B 0000D2B4 00000000
................
我們要記在其RVA=40D228-400000=0000D228。大小嘛,向下找到大量00位元組的地方。計算1B4=0040D3DC-0040D228。
(我想大一點也無所謂吧)
8、好了import table的問題結解決了。再來看看找Entry Point的問題。按F12鍵回到Notepad.exe領空。(如果你剛才中斷在Loadlibrarya領空時,沒有按F12的話)顯示如下:(需要把游標向上移動幾行才能看到我這樣的顯示結果)
015F:0040596C BE00600000 MOV
ESI,00006000
015F:00405971 03F5
ADD ESI,EBP
015F:00405973 8D8D00080000 LEA
ECX,[EBP+00000800]
015F:00405979 8BD8
MOV EBX,EAX
015F:0040597B 833E00 CMP
DWORD PTR [ESI],00
015F:0040597E 0F840E020000 JZ
00405B92 <---注意了,下一段是迴圈。這裡才是跳出大迴圈的地方
015F:00405984 51
PUSH ECX
015F:00405985 51
PUSH ECX
015F:00405986 FF9590070000 CALL
[EBP+00000790]
015F:0040598C 85C0
TEST EAX,EAX <---按F12後,你回到的就是這個地方
015F:0040598E 0F84DF000000 JZ
00405A73
015F:00405994 8BF8
MOV EDI,EAX
015F:00405996 03403C ADD
EAX,[EAX+3C]
015F:00405999 8B4078 MOV
EAX,[EAX+78]
015F:0040599C FF743818 PUSH
DWORD PTR [EDI+EAX+18]
015F:004059A0 8B4C3824 MOV
ECX,[EDI+EAX+24]
9、對於大迴圈,我們可以直接跳出,下指令
bd *
bpx 405B92
10、按F5鍵,中斷在此:
015F:00405B92 59
POP ECX <--你停在此處
015F:00405B93 5E
POP ESI
015F:00405B94 FD
STD
015F:00405B95 33C0
XOR EAX,EAX
015F:00405B97 B956030000 MOV
ECX,00000356
015F:00405B9C E898740000 CALL
0040D039 <--小心了,按F8鍵進入
11、按F8鍵進入Call 0040D039,就到了程式的入口處了。如下:
015F:0040D039 5F
POP EDI
015F:0040D03A F3AA
REPZ STOSB
015F:0040D03C 61
POPAD
015F:0040D03D 669D
POPF
015F:0040D03F 83C408 ADD
ESP,08
015F:0040D042 E98540FFFF JMP
004010CC <--這就是真正程式的Entry Point了
12、在JMP 004010CC處,儲存記憶體的映象的時候到了。下指令
Pagein d 400000 e000 c:\temp\dump.exe
13、開始修補dump.exe。用ProcDump把每個Section的Offset改成RVA大小。把PSize改成VSize大小。
把Entry Point改成000010CC (即004010CC-00400000=10CC)。把Directory中的Import Table的RVA改成D228,Size改成1B4即可。
後記:(現在我怎麼這麼多廢話)
從步驟8-13可以發現。Petite2.2加殼的程式一般從Loadlibrarya中斷回來就快到真正程式的Entry Point了。一般在迴圈退出後的一個Call呼叫內就可以看到Entry
Point了。(該迴圈應該是載入動態連結庫的各個函式吧) 而真正的import table一般在LoadLibrarya中斷後用搜尋的方法可以找到。
俺現在還沒能寫出ProcDump的Script :-( 。只好Post此文濫芋充數了。不過還好,寫此文只花俺1個多小時。寫文章看來同樣也是熟能生巧的哦。:-)
好了,寫Script的歷史暫時告一段落。對於寫ProcDump中的Bhrama Client不是一日之功,以後有時間再學習學習。
或者哪位高手寫個教學,我再學習後再說,那樣可以省不少摸索的功夫了。呵呵....