老文章档案 · 2003 年

keygenning4newbies keygenme #3 注册算法,虽然说是初学者的crackme,可是

破解教程 · 算法分析 · 2003-09-15 · 作者:人气: · 出处:赢政天下整理收藏)

我输入的名字是:TAE!

注册码:78787878

下面是检查注册码个数的地方,和普通的检测方法不一样,瞧瞧:

:004011F5 6BC003 imul eax, 00000003 ;eax是假注册码的个数

:004011F8 C1E002 shl eax, 02 ;右移两位

:004011FB 05CD000000 add eax, 000000CD ;加上0xCD

:00401200 8945FC mov dword ptr [ebp-04], eax ;保存

:00401203 817DFCA5010000 cmp dword ptr [ebp-04], 000001A5;和0x1A5比较

:0040120A 0F85BC000000 jne 004012CC ;不同就跳走了

:00401210 33C0 xor eax, eax ;清零

:00401212 8A4594 mov al, byte ptr [ebp-6C] ;依次取注册码字符

:00401215 84C0 test al, al ;是最后一个字符吗?

:00401217 7413 je 0040122C ;是就跳走了!准备计算

:00401219 8D4D94 lea ecx, dword ptr [ebp-6C] ;指向注册码

根据上面的算法,可以得到这样一个方程式:

(个数*3*2^2)+0xCD=0x1A5 (注:"2^2"指的是2的平方!)

既然知道了这个,求“个数”应该就非常简单了吧?用Windows的计算器简单的算一下,

0x1A5-0xCD=0xD8,用0xD8/2^2=0x36,最后用0x36/3=0x12,换算成10进制,那么就是18,

所以,根据上面的算法可以知道注册码必须是18个字符!那么输入787878787878787878

继续跟踪来到下面,这里是检查注册码中是否有小于0的Ascii码的字符。有的话程序就

判断注册码是错的!

:0040121C 3C30 cmp al, 30 ;小于零吗?

:0040121E 0F82C6000000 jb 004012EA ;小于就跳走了!完蛋!

:00401224 8A4101 mov al, byte ptr [ecx+01] ;否则就将下一个字符给al

:00401227 41 inc ecx ;指向下一个字符

:00401228 84C0 test al, al ;是空吗

:0040122A 75F0 jne 0040121C ;没有结束就跳,形成循环

出了上面那个循环,我们便来到了下面:

:0040122C E8CFFDFFFF call 00401000 ;这里面会将eax,ebx,ecx,edx清零

:00401231 8D852CFFFFFF lea eax, dword ptr [ebp+FFFFFF2C];指向用户名

:00401237 50 push eax ;将用户名压入堆栈

:00401238 E843FEFFFF call 00401080 ;里面会对用户名进行操作

给初学者介绍一点经验,如果你发现程序先将用户名压入堆栈,后面紧跟着一个Call,那

你就得非常注意了,除了计算个数,那么很可能就是计算注册码了!所以我们一定得进去

看看到底发生了什么!

:00401080 55 push ebp

:00401081 8BEC mov ebp, esp

:00401083 51 push ecx

:00401084 53 push ebx

:00401085 56 push esi

:00401086 57 push edi

* Possible StringData Ref from Data Obj ->"eheh" //注意这个哟

|

:00401087 6880504000 push 00405080

:0040108C 6A00 push 00000000

:0040108E E8ADFFFFFF call 00401040 ;将上面的字符Ascii反相放入eax

:00401093 83C408 add esp, 00000008

:00401096 8BD8 mov ebx, eax ;再放到ebx中去

:00401098 E863FFFFFF call 00401000

* Possible StringData Ref from Data Obj ->" is a whore." //什么?妓女??

|

:0040109D BF70504000 mov edi, 00405070

:004010A2 83C9FF or ecx, FFFFFFFF

:004010A5 33C0 xor eax, eax

:004010A7 F2 repnz

.......

:004010CC 8B4508 mov eax, dword ptr [ebp+08]

:004010CF 50 push eax ;到了这里,用户名就和"is a whore"给串连了!

:004010D0 56 push esi ;妈的,竟然说咱是妓女!

:004010D1 E86AFFFFFF call 00401040 ;每次取串连后的四个字符

:004010D6 8B8E30504000 mov ecx, dword ptr [esi+00405030] ;将"12"放入ecx

:004010DC 83C408 add esp, 00000008

:004010DF 33CF xor ecx, edi ;异或结果放入ecx

:004010E1 03C1 add eax, ecx ;用四个字符的十六进制加上ecx

:004010E3 8945FC mov dword ptr [ebp-04], eax;保存

:004010E6 C145FC07 rol dword ptr [ebp-04], 07 ;带进位的左移七位

:004010EA 8B45FC mov eax, dword ptr [ebp-04];结果放入eax

:004010ED 83C604 add esi, 00000004

:004010F0 33D8 xor ebx, eax ;异或(ebx是"eheh"的十六进制)

:004010F2 47 inc edi

:004010F3 83FE40 cmp esi, 00000040 ;哇!做六十四次!!

:004010F6 7CD4 jl 004010CC ;跳转形成循环!

:004010F8 5F pop edi

:004010F9 8BC3 mov eax, ebx

:004010FB 5E pop esi

:004010FC 5B pop ebx

:004010FD 8BE5 mov esp, ebp

:004010FF 5D pop ebp

:00401100 C3 ret

上面算出一个结果在eax和ebx中

好啦,终于可以回去了!

:0040123D 8945FC mov dword ptr [ebp-04], eax ;保存

:00401240 E8BBFDFFFF call 00401000 ;这里面会将eax,ebx,ecx,edx清零

:00401245 8D8D2CFFFFFF lea ecx, dword ptr [ebp+FFFFFF2C];"TAE! is a whore"字符串

:0040124B 56 push esi

:0040124C 51 push ecx

:0040124D E8BEFDFFFF call 00401010

:00401252 83C40C add esp, 0000000C

:00401255 33C9 xor ecx, ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00401284(C)

|

:00401257 8B45FC mov eax, dword ptr [ebp-04] ;记得这个吗?就是上面计算出的值啦!

:0040125A 33D2 xor edx, edx ;清零

:0040125C BE1A000000 mov esi, 0000001A ;0x1A放入esi

:00401261 F7F6 div esi ;用上面的值除以0x1A

:00401263 8A941510FFFFFF mov dl, byte ptr [ebp+edx-000000F0] ;查一张由26个大写字母组成的表

:0040126A 88540DC8 mov byte ptr [ebp+ecx-38], dl ;保存

:0040126E 8B45FC mov eax, dword ptr [ebp-04] ;取值放入eax

:00401271 C1E003 shl eax, 03 ;将它乘以8

:00401274 BA45230100 mov edx, 00012345 ;0x12345放入edx

:00401279 F7E8 imul eax ;乘以eax

:0040127B 03C2 add eax, edx ;和0x12345相加

:0040127D 8945FC mov dword ptr [ebp-04], eax ;又保存喽!

:00401280 41 inc ecx ;计数器

:00401281 83F912 cmp ecx, 00000012 ;结束了吗?

:00401284 72D1 jb 00401257 ;没有就跳转

:00401286 E875FDFFFF call 00401000

:0040128B 33C0 xor eax, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:004012A2(C)

|

:0040128D 8A4C0594 mov cl, byte ptr [ebp+eax-6C] ;输入的注册码

:00401291 8A5405C8 mov dl, byte ptr [ebp+eax-38] ;查表得到的字母

:00401295 80E930 sub cl, 30 ;Ascii减0x30

:00401298 32D1 xor dl, cl ;和查表后的字母异或

:0040129A 885405C8 mov byte ptr [ebp+eax-38], dl ;保存

:0040129E 40 inc eax ;计数器

:0040129F 83F812 cmp eax, 00000012 ;结束了?

:004012A2 72E9 jb 0040128D ;未结束就跳!

:004012A4 E857FDFFFF call 00401000

:004012A9 8D55C8 lea edx, dword ptr [ebp-38]

:004012AC 52 push edx

:004012AD E85EFEFFFF call 00401110 ;这里面是最后的运算!

:004012B2 E849FDFFFF call 00401000

:004012B7 8D45C8 lea eax, dword ptr [ebp-38]

进入call 00401110

:00401110 8B4C2404 mov ecx, dword ptr [esp+04]

:00401114 33C0 xor eax, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00401122(C)

|

:00401116 8A1408 mov dl, byte ptr [eax+ecx] ;上面结果的一个数

:00401119 32D0 xor dl,al ;和位数异或(从零开始)

:0040111B 881408 mov byte ptr [eax+ecx], dl ;保存!

:0040111E 40 inc eax

:0040111F 83F812 cmp eax, 00000012 ;又是这么多的循环

:00401122 72F2 jb 00401116 ;循环

:00401124 C3 ret

回去喽!

下面就是最后的比较了!呼,好累!

* Possible StringData Ref from Data Obj ->"KEYGENNING4NEWBIES"

