• 标 题:小李注册表大师 v1.41 注册算法分析--献给 LILITH 和解密算法初学者 (10千字)
  • 作 者:PaulYoung[CCG]
  • 时 间:2001-11-9 19:09:59
  • 链 接:http://bbs.pediy.com

小李注册表大师 v1.41 注册算法分析--献给 LILITH 和解密算法初学者

作者:PaulYoung ( 属于 China Cracking Group )
难度:0 级 (共分 10 级,0 级最易)
软件:小李注册表大师 v1.41
下载:http://www.csdn.net/soft/openfile.asp?kind=1&id=14499  ( 456 KB )
简介:看软件名就知道干啥用的了
工具:SoftICE V4.05
日期:2001.11.07

************************************************************************************************

  今天,“理你死”??!!哦……不是,是“LILITH”(MM ?!  :)~  No, 靓仔一名 :( ),在看雪论坛发篇关于小李注册表大师 v1.41 的注册码 D 注册码大法,可惜此兄太懒,不愿跟算法,无奈,就让我这个当师父的来代劳吧。
  这个软件是明码比较,非常傻瓜的那种,如何取注册码, LILITH 兄已经说得非常清楚了,在此我就省略那些无关枝节吧,重点分析它的注册算法。

  Let's Go!! 想学算法的 Cracker 们!

  为方便大家理解,以我的注册序列号" 1D6D-17E5 "和输入的用户名是" CCG "为例,说说这个软件的注册算法。跟踪法请看 LILITH 大侠的文章 :) 。

== 1 ==

* Possible StringData Ref from Code Obj ->"key"
                                  |
:00490EF1 BAD4104900              mov edx, 004910D4
:00490EF6 E88562FEFF              call 00477180
:00490EFB A1D4034A00              mov eax, dword ptr [004A03D4]
:00490F00 8B00                    mov eax, dword ptr [eax]
:00490F02 E8D95BFEFF              call 00476AE0
:00490F07 8D55E8                  lea edx, dword ptr [ebp-18]
:00490F0A A1EC024A00              mov eax, dword ptr [004A02EC]
:00490F0F 8B00                    mov eax, dword ptr [eax]
:00490F11 E88673F7FF              call 0040829C                //取序列号"1D6D-17E5"
:00490F16 8D45E8                  lea eax, dword ptr [ebp-18]
:00490F19 50                      push eax
:00490F1A 8D55E4                  lea edx, dword ptr [ebp-1C]
:00490F1D 8B83DC020000            mov eax, dword ptr [ebx+000002DC]
:00490F23 E89403FAFF              call 004312BC
:00490F28 8B55E4                  mov edx, dword ptr [ebp-1C]
:00490F2B 58                      pop eax
:00490F2C E8372EF7FF              call 00403D68                //取用户名"CCG"
:00490F31 8B45E8                  mov eax, dword ptr [ebp-18]
:00490F34 8D55EC                  lea edx, dword ptr [ebp-14]
:00490F37 E86875F7FF              call 004084A4  //把序列号小写和用户名连成一串"1d6d-17e5CCG"
:00490F3C 8B55EC                  mov edx, dword ptr [ebp-14]
:00490F3F A174014A00              mov eax, dword ptr [004A0174]
:00490F44 8B00                    mov eax, dword ptr [eax]
:00490F46 8B8064030000            mov eax, dword ptr [eax+00000364]
:00490F4C E8EB2DFEFF              call 00473D3C                //开始计算,F8跟进
:00490F51 8D45FC                  lea eax, dword ptr [ebp-04]  //下面都是些老掉牙的东东,不用多说
:00490F54 8B1574014A00            mov edx, dword ptr [004A0174]
:00490F5A 8B12                    mov edx, dword ptr [edx]
:00490F5C 8B9264030000            mov edx, dword ptr [edx+00000364]
:00490F62 8B524C                  mov edx, dword ptr [edx+4C]
:00490F65 E80E2CF7FF              call 00403B78
:00490F6A 8D55E0                  lea edx, dword ptr [ebp-20]
:00490F6D 8B83E0020000            mov eax, dword ptr [ebx+000002E0]
:00490F73 E84403FAFF              call 004312BC
:00490F78 8B45E0                  mov eax, dword ptr [ebp-20]
:00490F7B 8B55FC                  mov edx, dword ptr [ebp-04]
:00490F7E E8ED2EF7FF              call 00403E70             
:00490F83 7567                    jne 00490FEC               
:00490F85 8D55D8                  lea edx, dword ptr [ebp-28]
:00490F88 8B83DC020000            mov eax, dword ptr [ebx+000002DC]
:00490F8E E82903FAFF              call 004312BC
:00490F93 8B4DD8                  mov ecx, dword ptr [ebp-28]
:00490F96 8D45DC                  lea eax, dword ptr [ebp-24]

* Possible StringData Ref from Code Obj ->"小李注册表大师已经注册给"
                                  |
:00490F99 BAE0104900              mov edx, 004910E0

== 2 ==

:00473D3C 55                      push ebp
:00473D3D 8BEC                    mov ebp, esp
:00473D3F 83C4F8                  add esp, FFFFFFF8
:00473D42 53                      push ebx
:00473D43 56                      push esi
:00473D44 33C9                    xor ecx, ecx
:00473D46 894DF8                  mov dword ptr [ebp-08], ecx
:00473D49 8955FC                  mov dword ptr [ebp-04], edx
:00473D4C 8BD8                    mov ebx, eax
:00473D4E 8B45FC                  mov eax, dword ptr [ebp-04]
:00473D51 E8BE01F9FF              call 00403F14
:00473D56 33C0                    xor eax, eax
:00473D58 55                      push ebp
:00473D59 68E33D4700              push 00473DE3
:00473D5E 64FF30                  push dword ptr fs:[eax]
:00473D61 648920                  mov dword ptr fs:[eax], esp
:00473D64 33F6                    xor esi, esi
:00473D66 8D4350                  lea eax, dword ptr [ebx+50]
:00473D69 8B55FC                  mov edx, dword ptr [ebp-04]
:00473D6C E8C3FDF8FF              call 00403B34
:00473D71 8B4350                  mov eax, dword ptr [ebx+50]
:00473D74 E8E7FFF8FF              call 00403D60    //取字符串"1d6d-17e5CCG"长度,保存到 eax
:00473D79 85C0                    test eax, eax
:00473D7B 7E20                    jle 00473D9D
:00473D7D 8B4350                  mov eax, dword ptr [ebx+50]
:00473D80 E8DBFFF8FF              call 00403D60    //取字符串"1d6d-17e5CCG"长度,保存到 eax
:00473D85 85C0                    test eax, eax
:00473D87 7C14                    jl 00473D9D
:00473D89 40                      inc eax          // eax+1 ,即字符串长度加1,就是下面的循环次数
:00473D8A 33D2                    xor edx, edx    // edx 初始值为 0

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00473D9B(C)
|
:00473D8C 8B4B50                  mov ecx, dword ptr [ebx+50]      //载入字符串
:00473D8F 0FB64C11FF              movzx ecx, byte ptr [ecx+edx-01] //依次取字符串以ASCII形式保存到 ecx ,第一次循环值为0
:00473D94 03F1                    add esi, ecx                    //与上一次循环后得到的累加值相加
:00473D96 037354                  add esi, dword ptr [ebx+54]      //当前字符 ASCII 值 + 57791
:00473D99 42                      inc edx                        // edx 递增
:00473D9A 48                      dec eax                        // eax 即循环次数递减
:00473D9B 75EF                    jne 00473D8C                    // eax>0 ?未算完,继续吧…… :(

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00473D7B(C), :00473D87(C)
|
:00473D9D 8D55F8                  lea edx, dword ptr [ebp-08]
:00473DA0 8BC6                    mov eax, esi          //把累加值"752094"放到 eax
:00473DA2 E87D48F9FF              call 00408624
:00473DA7 FF7344                  push [ebx+44]
:00473DAA FF75F8                  push [ebp-08]
:00473DAD FF7348                  push [ebx+48]
:00473DB0 8D45F8                  lea eax, dword ptr [ebp-08]
:00473DB3 BA03000000              mov edx, 00000003    //把 edx 置值为3,即下面循环的次数
:00473DB8 E86300F9FF              call 00403E20        //再次运算,F8进入
:00473DBD 8D434C                  lea eax, dword ptr [ebx+4C]

== 3 ==

:00403E20 53                      push ebx
:00403E21 56                      push esi
:00403E22 52                      push edx
:00403E23 50                      push eax
:00403E24 89D3                    mov ebx, edx
:00403E26 31C0                    xor eax, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403E34(C)
|
:00403E28 8B4C9410                mov ecx, dword ptr [esp+4*edx+10] -----
:00403E2C 85C9                    test ecx, ecx                          |
:00403E2E 7403                    je 00403E33                            |
:00403E30 0341FC                  add eax, dword ptr [ecx-04]            |循环 3 次,
                                                                        |在"752094"前后分别
* Referenced by a (U)nconditional or (C)onditional Jump at Address:      |加上"8" , "2"
|:00403E2E(C)                                                            |
|                                                                        |
:00403E33 4A                      dec edx      //循环次数递减        |
:00403E34 75F2                    jne 00403E28    -----------------------
:00403E36 E869FDFFFF              call 00403BA4
:00403E3B 50                      push eax
:00403E3C 89C6                    mov esi, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403E53(C)
|
:00403E3E 8B449C14                mov eax, dword ptr [esp+4*ebx+14] -------------
:00403E42 89F2                    mov edx, esi                                  |
:00403E44 85C0                    test eax, eax                                  |
:00403E46 740A                    je 00403E52                                    |
:00403E48 8B48FC                  mov ecx, dword ptr [eax-04]                    |
:00403E4B 01CE                    add esi, ecx                                  |再循环3次,
:00403E4D E8F6EAFFFF              call 00402948                                  |检查注册码格式
                                                 |
* Referenced by a (U)nconditional or (C)onditional Jump at Address:              |
|:00403E46(C)                                     |    
|                                         |
:00403E52 4B                      dec ebx      //循环次数递减            |
:00403E53 75E9                    jne 00403E3E-----------------------------------
:00403E55 5A                      pop edx
:00403E56 58                      pop eax
:00403E57 85D2                    test edx, edx
:00403E59 7403                    je 00403E5E
:00403E5B FF4AF8                  dec [edx-08]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403E59(C)
|
:00403E5E E8D1FCFFFF              call 00403B34    //至此,正确的注册码已经生成!
:00403E63 5A                      pop edx
:00403E64 5E                      pop esi
:00403E65 5B                      pop ebx
:00403E66 58                      pop eax
:00403E67 8D2494                  lea esp, dword ptr [esp+4*edx]
:00403E6A FFE0                    jmp eax
:00403E6C C3                      ret


算法总结:
  1、软件取你的硬盘序列号并转换成十六进制,然后在中间加上"-",作为你的注册序列号(此步可忽略);
  2、将你的注册序列号转换成小写并与用户名组成一个字符串;
  3、将字符串的每个字符都转换成 ASCII ,并逐个循环与 57791 相加并将每次的值累加,循环次数是字符串长度加一,初次循环的累加值为 57791 ,直到取完所有字符为止,如以"1d6d-17e5CCG"为例,计算公式为:57791+(49+57791)+(100+57791)+(54+57791)+(100+57791)+(45+57791)+(49+57791)+(55+57791)+(101+57791)+(53+57791)+(67+57791)+(67+57791)+(71+57791)=(49+100+54+100+45+49+55+101+53+67+67+71)+(13*57791)=752094
  4、最后,再在752094前后分别加上8、2,变成 87520942 ,就是正确的序列号了。

  是不是好弱智???注册机就有劳伪装者[CCG]教大家如何写了,还有我,呵……

  • 标 题:小李注册表大师 v1.41 注册机(TC) (497字)
  • 作 者:8989
  • 时 间:2001-11-10 9:40:17

小李注册表大师 v1.41 注册机(TC)
#include "stdio.h"
main()
{
unsigned char string[40],string1[20];
int i,c,b1,b2;
long d=0;
clrscr();
printf("******RegMaster 1.41********\nAuthor>> fpx.yeah.net\nYour ID : ");
gets(string1);
b1=strlen(string1);
for(i=0;(c=string1[i])!='\0';i++)
{if((c>64)&&(c<91)) {c=c+32;}
d+=c;}
printf("Your name:");
gets(string);
b2=strlen(string);
d+=(b1+b2+1)*57791;
printf("Your Code: ");
for(i=0;(c=string[i])!='\0';i++)
{d+=c;}
printf("8%ld2",d);
}

  • 标 题:谢谢PaulYoung[CCG]大侠指点!我一定将它写得更长!刚才没有拜读大侠的大作,实是遗憾。拜读之后,豁然开朗... (6千字)
  • 作 者:5,555
  • 时 间:2001-11-11 8:21:01

标题: 谢谢PaulYoung[CCG]大侠指点!我一定将它写得更长!刚才没有拜读大侠的大作,实是遗憾。拜读之后,豁然开朗,于是又加上了自动获得ID的功能!

内容:
这个功能未加测试,本人没有这个软件,只是照本宣科,做了这个东东。假设ID是DOS命令VOL显示的硬盘序列号:)
这次变动主要是数据段加了几个定义,INIT处加了Call GetID,当然又加了一个GedID Proc啦。本人有个毛病,复制和粘贴往往点错,于是又在序列号框中发送了一个只读的消息,这样就不会“误贴”啦~~~~~~~~~~

.386
  .model flat,stdcall
  option casemap:none
  include hd.h
  _ProcDlg proto :DWORD,:DWORD,:DWORD,:DWORD

.data
  NameLen  dd 0
  IDLen    dd 0
  IDSum    dd 0
  DecLen  dd 0
  InputOK  dd 0
  MsgMesaage1 db "请输入您的ID和用户名!",0
  MsgCap      db "小李注册表大师 v1.41 注册机  by 5,555",0
  VName    db 256 dup (0)
  FSName    db 256 dup (0)
  Drive    db "C:\",0
  VID      dd 0


.data?
  hInstance  HANDLE ?
  UserName db 80 dup (?)
  ID      db 80 dup (?)
  RegNum  db 80 dup (?)

.const
  DLG_MAIN  equ    1000
  IDC_ID    equ    1001
  IDC_RN    equ    1002
  ID_GEN    equ    1003
  ID_EXIT  equ    1004
  IDC_USER  equ    1005

.code
  start:
      invoke    GetModuleHandle,NULL
      mov    hInstance,eax
      invoke    DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlg,0
      invoke    ExitProcess,NULL

  _ProcDlg    proc    uses ebx edi esi, \
          hWnd:DWORD,wMsg:DWORD,wParam:DWORD,lParam:DWORD

          mov    eax,wMsg
          .if        eax == WM_CLOSE
                    invoke    EndDialog,hWnd,NULL
          .elseif    eax == WM_INITDIALOG
                    call GetID
                    invoke SetDlgItemText,hWnd,IDC_ID,addr ID
                    invoke SetWindowText,hWnd,ADDR MsgCap
                    invoke SendDlgItemMessage,hWnd,IDC_RN,EM_SETREADONLY,TRUE,NULL
          .elseif    eax == WM_COMMAND
                    mov eax,wParam
                    .IF lParam!=0
                        .if  ax==ID_GEN
                            mov dword ptr InputOK,0
                            invoke RtlZeroMemory,addr ID,80
                            invoke RtlZeroMemory,addr UserName,80
                            invoke RtlZeroMemory,addr RegNum,80
                            invoke GetDlgItemText,hWnd,IDC_ID,addr ID,80
                            .IF eax != NULL
                                mov IDLen,eax
                                invoke GetDlgItemText,hWnd,IDC_USER,addr UserName,80
                                .IF  eax != NULL
                                    mov NameLen,eax
                                    mov dword ptr InputOK,1
                                    call Cal
                                    invoke SetDlgItemText,hWnd,IDC_RN,addr RegNum
                                .ENDIF
                            .ENDIF
                            cmp dword ptr InputOK,1
                            jz  Main_Exit
                            invoke MessageBox,NULL,addr MsgMesaage1,addr MsgCap,MB_OK or MB_ICONEXCLAMATION
                        .elseif ax==ID_EXIT
                                invoke SendMessage,hWnd,WM_CLOSE,NULL,NULL
                        .endif
                    .ENDIF
          .else
                  mov eax,FALSE
                  ret
          .endif
Main_Exit:
          mov eax,TRUE
          ret
_ProcDlg  ENDP


