- UID
- 35582
注册时间2007-8-28
阅读权限20
最后登录1970-1-1
以武会友
该用户从未签到
|
查壳,无!
OD载入,输入试炼码,有提示,查找参考字符………………
找到关键段的段首后,F8单步:
====================================================
0041A980 /. 55 push ebp
0041A981 |. 8BEC mov ebp, esp
0041A983 |. 83EC 20 sub esp, 20
………………
0041A999 |. E8 F210FFFF call 0040BA90 //取用户名的长度
0041A99E |. 83F8 02 cmp eax, 2 ; 用户名必须大于2位
0041A9A1 |. 7D 13 jge short 0041A9B6
0041A9A3 |. 6A 00 push 0
0041A9A5 |. 6A 00 push 0
0041A9A7 |. 68 F8E34400 push 0044E3F8 ; please input correct user name!
0041A9BC |. E8 CF10FFFF call 0040BA90 //取注册码的长度
0041A9C1 |. 83F8 08 cmp eax, 8 ; 注册码必须>=8位
0041A9C4 |. 7D 13 jge short 0041A9D9
0041A9C6 |. 6A 00 push 0
0041A9C8 |. 6A 00 push 0
0041A9CA |. 68 18E44400 push 0044E418 ; please input correct registration code!
0041A9D9 |> \6A 00 push 0 ; /Arg1 = 00000000
0041A9DB |. 8B4D E0 mov ecx, dword ptr [ebp-20] ; |
0041A9DE |. 83C1 70 add ecx, 70 ; |
0041A9E1 |. E8 0ACEFFFF call 004177F0 ; \F7进入,频繁调用,涉及算法
//下面一大堆都是调用这个函数,呵呵,调用的形式如:
int func1(int i,char* str)
作用:取指定字符串中的i位的字符
*****************************
子函数:CALL 004177F0:
*****************************
004177F3 |. 51 push ecx
//
004177F4 |. 894D FC mov dword ptr [ebp-4], ecx
004177F7 |. 837D 08 00 cmp dword ptr [ebp+8], 0
004177FB |. 7C 0D jl short 0041780A
004177FD |. 8B4D FC mov ecx, dword ptr [ebp-4]
00417800 |. E8 8B42FFFF call 0040BA90
00417805 |. 3945 08 cmp dword ptr [ebp+8], eax
00417808 |. 7E 0A jle short 00417814
0041780A |> 68 57000780 push 80070057 ; /Arg1 = 80070057
0041780F |. E8 5C36FFFF call 0040AE70 ; \CDDVDDR.0040AE70
00417814 |> 8B45 FC mov eax, dword ptr [ebp-4]
00417817 |. 8B08 mov ecx, dword ptr [eax]
00417819 |. 8B55 08 mov edx, dword ptr [ebp+8]
0041781C |. 8A0411 mov al, byte ptr [ecx+edx]
先是对用户名的前两位各取了两次:
0041A9D9 |> \6A 00 push 0 ; /Arg1 = 00000000
0041A9DB |. 8B4D E0 mov ecx, dword ptr [ebp-20] ; |
0041A9DE |. 83C1 70 add ecx, 70 ; |
0041A9E1 |. E8 0ACEFFFF call 004177F0 ; \CDDVDDR.004177F0
0041A9E6 |. 8845 EF mov byte ptr [ebp-11], al ; 取用户名的第1个字符
0041A9E9 |. 6A 01 push 1 ; /Arg1 = 00000001
0041A9EB |. 8B4D E0 mov ecx, dword ptr [ebp-20] ; |
0041A9EE |. 83C1 70 add ecx, 70 ; |
0041A9F1 |. E8 FACDFFFF call 004177F0 ; \CDDVDDR.004177F0
0041A9F6 |. 8845 F8 mov byte ptr [ebp-8], al ; 取用户名第2位
0041A9F9 |. 6A 00 push 0 ; /Arg1 = 00000000
0041A9FB |. 8B4D E0 mov ecx, dword ptr [ebp-20] ; |
0041A9FE |. 83C1 70 add ecx, 70 ; |
0041AA01 |. E8 EACDFFFF call 004177F0 ; \CDDVDDR.004177F0
0041AA06 |. 8845 FF mov byte ptr [ebp-1], al
0041AA09 |. 6A 01 push 1 ; /Arg1 = 00000001
0041AA0B |. 8B4D E0 mov ecx, dword ptr [ebp-20] ; |
0041AA0E |. 83C1 70 add ecx, 70 ; |
0041AA11 |. E8 DACDFFFF call 004177F0 ; \CDDVDDR.004177F0
然后分别对取出的4位进行运算:
0041AA19 |. 0FB645 EF movzx eax, byte ptr [ebp-11]
0041AA1D |. 83C8 43 or eax, 43
0041AA20 |. 8845 EF mov byte ptr [ebp-11], al
只是其中的常量在改变,呵呵…………
换位表达如:
*******************************************************
第1位------->EAX------->EAX=EAX OR 43
AL------->[ebp-11]
第2位------->ECX------->ECX=ECX OR 44
CL------->[ebp-8]
第1位------->EDX------->EDX=EAX OR 52
DL------->[ebp-1]
第2位------->EAX------->ECX=ECX OR 44
CL------->[ebp-6]
继续对取出的4位计算,方式如:
0041AA41 |. 0FB645 EF movzx eax, byte ptr [ebp-11]
0041AA45 |. 99 cdq
0041AA46 |. B9 0A000000 mov ecx, 0A
0041AA4B |. F7F9 idiv ecx
0041AA4D |. 8855 EF mov byte ptr [ebp-11], dl
其实也就是一个求余的运算,换位表达如下:
[ebp-11]=[ebp-11] MOD A
[ebp-8]=[ebp-8] MOD A
[ebp-1]=[ebp-1] MOD A
[ebp-6]=[ebp-6] MOD A
又是一个大循环:
0041AA7D |. C745 F0 00000>mov dword ptr [ebp-10], 0
0041AA84 |. C745 E8 00000>mov dword ptr [ebp-18], 0 ; 相当于计时器
0041AA8B |. EB 09 jmp short 0041AA96
0041AA8D |> 8B55 E8 /mov edx, dword ptr [ebp-18]
0041AA90 |. 83C2 01 |add edx, 1
0041AA93 |. 8955 E8 |mov dword ptr [ebp-18], edx
0041AA96 |> 8B4D E0 mov ecx, dword ptr [ebp-20]
0041AA99 |. 83C1 70 |add ecx, 70
0041AA9C |. E8 EF0FFFFF |call 0040BA90 ; 子函数,取用户名LEN
0041AAA1 |. 3945 E8 |cmp dword ptr [ebp-18], eax
0041AAA4 |. 7D 1E |jge short 0041AAC4
0041AAA6 |. 8B45 E8 |mov eax, dword ptr [ebp-18]
0041AAA9 |. 50 |push eax ; /Arg1
0041AAAA |. 8B4D E0 |mov ecx, dword ptr [ebp-20] ; |
0041AAAD |. 83C1 70 |add ecx, 70 ; |
0041AAB0 |. E8 3BCDFFFF |call 004177F0 ; \CDDVDDR.004177F0
0041AAB5 |. 8845 E7 |mov byte ptr [ebp-19], al
0041AAB8 |. 0FB64D E7 |movzx ecx, byte ptr [ebp-19]
0041AABC |. 034D F0 |add ecx, dword ptr [ebp-10]
0041AABF |. 894D F0 |mov dword ptr [ebp-10], ecx
0041AAC2 |.^ EB C9 \jmp short 0041AA8D ; 用户名各位字符的ASCII累加到EBP-10
0041AAC4 |> 8B45 F0 mov eax, dword ptr [ebp-10] ; 将累加值送入EAX
这个更清晰了,就是累加用户名各位的字符的ASCII
换位表达如下:
total=0;
for(i=0;i<len(name);i++)
total+=name
然后将total MOD A求余,值送往[ebp-C]
接下来就是对注册码的判断了,看完了就会发现,其实上面做的一切就是“白搭”,呵呵
先假设一下,我们输入的注册码为code[n]
0041AAD2 |. 6A 00 push 0 ; /Arg1 = 00000000
0041AAD4 |. 8B4D E0 mov ecx, dword ptr [ebp-20] ; |
0041AAD7 |. 83C1 74 add ecx, 74 ; |
0041AADA |. E8 11CDFFFF call 004177F0 ; \CDDVDDR.004177F0
0041AADF |. 8845 FC mov byte ptr [ebp-4], al
……………………………………
0041AB42 |. 6A 07 push 7 ; /Arg1 = 00000007
0041AB44 |. 8B4D E0 mov ecx, dword ptr [ebp-20] ; |
0041AB47 |. 83C1 74 add ecx, 74 ; |
0041AB4A |. E8 A1CCFFFF call 004177F0 ; \CDDVDDR.004177F0
0041AB4F |. 8845 FB mov byte ptr [ebp-5], al
上面一段取码行为的结果就是:
[ebp-2]=code[6]
[ebp-3]=code[1]
[ebp-4]=code[0]
[ebp-5]=code[7]
[ebp-6]
[ebp-7]=code[4]
[ebp-8]
[ebp-9]=code[5]
[ebp-A]=code[2]
[ebp-B]=code[3]
看了一大堆,其实只需要这一段就OK了,
0041AB52 |. 0FB655 EF movzx edx, byte ptr [ebp-11]
0041AB56 |. 0FB645 FC movzx eax, byte ptr [ebp-4]
0041AB5A |. 83E8 30 sub eax, 30
0041AB5D |. 3BD0 cmp edx, eax
0041AB5F |. 75 3C jnz short 0041AB9D
希望你没有那么不幸,刚好此处的跳转没跳,那样你可能要多走一段弯路,不过那样的机率很小,/:013 。
我很幸运,跳转实现了,直接来到了下面这段代码:
==========================================================
0041ABA1 |. 83F8 39 cmp eax, 39
0041ABA4 |. 0F85 A7000000 jnz 0041AC51
0041ABAA |. 0FB64D FD movzx ecx, byte ptr [ebp-3]
0041ABAE |. 83F9 33 cmp ecx, 33
0041ABB1 |. 0F85 9A000000 jnz 0041AC51
0041ABB7 |. 0FB655 F6 movzx edx, byte ptr [ebp-A]
0041ABBB |. 83FA 30 cmp edx, 30
0041ABBE |. 0F85 8D000000 jnz 0041AC51
0041ABC4 |. 0FB645 F5 movzx eax, byte ptr [ebp-B]
0041ABC8 |. 83F8 31 cmp eax, 31
0041ABCB |. 0F85 80000000 jnz 0041AC51
0041ABD1 |. 0FB64D F9 movzx ecx, byte ptr [ebp-7]
0041ABD5 |. 83F9 36 cmp ecx, 36
0041ABD8 |. 75 77 jnz short 0041AC51
0041ABDA |. 0FB655 F7 movzx edx, byte ptr [ebp-9]
0041ABDE |. 83FA 36 cmp edx, 36
0041ABE1 |. 75 6E jnz short 0041AC51
0041ABE3 |. 0FB645 FE movzx eax, byte ptr [ebp-2]
0041ABE7 |. 83F8 36 cmp eax, 36
0041ABEA |. 75 65 jnz short 0041AC51
0041ABEC |. 0FB64D FB movzx ecx, byte ptr [ebp-5]
0041ABF0 |. 83F9 36 cmp ecx, 36
0041ABF3 |. 75 5C jnz short 0041AC51
========对照如下,只要符合下面的条件就OK了,花了半多个小时看前面,
========哎,……
========现在明白没有,
code[0]==39
[ebp-3] code[1]=33
[ebp-A] code[2]=30
[ebp-B] code[3]=31
[ebp-7] code[4]=36
[ebp-9] code[5]=36
[ebp-2] code[6]=36
[ebp-5] code[7]=36
只要注册码满足下面的条件,就OK了,就这么简单,都不知道作者绕那么多弯弯是为什么???
即:93016666****
另,注册码必须大于等于8位
程序运行界面如下:
附件为目标程序和算法跟踪过程:
cddvddr.rar
(200.12 KB, 下载次数: 2)
[ 本帖最后由 iawen 于 2007-12-29 17:02 编辑 ] |
|