吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 16689|回复: 28
收起左侧

[原创] 详解OD脚本的写法续之进阶篇

  [复制链接]
ximo 发表于 2008-7-26 13:38
昨天给大家写了简单壳的脚本的写法,相信大家对一些简单壳都已经学会自己去写脚本了,至少已经能看懂脚本了吧。
好,今天就继续给大家讲稍微难点的壳的脚本的写法,希望大家能好好掌握。前提是,你已经看了昨天的基础篇,并已经学会写一些简单的脚本。

废话不多说,开始今天的内容。

首先来个稍微简单点的壳的脚本的写法:MoleBox 2.x的壳

当然,我们首先还是来手脱一下这个壳。所以说,写脚本的前提是你已经学会了手脱这个壳,并且掌握了这个壳的一些脱壳的规律。

00596BD3 >E8 00000000 call Notepad.00596BD8//载入到这,F8,2次
00596BD860pushad
00596BD9E8 4F000000 call Notepad.00596C2D//2次后来到这,在ESP处下硬件访问断点
00596BDE0D 76CC70B0 or eax,B070CC76
00596BE3^ EB 81 jmp short Notepad.00596B66
00596BE56Fouts dx,dword ptr es:[edi]
00596BE637aaa
00596BE704 57 add al,57

先不要着急着运行,由于我们知道这个壳对IAT有加密,所以,我们再去OEP之前,首先得处理下IAT。
于是我们下断点:bp VirtualProtect,SHIFT+F9,中断后,取消断点,并ALT+F9返回
然后我们查找 89 01
然后把它NOP掉
因为我们知道,只要NOP掉这一句后,即可跳过壳对IAT的加密。
PS:具体的请参看脱这壳的相关文章,这里不再赘述!

处理完后,我们就F9运行

005967B158pop eax//来到这,F8走
005967B258pop eax
005967B3FFD0call eax //走到这里后,F7进去,就来到了OEP!
005967B5E8 F5CB0000 call Notepad.005A33AF
005967BACCint3
005967BBCCint3


004A2ADCE8 B6A40000 call Notepad.004ACF97 //OEP!
004A2AE1^ E9 16FEFFFF jmp Notepad.004A28FC
004A2AE6CCint3
004A2AE7CCint3
004A2AE8CCint3
004A2AE9CCint3
004A2AEACCint3
004A2AEBCCint3
004A2AECCCint3
004A2AEDCCint3
004A2AEECCint3
004A2AEFCCint3

根据上面的流程,我们就可以开始写脱壳的脚本了!

---------------------------------------------------------------------------------------------------------
////////////////////////////////////////////////////////////
/// MoleBox v2.X 脱壳脚本///
/// by 徐超(ximo) QQ:178911980 ///
/// http://www.54soft.com.cn ///
///http://www.52pojie.net ///
//////
/// 2008.7.26///
////////////////////////////////////////////////////////////

var addr //定义一个变量,用来放ESP的值
sto
sto//单步2次
mov addr,esp //把ESP的值,放变量addr中
bphws addr,"r" //下硬件访问断点

/*接着来处理IAT*/

gpa "VirtualProtect","kernel32.dll"//查找特征API,并把查找到的地址放RESULT中
bp $RESULT //对找到的地址处,下F2断点,也就是BP
run//运行
bc $RESULT //取消断点
rtu//ALT+F9返回


/*返回后,找特征加密语句,处理IAT的加密*/

find eip,#8901#//查找特征加密语句
bp $RESULT //对返回的地址处F2下断
run//运行到该处
bc $RESULT //取消断点
repl eip, #8901#, #9090#, 10 //把加密语句NOP掉,即替换为9090

/*下面就去OEP了*/

run//由于刚才已经下好了硬件断点,现在只要运行即可
bphwc addr //取消断点
sto
sto//单步走2次
sti//F7跟进,就来到了OEP了
cmt eip,"这里就是OEP!"//在EIP处,也就是现在OD停留了位置加注释
MSG "感谢使用此脚本,现在可以脱壳了" //加个对话框,给出一些提示信息
ret//结束脚本


---------------------------------------------------------------------------------------------------------

OK,这个脚本就顺利写完了。去试下效果吧,哈,一切OK!

有了写这个壳的脚本来练手,我们就再来个更强点的壳吧,哈,穿山甲上场!
当然,我们这里只给大家讲解下单进程标准壳的写法,至于其他的保护方式,大家可以自己去举一反三,自己学着写,或者,自己去网上找些脚本的资料,至少去看懂脚本的内容!

好,我们开始吧:

穿山甲标准壳的脱壳相对简单点:

1、寻找magic jump,避开IAT加密
我们CTRL+G GetModuleHandleA,查找到这里

7C80B6A1 >8BFFmov edi,edi //查找到这里
7C80B6A355push ebp
7C80B6A48BECmov ebp,esp
7C80B6A6837D 08 00cmp dword ptr ss:[ebp+8],0
7C80B6AA74 18 je short kernel32.7C80B6C4 //在这里我们下硬件执行断点,可以发现,是找到的地址+5
7C80B6ACFF75 08 push dword ptr ss:[ebp+8]
7C80B6AFE8 C0290000 call kernel32.7C80E074
7C80B6B485C0test eax,eax
7C80B6B674 08 je short kernel32.7C80B6C0


然后我们SHIFT+F9运行,仔细观察堆栈窗口和寄存器窗口,找适当的时机返回

第一次:

堆栈:

000794FC/0007EC44
00079500|00B46DF3返回到 00B46DF3 来自 kernel32.GetModuleHandleA
00079504|00B5BC1CASCII "kernel32.dll"
00079508|00B5CEC4ASCII "VirtualAlloc"
0007950C|00B5FA98
00079510|7C9210EDntdll.RtlLeaveCriticalSection

寄存器:

EAX 77DCCBAC ADVAPI32.77DCCBAC
ECX 00000001
EDX EBF07409
EBX 00000000
ESP 000794FC
EBP 000794FC
ESI 7C9210ED ntdll.RtlLeaveCriticalSection
EDI 00B5FA98
EIP 7C80B6AA kernel32.7C80B6AA

第二次:

堆栈:

000794FC/0007EC44
00079500|00B46E10返回到 00B46E10 来自 kernel32.GetModuleHandleA
00079504|00B5BC1CASCII "kernel32.dll"
00079508|00B5CEB8ASCII "VirtualFree"
0007950C|00B5FA98
00079510|7C9210EDntdll.RtlLeaveCriticalSection

寄存器:

EAX 7C809A51 kernel32.VirtualAlloc
ECX 00B5CEC4 ASCII "VirtualAlloc"
EDX 00B5CED0
EBX 00000000
ESP 000794FC
EBP 000794FC
ESI 7C9210ED ntdll.RtlLeaveCriticalSection
EDI 00B5FA98
EIP 7C80B6AA kernel32.7C80B6AA

第三次:

堆栈:

00079260/00079500
00079264|00B35CE1返回到 00B35CE1 来自 kernel32.GetModuleHandleA
00079268|000793B4ASCII "kernel32.dll"
0007926C|00000000

寄存器:

EAX 000793B4 ASCII "kernel32.dll"
ECX 000793C0
EDX 000793B4 ASCII "kernel32.dll"
EBX 00000000
ESP 00079260
EBP 00079260
ESI 00000000
EDI 00B5B0F4
EIP 7C80B6AA kernel32.7C80B6AA

很明显,这里就是返回的时机了。

当然我们也找到了这么个规律,就是EAX的值为VirtualAlloc的下一次,就是我们的返回时机!

好,接着我们就取消硬件断点,ALT+F9运行

00B35CE18B0D AC40B600 mov ecx,dword ptr ds:[B640AC] //返回到这里
00B35CE789040Emov dword ptr ds:[esi+ecx],eax
00B35CEAA1 AC40B600 mov eax,dword ptr ds:[B640AC]
00B35CEF391C06cmp dword ptr ds:[esi+eax],ebx
00B35CF275 16 jnz short 00B35D0A
00B35CF48D85 B4FEFFFF lea eax,dword ptr ss:[ebp-14C]
00B35CFA50push eax
00B35CFBFF15 BC62B500 call dword ptr ds:[B562BC] ; kernel32.LoadLibraryA
00B35D018B0D AC40B600 mov ecx,dword ptr ds:[B640AC]
00B35D0789040Emov dword ptr ds:[esi+ecx],eax
00B35D0AA1 AC40B600 mov eax,dword ptr ds:[B640AC]
00B35D0F391C06cmp dword ptr ds:[esi+eax],ebx
00B35D120F84 2F010000 je 00B35E47 //这就是magic jump,改JMP吧!
00B35D1833C9xor ecx,ecx
00B35D1A8B07mov eax,dword ptr ds:[edi]
00B35D1C3918cmp dword ptr ds:[eax],ebx
00B35D1E74 06 je short 00B35D26
00B35D2041inc ecx
00B35D2183C0 0C add eax,0C
00B35D24^ EB F6 jmp short 00B35D1C
00B35D268BD9mov ebx,ecx
00B35D28C1E3 02 shl ebx,2

处理完IAT后,我们就找OEP了!

下断点bp CreateThread,shift+f9运行,中断后取消断点,ALT+F9返回

返回后就去单步走,去OEP吧

00B4F6ABA1 E400B600 mov eax,dword ptr ds:[B600E4]
00B4F6B03190 88000000 xor dword ptr ds:[eax+88],edx
00B4F6B6A1 E400B600 mov eax,dword ptr ds:[B600E4]
00B4F6BB3190 88000000 xor dword ptr ds:[eax+88],edx
00B4F6C1A1 E400B600 mov eax,dword ptr ds:[B600E4]
00B4F6C68B88 90000000 mov ecx,dword ptr ds:[eax+90]
00B4F6CC3348 2C xor ecx,dword ptr ds:[eax+2C]
00B4F6CF3348 18 xor ecx,dword ptr ds:[eax+18]
00B4F6D2030D FC00B600 add ecx,dword ptr ds:[B600FC]; sol.01000000
00B4F6D88B17mov edx,dword ptr ds:[edi]
00B4F6DA85D2test edx,edx
00B4F6DC75 1B jnz short 00B4F6F9
00B4F6DEFF77 18 push dword ptr ds:[edi+18]
00B4F6E1FF77 14 push dword ptr ds:[edi+14]
00B4F6E4FF77 10 push dword ptr ds:[edi+10]
00B4F6E78B90 90000000 mov edx,dword ptr ds:[eax+90]
00B4F6ED3350 40 xor edx,dword ptr ds:[eax+40]
00B4F6F03350 04 xor edx,dword ptr ds:[eax+4]
00B4F6F32BCAsub ecx,edx
00B4F6F5FFD1call ecx//这里F7进去,就是OEP了!
00B4F6F7EB 20 jmp short 00B4F719
00B4F6F983FA 01 cmp edx,1
00B4F6FC75 1E jnz short 00B4F71C
00B4F6FEFF77 04 push dword ptr ds:[edi+4]

01005F856A 70 push 70 //这里就是OEP了
01005F8768 F8120001 push sol.010012F8
01005F8CE8 DF010000 call sol.01006170
01005F9133DBxor ebx,ebx
01005F9353push ebx
01005F948B3D 98100001 mov edi,dword ptr ds:[1001098] ; kernel32.GetModuleHandleA
01005F9AFFD7call edi
01005F9C66:8138 4D5Acmp word ptr ds:[eax],5A4D
01005FA175 1F jnz short sol.01005FC2
01005FA38B48 3C mov ecx,dword ptr ds:[eax+3C]

好,有了上面的分析,我们又可以来写脚本了!哈~


---------------------------------------------------------------------------------------------------------
////////////////////////////////////////////////////////////
/// Armadillo 3.78 - 4.xx标准单进程脱壳脚本///
/// by 徐超(ximo) QQ:178911980 ///
/// http://www.54soft.com.cn ///
///http://www.52pojie.net ///
//////
/// 2008.7.26///
////////////////////////////////////////////////////////////

var GetModuleHandleA
var VirtualAlloc
var CreateThread
var OEP //定义4个变量

MSGYN "请取消所以的断点,忽略所有异常,并添加C000001D..C000001E到异常中!"//提示运行脚本前的一些信息
cmp $RESULT, 0//比较是否点"否"或"取消"
je end//如果点"否"或"取消",就来到end处

