题目:Brad Soblesky.2的算法分析
软件:Brad Soblesky.2
工具:PEID,OD
破文作者:rockandtcl
个人网页:http://18232.tianyablog.com
介绍:这是从《加密解密实战攻略》的光盘上拿来的,在第七章。书中是通过WINHEX查看内存方式得到注册码的,最近的我几乎痴迷的对算法有了很大的破解愿望。所以就做了算法分析。有不足的地方和错误的地方还请指教,谢谢!
首先运行下
输入注册名:rockandtcl
输入注册码:123456789
出现错误提示:
好开始破解
用PEID看了下发现无壳
用OD载入,我比较喜欢的是查看参考字符串,于是就找到了个,双击进入CPU查看。
往上找呀找呀,历经了千辛万苦总算被我找到断点(要不怎么说我菜呢),呵呵。设置断点,重新载入
还是输入刚才的注册名和注册码
现在开始分析代码:
0040156D |. E8 DE020000 call Brad_Sob.00401850
关键断点
00401572 |. 8945 E4 mov dword ptr ss:[ebp-1C],eax
00401575 |. 837D E4 05 cmp dword ptr ss:[ebp-1C],5
00401579 |. 7D 43 jge short Brad_Sob.004015BE
比较注册名是否大于等于5位,如果成立就跳到循环位置。
0040157B |. 6A 40 push 40
0040157D |. 68 20404000 push Brad_Sob.00404020 ; ASCII "CrackMe"
00401582 |. 68 28404000 push Brad_Sob.00404028 ; ASCII "User Name must have at least 5 characters."
代码省略..............
004015BE |> C745 E0 000>mov dword ptr ss:[ebp-20],0
计算前清零,以后这个就是保存计算结果的
004015C5 |. EB 09 jmp short Brad_Sob.004015D0
以下是循环部分。不过第一次循环是从004015D0 mov eax,dword ptr ss:[ebp-20]开始的
004015C7 |> 8B55 E0 /mov edx,dword ptr ss:[ebp-20]
004015CA |. 83C2 01 |add edx,1
004015CD |. 8955 E0 |mov dword ptr ss:[ebp-20],edx
004015D0 |> 8B45 E0 mov eax,dword ptr ss:[ebp-20]
004015D3 |. 3B45 E4 |cmp eax,dword ptr ss:[ebp-1C]
004015D6 |. 7D 42 |jge short Brad_Sob.0040161A
比较是否取完
004015D8 |. 8B4D E0 |mov ecx,dword ptr ss:[ebp-20]
004015DB |. 51 |push ecx ; /Arg1
004015DC |. 8D4D EC |lea ecx,dword ptr ss:[ebp-14] ; |
004015DF |. E8 1C030000 |call Brad_Sob.00401900 ; \Brad_Sob.00401900
逐个取注册码,并换成16进制数值,现在是rockandtcl所以第一次的话取'r'->72
004015E4 |. 0FBED0 |movsx edx,al
EDX=72
004015E7 |. 8B45 F0 |mov eax,dword ptr ss:[ebp-10]
第一次是装入常数81276345(16进制)放在EAX
004015EA |. 03C2 |add eax,edx
EAX与EDX相加保存在EAX=812763B7
004015EC |. 8945 F0 |mov dword ptr ss:[ebp-10],eax
保存相加的结果
004015EF |. 8B4D E0 |mov ecx,dword ptr ss:[ebp-20]
取位置数,因为是C编写的,根据字符数组的定义,第一个字符是STRING[0],所以这时候ECX=0
004015F2 |. C1E1 08 |shl ecx,8
移位,现在是0,所以移位后还是0,如果是1的话就是100,依此类推
004015F5 |. 8B55 F0 |mov edx,dword ptr ss:[ebp-10]
EDX=812763B7
004015F8 |. 33D1 |xor edx,ecx
异或运算后 保存在EDX
004015FA |. 8955 F0 |mov dword ptr ss:[ebp-10],edx
保存刚才异或运算后的结果 812763B7
004015FD |. 8B45 E0 |mov eax,dword ptr ss:[ebp-20]
取相加的结果 812763B7
00401600 |. 83C0 01 |add eax,1
注册名字符的位置数加1放在EAX,EAX=1
00401603 |. 8B4D E4 |mov ecx,dword ptr ss:[ebp-1C]
00401606 |. 0FAF4D E0 |imul ecx,dword ptr ss:[ebp-20]
注册名字符的位置数与注册名的总长度相乘,放在ECX,第一次的时候位置数为0
所以相乘的结果是0,保存在ECX中
0040160A |. F7D1 |not ecx
非运算 ECX=FFFFFFFF
0040160C |. 0FAFC1 |imul eax,ecx
这时候EAX=FFFFFFFF
0040160F |. 8B55 F0 |mov edx,dword ptr ss:[ebp-10]
取异或的结果 放在EDX。EDX=812763B7
00401612 |. 0FAFD0 |imul edx,eax
这得想说明下,理清下思路:
1.首先装入个初始值:81276345
2,加上了'r'的ASCII码的值:72这时候的值为812763B7
3,对注册名字符串位置数,做移8位处理,转为16进制,然后与相加的值做异或运算
4,r的位置在字符串[根据C的定义]为0,加上1(放着)
5,位置数与总长度相乘,然后取非,与(位置+1)相乘。
6,5的结果和3的结果相乘,如果溢出取后32位
总结下,这时候第一次取注册码的结果是:7ED89C49
00401615 |. 8955 F0 |mov dword ptr ss:[ebp-10],edx
保存结果
00401618 |.^ EB AD \jmp short Brad_Sob.004015C7
重新开始循环
那循环开始的代码什么意思呢?
004015C7 |> 8B55 E0 /mov edx,dword ptr ss:[ebp-20]
004015CA |. 83C2 01 |add edx,1
004015CD |. 8955 E0 |mov dword ptr ss:[ebp-20],edx
004015D0 |> 8B45 E0 mov eax,dword ptr ss:[ebp-20]
004015D3 |. 3B45 E4 |cmp eax,dword ptr ss:[ebp-1C]
004015D6 |. 7D 42 |jge short Brad_Sob.0040161A
只是判断是否取完。这个判断是从第二次循环开始的
所以呢:总结下
注册码是:rockandtcl
对应的数值是:72 6F 63 6B 61 6E 64 74 63 6C
第一做完后的结果是:7ED89C49,第二次:19627230,第三次:C0C64BD3,第四次:9FF19DF8
第五次:EB8766BB第六次:782CAAFE,第七次:8D7ACD8A,第八次:178D9C70,第九次:EDD33325,第十次:9B25D092
十次循环结束了,现在继续分析:
0040161A |> \8B45 F0 mov eax,dword ptr ss:[ebp-10]
保存结果,EAX=9B25D092
0040161D |. 50 push eax
0040161E |. 68 54404000 push Brad_Sob.00404054 ; ASCII "%lu"
00401623 |. 8D4D DC lea ecx,dword ptr ss:[ebp-24]
00401626 |. 51 push ecx
00401627 |. E8 52070000 call <jmp.&MFC42.#2818>
把9B25D092换成十进制的数后转化成字符串:2602946706
0040162C |. 83C4 0C add esp,0C
0040162F |. 8D4D DC lea ecx,dword ptr ss:[ebp-24]
00401632 |. E8 79020000 call Brad_Sob.004018B0
00401637 |. 50 push eax ; /Arg1
00401638 |. 8D4D E8 lea ecx,dword ptr ss:[ebp-18] ; |
0040163B |. E8 80020000 call Brad_Sob.004018C0 ; \Brad_Sob.004018C0
步入,省略代码
004018CB |. 8B4D FC mov ecx,dword ptr ss:[ebp-4] ; |
取计算好的值
004018CE |. 8B11 mov edx,dword ptr ds:[ecx] ; |
取输入的假的注册码
004018D0 |. 52 push edx ; |Arg1
004018D1 |. E8 0A000000 call Brad_Sob.004018E0
; \Brad_Sob.004018E0
两者对比。不等于则-1保存在EAX中
返回,
00401640 |. 85C0 test eax,eax
00401642 |. 0F85 FF0000>jnz Brad_Sob.00401747
不相等,则死。相等的话就继续往下。得到正确的提示窗口
00401648 |. 8D8D ACFEFF>lea ecx,dword ptr ss:[ebp-154]
0040164E |. E8 19070000 call <jmp.&MFC42.#540>
00401653 |. C645 FC 03 mov byte ptr ss:[ebp-4],3
00401657 |. 6A 66 push 66
00401659 |. 8D8D ACFEFF>lea ecx,dword ptr ss:[ebp-154]
0040165F |. E8 02070000 call <jmp.&MFC42.#4160>
00401664 |. B9 07000000 mov ecx,7
00401669 |. BE 58404000 mov esi,Brad_Sob.00404058 ; ASCII "Correct!! "
主要是算法很是麻烦,有很多的位运算和一些溢出后的取值等,我是十分菜,写不出注册机
还请各位高手指点一二,在此先谢过。
最后再总结下
注册码是:rockandtcl
对应的数值是:72 6F 63 6B 61 6E 64 74 63 6C
1.首先装入个初始值:81276345
2,加上了'r'的ASCII码的值:72这时候的值为812763B7
3,对注册名字符串位置数,做移8位处理,转为16进制,然后与相加的值做异或运算
4,r的位置在字符串[根据C的定义]为0,加上1(放着)
5,位置数与总长度相乘,然后取非,与(位置+1)相乘。
6,5的结果和3的结果相乘,如果溢出取后32位,保留数值
7, 继续第2步操作
第一做完后的结果是:7ED89C49,第二次:19627230,第三次:C0C64BD3,第四次:9FF19DF8
第五次:EB8766BB第六次:782CAAFE,第七次:8D7ACD8A,第八次:178D9C70,第九次:EDD33325,第十次:9B25D092
然后把9B25D092,转化成10进制的数值就是注册码:2602946706
所以
注册名为:rockandtcl
注册码为:2602946706
有错误的地方还请指出,谢谢
压缩包中有破文和这个Brad Soblesky.2
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!