• 标 题:拼图游戏 (32千字)
  • 作 者:lq7972 
  • 时 间:2004-03-05 16:59:11
  • 链 接:http://bbs.pediy.com

Software:B-Jigsaw V7.7
拼图游戏。可任意选择图片,可将你自己的图片分成数块后生成为exe文件,将之发送给朋友
可自定义伴音,对图块可设置阴影及边框效果
试用 10 天,等你上瘾后,付 $14.95 (美金)再继续
http://www.adcsoft.com/bjigsaw.html
Tools:pe-scan 3.31, DeDe 3.50, OllyDbg 1.09
Cracker:lq7972 [bruceyu13@sina.com]
Notes:菜鸟一个,向大家学习


这个软件主程序的壳是 ASPack 2.12 -> Alexey Solodovnikov,用 pe-scan 脱,能运行
用 W32Dasm 反编译会不响应,只好用 DeDe 了( Borland C++ )
在【过程】栏有【license】单元有【BitBtnRegCodeClick】事件即程序启动画面上的【Enter reg cod】按钮,双击打开代码过程,信息很多也很有用:

* Reference to : TFormTimes._PROC_00413A70()
* Reference to: controls.TControl.GetText(TControl):TCaption;
* Reference to: controls.TControl.GetText(TControl):TCaption;
* Reference to : TFormMain._PROC_004116E8()
* Reference to class TRegistry
* Reference to: registry.constructorTRegistry.Create(TRegistry;boolean);

这是一个注册流程,先得到用户输入,生成注册码(T),然后将其与用户输入的注册码(F)比较,不等就"Invalid user name or registration code.",对呢就写注册表并"Thank you for registering."
其次,我们可以得到我们跟踪的下手(断点)的地方:
BitBtnRegCodeClick 00411040 0019
注意,还有一个【reg】单元,初下手时我们更愿意去分析和跟踪它;不过我没有这样去做,软件有这么一个简明的注册流程(真是方便了广大Cracker),为什么不用呢?在那里的分析可能是做无用功(我没有仔细看,不敢肯定;希望你研究后告诉我,期待ing……)


下面我们来动态跟踪调试:
(如果在软件启动画面出来前断点,退出)
打开 OllyDbg ,载入主程序,在 00411040 处 F2 断点,F9 运行,等上 3 秒钟后单击【Enter reg code】,拦住:

00411040  /. 55             push    ebp
; ……
00411070  |. FF92 CC000000  call    dword ptr ds:[edx+CC]              这里弹出注册窗dword p
00411076  |. 48             dec     eax
00411077     0F85 A1020000  jnz     0041131E                           bt.0041131E
0041107D  |. 66:C745 B4 140>mov     word ptr ss:[ebp-4C], 14
00411083  |. 33C9           xor     ecxecx
00411085  |. A1 C0DF4D00    mov     eaxdword ptr ds:[4DDFC0]
0041108A  |. 894D FC        mov     dword ptr ss:[ebp-4], ecx
0041108D  |. 8D55 FC        lea     edxdword ptr ss:[ebp-4]
00411090  |. FF45 C0        inc     dword ptr ss:[ebp-40]
00411093  |. 8B08           mov     ecxdword ptr ds:[eax]
00411095  |. 8B81 D4020000  mov     eaxdword ptr ds:[ecx+2D4]
0041109B  |. E8 70CC0700    call    0048DD10                           eax = name_len
004110A0  |. 66:C745 B4 080>mov     word ptr ss:[ebp-4C], 8
004110A6  |. 66:C745 B4 200>mov     word ptr ss:[ebp-4C], 20
004110AC  |. 33D2           xor     edxedx
004110AE  |. A1 C0DF4D00    mov     eaxdword ptr ds:[4DDFC0]
004110B3  |. 8955 F8        mov     dword ptr ss:[ebp-8], edx
004110B6  |. 8D55 F8        lea     edxdword ptr ss:[ebp-8]
004110B9  |. FF45 C0        inc     dword ptr ss:[ebp-40]
004110BC  |. 8B08           mov     ecxdword ptr ds:[eax]
004110BE  |. 8B81 D8020000  mov     eaxdword ptr ds:[ecx+2D8]
004110C4  |. E8 47CC0700    call    0048DD10                           得到用户输入的注册码(F),eax = reg_code(F)_len
004110C9  |. 66:C745 B4 080>mov     word ptr ss:[ebp-4C], 8
004110CF  |. 8BC3           mov     eaxebx
004110D1  |. E8 A60B0000    call    00411C7C                           bt.00411C7C
004110D6  |. 66:C745 B4 2C0>mov     word ptr ss:[ebp-4C], 2C
004110DC  |. 33D2           xor     edxedx
004110DE  |. 8D4D F4        lea     ecxdword ptr ss:[ebp-C]
004110E1  |. 8955 F4        mov     dword ptr ss:[ebp-C], edx
004110E4  |. 8BC3           mov     eaxebx
004110E6  |. FF45 C0        inc     dword ptr ss:[ebp-40]
004110E9  |. 8B55 FC        mov     edxdword ptr ss:[ebp-4]          user_name
004110EC  |. E8 F7050000    call    004116E8                           生成注册码算法 004116E8 见下
004110F1  |. 8D55 F4        lea     edxdword ptr ss:[ebp-C]          reg_code(T)_addr
004110F4  |. 8D45 F8        lea     eaxdword ptr ss:[ebp-8]          reg_code(F)_addr
004110F7  |. E8 A0FE0B00    call    004D0F9C                           当然是比较啦,不等 eax = 0
004110FC  |. 50             push    eax                               /Arg1
004110FD  |. FF4D C0        dec     dword ptr ss:[ebp-40]             |
00411100  |. 8D45 F4        lea     eaxdword ptr ss:[ebp-C]         |
00411103  |. BA 02000000    mov     edx, 2                            |
00411108  |. E8 ABFD0B00    call    004D0EB8                          \bt.004D0EB8
0041110D  |. 59             pop     ecx                                不等则 0  
0041110E  |. 84C9           test    clcl
00411110     0F84 63010000  je      00411279                           jump, gAMeoVeR
00411116  |. B2 01          mov     dl, 1
00411118  |. A1 50814600    mov     eaxdword ptr ds:[468150]
0041111D  |. E8 DA710500    call    004682FC                           写注册表   


