OD脚本入门

用一个最最简单的ASPack壳为例子,来进行讲解!

我们先来脱一下这个壳吧:

方法一:

00430001 >60pushad //入口点,F8
00430002E8 03000000 call QQ个性网.0043000A //到这后,用ESP定律,下硬件

访问断点
00430007- E9 EB045D45 jmp 45A004F7
0043000C55push ebp
0043000DC3retn
0043000EE8 01000000 call QQ个性网.00430014
00430013EB 5D jmp short QQ个性网.00430072
00430015BB EDFFFFFF mov ebx,-13
0043001A03DDadd ebx,ebp
0043001C81EB 00000300 sub ebx,30000
0043002283BD 22040000 0>cmp dword ptr ss:[ebp+422],0
00430029899D 22040000 mov dword ptr ss:[ebp+422],ebx
0043002F0F85 65030000 jnz QQ个性网.0043039A
004300358D85 2E040000 lea eax,dword ptr ss:[ebp+42E]

下完硬件断点后,F9运行,来到这

004303B0 /75 08 jnz short QQ个性网.004303BA //来到这。接着F8
004303B2 |B8 01000000 mov eax,1
004303B7 |C2 0C00 retn 0C
004303BA \68 D4124000 push QQ个性网.004012D4; //来到这,接着F8
004303BFC3retn//到这,接着F8
004303C08B85 26040000 mov eax,dword ptr ss:[ebp+426]
004303C68D8D 3B040000 lea ecx,dword ptr ss:[ebp+43B]
004303CC51push ecx
004303CD50push eax
004303CEFF95 490F0000 call dword ptr ss:[ebp+F49]

OK,这就来到OEP了!

004012D468 54474000 push QQ个性网.00404754; 这里就是OEP了!
004012D9E8 F0FFFFFF call QQ个性网.004012CE; jmp 到
004012DE0000add byte ptr ds:[eax],al
004012E00000add byte ptr ds:[eax],al
004012E20000add byte ptr ds:[eax],al
004012E43000xor byte ptr ds:[eax],al
004012E60000add byte ptr ds:[eax],al
004012E848dec eax
004012E90000add byte ptr ds:[eax],al
004012EB0000add byte ptr ds:[eax],al

好的,我们来总结一下吧:

1、单步F8
2、记录ESP的地址
3、在ESP的地址处,下硬件访问断点
4、接着运行
5、删除硬件断点
6、单步走3次
7、就来到OEP了!

有了这个流程,我们就可以开始写脱壳脚本了,可以这么写:
———————————————————————-

———————————–
///////////////////////////////////////////////////////////////////////

///////////////////////////////
/// ASPack 2.12 -> Alexey Solodovnikov脱壳脚本///
/// 2011.4.3 ///
///////////////////////////////////////////////////////////////////////

////////////////////////////////

var addr//定义一个变量addr
sto //单步,也就是F8
mov addr,esp //把此处ESP的地址给变量addr
bphws addr,"r"//下硬件读取断点,也就是硬件访问断点
run//运行,也就是F9
BPHWC addr //取消断点
sto //单步,也就是F8,第1次
sto //单步,也就是F8,第2次
sto //单步,也就是F8,第3次
cmt eip,"这里就是OEP!"//在EIP处,也就是现在OD停留了位置加注释
MSG "感谢使用此脚本,现在可以脱壳了"//加个对话框,给出一些提示信息
ret//结束脚本

———————————————————————-

———————————–

OK,脚本就这么写完了,相信大家都应该明白了吧。下面接着来方法二!

方法二:

由于是ASPack的壳,所以,我们直接来查找关键代码"popad",写就是"61"

004303AF61popad//查找到这里,在这里下断,为了防止检测,直接下硬件断点,

中断后就F8走吧
004303B075 08 jnz short QQ个性网.004303BA//继续F8
004303B2B8 01000000 mov eax,1
004303B7C2 0C00 retn 0C
004303BA68 00000000 push 0   //F8
004303BFC3retn   //F8
004303C08B85 26040000 mov eax,dword ptr ss:[ebp+426]
004303C68D8D 3B040000 lea ecx,dword ptr ss:[ebp+43B]

OK,又来到OEP了!

004012D468 54474000 push QQ个性网.00404754; 这里就是OEP了!
004012D9E8 F0FFFFFF call QQ个性网.004012CE; jmp 到
004012DE0000add byte ptr ds:[eax],al
004012E00000add byte ptr ds:[eax],al
004012E20000add byte ptr ds:[eax],al
004012E43000xor byte ptr ds:[eax],al
004012E60000add byte ptr ds:[eax],al
004012E848dec eax
004012E90000add byte ptr ds:[eax],al
004012EB0000add byte ptr ds:[eax],al