Cal        PROC
            pushad
            xor ebx,ebx
            xor eax,eax
            lea esi,ID
Cal_Lop1:
            lodsb
            test al,al
            jz Cal_2
            cmp al,'A'
            jb Cal_1
            cmp al,'Z'
            ja Cal_1
            add al,'a'-'A'
Cal_1:
            add ebx,eax
            jmp Cal_Lop1
Cal_2:
            mov IDSum,ebx
            mov eax,IDLen
            add eax,NameLen
            inc eax
            mov ecx,57791
            imul ecx
            add ebx,eax
            lea esi,UserName
            xor eax,eax
Cal_Lop2:
            lodsb
            test al,al
            jz ToAsc
            add ebx,eax
            jmp Cal_Lop2
ToAsc:
            mov eax,ebx
            lea ebp,RegNum
            mov byte ptr [ebp],'8'
            inc ebp
            call Num2Dec
            add ebp,DecLen
            mov byte ptr [ebp],'2'
            mov byte ptr [ebp+1],0
Cal_Exit:
            popad
            ret
Cal        endp

Num2Dec Proc    ;eax:Num to convert, ebp-->buffer
        pushad
        xor ecx,ecx
        mov ebx,10
@Num2Dec_Lop1:
        cdq
        div ebx
        push edx
        inc ecx
        test eax,eax
        jnz @Num2Dec_Lop1
        mov DecLen,ecx
@Num2Dec_Lop2:
        pop eax
        add al,'0'
        mov byte ptr [ebp],al
        inc ebp
        dec ecx
        jnz @Num2Dec_Lop2
        mov byte ptr [ebp],0
        popad
        ret
Num2Dec Endp

GetID  Proc
        pushad
        invoke  GetVolumeInformation, addr Drive, addr VName, 255, addr VID, 0, 0, addr FSName, 255
        mov eax,VID
       
        lea ebp,ID
        mov ecx,8
Num2Asc_Lop1:
        rol eax,4
        mov edx,eax
        and dl,0fh
        cmp dl,9
        jna Digital
        add dl,'A'-'0'-0ah
Digital:
        add dl,'0'
        cmp ecx,4
        jnz StoreID
        mov byte ptr [ebp],'-'
        inc ebp
StoreID:
        mov [ebp],dl
        inc ebp
        loop Num2Asc_Lop1
       
        popad
        ret
GetID  Endp
        end start

;以下为rsrc.rc:
#include <\masm32\include\resource.h>
#define DLG_MAIN  1000
#define IDC_ID    1001
#define IDC_RN    1002
#define ID_GEN    1003
#define ID_EXIT  1004
#define IDC_USER    1005
DLG_MAIN DIALOG 64,53,180,80
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "小李注册表大师 v1.41 注册机  by 5,555"
FONT 9, "宋体"
{
DEFPUSHBUTTON "注册", ID_GEN, 140, 10, 25, 14
PUSHBUTTON "退出", ID_EXIT, 140, 42, 25, 14
EDITTEXT IDC_ID, 52, 10, 78, 12, WS_BORDER | WS_TABSTOP
EDITTEXT IDC_USER, 52, 29, 78, 13, WS_BORDER | WS_TABSTOP
EDITTEXT IDC_RN, 52, 48, 78, 14, WS_BORDER | WS_TABSTOP
LTEXT "ID号码:", -1, 8, 12, 40, 10
LTEXT "用户名:", -1, 8, 30, 41, 9
LTEXT "序列号:", -1, 8, 48, 42, 8
}

;HD.h,大家都有的
      include \masm32\include\windows.inc
      include \masm32\include\user32.inc
      include \masm32\include\kernel32.inc
      include \masm32\include\gdi32.inc
      include \masm32\include\comctl32.inc
      include \masm32\include\comdlg32.inc
      include \masm32\include\shell32.inc
    include \masm32\include\advapi32.inc

      includelib \masm32\lib\user32.lib
      includelib \masm32\lib\kernel32.lib
      includelib \masm32\lib\gdi32.lib
      includelib \masm32\lib\comctl32.lib
      includelib \masm32\lib\comdlg32.lib
      includelib \masm32\lib\shell32.lib
    includelib \masm32\lib\advapi32.lib