較完善的舊版Acprotect1.0x-1.2x脫殼指令碼

看雪資料發表於2004-12-20

歷時7小時寫成,要相容各版本Ac,語言,處理方法,哎,累。

環境,Win2k/xp,UnkillOD,Flyod1.10,指令碼器0.92,忽略除記憶體異常外的全部異常.

// Acprotect OEP or FOEP and Patch IAT  v0.3
// 作者: Mr.David
// 主頁: www.chinadfcg.com

msg "請設定OD異常設定不忽略記憶體異常,其它全部忽略,然後從選單處繼續執行指令碼"

pause

dbh  //隱藏偵錯程式

var cbase

gmi eip, CODEBASE
mov cbase, $RESULT    
log cbase            //記錄程式碼段基地址,一般是401000

var k
var imgbase

gmi eip,MODULEBASE      //模組基地址400000
mov imgbase,$RESULT
mov k,imgbase
add k,3C               //40003C
mov k,[k]
add k,imgbase         
add k,f8              //第一區段名
log k
add k,8              //地址加8位元組的偏移就是區段大小      
mov k,[k]           //401000處第一區段大小
log k        

var addr1           //通用臨時變數

var addr2
mov addr2,ebp      //儲存ebp=12fff0判斷後面是否到達OEP 或 FOEP

var addr3
sub ebp,30        //實際取ebp=12ffc0判斷後面是否到達OEP 或 FOEP
mov addr3,ebp
add ebp,30      //修改了暫存器值得還原

var addr6      //Replace Code判斷變數

Msg "請耐心等候IAT處理"

gpa "GlobalAlloc","kernel32.dll"
mov addr1,$RESULT                    //捷徑 API斷點GlobalAlloc
bp addr1
run
bc addr1    //Clear break point  //取消斷點

gpa "GetProcAddress","kernel32.dll"
mov addr1,$RESULT                  //AC敏感捷徑 API斷點GetProcAddress
add addr1,5                       //GetProcAddress+5
bp addr1     

eoe end2      //Acprotect1.10 Build123之C語言篇的IAT處理在INT1中斷前面,設定INT1陷阱             
esto

loop:                      //迴圈標記

Bc addr1
rtu                      //Alt+F9
cmp eip,70000000       //判斷是否在系統領空

ja loop              //地址大於70000000則迴圈

find eip,#0BC0#     //查詢特徵指令 or eax,eax 以定位處理MessageBoxA的位置
                   //有些版本這裡返回後還要bp GetProcAddress+5 中斷一次後返回才處理IAT,如記事本                                                   
                
            
cmp eip,$RESULT  //如果當前返回指令是 or eax,eax 則需要繼續中斷處理

je BGPA  //跳到標籤BGPA即是 Bp GetProcAddress 縮寫

Back1:  //返回或正常流程

find eip,#750A#    //特徵指令  
mov addr1,$RESULT 
repl addr1, #750A#, #EB??#,10      //有病治病,無病強身,處理MessageBoxA

find eip,#7F??#    //特徵指令     //jg xxxxx 不確定調轉路徑用7F??,處理IAT
mov addr1,$RESULT 
repl addr1, #7F??#, #EB??#,10     //有病治病,無病強身  //這裡結束處理IAT 是否加密


//下面開始分界,有些Acprotect有Replace Code,有些沒有,給指令碼編寫加大難度,這裡處理方法不同。

cmp addr6,1  //如果確認沒有Replace Code,則直接跳到取OEP位置程式碼處
je label69

gpa "GlobalAlloc","kernel32.dll"
mov addr1,$RESULT                    //如果要尋找Replace Code處理位置就得繼續下捷徑 API斷點GlobalAlloc
bp addr1

eoe end
run  //INT1陷阱,異常則去end處理

bpmc //記憶體不中斷執行這裡則清除記憶體斷點。
bc addr1  //清除GlobalAlloc斷點。
rtu

label32: //這裡我們尋找Replace Code位置。

find eip,#8BF8#    //如果當前返回點程式碼就是mov edi,eax,則可確認就是Replace Code位置,否則迴圈。
cmp eip,$RESULT 
je label77       //如果發現mov edi,eax則跳出迴圈。

label66:
gpa "GlobalAlloc","kernel32.dll"
mov addr1,$RESULT                    //捷徑 API斷點GlobalAlloc
bp addr1
run
rtu
jmp label32

label77:

bc addr1

Msg "IAT已經修復,想狸貓換太子嗎?請修改資訊框處EAX值,處理完從選單處繼續執行!"
pause

label69:

bprm cbase, k //然後就是跳OEP或FOEP了,記憶體映象斷點

esto //Shift+F9


label444:  //這裡我用一個條件判斷OEP OR FOEP,有些AC殼到OEP或FOEP時候EBP一般是12fff0,或是12ffc0,401000處中斷一般都是OEP。

cmp eip,401000           //彙編比較常用

je label333

cmp ebp,addr2         //12fff0一般沒有抽程式碼 

je label333

cmp ebp,addr3       //12ffc0,抽程式碼常見

je label333

cmp ebp,12fff2    //12fff2,VB類

je label333

var addr4

add addr4,1

cmp addr4,70   //定義迴圈上限,如果Code段執行70行程式碼仍然無法發現OEP則認為死迴圈。

ja Sorry

esto

jmp label444  //迴圈直到條件成立,當然有些AC版本會跑飛。
   
label333:
        
Msg "IAT已經修復,FOEP請補上被盜位元組"
cmt eip,"OEP Or Next Shell To Get,Please dumped it,Enjoy!"
bpmc
ret


BGPA:  //繼續GetProcAddress+5中斷

gpa "GetProcAddress","kernel32.dll"
mov addr1,$RESULT                    //捷徑 API斷點GetProcAddress+5
add addr1,5
bp addr1
run

bc addr1
rtu

jmp Back1


end:      //INT1

coe
bprm 401000, k //記憶體映象斷點     //意外情況,沒有Replace Code的程式,這時要跳FOEP了,得攔住
bc addr1 //清除GlobalAlloc斷點

jmp label444


Sorry:

Msg "估計指令碼陷入死迴圈,提前結束。"
ret

end2:   //INT1

coe
mov addr6,1 //如果INT1在IAT處理以前,這些版本的AC一般沒有Replace Code,賦標記1讓他直接去記憶體映象斷點處。
esto

jmp loop

相關文章