;+++++++++++++++++++++++++++++++++++++++++++++++++++++++
; 注册算法
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++
004116E8   $ 55             push    ebp
004116E9   . 8BEC           mov     ebpesp
004116EB   . 83C4 8C        add     esp, -74
004116EE   . B8 38634D00    mov     eax, 4D6338
004116F3   . 53             push    ebx
004116F4   . 56             push    esi
004116F5   . 57             push    edi
004116F6   . 894D BC        mov     dword ptr ss:[ebp-44], ecx         0
004116F9   . 8955 F8        mov     dword ptr ss:[ebp-8], edx          user_name
004116FC   . E8 F3450B00    call    004C5CF4                           bt.004C5CF4
00411701   . C745 B4 010000>mov     dword ptr ss:[ebp-4C], 1
00411708   . 8D55 F8        lea     edxdword ptr ss:[ebp-8]          user_name_addr
0041170B   . 8D45 F8        lea     eaxdword ptr ss:[ebp-8]
0041170E   . E8 D9F60B00    call    004D0DEC                           bt.004D0DEC
00411713   . FF45 B4        inc     dword ptr ss:[ebp-4C]
00411716   . 66:C745 A8 080>mov     word ptr ss:[ebp-58], 8
0041171C   . 8D45 F8        lea     eaxdword ptr ss:[ebp-8]          user_name_addr
0041171F   . E8 04F90B00    call    004D1028                           eax = user_name_len
00411724   . 83F8 08        cmp     eax, 8
00411727   . 7F 5E          jg      short 00411787                     如果大/等于 8,就直接进入注册码计算  00411787
00411729   . 66:C745 A8 140>mov     word ptr ss:[ebp-58], 14
0041172F   . 33D2           xor     edxedx
00411731   . 8955 EC        mov     dword ptr ss:[ebp-14], edx
00411734   . 8D4D EC        lea     ecxdword ptr ss:[ebp-14]
00411737   . FF45 B4        inc     dword ptr ss:[ebp-4C]
0041173A   . BA 08000000    mov     edx, 8
0041173F   . B0 20          mov     al, 20
00411741   . E8 02F90B00    call    004D1048                           得到 8 个空格
00411746   . 8D55 EC        lea     edxdword ptr ss:[ebp-14]         8 个空格
00411749   . 33C0           xor     eaxeax
0041174B   . 8945 E8        mov     dword ptr ss:[ebp-18], eax
0041174E   . 8D4D E8        lea     ecxdword ptr ss:[ebp-18]
00411751   . FF45 B4        inc     dword ptr ss:[ebp-4C]
00411754   . 8D45 F8        lea     eaxdword ptr ss:[ebp-8]          user_name
00411757   . E8 B4F70B00    call    004D0F10                           "user_name"+8个" "~new_user_name 
0041175C   . 8D55 E8        lea     edxdword ptr ss:[ebp-18]         new_user_name
0041175F   . 8D45 F8        lea     eaxdword ptr ss:[ebp-8]          "user_name"  ~ old_user_namep
00411762   . E8 81F70B00    call    004D0EE8                           将 new_user_name 替 old_user_nam
00411767   . FF4D B4        dec     dword ptr ss:[ebp-4C]
0041176A   . 8D45 E8        lea     eaxdword ptr ss:[ebp-18]
0041176D   . BA 02000000    mov     edx, 2
00411772   . E8 41F70B00    call    004D0EB8                           bt.004D0EB8
00411777   . FF4D B4        dec     dword ptr ss:[ebp-4C]
0041177A   . 8D45 EC        lea     eaxdword ptr ss:[ebp-14]
0041177D   . BA 02000000    mov     edx, 2
00411782   . E8 31F70B00    call    004D0EB8                           bt.004D0EB8
00411787   > E8 44FF0B00    call    004D16D0                          [GetTickCount]
0041178C   . 8945 94        mov     dword ptr ss:[ebp-6C], eax         作反跟踪用
0041178F   . 66:C745 A8 080>mov     word ptr ss:[ebp-58], 8
00411795   . B8 01000000    mov     eax, 1
0041179A   > 40             inc     eax
0041179B   . 83F8 64        cmp     eax, 64
0041179E   .^7C FA          jl      short 0041179A                     bt.0041179A
004117A0   . E8 2BFF0B00    call    004D16D0                          [GetTickCount]
004117A5   . 8B55 94        mov     edxdword ptr ss:[ebp-6C]
004117A8   . 2BC2           sub     eaxedx
004117AA   . 3D E8030000    cmp     eax, 3E8
004117AF   . 76 0D          jbe     short 004117BE                     bt.004117BE
004117B1   . 8B0D FCDF4D00  mov     ecxdword ptr ds:[4DDFFC]         bt.004DE7AC
004117B7   . 8B01           mov     eaxdword ptr ds:[ecx]
004117B9   . E8 06200700    call    004837C4                           bt.004837C4
004117BE   > 66:C745 A8 080>mov     word ptr ss:[ebp-58], 8
004117C4   . 66:C745 A8 200>mov     word ptr ss:[ebp-58], 20
004117CA   . 33C0           xor     eaxeax
004117CC   . BB 01000000    mov     ebx, 1                             ebx = 1
004117D1   . 8945 F4        mov     dword ptr ss:[ebp-C], eax
004117D4   . FF45 B4        inc     dword ptr ss:[ebp-4C]
004117D7   . 83FB 08        cmp     ebx, 8
004117DA   . 66:C745 A8 080>mov     word ptr ss:[ebp-58], 8
004117E0   . 0F8F 4A020000  jg      00411A30                           bt.00411A30

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 这是第一次运算,实质是字符 Xor,再 Reverse
004117E6   > 8B3D 50584D00  mov     edidword ptr ds:[4D5850]         bt.004D5860
004117EC   . 57             push    edi                                "awgsJiBtAANrPNYOntA" ~ string
004117ED   . E8 36420B00    call    004C5A28
004117F2   . 59             pop     ecx                                string
004117F3   . 50             push    eax                                string_len = 19
004117F4   . 8BC3           mov     eaxebx                           eax = ebx
004117F6   . 5A             pop     edx                                edx = 19
004117F7   . 8BCA           mov     ecxedx
004117F9   . 33D2           xor     edxedx
004117FB   . F7F1           div     ecx                                eax div ecxeax = eax/ecxedx = eax % ecx
004117FD   . 8A0417         mov     albyte ptr ds:[edi+edx]          string [ebx], (1, ...)
00411800   . 50             push    eax
00411801   . 8BF3           mov     esiebx
00411803   . 56             push    esi                               /Arg2
00411804   . 8D45 F8        lea     eaxdword ptr ss:[ebp-8]         |new_user_name_addr
00411807   . 50             push    eax                               |Arg1
00411808   . E8 23F50B00    call    004D0D30                          \bt.004D0D30
0041180D   . 83C4 08        add     esp, 8
00411810   . 8D45 F8        lea     eaxdword ptr ss:[ebp-8]
00411813   . E8 A4F90B00    call    004D11BC                           edx = new_user_name
00411818   . 8B55 F8        mov     edxdword ptr ss:[ebp-8]
0041181B   . 03F2           add     esiedx
0041181D   . 4E             dec     esi                                new_user_name [ebx-1], (0,...)
0041181E   . 58             pop     eax                                string [ebx]
0041181F   . 8A16           mov     dlbyte ptr ds:[esi]              new_user_name [ebx-1]
00411821   . 32C2           xor     aldl                             string [ebxxor new_user_name [ebx-1]
00411823   . 0FBEC0         movsx   eaxal
00411826   . 66:C745 A8 080>mov     word ptr ss:[ebp-58], 8
0041182C   . 85C0           test    eaxeax
0041182E   . 7D 02          jge     short 00411832                     大/等于0则跳 bt.00411832
00411830   . F7D8           neg     eax        否则(主要是宽字符), (opr) ← -(opr)
00411832   > 66:C745 A8 380>mov     word ptr ss:[ebp-58], 38
00411838   . 33D2           xor     edxedx
0041183A   . 8955 E4        mov     dword ptr ss:[ebp-1C], edx
0041183D   . 8D55 E4        lea     edxdword ptr ss:[ebp-1C]
00411840   . FF45 B4        inc     dword ptr ss:[ebp-4C]
00411843   . E8 38950A00    call    004BAD80                           把 al xor dl 的结果 Hex2Dec2Str
00411848   . 66:C745 A8 2C0>mov     word ptr ss:[ebp-58], 2C
0041184E   . 8D45 E4        lea     eaxdword ptr ss:[ebp-1C]
00411851   . E8 D2F70B00    call    004D1028                           new_user_name_len->tmp_reg_code_len
00411856   . 48             dec     eax
00411857   . 7E 22          jle     short 0041187B                     <= 0 ? 即 eax <= 1,或者说xor的结果是一位数(<10)
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00411859   . 6A 02          push    2                                 /Arg2 = 00000002
0041185B   . 8D4D E4        lea     ecxdword ptr ss:[ebp-1C]        |
0041185E   . 51             push    ecx                               |Arg1
0041185F   . E8 CCF40B00    call    004D0D30                          \bt.004D0D30
00411864   . 83C4 08        add     esp, 8
00411867   . 8D45 E4        lea     eaxdword ptr ss:[ebp-1C]         tmp_reg_code_addr
0041186A   . E8 4DF90B00    call    004D11BC                           bt.004D11BC
0041186F   . 8B55 E4        mov     edxdword ptr ss:[ebp-1C]         edx = tmp_reg_code
00411872   . 42             inc     edx                                tmp_reg_code [1]
00411873   . 0FBE0A         movsx   ecxbyte ptr ds:[edx]
00411876   . 83F9 30        cmp     ecx, 30                            equal to 0 ? 即xor的结果(>=10)%10=0
00411879   . 75 56          jnz     short 004118D1                     bt.004118D1
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; 上述两种情况的处理是一样的
0041187B   > 66:C745 A8 440>mov     word ptr ss:[ebp-58], 44
;  即用 "1" 来代替 "0",连到 reg_code_A[0]
; 省略 N 行……

004118CF   . EB 6E          jmp     short 0041193F                     bt.0041193F
;===================================================================================================
004118D1   > 66:C745 A8 500>mov     word ptr ss:[ebp-58], 50
004118D7   . 6A 02          push    2                                 /Arg2 = 00000002
004118D9   . 8D4D E4        lea     ecxdword ptr ss:[ebp-1C]        |tmp_reg_code_addr
004118DC   . 51             push    ecx                               |Arg1
004118DD   . E8 4EF40B00    call    004D0D30                          \bt.004D0D30
004118E2   . 83C4 08        add     esp, 8
004118E5   . 8D45 E4        lea     eaxdword ptr ss:[ebp-1C]
004118E8   . E8 CFF80B00    call    004D11BC                           bt.004D11BC
004118ED   . 8B55 E4        mov     edxdword ptr ss:[ebp-1C]
004118F0   . 8D45 D8        lea     eaxdword ptr ss:[ebp-28]
004118F3   . 42             inc     edx                                tmp_reg_code [1]
004118F4   . 8A12           mov     dlbyte ptr ds:[edx]
004118F6   . E8 2DF50B00    call    004D0E28                           bt.004D0E28
004118FB   . FF45 B4        inc     dword ptr ss:[ebp-4C]
004118FE   . 33C0           xor     eaxeax
00411900   . 8945 D4        mov     dword ptr ss:[ebp-2C], eax
00411903   . 8D45 F4        lea     eaxdword ptr ss:[ebp-C]          reg_code_A(S)_addr
00411906   . FF45 B4        inc     dword ptr ss:[ebp-4C]
00411909   . 8D55 D8        lea     edxdword ptr ss:[ebp-28]
0041190C   . 8D4D D4        lea     ecxdword ptr ss:[ebp-2C]
0041190F   . E8 FCF50B00    call    004D0F10        提 tmp_reg_code[1] 出来
00411914   . 8D55 D4        lea     edxdword ptr ss:[ebp-2C]
00411917   . 8D45 F4        lea     eaxdword ptr ss:[ebp-C]
0041191A   . E8 C9F50B00    call    004D0EE8                           reg_code_A(S)[0] = tmp_reg_code[1]
0041191F   . FF4D B4        dec     dword ptr ss:[ebp-4C]
00411922   . 8D45 D4        lea     eaxdword ptr ss:[ebp-2C]
00411925   . BA 02000000    mov     edx, 2
0041192A   . E8 89F50B00    call    004D0EB8                           bt.004D0EB8
0041192F   . FF4D B4        dec     dword ptr ss:[ebp-4C]
00411932   . 8D45 D8        lea     eaxdword ptr ss:[ebp-28]
00411935   . BA 02000000    mov     edx, 2
0041193A   . E8 79F50B00    call    004D0EB8                           bt.004D0EB8
;===================================================================================================
0041193F   > 8D45 E4        lea     eaxdword ptr ss:[ebp-1C]

; 省略 N 行……
004119DE   . E8 2DF50B00    call    004D0F10        提 tmp_reg_code[0] 出来
004119E3   . 8D55 C4        lea     edxdword ptr ss:[ebp-3C]
004119E6   . 8D45 F4        lea     eaxdword ptr ss:[ebp-C]
004119E9   . E8 FAF40B00    call    004D0EE8                           reg_code_A(S)[1] = tmp_reg_code[0]
004119EE   . FF4D B4        dec     dword ptr ss:[ebp-4C]
004119F1   . 8D45 C4        lea     eaxdword ptr ss:[ebp-3C]
004119F4   . BA 02000000    mov     edx, 2
004119F9   . E8 BAF40B00    call    004D0EB8                           清除临时变量值  004D0EB
004119FE   . FF4D B4        dec     dword ptr ss:[ebp-4C]
00411A01   . 8D45 C8        lea     eaxdword ptr ss:[ebp-38]
00411A04   . BA 02000000    mov     edx, 2
00411A09   . E8 AAF40B00    call    004D0EB8                           bt.004D0EB8
00411A0E   > 83C3 02        add     ebx, 2                             ebx += 2
00411A11   . FF4D B4        dec     dword ptr ss:[ebp-4C]
00411A14   . 8D45 E4        lea     eaxdword ptr ss:[ebp-1C]
00411A17   . BA 02000000    mov     edx, 2
00411A1C   . E8 97F40B00    call    004D0EB8                           清除 tmp_reg_code 的值
00411A21   . 66:C745 A8 080>mov     word ptr ss:[ebp-58], 8
00411A27   . 83FB 08        cmp     ebx, 8                             ebx <= 8 ?
00411A2A   .^0F8E B6FDFFFF  jle     004117E6                           yes, jump
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

00411A30   > E8 9BFC0B00    call    004D16D0                          [GetTickCount]
00411A35   . 8B4D 94        mov     ecxdword ptr ss:[ebp-6C]
00411A38   . 2BC1           sub     eaxecx
00411A3A   . 3D E8030000    cmp     eax, 3E8
00411A3F   . 76 0C          jbe     short 00411A4D                     bt.00411A4D
00411A41   . A1 FCDF4D00    mov     eaxdword ptr ds:[4DDFFC]
00411A46   . 8B00           mov     eaxdword ptr ds:[eax]
00411A48   . E8 771D0700    call    004837C4                           bt.004837C4
00411A4D   > 66:C745 A8 740>mov     word ptr ss:[ebp-58], 74
00411A53   . 8B45 F4        mov     eaxdword ptr ss:[ebp-C]          reg_code_A
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 第二次运算,对 new_user_name 操作,累加到 reg_code_A(N)
00411A56   . E8 55930A00    call    004BADB0                           reg_code_A(N), Dec2Hex  bt.004BADB0
00411A5B   . 66:C745 A8 080>mov     word ptr ss:[ebp-58], 8
00411A61   . 8BF0           mov     esieax
00411A63   . EB 0D          jmp     short 00411A72                     bt.00411A72
00411A65   . 33F6           xor     esiesi
00411A67   . 66:C745 A8 7C0>mov     word ptr ss:[ebp-58], 7C
00411A6D   . E8 F8C50B00    call    004CE06A
00411A72   > 66:C745 A8 080>mov     word ptr ss:[ebp-58], 8
00411A78   . BB 01000000    mov     ebx, 1                             ebx = 1
00411A7D   . EB 2E          jmp     short 00411AAD                     bt.00411AAD
;=======================================================================================================================
00411A7F   > 8BFB           mov     ediebx                           edi = ebx
00411A81   . 57             push    edi                               /Arg2
00411A82   . 8D45 F8        lea     eaxdword ptr ss:[ebp-8]         |new_user_name_addr
00411A85   . 50             push    eax                               |Arg1
00411A86   . E8 A5F20B00    call    004D0D30                          \bt.004D0D30
00411A8B   . 83C4 08        add     esp, 8
00411A8E   . 8D45 F8        lea     eaxdword ptr ss:[ebp-8]
00411A91   . E8 26F70B00    call    004D11BC                           edx = new_user_name
00411A96   . 8B55 F8        mov     edxdword ptr ss:[ebp-8]
00411A99   . 8D041B         lea     eaxdword ptr ds:[ebx+ebx]        eax = ebx+ebx
00411A9C   . 03FA           add     ediedx                           edi = new_user_name [edi]
00411A9E   . 8D53 FF        lea     edxdword ptr ds:[ebx-1]          edx = ebx-1
00411AA1   . F7EA           imul    edx                                eax IMUL edx,高位在 edx,低位在 eax
00411AA3   . 4F             dec     edi                                new_user_name [edi-1]
00411AA4   . 0FBE0F         movsx   ecxbyte ptr ds:[edi]             
00411AA7   . 0FAFC8         imul    ecxeax
00411AAA   . 03F1           add     esiecx                           reg_code_A(N) += ecx
00411AAC   . 43             inc     ebx                                ebx ++
00411AAD   > 8D45 F8        lea     eaxdword ptr ss:[ebp-8]          new_user_name_addr
00411AB0   . E8 73F50B00    call    004D1028                           eax = new_user_name_len
00411AB5   . 3BD8           cmp     ebxeax
00411AB7   .^7E C6          jle     short 00411A7F                     bt.00411A7F
;=======================================================================================================================
00411AB9   . E8 12FC0B00    call    004D16D0                          [GetTickCount]
00411ABE   . 8B55 94        mov     edxdword ptr ss:[ebp-6C]
00411AC1   . 2BC2           sub     eaxedx
00411AC3   . 3D E8030000    cmp     eax, 3E8
00411AC8   . 76 0D          jbe     short 00411AD7                     bt.00411AD7
00411ACA   . 8B0D FCDF4D00  mov     ecxdword ptr ds:[4DDFFC]         bt.004DE7AC
00411AD0   . 8B01           mov     eaxdword ptr ds:[ecx]
00411AD2   . E8 ED1C0700    call    004837C4                           bt.004837C4
00411AD7   > 66:C745 A8 080>mov     word ptr ss:[ebp-58], 8

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 第三次运算,分三步,都是对 new_user_name 操作,累加到 reg_code_A(N)
00411ADD   . BB 01000000    mov     ebx, 1                             ebx = 1
00411AE2   . E9 93000000    jmp     00411B7A                           bt.00411B7A
;=======================================================================================================================
00411AE7   > 8BFB           mov     ediebx                           edi=ebx
00411AE9   . 57             push    edi                               /Arg2
00411AEA   . 8D45 F8        lea     eaxdword ptr ss:[ebp-8]         |new_user_name_addr
00411AED   . 50             push    eax                               |Arg1
00411AEE   . E8 3DF20B00    call    004D0D30                          \bt.004D0D30
00411AF3   . 83C4 08        add     esp, 8
00411AF6   . 8D45 F8        lea     eaxdword ptr ss:[ebp-8]
00411AF9   . E8 BEF60B00    call    004D11BC                           edx = new_user_name
00411AFE   . 8B55 F8        mov     edxdword ptr ss:[ebp-8]
00411B01   . 03FA           add     ediedx
00411B03   . 4F             dec     edi                                edi = new_user_name [i++], i=0,...
00411B04   . 0FBE0F         movsx   ecxbyte ptr ds:[edi]
00411B07   . 8BC1           mov     eaxecx
00411B09   . 895D 90        mov     dword ptr ss:[ebp-70], ebx        = ebx
00411B0C   . C1E0 03        shl     eax, 3
00411B0F   . 8B55 90        mov     edxdword ptr ss:[ebp-70]
00411B12   . 2BC1           sub     eaxecx
00411B14   . 8D4D F8        lea     ecxdword ptr ss:[ebp-8]
00411B17   . 52             push    edx                               /Arg2
00411B18   . 51             push    ecx                               |Arg1
00411B19   . 03F0           add     esieax                          |reg_code_A(N) += eax
00411B1B   . E8 10F20B00    call    004D0D30                          \bt.004D0D30
; 第一步过
;****************************************************************************************************************
00411B20   . 83C4 08        add     esp, 8
00411B23   . 8D45 F8        lea     eaxdword ptr ss:[ebp-8]
00411B26   . E8 91F60B00    call    004D11BC                           ecx = new_user_name
00411B2B   . 8B55 90        mov     edxdword ptr ss:[ebp-70]         还记得这个吗?
00411B2E   . 8B4D F8        mov     ecxdword ptr ss:[ebp-8]
00411B31   . 03D1           add     edxecx
00411B33   . 4A             dec     edx                                edx = new_user_name [i++], i=0,...
00411B34   . 0FBE02         movsx   eaxbyte ptr ds:[edx]
00411B37   . 8BD0           mov     edxeax
00411B39   . 895D 8C        mov     dword ptr ss:[ebp-74], ebx
00411B3C   . C1E2 04        shl     edx, 4
00411B3F   . 8B4D 8C        mov     ecxdword ptr ss:[ebp-74]
00411B42   . 2BD0           sub     edxeax
00411B44   . 51             push    ecx                               /Arg2
00411B45   . 8D1490         lea     edxdword ptr ds:[eax+edx*4]     |edx = eax+edx*4
00411B48   . 8D45 F8        lea     eaxdword ptr ss:[ebp-8]         |
00411B4B   . 50             push    eax                               |Arg1
00411B4C   . 03F2           add     esiedx                          |reg_code_A(N) += edx
00411B4E   . E8 DDF10B00    call    004D0D30                          \bt.004D0D30
; 第二步过
;****************************************************************************************************************
00411B53   . 83C4 08        add     esp, 8
00411B56   . 8D45 F8        lea     eaxdword ptr ss:[ebp-8]
00411B59   . E8 5EF60B00    call    004D11BC                           bt.004D11BC
00411B5E   . 8B55 8C        mov     edxdword ptr ss:[ebp-74]
00411B61   . 8B4D F8        mov     ecxdword ptr ss:[ebp-8]
00411B64   . 03D1           add     edxecx
00411B66   . 4A             dec     edx                                edx = new_user_name [i++], i=0,...
00411B67   . 0FBE02         movsx   eaxbyte ptr ds:[edx]
00411B6A   . 8D1440         lea     edxdword ptr ds:[eax+eax*2]      edx = eax+eax*2
00411B6D   . C1E2 05        shl     edx, 5
00411B70   . 2BD0           sub     edxeax
00411B72   . C1E2 04        shl     edx, 4
00411B75   . 03D0           add     edxeax
00411B77   . 03F2           add     esiedx                           reg_code_A(N) += edx
; 第三步过
;****************************************************************************************************************
00411B79   . 43             inc     ebx
00411B7A   > 8D45 F8        lea     eaxdword ptr ss:[ebp-8]          new_user_name_addr
00411B7D   . E8 A6F40B00    call    004D1028                           eax = new_user_name_len
00411B82   . 3BD8           cmp     ebxeax
00411B84   .^0F8E 5DFFFFFF  jle     00411AE7                           bt.00411AE7
;=======================================================================================================================

00411B8A   . E8 41FB0B00    call    004D16D0                          [GetTickCount]
00411B8F   . 8B55 94        mov     edxdword ptr ss:[ebp-6C]
00411B92   . 2BC2           sub     eaxedx
00411B94   . 3D E8030000    cmp     eax, 3E8
00411B99   . 76 0D          jbe     short 00411BA8                     bt.00411BA8
00411B9B   . 8B0D FCDF4D00  mov     ecxdword ptr ds:[4DDFFC]         bt.004DE7AC
00411BA1   . 8B01           mov     eaxdword ptr ds:[ecx]
00411BA3   . E8 1C1C0700    call    004837C4                           bt.004837C4
00411BA8   > 66:C745 A8 800>mov     word ptr ss:[ebp-58], 80
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 下面是连接 "BJ" 和 reg_code_A ,这就是我们所要得到的
00411BAE   . BA 4A5A4D00    mov     edx, 4D5A4A                        ASCII "BJ"
00411BB3   . 8D45 F0        lea     eaxdword ptr ss:[ebp-10]         reg_code(F)_addr
00411BB6   . E8 F9F10B00    call    004D0DB4                           reg_code = "BJ"
00411BBB   . FF45 B4        inc     dword ptr ss:[ebp-4C]
00411BBE   . 33D2           xor     edxedx
00411BC0   . 66:C745 A8 080>mov     word ptr ss:[ebp-58], 8
00411BC6   . 66:C745 A8 8C0>mov     word ptr ss:[ebp-58], 8C
00411BCC   . 8955 C0        mov     dword ptr ss:[ebp-40], edx
00411BCF   . 8D55 C0        lea     edxdword ptr ss:[ebp-40]
00411BD2   . FF45 B4        inc     dword ptr ss:[ebp-4C]
00411BD5   . 8BC6           mov     eaxesi                           eax = reg_code_A(N)
00411BD7   . E8 A4910A00    call    004BAD80                           reg_code_A(N) : Hex2Dec2Str
00411BDC   . 8D55 C0        lea     edxdword ptr ss:[ebp-40]         reg_code_A(S)
00411BDF   . 8D45 F0        lea     eaxdword ptr ss:[ebp-10]         reg_code
00411BE2   . E8 15F30B00    call    004D0EFC                           reg_code += reg_code_A(S)
00411BE7   . FF4D B4        dec     dword ptr ss:[ebp-4C]
; ……

00411C1D   . E8 96F20B00    call    004D0EB8                           edx = reg_code

;……
00411C5C   . C3             retn

【总结】
我想上面应该讲的比较清楚,这里归纳一下:
1、软件获得用户输入后,比较用户名长度(user_name_len)是否小/等于 8;是,则在后面添上 8 个 0x20,得到 new_user_name
2、对 new_user_name 与 string 依次作 XOR ,将其结果(十进制)转为字符再调换前后位置;
     这里要注意,不管你的用户名多长,它总只取到 8 并且取奇数位;
     其次,程序还判断 XOR 的结果是否 <= 0,只有一位数,和有两位但个位是 0 等三种情况,这需要一些经验(ASM, CRACK)
3、接下来就比较简单了,两个循环依次从 new_user_name 取值运算(各具体操作不同,见前),并累加到 reg_code_A(N),然后累加到 reg_code_A(N);
   第二次循环有这样的三步。(S)表示这是字符串,(N)表示是值
4、连接 "BJ" 和 reg_code_A(S),就是 reg_code

注册成功,则没有启动画面,并在注册表中写入信息:
[HKEY\CURRENT_USER\Software\ADCSotf\BJigsaw]
"RegCode"="BJ74029154"
"UserName"="lq7972"

软件给出的字符串:string : "awgsJiBtAANrPNYOntA"

【注册机】
/* BJigsaw V 7.7 KeyGen */
/* with C Language */
/* by lq7972 */
/* bruceyu13@sina.com */

#include 
#include 
#include 

/*///////////////////////////////////////////////////////*/
/* 主程序 */
int main ()
{
   int  i=0, j;
   int  nameLen;
   int  tmp01, tmp02, tmp03;
   int  regCode_N;
   char regCode_S [10] = "0";
   char regName [255];
   char * setString = "awgsJiBtAANrPNYOntA";
   
   printf ("Enter your name : ");
   gets (regName);
   nameLen = strlen (regName);
   
   /* 根据用户名长度作相应处理 */ 
   if (nameLen < 8) {
      while (i++ <= 8)
         regName [nameLen+i-1] = 0x20;       /* space character */
               
      regName [nameLen+i-2] = 0;             /* nul */
      nameLen = strlen (regName);
   }
   
   /* 做第一次运算 */
   for (i=1, j=0; i <= 8; i += 2, j += 2) {
      tmp01 = setString [i];
      tmp02 = regName [i-1];
      tmp03 = tmp01 ^ tmp02;
      
      if (tmp03 < 0)
         tmp03 *= -1;
         
      tmp01 = tmp03 % 10; tmp02 =  tmp03 / 10;
      if (0 == tmp02) {
         regCode_S [j] = 0x31;
         regCode_S [j+1] = tmp01 + 0x30;
      }         
      else if (0 == tmp01) {
         regCode_S [j] = 0x31;
         regCode_S [j+1] = tmp01 + 0x30;
      }
      
      else {
         regCode_S [j] = tmp01 + 0x30;
         regCode_S [j+1] = tmp02 + 0x30;
      }
   }
   regCode_N = atoi (regCode_S);
   
   /* 第二次运算 */
   for (i=1; i <= nameLen; i ++) {
      tmp01 = i+i; tmp02 = regName [i-1]; tmp03 = i-1;
      regCode_N += tmp01 * tmp03 * tmp02;
   }
   printf ("\n\n");

   /* 第三步运算 */
   for (i=1; i <= nameLen; i ++) {
      tmp01 = tmp02 = tmp03 = regName [i-1];
      
      tmp01 <<= 3; tmp01 -= tmp03;
      regCode_N += tmp01;
      
      tmp02 <<= 4; tmp02 -= tmp03;
      tmp01 = tmp03+tmp02*4;
      regCode_N += tmp01;
      
      tmp01 = tmp03 + tmp03*2;
      tmp01 <<= 5; tmp01 -= tmp03;
      tmp01 <<= 4; tmp01 += tmp03;
      regCode_N += tmp01;
   }
   
   printf ("You Reg Code : %s%d\n", "BJ", regCode_N);
   
   return 0;
}

/* Thanks. */