-
-
[旧帖] 延迟导致重复发帖,致歉,请管理员删除此帖 0.00雪花
-
发表于: 2010-4-8 12:26 1231
-
软件名称:ZIPPasswordUnlocker。
来源:互联网下载
作者:Bony
做了一个很简单的软件小爆破,给初学者提供一些思路。这其中我会穿插一些简单
的基础知识。我也是一个菜鸟。不足之处还请大家批评指正。软件我也会传上去。大家
也可以不用爆破别的方法也可以,大家可以试一试。一个很好的学习爆破的软件。首先
查壳,Microsoft Visual Studio .NET 2005 -- 2008 -> Microsoft Corporation.
没有壳。那好吧,直接先OD载入,运行一下,注册。随便输入一个注册码。提示
the code you've entered invalid。从这里,我们就可以找到一些线索。有了字符串提
示。
大家知道,在一个程序中这样的提示字符串是以常量保存在内存中。我们只要找到
这个字符串的地址,也就可以找到其注册的事件代码。OD为我们提供了这个功能,在代
码区右键菜单--查找--所有参考文本。
然后在查找文本段的地方右键菜单--查找文本。找到刚才那句话,双击来到这个内
存地址004021C1 . 68 787F4600 push 00467F78 ; UNICODE
"The code you've entered invalid!"
OK,现在找到了这段程序的注册代码。我们现在先看看上下的所有代码。
00402156 . /75 2B jnz short 00402183 ; 这里的JNZ是对非空
的跳转,如果空就不跳,根据前一个结果的值来判断
00402158 . |6A 30 push 30
0040215A . |68 A87C4600 push 00467CA8 ; UNICODE
"Registration"
0040215F . |68 BC7F4600 push 00467FBC ; UNICODE
"Please enter register code!"
00402164 . |8BCE mov ecx, esi ; 上面是对于空的序列号
的判断
00402166 . |E8 C39F0100 call 0041C12E
0040216B . |68 26040000 push 426
00402170 . |8BCE mov ecx, esi
00402172 . |E8 0BEC0100 call 00420D82
00402177 . |8BC8 mov ecx, eax
00402179 . |E8 4FEE0100 call 00420FCD
0040217E . |E9 CD000000 jmp 00402250 ; 这个JMP直接跳出
了判断
00402183 > \8D4C24 0C lea ecx, dword ptr [esp+C]
00402187 . E8 94FEFFFF call 00402020
0040218C . 8BC8 mov ecx, eax
0040218E . E8 3DFCFFFF call 00401DD0
00402193 . 8BF8 mov edi, eax
00402195 . 8B07 mov eax, dword ptr [edi]
00402197 . 83E8 10 sub eax, 10
0040219A . 8378 0C 01 cmp dword ptr [eax+C], 1
0040219E . 7E 0B jle short 004021AB
004021A0 . 8B48 04 mov ecx, dword ptr [eax+4]
004021A3 . 51 push ecx
004021A4 . 8BCF mov ecx, edi
004021A6 . E8 65F0FFFF call 00401210
004021AB > 8B3F mov edi, dword ptr [edi]
004021AD . 57 push edi
004021AE . E8 5D240000 call 00404610
004021B3 . 83C4 04 add esp, 4
004021B6 . 85C0 test eax, eax
004021B8 75 44 jnz short 004021FE ; 这个JNZ就是跳转到
正确判断的地方。这是一个有条件跳转。
004021BA 6A 30 push 30
004021BC . 68 A87C4600 push 00467CA8 ; UNICODE
"Registration"
004021C1 . 68 787F4600 push 00467F78 ; UNICODE "The
code you've entered invalid!"
004021C6 . 8BCE mov ecx, esi ; 这是错误序列号的判断
004021C8 . E8 619F0100 call 0041C12E
004021CD . 68 26040000 push 426
004021D2 . 8BCE mov ecx, esi
004021D4 . E8 A9EB0100 call 00420D82
004021D9 . 8BC8 mov ecx, eax
004021DB . E8 EDED0100 call 00420FCD
004021E0 . 8B4424 0C mov eax, dword ptr [esp+C]
004021E4 . 83C0 F0 add eax, -10
004021E7 . C74424 1C FFF>mov dword ptr [esp+1C], -1
004021EF . 8D50 0C lea edx, dword ptr [eax+C]
004021F2 . 83C9 FF or ecx, FFFFFFFF
004021F5 . F0:0FC10A lock xadd dword ptr [edx], ecx
004021F9 . 49 dec ecx
004021FA . 85C9 test ecx, ecx
004021FC . EB 6A jmp short 00402268
004021FE > 8D4C24 0C lea ecx, dword ptr [esp+C]
00402202 . E8 19FEFFFF call 00402020
00402207 . 8BC8 mov ecx, eax
00402209 . E8 C2FBFFFF call 00401DD0
0040220E . 8BF8 mov edi, eax
00402210 . 8B07 mov eax, dword ptr [edi]
00402212 . 83E8 10 sub eax, 10
00402215 . 8378 0C 01 cmp dword ptr [eax+C], 1
00402219 . 7E 0B jle short 00402226
0040221B . 8B48 04 mov ecx, dword ptr [eax+4]
0040221E . 51 push ecx
0040221F . 8BCF mov ecx, edi
00402221 . E8 EAEFFFFF call 00401210
00402226 > 8B3F mov edi, dword ptr [edi]
00402228 . 57 push edi
00402229 . E8 02230000 call 00404530
0040222E . 83C4 04 add esp, 4
00402231 . 6A 40 push 40
00402233 . 68 A87C4600 push 00467CA8 ; UNICODE
"Registration"
00402238 . 68 107F4600 push 00467F10 ; UNICODE
"Thank you for registering ZIP Password Unlocker!"
0040223D . 8BCE mov ecx, esi ; 这里是对正确序列号的
判断
0040223F . E8 EA9E0100 call 0041C12E
00402244 . 8B16 mov edx, dword ptr [esi]
00402246 . 8B82 58010000 mov eax, dword ptr [edx+158]
0040224C . 8BCE mov ecx, esi
0040224E . FFD0 call eax
00402250 > 8B4424 0C mov eax, dword ptr [esp+C]
从上面的代码,我们可以看出。这个程序做了三个判断,我也加入了注释。很直观很简
单的实现注册码判断。现在,我们需要是让程序跳到
00402238 . 68 107F4600 push 00467F10 ; UNICODE
"Thank you for registering ZIP Password Unlocker!"这句话这里。那么该如何实现
呢?我们往上看。
004021AE . E8 5D240000 call 00404610
004021B3 . 83C4 04 add esp, 4
004021B6 . 85C0 test eax, eax
004021B8 75 44 jnz short 004021FE ; 这个JNZ就是跳转到
正确判断的地方。这是一个有条件跳转。
004021BA 6A 30 push 30
004021BC . 68 A87C4600 push 00467CA8 ; UNICODE
"Registration"
004021C1 . 68 787F4600 push 00467F78 ; UNICODE "The
code you've entered invalid!"
找到了错误判断的这里。看看在这里的jnz,大家可以查一查汇编手册,jnz是有条件跳
转,jnz跳转的条件ZF标志位不为0跳转。之前的这一句
004021B6 . 85C0 test eax, eax
测试eax是否为0,意思就是用eax逻辑运算与eax。其结果如果不为0则跳。逻辑与大家
应该知道吧。0001与0001还是0001。也就是如果eax不为0就可以跳。说到这里,其实
一种简单爆破方法就已经形成了。直接修改jnz为jmp。无条件跳转,修改后无论是什么注
册码都会注册成功。但是大家一定会问既然有条件,我们就去找个条件然后去符合这个
条件。这样不是合理么?是的。那么eax又受到哪里影响呢?看这一句话。
004021AE . E8 5D240000 call 00404610
call指令,call指令就是调用了子程序。什么是子程序?就是相当于一些代码段的封装。
如果大家知道c语言的话,我做一个错误的,但是大家可以理解的比喻。就是一个函数。
call就调用这个函数,这个函数的首地址就是 00404610。其原理就是让程序来到这里
来执行。然后返回结果。好,我们过去看看。在这里就要用到了断点,我们在这个call
下一个断点。运行起来程序。单步步入,进入这个子程序。
00404610 /$ 6A FF push -1
00404612 |. 68 E6274600 push 004627E6
00404617 |. 64:A1 0000000>mov eax, dword ptr fs:[0]
0040461D |. 50 push eax
0040461E |. 81EC 88020000 sub esp, 288
00404624 |. A1 78204A00 mov eax, dword ptr [4A2078]
00404629 |. 33C4 xor eax, esp
0040462B |. 898424 840200>mov dword ptr [esp+284], eax
00404632 |. 53 push ebx
00404633 |. 56 push esi
00404634 |. A1 78204A00 mov eax, dword ptr [4A2078]
00404639 |. 33C4 xor eax, esp
0040463B |. 50 push eax
0040463C |. 8D8424 940200>lea eax, dword ptr [esp+294]
00404643 |. 64:A3 0000000>mov dword ptr fs:[0], eax
00404649 |. 8BB424 A40200>mov esi, dword ptr [esp+2A4]
00404650 |. 33DB xor ebx, ebx
00404652 |. C74424 28 0F0>mov dword ptr [esp+28], 0F
0040465A |. 895C24 24 mov dword ptr [esp+24], ebx
0040465E |. 885C24 14 mov byte ptr [esp+14], bl
00404662 |. 8D4C24 2C lea ecx, dword ptr [esp+2C]
00404666 |. 899C24 9C0200>mov dword ptr [esp+29C], ebx
0040466D |. E8 EE040100 call 00414B60
00404672 |. 33C0 xor eax, eax
00404674 |. 898424 700200>mov dword ptr [esp+270], eax
0040467B |. 898424 740200>mov dword ptr [esp+274], eax
00404682 |. 898424 780200>mov dword ptr [esp+278], eax
00404689 |. 898424 7C0200>mov dword ptr [esp+27C], eax
00404690 |. 898424 800200>mov dword ptr [esp+280], eax
00404697 |. 898424 840200>mov dword ptr [esp+284], eax
0040469E |. 898424 880200>mov dword ptr [esp+288], eax
004046A5 |. 898424 8C0200>mov dword ptr [esp+28C], eax
004046AC |. 8BC6 mov eax, esi
004046AE |. C68424 9C0200>mov byte ptr [esp+29C], 1
004046B6 |. 8D50 02 lea edx, dword ptr [eax+2]
004046B9 |. 8DA424 000000>lea esp, dword ptr [esp]
004046C0 |> 66:8B08 /mov cx, word ptr [eax]
004046C3 |. 83C0 02 |add eax, 2
004046C6 |. 66:3BCB |cmp cx, bx
004046C9 |.^ 75 F5 \jnz short 004046C0
004046CB |. 53 push ebx ; /pDefaultCharUsed
004046CC |. 53 push ebx ; |pDefaultChar
004046CD |. 2BC2 sub eax, edx ; |
004046CF |. D1F8 sar eax, 1 ; |
004046D1 |. 50 push eax ; |MultiByteCount
004046D2 |. 8D8424 7C0200>lea eax, dword ptr [esp+27C] ; |
004046D9 |. 50 push eax ; |MultiByteStr
004046DA |. 6A FF push -1 ; |WideCharCount =
FFFFFFFF (-1.)
004046DC |. 56 push esi ; |WideCharStr
004046DD |. 53 push ebx ; |Options
004046DE |. 53 push ebx ; |CodePage
004046DF |. FF15 70734600 call dword ptr [<&KERNEL32.WideCharTo>;
\WideCharToMultiByte
004046E5 |. 8D4C24 2C lea ecx, dword ptr [esp+2C]
004046E9 |. E8 B2E00000 call 004127A0
004046EE |. 83EC 1C sub esp, 1C
004046F1 |. 8BCC mov ecx, esp
004046F3 |. 8D8424 8C0200>lea eax, dword ptr [esp+28C]
004046FA |. C741 18 0F000>mov dword ptr [ecx+18], 0F
00404701 |. 8959 14 mov dword ptr [ecx+14], ebx
00404704 |. 896424 28 mov dword ptr [esp+28], esp
00404708 |. 8859 04 mov byte ptr [ecx+4], bl
0040470B |. 8D70 01 lea esi, dword ptr [eax+1]
0040470E |. 8BFF mov edi, edi
00404710 |> 8A10 /mov dl, byte ptr [eax]
00404712 |. 40 |inc eax
00404713 |. 3AD3 |cmp dl, bl
00404715 |.^ 75 F9 \jnz short 00404710
00404717 |. 2BC6 sub eax, esi
00404719 |. 50 push eax
0040471A |. 8D9424 900200>lea edx, dword ptr [esp+290]
00404721 |. 52 push edx
00404722 |. E8 69E6FFFF call 00402D90
00404727 |. 8D4C24 48 lea ecx, dword ptr [esp+48]
0040472B |. E8 80E20000 call 004129B0
00404730 |. 3BC3 cmp eax, ebx
00404732 |. 75 28 jnz short 0040475C
00404734 |. 889C24 9C0200>mov byte ptr [esp+29C], bl
0040473B |. 8D4C24 2C lea ecx, dword ptr [esp+2C]
0040473F |> E8 CC020100 call 00414A10
00404744 |. 837C24 28 10 cmp dword ptr [esp+28], 10
00404749 |. 72 0D jb short 00404758
0040474B |. 8B4424 14 mov eax, dword ptr [esp+14]
0040474F |. 50 push eax
00404750 |. E8 F1380100 call 00418046
00404755 |. 83C4 04 add esp, 4
00404758 |> 33C0 xor eax, eax
0040475A |. EB 51 jmp short 004047AD
0040475C |> 8D4C24 10 lea ecx, dword ptr [esp+10]
00404760 |. 51 push ecx
00404761 |. 8D4C24 30 lea ecx, dword ptr [esp+30]
00404765 |. E8 76DD0000 call 004124E0
0040476A |. 8B5424 24 mov edx, dword ptr [esp+24]
0040476E |. 6A 04 push 4
00404770 |. 68 28904600 push 00469028 ; ASCII "B65E"
00404775 |. 52 push edx
00404776 |. 53 push ebx
00404777 |. 8D4C24 20 lea ecx, dword ptr [esp+20]
0040477B |. E8 50FCFFFF call 004043D0
00404780 |. 889C24 9C0200>mov byte ptr [esp+29C], bl
00404787 |. 8D4C24 2C lea ecx, dword ptr [esp+2C]
0040478B |. 85C0 test eax, eax
0040478D |.^ 75 B0 jnz short 0040473F
0040478F |. E8 7C020100 call 00414A10
00404794 |. 837C24 28 10 cmp dword ptr [esp+28], 10
00404799 |. 72 0D jb short 004047A8
0040479B |. 8B4C24 14 mov ecx, dword ptr [esp+14]
0040479F |. 51 push ecx
004047A0 |. E8 A1380100 call 00418046
004047A5 |. 83C4 04 add esp, 4
004047A8 |> B8 01000000 mov eax, 1
004047AD |> 8B8C24 940200>mov ecx, dword ptr [esp+294]
004047B4 |. 64:890D 00000>mov dword ptr fs:[0], ecx
004047BB |. 59 pop ecx
004047BC |. 5E pop esi
004047BD |. 5B pop ebx
004047BE |. 8B8C24 840200>mov ecx, dword ptr [esp+284]
004047C5 |. 33CC xor ecx, esp
004047C7 |. E8 A74D0300 call 00439573
004047CC |. 81C4 94020000 add esp, 294
004047D2 \. C3 retn
哇,相当长啊。大家可能就没有什么耐心了。其实如果你静下心来,慢慢看其实发现也
没有那么难。我们来分析一下。
从头看一遍,我们是不是看到了许多的call,push和pop。push和pop都是堆栈操作,
push入栈,pop出栈。
其实上面这段代码就是对你输入的注册码做了一系列的操作然后去判断你的注册码。可
以看到有一些字符操作。
004046CB |. 53 push ebx ; /pDefaultCharUsed
004046CC |. 53 push ebx ; |pDefaultChar
004046CD |. 2BC2 sub eax, edx ; |
004046CF |. D1F8 sar eax, 1 ; |
004046D1 |. 50 push eax ; |MultiByteCount
004046D2 |. 8D8424 7C0200>lea eax, dword ptr [esp+27C] ; |
004046D9 |. 50 push eax ; |MultiByteStr
004046DA |. 6A FF push -1 ; |WideCharCount =
FFFFFFFF (-1.)
004046DC |. 56 push esi ; |WideCharStr
004046DD |. 53 push ebx ; |Options
004046DE |. 53 push ebx ; |CodePage
因为算法这一块我也很菜,就不去追它的注册码了。其实这个完全是可以做出注册机的
。我们就看后面的返回retn前面的几句代码。发现了一个可疑的call。没关系,我们进
去看看,单步步过走到这。这个过程中注意观察eax的值。
进到里面
00439573 $ 3B0D 78204A00 cmp ecx, dword ptr [4A2078]
00439579 . 75 02 jnz short 0043957D
0043957B . F3: prefix rep:
0043957C . C3 retn
继续单步走,观察eax的值,发现没有变化,没关系。那就暂时不用管这个call。重新运
行一次。有没有发现,当我们输入错误的注册码的时候这个
0040475A |. EB 51 jmp short 004047AD
就把我们跳到了004047AD,此时eax是0。返回以后肯定是错误的啊。那我们有没有什
么办法可以解决呢。我们先看看跳到哪了。
004047AD |> \8B8C24 940200>mov ecx, dword ptr [esp+294]
004047B4 |. 64:890D 00000>mov dword ptr fs:[0], ecx
004047BB |. 59 pop ecx
004047BC |. 5E pop esi
004047BD |. 5B pop ebx
004047BE |. 8B8C24 840200>mov ecx, dword ptr [esp+284]
004047C5 |. 33CC xor ecx, esp
004047C7 |. E8 A74D0300 call 00439573
004047CC |. 81C4 94020000 add esp, 294
004047D2 \. C3 retn
看到了吧。完全没有eax的操作。eax始终保持是0。完了。没关系,往上看一点。
004047A8 |> B8 01000000 mov eax, 1
这句话,看到没。给eax赋值1。嘿嘿,好了。有办法了。jmp不是跳到了004047AD么
。我们给它改成004047A8。
此时eax被赋值1。然后继续走。注册成功。
成功了。
以上的方法纯属爆破,只是用了一个简单程序去帮助大家去理解基本的破解,和程序的
运行过程。我们通过一点一点的分析,最终找出的破解办法。当然了办法也很初级,仅
供初学者么学习。让大家建立信心。只要努力就能成功。好了。谢谢大家。
如果大牛能做出注册机的话,如果可以请发个教程。膜拜大牛,向大牛学习。敬礼。
声明:本文仅供交流学习,不负担任何法律责任。
来源:互联网下载
作者:Bony
做了一个很简单的软件小爆破,给初学者提供一些思路。这其中我会穿插一些简单
的基础知识。我也是一个菜鸟。不足之处还请大家批评指正。软件我也会传上去。大家
也可以不用爆破别的方法也可以,大家可以试一试。一个很好的学习爆破的软件。首先
查壳,Microsoft Visual Studio .NET 2005 -- 2008 -> Microsoft Corporation.
没有壳。那好吧,直接先OD载入,运行一下,注册。随便输入一个注册码。提示
the code you've entered invalid。从这里,我们就可以找到一些线索。有了字符串提
示。
大家知道,在一个程序中这样的提示字符串是以常量保存在内存中。我们只要找到
这个字符串的地址,也就可以找到其注册的事件代码。OD为我们提供了这个功能,在代
码区右键菜单--查找--所有参考文本。
然后在查找文本段的地方右键菜单--查找文本。找到刚才那句话,双击来到这个内
存地址004021C1 . 68 787F4600 push 00467F78 ; UNICODE
"The code you've entered invalid!"
OK,现在找到了这段程序的注册代码。我们现在先看看上下的所有代码。
00402156 . /75 2B jnz short 00402183 ; 这里的JNZ是对非空
的跳转,如果空就不跳,根据前一个结果的值来判断
00402158 . |6A 30 push 30
0040215A . |68 A87C4600 push 00467CA8 ; UNICODE
"Registration"
0040215F . |68 BC7F4600 push 00467FBC ; UNICODE
"Please enter register code!"
00402164 . |8BCE mov ecx, esi ; 上面是对于空的序列号
的判断
00402166 . |E8 C39F0100 call 0041C12E
0040216B . |68 26040000 push 426
00402170 . |8BCE mov ecx, esi
00402172 . |E8 0BEC0100 call 00420D82
00402177 . |8BC8 mov ecx, eax
00402179 . |E8 4FEE0100 call 00420FCD
0040217E . |E9 CD000000 jmp 00402250 ; 这个JMP直接跳出
了判断
00402183 > \8D4C24 0C lea ecx, dword ptr [esp+C]
00402187 . E8 94FEFFFF call 00402020
0040218C . 8BC8 mov ecx, eax
0040218E . E8 3DFCFFFF call 00401DD0
00402193 . 8BF8 mov edi, eax
00402195 . 8B07 mov eax, dword ptr [edi]
00402197 . 83E8 10 sub eax, 10
0040219A . 8378 0C 01 cmp dword ptr [eax+C], 1
0040219E . 7E 0B jle short 004021AB
004021A0 . 8B48 04 mov ecx, dword ptr [eax+4]
004021A3 . 51 push ecx
004021A4 . 8BCF mov ecx, edi
004021A6 . E8 65F0FFFF call 00401210
004021AB > 8B3F mov edi, dword ptr [edi]
004021AD . 57 push edi
004021AE . E8 5D240000 call 00404610
004021B3 . 83C4 04 add esp, 4
004021B6 . 85C0 test eax, eax
004021B8 75 44 jnz short 004021FE ; 这个JNZ就是跳转到
正确判断的地方。这是一个有条件跳转。
004021BA 6A 30 push 30
004021BC . 68 A87C4600 push 00467CA8 ; UNICODE
"Registration"
004021C1 . 68 787F4600 push 00467F78 ; UNICODE "The
code you've entered invalid!"
004021C6 . 8BCE mov ecx, esi ; 这是错误序列号的判断
004021C8 . E8 619F0100 call 0041C12E
004021CD . 68 26040000 push 426
004021D2 . 8BCE mov ecx, esi
004021D4 . E8 A9EB0100 call 00420D82
004021D9 . 8BC8 mov ecx, eax
004021DB . E8 EDED0100 call 00420FCD
004021E0 . 8B4424 0C mov eax, dword ptr [esp+C]
004021E4 . 83C0 F0 add eax, -10
004021E7 . C74424 1C FFF>mov dword ptr [esp+1C], -1
004021EF . 8D50 0C lea edx, dword ptr [eax+C]
004021F2 . 83C9 FF or ecx, FFFFFFFF
004021F5 . F0:0FC10A lock xadd dword ptr [edx], ecx
004021F9 . 49 dec ecx
004021FA . 85C9 test ecx, ecx
004021FC . EB 6A jmp short 00402268
004021FE > 8D4C24 0C lea ecx, dword ptr [esp+C]
00402202 . E8 19FEFFFF call 00402020
00402207 . 8BC8 mov ecx, eax
00402209 . E8 C2FBFFFF call 00401DD0
0040220E . 8BF8 mov edi, eax
00402210 . 8B07 mov eax, dword ptr [edi]
00402212 . 83E8 10 sub eax, 10
00402215 . 8378 0C 01 cmp dword ptr [eax+C], 1
00402219 . 7E 0B jle short 00402226
0040221B . 8B48 04 mov ecx, dword ptr [eax+4]
0040221E . 51 push ecx
0040221F . 8BCF mov ecx, edi
00402221 . E8 EAEFFFFF call 00401210
00402226 > 8B3F mov edi, dword ptr [edi]
00402228 . 57 push edi
00402229 . E8 02230000 call 00404530
0040222E . 83C4 04 add esp, 4
00402231 . 6A 40 push 40
00402233 . 68 A87C4600 push 00467CA8 ; UNICODE
"Registration"
00402238 . 68 107F4600 push 00467F10 ; UNICODE
"Thank you for registering ZIP Password Unlocker!"
0040223D . 8BCE mov ecx, esi ; 这里是对正确序列号的
判断
0040223F . E8 EA9E0100 call 0041C12E
00402244 . 8B16 mov edx, dword ptr [esi]
00402246 . 8B82 58010000 mov eax, dword ptr [edx+158]
0040224C . 8BCE mov ecx, esi
0040224E . FFD0 call eax
00402250 > 8B4424 0C mov eax, dword ptr [esp+C]
从上面的代码,我们可以看出。这个程序做了三个判断,我也加入了注释。很直观很简
单的实现注册码判断。现在,我们需要是让程序跳到
00402238 . 68 107F4600 push 00467F10 ; UNICODE
"Thank you for registering ZIP Password Unlocker!"这句话这里。那么该如何实现
呢?我们往上看。
004021AE . E8 5D240000 call 00404610
004021B3 . 83C4 04 add esp, 4
004021B6 . 85C0 test eax, eax
004021B8 75 44 jnz short 004021FE ; 这个JNZ就是跳转到
正确判断的地方。这是一个有条件跳转。
004021BA 6A 30 push 30
004021BC . 68 A87C4600 push 00467CA8 ; UNICODE
"Registration"
004021C1 . 68 787F4600 push 00467F78 ; UNICODE "The
code you've entered invalid!"
找到了错误判断的这里。看看在这里的jnz,大家可以查一查汇编手册,jnz是有条件跳
转,jnz跳转的条件ZF标志位不为0跳转。之前的这一句
004021B6 . 85C0 test eax, eax
测试eax是否为0,意思就是用eax逻辑运算与eax。其结果如果不为0则跳。逻辑与大家
应该知道吧。0001与0001还是0001。也就是如果eax不为0就可以跳。说到这里,其实
一种简单爆破方法就已经形成了。直接修改jnz为jmp。无条件跳转,修改后无论是什么注
册码都会注册成功。但是大家一定会问既然有条件,我们就去找个条件然后去符合这个
条件。这样不是合理么?是的。那么eax又受到哪里影响呢?看这一句话。
004021AE . E8 5D240000 call 00404610
call指令,call指令就是调用了子程序。什么是子程序?就是相当于一些代码段的封装。
如果大家知道c语言的话,我做一个错误的,但是大家可以理解的比喻。就是一个函数。
call就调用这个函数,这个函数的首地址就是 00404610。其原理就是让程序来到这里
来执行。然后返回结果。好,我们过去看看。在这里就要用到了断点,我们在这个call
下一个断点。运行起来程序。单步步入,进入这个子程序。
00404610 /$ 6A FF push -1
00404612 |. 68 E6274600 push 004627E6
00404617 |. 64:A1 0000000>mov eax, dword ptr fs:[0]
0040461D |. 50 push eax
0040461E |. 81EC 88020000 sub esp, 288
00404624 |. A1 78204A00 mov eax, dword ptr [4A2078]
00404629 |. 33C4 xor eax, esp
0040462B |. 898424 840200>mov dword ptr [esp+284], eax
00404632 |. 53 push ebx
00404633 |. 56 push esi
00404634 |. A1 78204A00 mov eax, dword ptr [4A2078]
00404639 |. 33C4 xor eax, esp
0040463B |. 50 push eax
0040463C |. 8D8424 940200>lea eax, dword ptr [esp+294]
00404643 |. 64:A3 0000000>mov dword ptr fs:[0], eax
00404649 |. 8BB424 A40200>mov esi, dword ptr [esp+2A4]
00404650 |. 33DB xor ebx, ebx
00404652 |. C74424 28 0F0>mov dword ptr [esp+28], 0F
0040465A |. 895C24 24 mov dword ptr [esp+24], ebx
0040465E |. 885C24 14 mov byte ptr [esp+14], bl
00404662 |. 8D4C24 2C lea ecx, dword ptr [esp+2C]
00404666 |. 899C24 9C0200>mov dword ptr [esp+29C], ebx
0040466D |. E8 EE040100 call 00414B60
00404672 |. 33C0 xor eax, eax
00404674 |. 898424 700200>mov dword ptr [esp+270], eax
0040467B |. 898424 740200>mov dword ptr [esp+274], eax
00404682 |. 898424 780200>mov dword ptr [esp+278], eax
00404689 |. 898424 7C0200>mov dword ptr [esp+27C], eax
00404690 |. 898424 800200>mov dword ptr [esp+280], eax
00404697 |. 898424 840200>mov dword ptr [esp+284], eax
0040469E |. 898424 880200>mov dword ptr [esp+288], eax
004046A5 |. 898424 8C0200>mov dword ptr [esp+28C], eax
004046AC |. 8BC6 mov eax, esi
004046AE |. C68424 9C0200>mov byte ptr [esp+29C], 1
004046B6 |. 8D50 02 lea edx, dword ptr [eax+2]
004046B9 |. 8DA424 000000>lea esp, dword ptr [esp]
004046C0 |> 66:8B08 /mov cx, word ptr [eax]
004046C3 |. 83C0 02 |add eax, 2
004046C6 |. 66:3BCB |cmp cx, bx
004046C9 |.^ 75 F5 \jnz short 004046C0
004046CB |. 53 push ebx ; /pDefaultCharUsed
004046CC |. 53 push ebx ; |pDefaultChar
004046CD |. 2BC2 sub eax, edx ; |
004046CF |. D1F8 sar eax, 1 ; |
004046D1 |. 50 push eax ; |MultiByteCount
004046D2 |. 8D8424 7C0200>lea eax, dword ptr [esp+27C] ; |
004046D9 |. 50 push eax ; |MultiByteStr
004046DA |. 6A FF push -1 ; |WideCharCount =
FFFFFFFF (-1.)
004046DC |. 56 push esi ; |WideCharStr
004046DD |. 53 push ebx ; |Options
004046DE |. 53 push ebx ; |CodePage
004046DF |. FF15 70734600 call dword ptr [<&KERNEL32.WideCharTo>;
\WideCharToMultiByte
004046E5 |. 8D4C24 2C lea ecx, dword ptr [esp+2C]
004046E9 |. E8 B2E00000 call 004127A0
004046EE |. 83EC 1C sub esp, 1C
004046F1 |. 8BCC mov ecx, esp
004046F3 |. 8D8424 8C0200>lea eax, dword ptr [esp+28C]
004046FA |. C741 18 0F000>mov dword ptr [ecx+18], 0F
00404701 |. 8959 14 mov dword ptr [ecx+14], ebx
00404704 |. 896424 28 mov dword ptr [esp+28], esp
00404708 |. 8859 04 mov byte ptr [ecx+4], bl
0040470B |. 8D70 01 lea esi, dword ptr [eax+1]
0040470E |. 8BFF mov edi, edi
00404710 |> 8A10 /mov dl, byte ptr [eax]
00404712 |. 40 |inc eax
00404713 |. 3AD3 |cmp dl, bl
00404715 |.^ 75 F9 \jnz short 00404710
00404717 |. 2BC6 sub eax, esi
00404719 |. 50 push eax
0040471A |. 8D9424 900200>lea edx, dword ptr [esp+290]
00404721 |. 52 push edx
00404722 |. E8 69E6FFFF call 00402D90
00404727 |. 8D4C24 48 lea ecx, dword ptr [esp+48]
0040472B |. E8 80E20000 call 004129B0
00404730 |. 3BC3 cmp eax, ebx
00404732 |. 75 28 jnz short 0040475C
00404734 |. 889C24 9C0200>mov byte ptr [esp+29C], bl
0040473B |. 8D4C24 2C lea ecx, dword ptr [esp+2C]
0040473F |> E8 CC020100 call 00414A10
00404744 |. 837C24 28 10 cmp dword ptr [esp+28], 10
00404749 |. 72 0D jb short 00404758
0040474B |. 8B4424 14 mov eax, dword ptr [esp+14]
0040474F |. 50 push eax
00404750 |. E8 F1380100 call 00418046
00404755 |. 83C4 04 add esp, 4
00404758 |> 33C0 xor eax, eax
0040475A |. EB 51 jmp short 004047AD
0040475C |> 8D4C24 10 lea ecx, dword ptr [esp+10]
00404760 |. 51 push ecx
00404761 |. 8D4C24 30 lea ecx, dword ptr [esp+30]
00404765 |. E8 76DD0000 call 004124E0
0040476A |. 8B5424 24 mov edx, dword ptr [esp+24]
0040476E |. 6A 04 push 4
00404770 |. 68 28904600 push 00469028 ; ASCII "B65E"
00404775 |. 52 push edx
00404776 |. 53 push ebx
00404777 |. 8D4C24 20 lea ecx, dword ptr [esp+20]
0040477B |. E8 50FCFFFF call 004043D0
00404780 |. 889C24 9C0200>mov byte ptr [esp+29C], bl
00404787 |. 8D4C24 2C lea ecx, dword ptr [esp+2C]
0040478B |. 85C0 test eax, eax
0040478D |.^ 75 B0 jnz short 0040473F
0040478F |. E8 7C020100 call 00414A10
00404794 |. 837C24 28 10 cmp dword ptr [esp+28], 10
00404799 |. 72 0D jb short 004047A8
0040479B |. 8B4C24 14 mov ecx, dword ptr [esp+14]
0040479F |. 51 push ecx
004047A0 |. E8 A1380100 call 00418046
004047A5 |. 83C4 04 add esp, 4
004047A8 |> B8 01000000 mov eax, 1
004047AD |> 8B8C24 940200>mov ecx, dword ptr [esp+294]
004047B4 |. 64:890D 00000>mov dword ptr fs:[0], ecx
004047BB |. 59 pop ecx
004047BC |. 5E pop esi
004047BD |. 5B pop ebx
004047BE |. 8B8C24 840200>mov ecx, dword ptr [esp+284]
004047C5 |. 33CC xor ecx, esp
004047C7 |. E8 A74D0300 call 00439573
004047CC |. 81C4 94020000 add esp, 294
004047D2 \. C3 retn
哇,相当长啊。大家可能就没有什么耐心了。其实如果你静下心来,慢慢看其实发现也
没有那么难。我们来分析一下。
从头看一遍,我们是不是看到了许多的call,push和pop。push和pop都是堆栈操作,
push入栈,pop出栈。
其实上面这段代码就是对你输入的注册码做了一系列的操作然后去判断你的注册码。可
以看到有一些字符操作。
004046CB |. 53 push ebx ; /pDefaultCharUsed
004046CC |. 53 push ebx ; |pDefaultChar
004046CD |. 2BC2 sub eax, edx ; |
004046CF |. D1F8 sar eax, 1 ; |
004046D1 |. 50 push eax ; |MultiByteCount
004046D2 |. 8D8424 7C0200>lea eax, dword ptr [esp+27C] ; |
004046D9 |. 50 push eax ; |MultiByteStr
004046DA |. 6A FF push -1 ; |WideCharCount =
FFFFFFFF (-1.)
004046DC |. 56 push esi ; |WideCharStr
004046DD |. 53 push ebx ; |Options
004046DE |. 53 push ebx ; |CodePage
因为算法这一块我也很菜,就不去追它的注册码了。其实这个完全是可以做出注册机的
。我们就看后面的返回retn前面的几句代码。发现了一个可疑的call。没关系,我们进
去看看,单步步过走到这。这个过程中注意观察eax的值。
进到里面
00439573 $ 3B0D 78204A00 cmp ecx, dword ptr [4A2078]
00439579 . 75 02 jnz short 0043957D
0043957B . F3: prefix rep:
0043957C . C3 retn
继续单步走,观察eax的值,发现没有变化,没关系。那就暂时不用管这个call。重新运
行一次。有没有发现,当我们输入错误的注册码的时候这个
0040475A |. EB 51 jmp short 004047AD
就把我们跳到了004047AD,此时eax是0。返回以后肯定是错误的啊。那我们有没有什
么办法可以解决呢。我们先看看跳到哪了。
004047AD |> \8B8C24 940200>mov ecx, dword ptr [esp+294]
004047B4 |. 64:890D 00000>mov dword ptr fs:[0], ecx
004047BB |. 59 pop ecx
004047BC |. 5E pop esi
004047BD |. 5B pop ebx
004047BE |. 8B8C24 840200>mov ecx, dword ptr [esp+284]
004047C5 |. 33CC xor ecx, esp
004047C7 |. E8 A74D0300 call 00439573
004047CC |. 81C4 94020000 add esp, 294
004047D2 \. C3 retn
看到了吧。完全没有eax的操作。eax始终保持是0。完了。没关系,往上看一点。
004047A8 |> B8 01000000 mov eax, 1
这句话,看到没。给eax赋值1。嘿嘿,好了。有办法了。jmp不是跳到了004047AD么
。我们给它改成004047A8。
此时eax被赋值1。然后继续走。注册成功。
成功了。
以上的方法纯属爆破,只是用了一个简单程序去帮助大家去理解基本的破解,和程序的
运行过程。我们通过一点一点的分析,最终找出的破解办法。当然了办法也很初级,仅
供初学者么学习。让大家建立信心。只要努力就能成功。好了。谢谢大家。
如果大牛能做出注册机的话,如果可以请发个教程。膜拜大牛,向大牛学习。敬礼。
声明:本文仅供交流学习,不负担任何法律责任。
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法
赞赏
他的文章
- 关于反调试技术[求助]标题增加长度----长度够了吧 3714
- [建议]强烈建议看雪老大出个IM工具 1742
- [注意]看雪换域名了。。。 1583
看原图
赞赏
雪币:
留言: