优化爆破修改标志位
很多朋友都想当然的以为爆破很简单,其实不然,想要做到简单且优美的爆破,并不是那么容易的。所以,我们今天就对如何优化爆破进行简单的讨论。
标志位修改是爆破当中技巧性较强的方法。如果能够用好标志位的修改,将会使软件爆破的复杂性大大降低,因而,我们有理由认为,标志位的修改与否,将是一个软件是否完美爆破的关键。
在谈到标志位的实现,大家不妨先看看下面的一个例子。
BOOL IsReg() //验证是否注册的函数
{
……
if(RegFlag==Ture) // RegFlag是注册标志
return Ture;
else
return False;
}
void Function1() //软件功能1
{
if(IsReg())
{
……
}
else
{
printf(“对不起,你还未注册,不能使用本功能1!”);
return;
}
}
void Function2() //软件功能2
{
if(IsReg())
{
……
}
else
{
printf(“对不起,你还未注册,不能使用本功能2!”);
return;
}
}
上面虽然是一个很简单的验证方法,但却是很多软件验证中的一道工序。对于类似的验证流程,一般的爆破改法是,在Function1()和Function2()内部的比较跳转中分别改JNE为JE。这样的改法虽然可行,但有一个很明显的缺点,那就是修改太多处,这是爆破的大忌。试想一下,如果软件中大量调用IsReg函数进行注册判断,那这种改法所耗的时间就不难想象了。因而,我们有必要寻找一种更简便的方法,能让我们以最少的时间,最小的修改达到同样的目的。这种方法就是修改标志位。为了更清楚的理解,大家不妨观察一下上面的代码。在上面的代码中,Function1和Function2对于是否实现本功能是根据IsReg是否为真这个条件决定的。现在我们换另一种思维思考,如果不管如何,IsReg都返回为真,那是不是Function1和Function2就能实现自身的功能呢?答案是肯定的。因而,我们可以找到IsReg这段代码,把返回值直接修改为真,也就是对返回值直接赋值为真,那么,软件便会照着预想的流程运行,这就是标志位的修改。为了大家更好的掌握这种方法,下面举两个很典型的例子。
修改标志位完美爆破Ultra MP3 to CD Burner v1.6.0
Ultra MP3 to CD Burner v1.6.0是一款功能强大操作简单的刻录软件,支持MP3、WAV、WMA、OGG等音频格式,整体感觉还是挺不错的。但它是一款共享软件,有时间限制,而且软件一启动,就会跳出一个提示注册的窗口,如图1所示。
图1
现在我们就来破解它。首先查壳,显示“Microsoft Visual C++ 6.0”编译。看来作者对自己的算法很自信呀,竟然没有加壳。好,用OD载入软件,忽略几个异常后,程序停在入口处。查找字符串参考,找到“invalid user name or register code”,双击来到相应代码处。
0040EA92 . E8 99F9FFFF CALL Ultra_MP.0040E430
0040EA97 . 83C4 08 ADD ESP,8
0040EA9A . 85C0 TEST EAX,EAX
0040EA9C 75 2B JNZ SHORT Ultra_MP.0040EAC9
0040EA9E . 6A 40 PUSH 40
0040EAA0 . 68 E49D4100 PUSH Ultra_MP.00419DE4;sorry
0040EAA5 . 68 C09D4100 PUSH Ultra_MP.00419DC0
;invalid user name or register code
我们选择在0040EA92处下断点,F9运行软件,在注册框中输入用户名“Hokkien”,注册码输入“12345abcde”,点确定后,程序被断在相应处。F7步入0040EA92,来到下面代码处。
0040E430 /$ 6A FF PUSH -1
0040E432 68D9384100 PUSH Ultra_MP.004138D9
;SE处理程序安装
0040E437 |. 64:A1 0000000>MOV EAX,DWORD PTR FS:[0]
0040E43D |. 50 PUSH EAX
0040E43E |. 64:8925 00000>MOV DWORD PTR FS:[0],ESP
0040E445 |. 81EC 94000000 SUB ESP,94
0040E44B |. 8B8424 A40000>MOV EAX,DWORD PTR SS:[ESP+A4]
0040E452 |. 53 PUSH EBX
0040E453 |. 56 PUSH ESI
0040E454 |. 50 PUSH EAX
0040E455 |. 8D4C24 10 LEA ECX,DWORD PTR SS:[ESP+10]
0040E459 |. C74424 60 E1B>MOV DWORD PTR SS:[ESP+60],6547BCE1
0040E461 |. C74424 64 133>MOV DWORD PTR SS:[ESP+64],C43F3613
0040E469 |. C74424 68 CF1>MOV DWORD PTR SS:[ESP+68],2EFD1DCF
0040E471 |. C74424 6C C56>MOV DWORD PTR SS:[ESP+6C],1D286CC5
0040E479 |. C74424 70 7F7>MOV DWORD PTR SS:[ESP+70],1DB07B7F
0040E481 |. C74424 74 016>MOV DWORD PTR SS:[ESP+74],775F6901
0040E489 |. C74424 78 B94>MOV DWORD PTR SS:[ESP+78],5BEC44B9
0040E491 |. C74424 7C 38D>MOV DWORD PTR SS:[ESP+7C],3637D938
哇,这么多数字!看来,算法确实很复杂!不过我们不用管它,因为我们的目的是爆破。但在爆破之前,不要着急,不妨把OD上下的代码粗略看看,这样有助于发现爆破点。继续往下翻代码,来到这里。
0040EA92 . E8 99F9FFFF call 0040E430
0040EA97 . 83C4 08 add esp, 8
0040EA9A . 85C0 test eax, eax
0040EA9C . 75 2B jnz short 0040EAC9;关键跳转
0040EA9E . 6A 40 push 40
0040EAA0 . 68 E49D4100 push 00419DE4; ASCII "Sorry"
0040EAA5 . 68 C09D4100 push 00419DC0
; ASCII "Invalid user name or register code"
看到这段代码,我们心里有数了,上面不就是关键跳吗?那能不能修改这个关键跳就爆破成功呢?实践表明,这样是不会成功的,有兴趣的朋友可以试下,这里就不再废话了。那是不是爆破不了了呢?回答这个问题之前,让我们先分析一下上面这段代码。
0040EA9A . 85C0 test eax, eax
0040EA9C . 75 2B jnz short 0040EAC9
这2行代码对EAX进行测试,如果等于0的话则注册失败。很明显,上面应该有个CALL。那么,这个CALL就相当于C语言中声明的BOOL型,如果注册为真返回TRUE,否则返回FAULSE。所以,爆破的关键是,查找上面CALL的对EAX赋值的代码,然后进行修改。好了,按照这个思路,我们进入上面那个CALL看看,来到下面的代码处。
0040E696 |. 85C0 test eax, eax
0040E698 |. C68424 A40000>mov byte ptr [esp+A4], 6
0040E6A0 0F84 86000000 je 0040E72C;关键跳转!
0040E6A6 |. E8 0F350000 call <jmp.&MFC42.#800>
0040E6AB |. 8D4C24 4C lea ecx, dword ptr [esp+4C]
0040E6AF |. C68424 A40000>mov byte ptr [esp+A4], 5
0040E6B7 |. E8 E4260000 call 00410DA0
0040E6BC |. 8D4C24 34 lea ecx, dword ptr [esp+34]
0040E6C0 |. 889C24 A40000>mov byte ptr [esp+A4], bl
0040E6C7 |. E8 D4260000 call 00410DA0
0040E6CC |. 8D4C24 44 lea ecx, dword ptr [esp+44]
0040E6D0 |. C68424 A40000>mov byte ptr [esp+A4], 8
0040E6D8 |. E8 C3260000 call 00410DA0
0040E6DD |. 8D4C24 3C lea ecx, dword ptr [esp+3C]
0040E6E1 |. C68424 A40000>mov byte ptr [esp+A4], 1
0040E6E9 |. E8 B2260000 call 00410DA0
0040E6EE |> 8D4C24 08 lea ecx, dword ptr [esp+8]
0040E6F2 |. C68424 A40000>mov byte ptr [esp+A4], 0
0040E6FA |. E8 BB340000 call <jmp.&MFC42.#800>
0040E6FF |. 8D4C24 0C lea &nb
上一篇: 使用TCP协议的NAT穿透技术