│破解作者│ 大菜一号(西哈`就是偶啦!)
│对 象│ 一个CrackMe6.0->简单
│平 台│ 自己乱封装的D版XP
│目 的│ 很简单的CrackMe,主要分析算法,纯技术交流!
│声明声明│
`呵~~突然搞到这个小程序,就献丑下
***********************************************
该crackme是个用masm写的`才8K的小程序`羡慕ing..这个汇编偶总是半桶水->汗
没壳
算法简单
有一个超酷骷髅图标
6.0版
(废话太多,被扁得满头包``) name :jiangwu55
* Referenced by a CALL at Address: serial:121212
|:004010A7
|
:00401139 6A32 push 00000032 <-OD中断在这
:0040113B 68F3204000 push 004020F3
* Possible Reference to Dialog: DialogID_0064, CONTROL_ID:00C8, ""
|
:00401140 68C8000000 push 000000C8
:00401145 FF7508 push [ebp+08]
* Reference To: USER32.GetDlgItemTextA, Ord:0000h
|
:00401148 E8DE000000 Call 0040122B //取name长度
:0040114D 83F800 cmp eax, 00000000 //name长度和0比较
:00401150 0F8499000000 je 004011EF //等于0就是你太懒,啥都没输,就跳咯`跳就完咯
:00401156 83F804 cmp eax, 00000004 //你有输入的话就和4比较
:00401159 0F8290000000 jb 004011EF //如果你小气输个小于4位的就完咯
:0040115F 33C9 xor ecx, ecx
:00401161 33DB xor ebx, ebx
:00401163 33F6 xor esi, esi
:00401165 8945FC mov dword ptr [ebp-04], eax //上面知道eax是name长度了,就把它搞到[ebp-4]地址里面
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040117F(C)
|
:00401168 0FBE81F3204000 movsx eax, byte ptr [ecx+004020F3] //嗯``这里开始循环了,d 4020f3可以看到你的name每次循环依次取name的字符
:0040116F 83F820 cmp eax, 00000020 //name字符和0x20比较,也就是空格了
:00401172 7407 je 0040117B //等于空格的话下面就不算了,直接name长度加一后进行下次循环
:00401174 6BC004 imul eax, 00000004 //不等于空格就*4到eax
:00401177 03D8 add ebx, eax //现在ebx里面是0,把*4后结果加到里面去,看来是累加了
:00401179 8BF3 mov esi, ebx //把上面算的结果搞进esi里
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401172(C)
|
:0040117B 41 inc ecx//ecx+1(循环次数加一)
:0040117C 3B4DFC cmp ecx, dword ptr [ebp-04] //比较看看,运算完没有
:0040117F 75E7 jne 00401168 //没有就跳上去
:00401181 83FE00 cmp esi, 00000000 //esi里是上面循环后的结果,这里和0比较
:00401184 7469 je 004011EF//算出来结果是0就完了 好,到这里总结下`输入的name得大于4位且不能有空格,再看下面:
:00401186 BB89476500 mov ebx, 00654789把0x654789传到ebx(这个....很可疑)
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040119A(C)
|
:0040118B 0FBE81F2204000 movsx eax, byte ptr [ecx+004020F2] //又要开始循环了,这里取name的字符,不过是倒着取的(其实根本没对字符进行运算)
:00401192 4B dec ebx //0x654789-1(第一次循环是这样,后面再循环就是上一次循环的结果减一了)
:00401193 6BC302 imul eax, ebx, 00000002 //减一后*2->eax
:00401196 03D8 add ebx, eax //加到ebx里去`也就是加上上面减一后的结果
:00401198 4B dec ebx //ebx又减一,这样每次循环就减了两次一了,计算前减一,计算完后又减一
:00401199 49 dec ecx //计数器减一
:0040119A 75EF jne 0040118B //没完跳上去 好,这里也总结下`把每次循环的结果减一后开始运算(当然,第一次是拿0x654789作为操作数),*2后累加起来再减一,下面比对:
:0040119C 56 push esi //esi->这个是第一次循环的结果,没忘吧
:0040119D 53 push ebx //ebx->这个是上面循环后的结果 两个都进栈了`可疑
* Possible StringData Ref from Data Obj ->"BS-%lX-%lu"->哦``这个..在OD里上面进栈的时候可以看到了,都分别把两个结果都格式 化为%1X(以大写字母表示的十六进制数)和%1u(十进制无符号整数)难道..呃`注册码是这种格式,以'-'格开,前面为BS?西西~~看下面
|
:0040119E 68C7204000 push 004020C7
:004011A3 68BB214000 push 004021BB
* Reference To: USER32.wsprintfA, Ord:0000h
|
:004011A8 E86C000000 Call 00401219 //这个call把注册码连起来咯,格式化成这个格式 "BS-...-..." 嗯
:004011AD 58 pop eax
:004011AE 58 pop eax
:004011AF 58 pop eax
:004011B0 58 pop eax
:004011B1 E801000000 call 004011B7 //这个call比较,`不过那个'-'不参与比较``跟进后就跑到下面去了
:004011B6 C3 ret
* Referenced by a CALL at Address:
|:004011B1
|
:004011B7 33C9 xor ecx, ecx //上面跟进就到这
:004011B9 6A32 push 00000032
:004011BB 6857214000 push 00402157
* Possible Reference to Dialog: DialogID_0064, CONTROL_ID:00C9, ""
|
:004011C0 68C9000000 push 000000C9
:004011C5 FF7508 push [ebp+08]
* Reference To: USER32.GetDlgItemTextA, Ord:0000h
|
:004011C8 E85E000000 Call 0040122B
:004011CD 83F800 cmp eax, 00000000
:004011D0 741D je 004011EF
:004011D2 33C9 xor ecx, ecx
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004011EC(U)
|
:004011D4 0FBE8157214000 movsx eax, byte ptr [ecx+00402157] //取假码字符
:004011DB 0FBE99BB214000 movsx ebx, byte ptr [ecx+004021BB] //取真码字符
:004011E2 3BC3 cmp eax, ebx //比一比
:004011E4 7509 jne 004011EF //不等就完
:004011E6 83F800 cmp eax, 00000000
:004011E9 7419 je 00401204
:004011EB 41 inc ecx
:004011EC EBE6 jmp 004011D4
:004011EE C3 ret * Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00401150(C), :00401159(C), :00401184(C), :004011D0(C), :004011E4(C)
|
:004011EF 6A10 push 00000010
* Possible StringData Ref from Data Obj ->"Nope"
|
:004011F1 68E4204000 push 004020E4
* Possible StringData Ref from Data Obj ->"Try again" ->错了,“再试下啦`”呵
|
:004011F6 68E9204000 push 004020E9
:004011FB FF7508 push [ebp+08]
* Reference To: USER32.MessageBoxA, Ord:0000h
|
:004011FE E834000000 Call 00401237
:00401203 C3 ret
***************************************************************
好咧,算法总结下`:
name必须大于4且不能有空格字符,依次取name的各个字符乘以4后累加(结果记作a);
再根据name的长度对0x654789进行运算,第一次先用0x654789-1后*2+b(b=0),b-1(结果记作b),然后再用b减一后*2+b,b再减一
n次后....
注册码格式化为 BS-%1X(a)-%1u(b)
name: jiangwu55
serial: BS-6B0A80B7-3452
**************************************************************
OK`大家都知道VC主要是可视化的编程,其语法和C++没啥区别,代码我用C++贴上,VC的源就打包在rar里:
#include <iostream.h>
#include <stdio.h>
#include <string.h>
main()
{
int i,k;
long lu=0,li=0,a=0;
char name[100];
cout<<"Enter you name:";
cin>>name;
k=strlen(name);
for(i=0;i<k;i++)
{
li=li+name[i]*4;
}
lu=0x654789;
for(i=0;i<k;i++)
{
lu--;
a=lu*2;
lu=lu+a;
lu--;
}
sprintf(name,"BS-%X-%u",lu,li);
cout<<endl<<"Your code is:"<<name<<endl;
loop:
goto loop;
}
注册机里我没设置说不能输空格`如果想和自己做对就输入吧`呵`反正注册时会出错滴~~~~~~
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
上传的附件: