老文章档案 · 2003 年

DaBri Soft的“桥牌定约人练习”的注册机

破解教程 · 算法分析 · 2003-06-22 · 作者:peter888 人气: · 出处:嬴政天下整理收藏)

目标:DaBri-Soft Declarer's Play系列

工具:SOFTICE, IDA PRO

因为喜好桥牌,在看了blowfish大侠的文章后从www.dabrisoft.dk上下载了他们的Declarer's Play系列桥牌练习软件(由4个程序组成)。不过现在的版本升到了V3.0,除了压缩方法和注册方法不同外,练习的实际内容跟blowfish大侠介绍的1.1版可能差不多。下载后试了一下,觉得对桥牌做庄技术的练习和提高很有用处,就试着解出,以跟PD一同练习。用FI检查,所有安装后的程序都是用Softec Dev. installer压缩的。这是新西兰的一个小公司98年开发的一个VB3程序压缩软件。不过,用它压缩后的程序可以被VB23DECOMPILER反编译。因此破解这程序的第一步是用VB23DECOMPILER来反编译一下。果然,在rForm中看到调用"dptrumf.exe -dptrumf.dll " ... 等语句。原来程序安装时会将dptrumf.exe和dptrumf.dll两个文件装入WINDOWS目录下。在程序注册时,会用产品代码为参数调用dptrumf.dll中的lockbycode函数检验用户输入的access code,如果输入的数字是正确的,程序会在WINDOWS\SYSTEM目录下生成一个以产品代码和C盘序列号为基础生成的文件名命名的.sys隐含文件(文件长度183字节)。以后程序在启动的时候会打开这个文件进行校验,以确认程序已注册。

用SOFT ICE跟踪时,用"bpx getsystemdirectory"设置断点,调出注册窗口,输入“123454106212345”,两次F5,一次F12,再"g 152f",DB DS:E08,就得到了首5位字符。"BD *",F5,修改5位字符,一般这时就可以PASS了。如果不行,再将第6位开始的“41062”改为“21062”或更小,再试几次就会OK了。

用IDA PRO打开dptrumf.dll,可以看出校核算法为:

将installation code(实际上是C盘序列号与产品代码计算得出的)的前5位数字(一个十进制整数)与后5位字符串计算得出一个5位十进制整数,变为字符串后就是access code的前5位。把这个整数与一个10位的十进制数字字符串计算,得出的一个新的10位十进制数字字符串,取前4位得到一个4位的带符号十进制整数,只要这个整数大于等于0以及小于等于0x100C,这个10位十进制字符串加上算出的首5位,就是一个合法的15位access code.

代码如下:

cseg01:14DF 00C mov di, 0DE6h ; move the input string here

cseg01:14E2 00C mov cx, 14h

cseg01:14E5 00C repe movsb ;

cseg01:14E7 00C push es

cseg01:14E8 00E pop ds

cseg01:14E9 assume ds:nothing

cseg01:14E9 00C mov cx, 5

cseg01:14EC 00C mov bx, 0DE6h

cseg01:14EF

cseg01:14EF loc_0_14EF: ;

cseg01:14EF 00C mov al, [bx]

cseg01:14F1 00C inc bx ;

cseg01:14F2 00C cmp al, 0 ;

cseg01:14F4 00C jz loc_0_16C1 ;

cseg01:14F4

cseg01:14F8 00C loop loc_0_14EF ;

cseg01:14F8

cseg01:14FA 00C call openread_fileb22 ; read file b22 b7 bytes to e29

cseg01:14FA

cseg01:14FD 00C call sub_0_1E2D ; get reg code

cseg01:14FD

cseg01:1500 00C cmp ax, 0 ;

cseg01:1503 00C jnz loc_0_169A ;

cseg01:1503

cseg01:1507 00C call sub_0_1F4B ; 第一次计算

cseg01:1507

cseg01:150A 00C mov ax, ds:95h ; 产品编码

cseg01:150D 00C mov bx, 0E08h

cseg01:1510 00C mov cx, 5

cseg01:1513 00C call calculate_the_code ;得到首5位字符

cseg01:1513

cseg01:1516 00C mov cx, 5

cseg01:1519 00C mov bx, 0DE6h

cseg01:151C

cseg01:151C loc_0_151C: ;

cseg01:151C 00C mov al, [bx]

cseg01:151E 00C and al, 0F0h ;

cseg01:1520 00C cmp al, 30h ; '0' ;

cseg01:1522 00C jnz loc_0_16C1 ; 不是十进制数字?BAD GUY!!

cseg01:1522

cseg01:1526 00C inc bx ;

cseg01:1527 00C loop loc_0_151C ;

cseg01:1527

cseg01:1529 00C mov si, 0DE6h

cseg01:152C 00C mov di, 0E08h

cseg01:152F 00C mov cx, 5

cseg01:1532 00C repe cmpsb ;比较首5位字符是否一样

cseg01:1534 00C jnz loc_0_16B4 ; BAD GUY !!

cseg01:1534

cseg01:1538 00C mov bx, 0DEBh

cseg01:153B 00C mov al, [bx]

cseg01:153D 00C cmp al, 0 ;

cseg01:153F 00C jz loc_0_15E5 ;

cseg01:153F

cseg01:1543 00C mov cx, 0Ah

cseg01:1546 00C mov bx, 0DEBh

cseg01:1549

cseg01:1549 loc_0_1549: ;

cseg01:1549 00C mov al, [bx]

cseg01:154B 00C and al, 0F0h ;

cseg01:154D 00C cmp al, 30h ; '0' ;

cseg01:154F 00C jnz loc_0_16CE ; 不是十进制数字?BAD GUY!!

cseg01:154F

cseg01:1553 00C inc bx ;

cseg01:1554 00C loop loc_0_1549 ;

cseg01:1554

cseg01:1556 00C mov ax, 0

cseg01:1559 00C mov ds:0DFAh, ax

cseg01:155C 00C mov ds:0DFCh, al

cseg01:155F 00C mov al, ds:98h

cseg01:1562 00C mov ds:0DFDh, al

cseg01:1565 00C mov bx, 0DE6h

cseg01:1568 00C mov cx, 5

cseg01:156B 00C call strtoDEC ;

cseg01:156B

cseg01:156E 00C mov bx, 0DEBh

cseg01:1571 00C mov cx, 0Ah

cseg01:1574 00C call sub_0_3091 ; Get the new code

cseg01:1574

cseg01:1577 00C mov bx, 0DEBh

cseg01:157A 00C mov cx, 4

cseg01:157D 00C call strtoDEC ;

cseg01:157D

cseg01:1580 00C cmp ax, 0 ;

cseg01:1583 00C jz loc_0_15A8 ;

cseg01:1583

cseg01:1585 00C nop ;

cseg01:1586 00C nop ;

cseg01:1587 00C cmp ax, 100Ch ;

cseg01:158A 00C ja loc_0_16DB ; BAD GUY!!

cseg01:158A

cseg01:158E 00C cmp ax, 0 ;

cseg01:1591 00C jl loc_0_16DB ; BAD GUY!!

…………

主要的换算程序在calculate_the_code中。

cseg01:30B9 000 mov bx, ax

cseg01:30BB 000 and bx, 157h ;

cseg01:30BF 000 cmp bx, 0 ;

cseg01:30C2 000 jnz loc_0_30D4 ;

cseg01:30C2

cseg01:30C4 000 nop ;

cseg01:30C5 000 nop ;

cseg01:30C6 000 xor bx, 153h ;

cseg01:30CA 000 cmp bx, 0 ;

cseg01:30CD 000 jnz loc_0_30D4 ;

cseg01:30CD

cseg01:30CF 000 nop ;

cseg01:30D0 000 nop ;

cseg01:30D1 000 or bx, 53h ;

cseg01:30D4

cseg01:30D4 loc_0_30D4: ;

cseg01:30D4 ;

cseg01:30D4 000 cmp ax, bx ;

cseg01:30D6 000 jb loc_0_30DF ;

cseg01:30D6

cseg01:30D8 000 nop ;

cseg01:30D9 000 nop ;

cseg01:30DA 000 push ax

cseg01:30DB 002 mov ax, bx

cseg01:30DD 002 pop bx

cseg01:30DE 000 cwd ;

cseg01:30DF

cseg01:30DF loc_0_30DF: ;

cseg01:30DF 000 div bx ;

cseg01:30E1 000 mov cx, 0Ah

cseg01:30E4 000 mov bx, 0E13h

cseg01:30E7

cseg01:30E7 loc_0_30E7: ;

cseg01:30E7 000 mov word_36D_AC8, cx

cseg01:30EB 000 xor ax, dx ;

cseg01:30ED 000 ror dx, 1 ;

cseg01:30EF 000 ror dx, 1 ;

cseg01:30F1 000 ror dx, 1 ;

cseg01:30F3 000 ror dx, 1 ;

cseg01:30F5 000 ror dx, 1 ;

cseg01:30F7 000 mov cl, dl

cseg01:30F9 000 ror ax, cl ;

cseg01:30FB 000 xor ax, dx ;

cseg01:30FD 000 xor al, ah ;

cseg01:30FF 000 xor dl, al ;

cseg01:3101 000 mov cl, dl

cseg01:3103 000 rol ax, cl ;

cseg01:3105 000 and ax, 0F0Fh ;

cseg01:3108 000 mov [bx], ax

cseg01:310A 000 add bx, 2 ;

cseg01:310D 000 mov cx, word_36D_AC8

cseg01:3111 000 loop loc_0_30E7 ;

cseg01:3111

cseg01:3113 000 mov cx, 14h

cseg01:3116 000 mov si, 0E13h ;

cseg01:3119 000 mov di, 158Dh ; 查表

cseg01:311C 000 mov bx, 0

cseg01:311F

cseg01:311F loc_0_311F: ;

cseg01:311F 000 mov al, [si]

cseg01:3121 000 mov ah, 0

cseg01:3123 000 mov bx, di

cseg01:3125 000 add bx, ax ;

cseg01:3127 000 mov al, [bx]

cseg01:3129 000 mov [si], al

cseg01:312B 000 mov ax, di

cseg01:312D 000 add ax, 0Ah ;

cseg01:3130 000 mov di, ax

cseg01:3132 000 inc si ;

cseg01:3133 000 loop loc_0_311F ;

注册机的程序如下(C++BUILDER程序主要部分):

void __fastcall TForm1::Button1Click(TObject *Sender)

{

int rk;

char ctemp[10];

memset(ctemp,'\0',10);

randomize();

if (Edit1->Text.Length()!=10)

{

Application->MessageBox("请输入10位十进制数字", NULL, MB_OK);

return;

}

memcpy(input,Edit1->Text.c_str(),10);

input[10]='\0';

memcpy(sn1,input,5);

sn1[5]='\0';

memcpy(cs2,input+5,5);

cs2[5]='\0';

p1=cs2;

p2=cs3;

pt=table;

disk_sno1=atoi(sn1);

__asm

{

pushad

mov ax,[disk_sno1]

mov ebx,[p1]

mov cx,5

push ebx

push cx

clc

mov bx, ax

and bx, 157h

cmp bx, 0

jnz loc_0_30D4

nop

nop

xor bx, 153h

cmp bx, 0

jnz loc_0_30D4

nop

nop

or bx, 53h

loc_0_30D4:

cmp ax, bx

jb loc_0_30DF

nop

nop

push ax

mov ax, bx

pop bx

cwd

loc_0_30DF:

div bx

mov cx, 0Ah

mov ebx,[p2]

loc_0_30E7:

mov [k], cx

xor ax, dx

ror dx, 1

ror dx, 1

ror dx, 1

ror dx, 1

ror dx, 1

mov cl, dl

ror ax, cl

xor ax, dx

xor al, ah

xor dl, al

mov cl, dl

rol ax, cl

and ax, 0F0Fh

and eax,0ffffh

mov [ebx], ax

add ebx, 2

xor ecx,ecx

mov cx, [k]

loop loc_0_30E7

mov cx, 14h

mov esi,[p2]

mov edi,[pt]

mov bx, 0

loc_0_311F:

mov al, [esi]

mov ah, 0

mov ebx, edi

and eax,0ffffh

add ebx, eax

mov al, [ebx]

mov [esi], al

mov eax, edi

add eax, 0Ah

mov edi, eax

inc esi

loop loc_0_311F

pop cx

pop ebx

mov esi, ebx

mov ebx,[p2]

and ecx,0ffffh

loc_0_3078:

mov al, [ebx]

add al, 0

daa

mov ah, al

mov al, [esi]

and al, 0Fh

add al, ah

daa

and al, 0Fh

or al, 30h

mov [esi], al

inc esi

inc ebx

loop loc_0_3078

}

p1=cs2;

__asm

{

mov ax,[productsn]

mov ebx,[p1]

mov cx,5

push ebx

push cx

clc

mov bx, ax

and bx, 157h

cmp bx, 0

jnz loc_1_30D4

nop

nop

xor bx, 153h

cmp bx, 0

jnz loc_1_30D4

nop

nop

or bx, 53h

loc_1_30D4:

cmp ax, bx

jb loc_1_30DF

nop

nop

push ax

mov ax, bx

pop bx

cwd

loc_1_30DF:

div bx

mov cx, 0Ah

mov ebx,[p2]

loc_1_30E7:

mov [k], cx

xor ax, dx

ror dx, 1

ror dx, 1

ror dx, 1

ror dx, 1

ror dx, 1

mov cl, dl

ror ax, cl

xor ax, dx

xor al, ah

xor dl, al

mov cl, dl

rol ax, cl

and ax, 0F0Fh

and eax,0ffffh

mov [ebx], ax

add ebx, 2

xor ecx,ecx

mov cx, [k]

loop loc_1_30E7

mov cx, 14h

mov esi,[p2]

mov edi,[pt]

mov bx, 0

and ecx,0ffffh

loc_1_311F:

mov al, [esi]

mov ah, 0

mov ebx, edi

and eax, 0ffffh

add ebx, eax

mov al, [ebx]

mov [esi], al

mov eax, edi

add eax, 0Ah

mov edi, eax

inc esi

loop loc_1_311F

pop cx

pop ebx

mov esi, ebx

mov ebx,[p2]

and ecx,0ffffh

loc_1_3078:

mov al, [ebx]

add al, 0

daa

mov ah, al

mov al, [esi]

and al, 0Fh

add al, ah

daa

and al, 0Fh

or al, 30h

mov [esi], al

inc esi

inc ebx

loop loc_1_3078

popad

}

memset(keycode,'\0',16);

strcpy(keycode,cs2);

int cn1=atoi(cs2);

unsigned short uscn=(unsigned short)cn1;

char st1[11];

char st2[21];

memset(st2,'\0',21);

memset(st1,'\0',11);

char *p3;

p3=st2;

st1[5]='\0';

rk=(unsigned short)rand();

strcat(st1,"41062");

sprintf(ctemp,"%05d",rk);

strcat(st1,ctemp);

char stemp[11];

memcpy(stemp,st1,11);

for(signed char jk=4;jk>=0;jk--)

for(unsigned char jj=0;jj<=9;jj++)

{

if ((jk==4)&&(jj>1))

continue;

memcpy(st1,stemp,11);

st1[0]=jk+0x30;

stemp[0]=jk+0x30;

st1[1]=jj+0x30;

stemp[1]=jj+0x30;

p1=st1;

__asm

{

pushad

mov ax,[uscn]

mov ebx,[p1]

mov cx,5

push ebx

push cx

clc

mov bx, ax

and bx, 157h

cmp bx, 0

jnz loc_2_30D4

nop

nop

xor bx, 153h

cmp bx, 0

jnz loc_2_30D4

nop

nop

or bx, 53h

loc_2_30D4:

cmp ax, bx

jb loc_2_30DF

nop

nop

push ax

mov ax, bx

pop bx

cwd

loc_2_30DF:

div bx

mov cx, 0Ah

mov ebx,[p3]

loc_2_30E7:

mov [k], cx

xor ax, dx

ror dx, 1

ror dx, 1

ror dx, 1

ror dx, 1

ror dx, 1

mov cl, dl

ror ax, cl

xor ax, dx

xor al, ah

xor dl, al

mov cl, dl

rol ax, cl

and ax, 0F0Fh

and eax,0ffffh

mov [ebx], ax

add ebx, 2

xor ecx,ecx

mov cx, [k]

loop loc_2_30E7

mov cx, 14h

mov esi,[p3]

mov edi,[pt]

mov bx, 0

loc_2_311F:

mov al, [esi]

mov ah, 0

mov ebx, edi

and eax,0ffffh

add ebx, eax

mov al, [ebx]

mov [esi], al

mov eax, edi

add eax, 0Ah

mov edi, eax

inc esi

loop loc_2_311F

}

p3=st2;

__asm

{

pop cx

pop ebx

mov esi, ebx

mov ebx, [p3]

and ecx,0ffffh

loc_2_309D:

mov al, [ebx]

add al, 0

daa

mov ah, al

mov al, [esi]

and al, 0Fh

or al, 10h

sub al, ah

das

and al, 0Fh

or al, 30h

mov [esi], al

inc esi

inc ebx

loop loc_2_309D

popad

}

char cct[5];

memset(cct,'\0',5);

memcpy(cct,st1,4);

signed short il;

il=(signed short)(atoi(cct));

if ((il>=0)&&(il<=0x100c))

goto thatisit;

}

thatisit:

strcat(keycode,stemp);

Edit2->Text=keycode;

}

需要编译好的注册机的请留下EMAIL,我会发给你们。 (出处:嬴政天下整理收藏)

相关文章:

·ASProtect的加密算法初步分析

·MD5算法研究

·Active Ebook Compiler的注册算法

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

·简单算法——小护士 V1.2

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

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

·加密算法之RSA算法

·加密算法之DES算法

·加密算法之ElGamal算法

相关软件:

·胜新出纳-支票打印软件 V4.0X 的注册码算法

·胜新现代办公百宝箱 V5.01 的注册码算法

·胜新信函宝典-信封打印软件 V2.02 注册码的算法

·胜新通用企业计划管理系统的注册码算法

·共享软件加密算法库 V3.2

·操作系统内存分配银行家算法模拟系统 XP

→ 特别推荐

→ 热点TOP10

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

关于我们 |

帮助(?)

| 广告服务 |

版权声明 |

商业合作 |

发展历程 |

加盟我们 |

联系我们

Copyright © 1999-2003

winzheng.com All Rights Reserved.

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

Powered

by:MeSky.Net

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

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

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