• 标 题:DaBri Soft的“桥牌定约人练习”的注册机 (15千字)
  • 作 者:peter888
  • 时 间:2002-10-17 15:59:35
  • 链 接:http://bbs.pediy.com

目标: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,我会发给你们。