|

:004012BA 6814514000 push 00405114 ;这个是"KEYGENNING4NEWBIES"

:004012BF 50 push eax ;这个是最后运算出的结果

:004012C0 E86BFEFFFF call 00401130 ;比较是否相同

:004012C5 83C40C add esp, 0000000C

:004012C8 85C0 test eax, eax

:004012CA 753C jne 00401308

所以咱们的注册码经过运算后一定要和"KEYGENNING4NEWBIES"这个字符串相同,

好了,算法已经清楚了,谁来写个注册机?伪装者大侠?这个够级别吧?试试呀!也好让咱这些

向往搞注册机的朋友学习学习;)

标 题:帖这个的注册机,嵌入了一点汇编(没有办法的)不知道这个在TC下能否成功,在VC下这个是可以的 (1千字)

发信人:伪装者[CCG]

时 间:2001-8-19 11:56:39

详细信息:

#include "stdio.h"

#include "string.h"

#define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))

void main()

{FILE *p=fopen("sn.txt","wt");

unsigned char string[80];

int i,d,c;

int tb1[16]={0x12,0x5c,0x34,0x22,0xab,0x9d,0x54,0x00,0xdd,0x84,0xae,0x66,0x31,0x78,0x73,0xcf};

unsigned tb2[18];

char key[18]="KEYGENNING4NEWBIES";

unsigned long f=0,e=0x68656865;

printf("*********KEYGENME #3*********\nThis keygen is made by Pretender\nPlease input your name : ");

gets(string);

fputs("Name : ",p);

fputs(string,p);

fputc('\015',p);

fputc('\012',p);

fputs("SN : ",p);

printf("Your Register code is : ");

strcat(string," is a whore.");

d=strlen(string);

if(d%4!=0)

{for(i=d;i<d+4-d%4;i++)

string[i]='\0';

d=i;}

for(i=0;i<16;i++)

{if(i*4<d)

f=string[i*4]+string[i*4+1]*256+string[i*4+2]*65536+string[i*4+3]*256*65536;

else f=0;

c=tb1[i]^i;

f+=c;

f=ROTATE(f,7);

e^=f;}

for(i=0;i<18;i++)

{

tb2[i]=e%26;

tb2[i]+=65;

__asm {mov eax,e

shl eax,3

mov edx,0x12345

imul eax

add eax,edx

mov e,eax

}

}

for(i=0;i<18;i++)

{c=key[i];

tb2[i]^=i;

c^=tb2[i];

c+=0x30;

printf("%c",c);

fputc(c,p);

}

printf("\nYou can get the code in sn.txt");

printf("\n ***************************** --- --- ---\n *Welcome to WWW.CRACKNOW.COM* / / / --\n ***************************** --- --- --/\n");

} (出处:赢政天下整理收藏)

相关文章:

·语音界面2.0算法分析及注册机源码!

·侠客系统修改器1.21破解手记--算法分析

·中文拨号上网计时计费器 V4.12注册算法分析

·ClockWise 3.22e注册码算法分析

·CoolClock V1.02注册算法分析

·Directory Scanner v1.5 注册算法分析

·Disk Chief 1.2 简单注册算法分析

·EffeTech HTTP Sniffer 3.2注册算法分析

·eLib2.01算法分析

·EZ MP3 Recorder 1.15 注册算法分析

相关软件:

→ 特别推荐

→ 热点TOP10

我为人人《《==》》人人为我

关于我们 |

帮助(?)

| 广告服务 |

版权声明 |

商业合作 |

发展历程 |

加盟我们 |

联系我们

Copyright © 1999-2003

winzheng.com All Rights Reserved.

繁体版:由华琦数码技术提供

Powered

by:MeSky.Net

2003-2004 年,宽带刚刚普及,下载站的文章区是许多人学电脑的第一课堂。
🕰 → 🤖 从那时到现在

当年一篇教程能让一台电脑焕然一新;今天的效率工具换成了 AI。 想知道当下最可靠的 AI 模型怎么选?看 赢政指数——我们用了 28 年的选软件严谨,现在用来评测大模型。

档案性质声明:本页为赢政天下(1998-2011)老文章的历史档案复原, 内容反映当年发表时的原貌——包括当年的技术表述、软件版本与观点,部分方法在今天已不适用或不合规,仅作互联网历史记录与研究用途, 不提供任何形式的下载。原始数据经由公共网络存档(Internet Archive)复原。发现问题请联系我们
← 返回老文章档案 · 软件史档案馆 · 赢政天下站史