歷時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