/*做些准备工作,找到所要下的各函数的地址*/

gpa "GetModuleHandleA", "kernel32.dll"//找特征API函数GetModuleHandleA
mov GetModuleHandleA, $RESULT //把找到的地址放变量GetModuleHandleA中
add GetModuleHandleA,5//GetModuleHandleA=GetModuleHandleA+5
gpa "VirtualAlloc", "kernel32.dll"//找特征APIVirtualAlloc
mov VirtualAlloc, $RESULT //把找到的地址放变量VtrtualAlloc中
gpa "CreateThread", "kernel32.dll"//找特征APICreateThread
mov CreateThread, $RESULT //把找到的地址放变量CreateThread中

/*下断点GetModuleHandleA+5,找合适的时机返回*/

bphws GetModuleHandleA, "x" //在GetModuleHandleA+5处,下硬件执行断点

label1: //标签label1
esto//SHIFT+F9
cmp eax,VirtualAlloc//比较EAX的值是否为VirtualAlloc
jne label1//不是的话,来到标签label1,继续SHIFT+F9
esto//再SHIFT+F9,来到最佳的返回时机
bphwc GetModuleHandleA//取消此硬件断点
rtu //ALT+F9返回

/*找magic jump,并修改*/

find eip, #0F84????????#//查找magic jump的特征码,"?"为通配符
bp $RESULT//找到的地址处下断
esto//SHIFT+F9
bc $RESULT//取消断点
repl eip, #0F84????????#, #90E9????????#, 10//修改magic jump,即改为"90E9"。由于字节数不同,故NOP填充


/*寻找OEP*/

bp CreateThread //下断点bp CreateThread
run //运行
bc CreateThread //取消断点
rtu //ALT+F9返回
rtr //执行到返回,相当与CTRL+F9
sti //F7

/*例子中的特征代码:
00B4F6F32BCAsub ecx,edx
00B4F6F5FFD1call ecx
00B4F6F7EB 20 jmp short 00B4F719
*/


find eip, #2B??FF??8?#//找特征代码
mov OEP, $RESULT//把返回的值放变量OEP中
add OEP, 2//OEP=OEP+2,很明显找到地址的后2个字节就是
bp OEP//下断点
run //运行
bc OEP//取消断点
sti //F7进去,就是OEP了
cmt eip,"这里就是OEP!" //在EIP处,也就是现在OD停留了位置加注释
MSG "感谢使用此脚本,现在可以脱壳了"//加个对话框,给出一些提示信息
ret //结束脚本

end:
msg "您取消了脚本的运行!"//提示没有运行脚本
ret //结束脚本的运行


---------------------------------------------------------------------------------------------------------

哈,穿山甲的脚本就这么搞定了!测试一下效果吧,同样OK!

差不多到这里,看了这些讲解,大家对写脚本应该有个更加深刻的认识了吧!

以后的工作就是大家多多动手去实践了。

水平有限,讲的不是那么好,请大家谅解!

作者徐超,转载注明出处!谢谢合作!

脚本续.rar

1.18 MB, 下载次数: 260, 下载积分: 吾爱币 -1 CB

免费评分

参与人数 1热心值 +1 收起 理由
773827986 + 1 热心回复!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| ximo 发表于 2008-7-26 13:41
晕,论坛上的显示效果和我在笔记本中写的不一样. [s:44][s:44]
笔记本中写的明显整齐多了,呵呵
附件中就有完整的文章,2个脚本,以及教程中的程序!
Tale 发表于 2008-7-26 13:47
石头学破解 发表于 2008-7-26 15:20
zx278212442 发表于 2008-7-26 15:29
嗯嗯!~
很厉害~!佩服死了~!
我要是女的就嫁给你!~
wgz001 发表于 2008-7-26 15:41
这个厉害啊我下来用用

[s:43]
8221228 发表于 2008-7-26 16:28
晕,终于看见了 天书 [s:17][s:44]
8221228 发表于 2008-7-26 16:29
处理完IAT后,我们就找OEP了
niliu 发表于 2008-7-26 16:53
的确很强 超人啊。。。 学习下下
yuanyw2000 发表于 2008-7-26 22:32
[下个来试试.谢谢楼主的无私分享.
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-5-4 10:00

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表