//////////////////////////////////////////////////////////////
// arm4.00.0053客户版主程序的从双进程到单进程转换的Script自动运行脚本
// 本脚本完成双进程到单进程的自动转换和代码段自动修复功能
// 测试系统:winxpsp1
// 异常选项中去掉[忽略指定的异常范围],其余全部打勾
// 特别感谢Loveboom王子的帮助,感谢fly的测试。
// by fxyang
// 2005.4.15
//////////////////////////////////////////////////////////////
dbh
var address
gpa "OpenMutexA","kernel32.dll"
bp $RESULT
run
eoe code_1
code_1:
mov address,eip //获取第一次PREFIX LOCK:异常地址
esto
cmp eip,address //自动越过异常
ja begin
esto
//////////////////////////////////////////////////////////
//双进程到单进程的转换
//////////////////////////////////////////////////////////
begin:
exec
PUSHAD
PUSH EDX
push 0
push 0
CALL kernel32.CreateMutexA
POPAD
jmp kernel32.OpenMutexA
ende
//上面的代码就是在Script中运行从双进程到单进程的转换
bc $RESULT
gpa "CreateThread","kernel32.dll"
bp $RESULT
eob tmp1
esto
tmp1:
bc $RESULT
sto
sto
var variant
mov variant,ebp
add variant,18
mov [variant],#04000000#
//修改API参数,让线程挂起来
rtu
sto
sto
mov eax,0
/*
修改下面的跳转,防止程序anti time
00497215 TEST EAX,EAX
00497217 JE SHORT Armadill.00497231
00497219 CALL DWORD PTR DS:[<&KERNEL32.GetTickCou>; kernel32.GetTickCount
0049721F CMP EAX,DWORD PTR SS:[EBP-114]
00497225 JNB SHORT Armadill.00497231
00497227 PUSH 1
00497229 CALL DWORD PTR DS:[<&KERNEL32.Sleep>] ; kernel32.Sleep
0049722F JMP SHORT Armadill.0049720E
*/
//////////////////////////////////////////////////////////////////
//anti OutputDebugStringA 修复
//////////////////////////////////////////////////////////////////
var setc1
gpa "OutputDebugStringA","kernel32.dll"
mov address,0
mov setc1,$RESULT
bp setc1
eob setcode1
run
setcode1:
inc address
mov [eax],#00000000#
cmp address,2
je setcode2
run
setcode2:
rtu
gpa "GetVersion","kernel32.dll"
bp $RESULT
eob tmp2
run
tmp2:
bc $RESULT
rtu
gpa "GetPrivateProfileStringA","kernel32.dll"
bp $RESULT
eob tmp3
run
tmp3:
bc $RESULT
rtu
gpa "sprintf","msvcrt.dll"
bp $RESULT
eob tmp4
run
tmp4:
rtu
bc $RESULT
rtr
sto
gpa "memset","msvcrt.dll"
bp $RESULT
eob lbl1
esto
lbl1:
rtu
rtr
sto
mov address,0
gpa "RtlLeaveCriticalSection","ntdll"
bp $RESULT
eob lbl7
run
lbl7:
inc address
cmp address,2
je lbl8
run
lbl8:
bc $RESULT
mov address,0
gpa "memset","msvcrt.dll"
bp $RESULT
eob lbl2
run
lbl2:
bc $RESULT
rtu
mov address,eip
add address,2af
bp address
eob lbl9
run
lbl9:
bc address
mov eax,0 // <--anti 1
///////////////////////////////////////////////////////////
//上面一段都是为了定位到代码解码前的双进程效验
/*
00EF7B7A MOV EAX,DWORD PTR DS:[F123D0]
00EF7B7F MOV AL,BYTE PTR DS:[EAX+3D57]
00EF7B85 MOV BYTE PTR SS:[EBP+FFFF9CCC],AL
00EF7B8B MOVZX EAX,BYTE PTR SS:[EBP+FFFF9CCC]
00EF7B92 TEST EAX,EAX //修改这个值为0
00EF7B94 JE 00EF7CB4 //这里必须跳
*/
///////////////////////////////////////////////////////////
gpa "VirtualProtect","kernel32.dll"
var x
mov x,$RESULT
bp x
eob ll1
run
ll1:
rtu
sto
gpa "memcpy","msvcrt"
bp $RESULT
eob code1
run
code1:
rtu
mov [0044bd00],#609C8B5C243081C3001040008D5BFC8B1331108D40043D00BC44007CF4909D61C3#
sub esp,4
mov [esp],eip
mov eip,0044bd00
eob exitc
run
/////////////////////////////////////////////////////////////////////////
//上面这段是修复代码段解码后由于双进程转换到单进程后父进程未参与解码,
//引起代码段未正确还原
//第一次的VirtualProtect函数正好修改了代码段的属性为可写,是修复的好机会
//到这里代码段的还原工作完成:)
/////////////////////////////////////////////////////////////////////////
exitc:
bc x
rtu
msg "代码段已正确还原,下面是IAT还原,到达OEP地址。请努力!"
pause
脚本中的标签是调试时随便起的,可能不规范,不想修改了请见谅。
本脚本很容易修改成arm4.0版的其他加壳程序的脱壳辅助
[课程]Android-CTF解题方法汇总!