好,我们接着来总结一下:

1、查找16进制数"61",写就是"popad"
2、返回一个查找到的地址
3、在查找到的地方下断点
4、运行
5、取消断点
6、单步4次
7、来到OEP了

有了这个流程,我们又可以来写个简单的脚本了,脚本如下:

———————————————————————-

———————————–
///////////////////////////////////////////////////////////////////////

///////////////////////////////
/// ASPack 2.12 -> Alexey Solodovnikov脱壳脚本 ///
/// by ah伤星///
///www.ccc5.cc///
///http://www.ccc5.cc///
//////
/// 2011.4.3 ///
///////////////////////////////////////////////////////////////////////

///////////////////////////////

findop eip, #61# //查找"61",也就是"popad"
bphws $RESULT, "x" //返回查找到的地址,下硬件执行断点
run //运行
bphwc $RESULT //取消断点
sto//单步,也就是F8,第1次
sto//单步,也就是F8,第2次
sto   //单步,也就是F8,第3次
sto//单步,也就是F8,第4次
cmt eip,"这里就是OEP!"//在EIP处,也就是现在OD停留了位置加注释
MSG "感谢使用此脚本,现在可以脱壳了"//加个对话框,给出一些提示信息
ret   //结束脚本

———————————————————————-

———————————–

OK,用方法二写的脚本同样完成了!

对比一下,显然方法二比方法一效率更高,更为通用点!

对ASPack分析后,相信大家对写脚本已经有个大概的了解了吧!

好,我们接着来分析下FSG2.0的脚本的写法

通过前面的一些跟踪,我们可以找到如下的关键处:

004001C550push eax
004001C6FF53 10 call dword ptr ds:[ebx+10]
004001C995xchg eax,ebp
004001CA8B07mov eax,dword ptr ds:[edi]
004001CC40inc eax
004001CD^ 78 F3 js short qqspirit.004001C2
004001CF75 03 jnz short qqspirit.004001D4
004001D1- FF63 0C jmp dword ptr ds:[ebx+C] //这里,就跳向OEP了!我们F8
004001D450push eax

来到OEP!

0040A86D55push ebp //OEP
0040A86E8BECmov ebp,esp
0040A8706A FF push -1
0040A87268 78794200 push qqspirit.00427978
0040A87768 F4E14000 push qqspirit.0040E1F4
0040A87C64:A1 00000000mov eax,dword ptr fs:[0]
0040A88250push eax
0040A88364:8925 0000000>mov dword ptr fs:[0],esp
0040A88A83EC 58 sub esp,58
0040A88D53push ebx
0040A88E56push esi
0040A88F57push edi
0040A8908965 E8 mov dword ptr ss:[ebp-18],esp
0040A893FF15 10524200 call dword ptr ds:[425210] ; kernel32.GetVersion
0040A89933D2xor edx,edx
0040A89B8AD4mov dl,ah

我们再来总结一下:

1、查找特征码"FF630C"
2、保险起见,下硬件执行断点
3、取消断点
4、单步F8
5、到达OEP

有了上面的总结,又可以来写个简单的脚本了:

———————————————————————-

———————————–
///////////////////////////////////////////////////////////////////////

/////////////////////////
/// FSG 2.0 -> bart/xt查找OEP脚本///
/// by ah伤星 ///
///  www.ccc5.cc ///
///www.ccc5.cc///
//////
/// 2011.4.3///
///////////////////////////////////////////////////////////////////////

/////////////////////////

findop eip, #FF630C#//查找特征码"FF630C"
bphws $RESULT, "x"   //在查找到的地址处,下硬件执行断点
run //运行
bphwc $RESULT //取消断点
sto//单步F8
cmt eip,"这里就是OEP!"//在EIP处,也就是现在OD停留了位置加注释
MSG "感谢使用此脚本,现在可以脱壳了"//加个对话框,给出一些提示信息
ret   //结束脚本

———————————————————————-

———————————–

哈哈,脚本到此就结束了,下面的内容就自己脱壳修复了!

通过上面的讲解,大家也都发现了,其实写脚本并不是想象中的难吧!

大家也可以自己尝试着去写UPX啊,北斗啊等一些常见壳的脚本,来练习练手。
—————————————————————————————————————————————————–