VB程序的脱壳技巧
自己來解決吧,也許能搞出個自創(chuàng)的方法,叫什么Monster脫殼法。
在這里大家必須了解一引些小知識。
VB程序的啟動方式:每個VB程序通常都會調(diào)用到許多的API,但是其中有一個API是雷
打不動的,這就是我們都知道的ThunRTMain函數(shù)。VB程序在運(yùn)行時,都會首先調(diào)用
ThunRTMain函數(shù),ThunRTMain函數(shù)將會為程序初始化進(jìn)程,并獲取進(jìn)程ID等做一些
初始工作。
棧幀:每個任務(wù)(進(jìn)程)都有一個棧,而在這個進(jìn)程中的每個函數(shù)被調(diào)用時會分別從
這個棧中分出一段區(qū)域并占用它,這段區(qū)域我們稱它為棧幀
函數(shù)調(diào)用:每一個函數(shù)獨(dú)占自己的棧幀空間,當(dāng)前正在運(yùn)行的函數(shù)的棧幀總是在系統(tǒng)
棧的頂端,在程序運(yùn)行時當(dāng)遇到一個call指令,程序會自動跳到這個call指定所指的
的地址去執(zhí)行指令,這時call所指向的地址處的指令的開頭一般是這樣的:
push ebp ; 保存調(diào)用前的棧楨基址到堆棧
mov ebp, esp ; 把當(dāng)前堆棧棧頂當(dāng)做新棧楨基址
其實在做這個動作之前,call指令已經(jīng)做了另一個動作,就是把call指令下面一條指
令的地址作為被調(diào)用函數(shù)的返回地址也一起壓入了棧中,等到程序遇到retn指令時,
首先從棧中彈出返回地址,并跳到返回地址處執(zhí)行指令。
現(xiàn)在,我們首先打開VB,做出一個簡單的測試程序
接著我們再運(yùn)行OD,把剛做出來的測試程序載入到OD中,這時我們就可以看到程序停
在了這里
大家看這里的代碼:
00401128 > $ 68 9C124000 push 0040129C
0040112D . E8 F0FFFFFF call <jmp.&MSVBVM60.#100>
00401132 . 0000 add byte ptr [eax], al
對于一般來說,如果是用VB做的程序,那么它的的入口點(diǎn)基本都是這樣的,我們再來
看看第二句的call,這里的call調(diào)用了一個函數(shù)<jmp.&MSVBVM60.#100>,但是這到
底是個什么樣的函數(shù)呢?我們在OD中按Ctrl+N打開程序的輸入表看看
第一行就是這個MSVBVM60.#100函數(shù),我們選中這一行后按回車,然后代碼就來到了
這里
嘿嘿,原來#100就是ThunRTMain函數(shù)啊。
我們來用OD跟蹤一下程序,因為第二句就是一個call,所以我們要使用F7跟進(jìn)這個
call,這時,我們只需要F7一下就好,現(xiàn)在,我們來注意一下OD堆棧窗口中的數(shù)據(jù)
堆棧窗口中的第一句就是“0012FFBC 00401132 返回到無殼.00401132來自
<jmp.&MSVBVM60.#100>”,這是的00401132是什么呢?從上面的圖2中,我可以發(fā)現(xiàn)
,這就是ThunRTMain函數(shù)的返回地址,但是00401128才是我們程序的入口點(diǎn),從
ThunRTMain函數(shù)的返回地址和程序入口點(diǎn)的關(guān)系,我們可以得出這樣一個公式:
程序入口點(diǎn)=ThunRTMain函數(shù)的返回地址-AH(AH就是十進(jìn)制的10)
根據(jù)上面所得出的結(jié)論,我們現(xiàn)在可以進(jìn)行脫殼了。
實戰(zhàn)篇
現(xiàn)在我們給程序加個ASPack的外殼
把加了殼后的新文件載入OD,接著在OD的命令行窗口中輸入BP ThunRTMain,回車,
給ThunRTMain函數(shù)下個斷點(diǎn)
接著再按F9讓程序在OD中運(yùn)行起來,OD就會被斷在
這時就要發(fā)揮我們明銳的洞察能力了,嘿嘿,現(xiàn)在我們再來看一下OD右下角的堆棧窗
口中的內(nèi)容
我們看第一行,0012FFBC這里的數(shù)據(jù),是00401132,后面的說明是“返回到加
殼.00401132來自加殼.00401122”,這里告訴我們的地址00401132就應(yīng)該是
ThunRTMain函數(shù)的返回地址了,現(xiàn)在我們再回過頭來看看上面的圖2,00401132的確
就是ThunRTMain函數(shù)的返回地址,我們現(xiàn)在想對程序進(jìn)行脫殼,就需要知道程序的入
口點(diǎn),根據(jù)我們上面得出的那個公式我們來計算一下:
程序OEP=00401132-AH
00401132-AH=00401128
最后我們得出的程序的入口點(diǎn)就是00401128,現(xiàn)在我們知道了程序的入口點(diǎn),我們只
要把他DUMP出來就可以了,但是因為現(xiàn)在我們的OD正處于msvbvm60的領(lǐng)空,現(xiàn)在我們
DUMP是不合適的,我們必須先返回到程序的領(lǐng)空,我們在OD中按Alt+F9就可以完成這
一步驟,等OD返回程序的領(lǐng)空后,我們在OD的反匯編窗口中點(diǎn)擊鼠標(biāo)右鍵選擇“Dump?
debugger process”
接著在彈出的窗口中把Modify這一框中的內(nèi)容改為程序的入口點(diǎn)地址
現(xiàn)在我們只要把程序從內(nèi)在中給DUMP出來就可以了,用PEID 來檢測一下我們DUMP 后
的文件
運(yùn)行一下,脫殼成功。
在這里大家必須了解一引些小知識。
VB程序的啟動方式:每個VB程序通常都會調(diào)用到許多的API,但是其中有一個API是雷
打不動的,這就是我們都知道的ThunRTMain函數(shù)。VB程序在運(yùn)行時,都會首先調(diào)用
ThunRTMain函數(shù),ThunRTMain函數(shù)將會為程序初始化進(jìn)程,并獲取進(jìn)程ID等做一些
初始工作。
棧幀:每個任務(wù)(進(jìn)程)都有一個棧,而在這個進(jìn)程中的每個函數(shù)被調(diào)用時會分別從
這個棧中分出一段區(qū)域并占用它,這段區(qū)域我們稱它為棧幀
函數(shù)調(diào)用:每一個函數(shù)獨(dú)占自己的棧幀空間,當(dāng)前正在運(yùn)行的函數(shù)的棧幀總是在系統(tǒng)
棧的頂端,在程序運(yùn)行時當(dāng)遇到一個call指令,程序會自動跳到這個call指定所指的
的地址去執(zhí)行指令,這時call所指向的地址處的指令的開頭一般是這樣的:
push ebp ; 保存調(diào)用前的棧楨基址到堆棧
mov ebp, esp ; 把當(dāng)前堆棧棧頂當(dāng)做新棧楨基址
其實在做這個動作之前,call指令已經(jīng)做了另一個動作,就是把call指令下面一條指
令的地址作為被調(diào)用函數(shù)的返回地址也一起壓入了棧中,等到程序遇到retn指令時,
首先從棧中彈出返回地址,并跳到返回地址處執(zhí)行指令。
現(xiàn)在,我們首先打開VB,做出一個簡單的測試程序
接著我們再運(yùn)行OD,把剛做出來的測試程序載入到OD中,這時我們就可以看到程序停
在了這里
大家看這里的代碼:
00401128 > $ 68 9C124000 push 0040129C
0040112D . E8 F0FFFFFF call <jmp.&MSVBVM60.#100>
00401132 . 0000 add byte ptr [eax], al
對于一般來說,如果是用VB做的程序,那么它的的入口點(diǎn)基本都是這樣的,我們再來
看看第二句的call,這里的call調(diào)用了一個函數(shù)<jmp.&MSVBVM60.#100>,但是這到
底是個什么樣的函數(shù)呢?我們在OD中按Ctrl+N打開程序的輸入表看看
第一行就是這個MSVBVM60.#100函數(shù),我們選中這一行后按回車,然后代碼就來到了
這里
嘿嘿,原來#100就是ThunRTMain函數(shù)啊。
我們來用OD跟蹤一下程序,因為第二句就是一個call,所以我們要使用F7跟進(jìn)這個
call,這時,我們只需要F7一下就好,現(xiàn)在,我們來注意一下OD堆棧窗口中的數(shù)據(jù)
堆棧窗口中的第一句就是“0012FFBC 00401132 返回到無殼.00401132來自
<jmp.&MSVBVM60.#100>”,這是的00401132是什么呢?從上面的圖2中,我可以發(fā)現(xiàn)
,這就是ThunRTMain函數(shù)的返回地址,但是00401128才是我們程序的入口點(diǎn),從
ThunRTMain函數(shù)的返回地址和程序入口點(diǎn)的關(guān)系,我們可以得出這樣一個公式:
程序入口點(diǎn)=ThunRTMain函數(shù)的返回地址-AH(AH就是十進(jìn)制的10)
根據(jù)上面所得出的結(jié)論,我們現(xiàn)在可以進(jìn)行脫殼了。
實戰(zhàn)篇
現(xiàn)在我們給程序加個ASPack的外殼
把加了殼后的新文件載入OD,接著在OD的命令行窗口中輸入BP ThunRTMain,回車,
給ThunRTMain函數(shù)下個斷點(diǎn)
接著再按F9讓程序在OD中運(yùn)行起來,OD就會被斷在
這時就要發(fā)揮我們明銳的洞察能力了,嘿嘿,現(xiàn)在我們再來看一下OD右下角的堆棧窗
口中的內(nèi)容
我們看第一行,0012FFBC這里的數(shù)據(jù),是00401132,后面的說明是“返回到加
殼.00401132來自加殼.00401122”,這里告訴我們的地址00401132就應(yīng)該是
ThunRTMain函數(shù)的返回地址了,現(xiàn)在我們再回過頭來看看上面的圖2,00401132的確
就是ThunRTMain函數(shù)的返回地址,我們現(xiàn)在想對程序進(jìn)行脫殼,就需要知道程序的入
口點(diǎn),根據(jù)我們上面得出的那個公式我們來計算一下:
程序OEP=00401132-AH
00401132-AH=00401128
最后我們得出的程序的入口點(diǎn)就是00401128,現(xiàn)在我們知道了程序的入口點(diǎn),我們只
要把他DUMP出來就可以了,但是因為現(xiàn)在我們的OD正處于msvbvm60的領(lǐng)空,現(xiàn)在我們
DUMP是不合適的,我們必須先返回到程序的領(lǐng)空,我們在OD中按Alt+F9就可以完成這
一步驟,等OD返回程序的領(lǐng)空后,我們在OD的反匯編窗口中點(diǎn)擊鼠標(biāo)右鍵選擇“Dump?
debugger process”
接著在彈出的窗口中把Modify這一框中的內(nèi)容改為程序的入口點(diǎn)地址
現(xiàn)在我們只要把程序從內(nèi)在中給DUMP出來就可以了,用PEID 來檢測一下我們DUMP 后
的文件
運(yùn)行一下,脫殼成功。
總結(jié)
- 上一篇: Windows常见进程大全
- 下一篇: eXtremeComponents文档