【文章标题】: MP3 RM Converter V1.3注册算法分析
【文章作者】: xuecrack
【作者邮箱】: 243261920@163.com
【作者主页】: http://hi.csdn.net/haart
【作者QQ号】: 243261920
【软件名称】: MP3 RM Converter V1.3
【下载地址】: http://www.audiotoolsfactory.com(Homepage)
【加壳方式】: 未加壳
【编写语言】: Borland Delphi 6.0 - 7.0
【使用工具】: OD,PEID
【操作平台】: WinXP Sp3
【软件介绍】: 一个不错的音频转换软件,支持常见的音频格式相互转换
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!本文进攻学习参考!
--------------------------------------------------------------------------------
【详细过程】
  上次写了一篇破文,最后没能分析出注册算法,有点不爽。OK,今天这一篇破文把软件的注册算法给分析出来!
  
  首先把软件扔给PEID老兄,他嗲嗲的告诉我没加壳,接着试注册
  
  USER:PEDIY
  CODE:123456789
   
  弹出错误提示框,内容为“invalid register code! please retry!”。接下来用OD的超级字符串查找插件,查找UNICODE。查找“code”找到
  
   超级字串参考+        , 条目 462
   地址=0049A9B5
   反汇编=MOV EAX,MP3_RM_C.0049AB44
   文本字串=invalid register code! please retry!
  
  双击该行进入反汇编窗口。定位在0049A9B5这一行。
  
  0049A9AA  |.  6A 00         PUSH 0                                   ; /Arg1 = 00000000
  0049A9AC  |.  66:8B0D 38AB4>MOV CX,WORD PTR DS:[49AB38]              ; |
  0049A9B3  |.  B2 02         MOV DL,2                                 ; |
  0049A9B5  |.  B8 44AB4900   MOV EAX,MP3_RM_C.0049AB44                ; |invalid register code! please retry!
  0049A9BA  |.  E8 9D7CF9FF   CALL MP3_RM_C.0043265C                   ; \MP3_RM_C.0043265C
  
  向上找到段首下断,再次输入用户名,假码注册。程序被断下来,F8单步跟踪,   一些对注册没影响的CALL略过,跟踪过程记录如下。
  
  0049A928  /.  55            PUSH EBP
  0049A929  |.  8BEC          MOV EBP,ESP
  0049A92B  |.  33C9          XOR ECX,ECX
  0049A92D  |.  51            PUSH ECX
  0049A92E  |.  51            PUSH ECX
  0049A92F  |.  51            PUSH ECX
  0049A930  |.  51            PUSH ECX
  0049A931  |.  51            PUSH ECX
  0049A932  |.  51            PUSH ECX
  0049A933  |.  53            PUSH EBX
  0049A934  |.  56            PUSH ESI
  0049A935  |.  57            PUSH EDI
  0049A936  |.  8BF8          MOV EDI,EAX
  0049A938  |.  33C0          XOR EAX,EAX
  0049A93A  |.  55            PUSH EBP
  0049A93B  |.  68 2AAB4900   PUSH MP3_RM_C.0049AB2A
  0049A940  |.  64:FF30       PUSH DWORD PTR FS:[EAX]
  0049A943  |.  64:8920       MOV DWORD PTR FS:[EAX],ESP
  0049A946  |.  C605 0C2D4A00>MOV BYTE PTR DS:[4A2D0C],1
  0049A94D  |.  8D55 F4       LEA EDX,[LOCAL.3]
  0049A950  |.  8B87 1C030000 MOV EAX,DWORD PTR DS:[EDI+31C]
  0049A956  |.  E8 3132FCFF   CALL MP3_RM_C.0045DB8C                   ;  取用户名
  0049A95B  |.  8B45 F4       MOV EAX,[LOCAL.3]                        ;  把用户名放到EAX
  0049A95E  |.  8D55 FC       LEA EDX,[LOCAL.1]
  0049A961  |.  E8 3EDDF6FF   CALL MP3_RM_C.004086A4
  0049A966  |.  8D55 F0       LEA EDX,[LOCAL.4]
  0049A969  |.  8B45 FC       MOV EAX,[LOCAL.1]
  0049A96C  |.  E8 67DDF6FF   CALL MP3_RM_C.004086D8
  0049A971  |.  8B55 F0       MOV EDX,[LOCAL.4]
  0049A974  |.  8D45 FC       LEA EAX,[LOCAL.1]
  0049A977  |.  E8 9898F6FF   CALL MP3_RM_C.00404214
  0049A97C  |.  BB 15000000   MOV EBX,15
  0049A981  |.  BE F8174A00   MOV ESI,MP3_RM_C.004A17F8
  0049A986  |>  8B45 FC       /MOV EAX,[LOCAL.1]                       ;  用户名地址放到EAX
  0049A989  |.  8B16          |MOV EDX,DWORD PTR DS:[ESI]              ;  DS:[004A17F8]=0049A6E4 (MP3_RM_C.0049A6E4), ASCII "VS88T6-Vs86"
  0049A98B  |.  E8 F89BF6FF   |CALL MP3_RM_C.00404588                  ;  用户名与程序“固有注册名”比较,判断是否相等
  0049A990  |.  75 09         |JNZ SHORT MP3_RM_C.0049A99B
  0049A992  |.  C605 0C2D4A00>|MOV BYTE PTR DS:[4A2D0C],0              ;  把DS:[004A2D0C]置0
  0049A999  |.  EB 06         |JMP SHORT MP3_RM_C.0049A9A1
  0049A99B  |>  83C6 04       |ADD ESI,4
  0049A99E  |.  4B            |DEC EBX
  0049A99F  |.^ 75 E5         \JNZ SHORT MP3_RM_C.0049A986
  0049A9A1  |>  803D 0C2D4A00>CMP BYTE PTR DS:[4A2D0C],0               ;  判断DS:[004A2D0C]是否为0,不为0就失败
  0049A9A8  |.  74 1A         JE SHORT MP3_RM_C.0049A9C4               ;  必须跳,不跳就失败
  0049A9AA  |.  6A 00         PUSH 0                                   ; /Arg1 = 00000000
  0049A9AC  |.  66:8B0D 38AB4>MOV CX,WORD PTR DS:[49AB38]              ; |
  0049A9B3  |.  B2 02         MOV DL,2                                 ; |
  0049A9B5  |.  B8 44AB4900   MOV EAX,MP3_RM_C.0049AB44                ; |invalid register code! please retry!
  0049A9BA  |.  E8 9D7CF9FF   CALL MP3_RM_C.0043265C                   ; \MP3_RM_C.0043265C
  
  跟踪到0049A9A8这一行,程序没有跳,接下来弹出注册失败信息框。由上述记录分析
  
  0049A9A1  |>  803D 0C2D4A00>CMP BYTE PTR DS:[4A2D0C],0  
  
  这一行的判断很重要,DS:[4A2D0C]必须为0,再次注册断下时会发现DS:[4A2D0C]的值是为1的,也就是说DS:[4A2D0C]初始化为1,从记录再往上看
  
  0049A992  |.  C605 0C2D4A00>|MOV BYTE PTR DS:[4A2D0C],0             
  
  这一行代码正是把DS:[4A2D0C]置0,因此这一行必须执行。那么
  
  0049A990  |.  75 09         |JNZ SHORT MP3_RM_C.0049A99B
  
  一定不能跳。0049A980的上一行是比较输入的用户名与程序“固有用户名”的,二者不相等就跳。这里解释一下程序“固有注册名”,通过分析,我发现这软件的用户名必须与

软件本身的一些字符串相等,否则就会跳向失败。用十六进制编辑软件WINHEX打开MP3 RM Converter.exe,搜索可以找到十几个类似"VS88T6-Vs86"这样的字符串,程序运行时就把

他们载入内存。下面代码的作用就是循环读取程序“固有注册名”,比较我们输入的注册名“PEDIY”是否与之相等。若循环完没有与之相等的则失败!
  
  0049A989  |.  8B16          |MOV EDX,DWORD PTR DS:[ESI]              ;  DS:[004A17F8]=0049A6E4 (MP3_RM_C.0049A6E4), ASCII "VS88T6-Vs86"
  0049A98B  |.  E8 F89BF6FF   |CALL MP3_RM_C.00404588                  ;  判断用户名与程序“固有注册”名比较
  0049A990  |.  75 09         |JNZ SHORT MP3_RM_C.0049A99B
  0049A992  |.  C605 0C2D4A00>|MOV BYTE PTR DS:[4A2D0C],0              ;  把DS:[004A2D0C]置0
  0049A999  |.  EB 06         |JMP SHORT MP3_RM_C.0049A9A1
  0049A99B  |>  83C6 04       |ADD ESI,4
  0049A99E  |.  4B            |DEC EBX
  0049A99F  |.^ 75 E5         \JNZ SHORT MP3_RM_C.0049A986
  
  
  重新注册,输入用户名:VS88T6-Vs86,注册码:123456789,程序断下来,直接F4运行到
  
  0049A9A8  |. /74 1A         JE SHORT MP3_RM_C.0049A9C4              
  
  这回跳了,继续往下分析。
  
  0049A9A8  |. /74 1A         JE SHORT MP3_RM_C.0049A9C4               ;  必须跳,不跳就失败
  0049A9AA  |. |6A 00         PUSH 0                                   ; /Arg1 = 00000000
  0049A9AC  |. |66:8B0D 38AB4>MOV CX,WORD PTR DS:[49AB38]              ; |
  0049A9B3  |. |B2 02         MOV DL,2                                 ; |
  0049A9B5  |. |B8 44AB4900   MOV EAX,MP3_RM_C.0049AB44                ; |invalid register code! please retry!
  0049A9BA  |. |E8 9D7CF9FF   CALL MP3_RM_C.0043265C                   ; \MP3_RM_C.0043265C
  0049A9BF  |. |E9 2B010000   JMP MP3_RM_C.0049AAEF
  0049A9C4  |> \8D55 EC       LEA EDX,[LOCAL.5]
  0049A9C7  |.  8B87 20030000 MOV EAX,DWORD PTR DS:[EDI+320]
  0049A9CD  |.  E8 BA31FCFF   CALL MP3_RM_C.0045DB8C
  0049A9D2  |.  8B45 EC       MOV EAX,[LOCAL.5]                        ;  注册码放到EAX
  0049A9D5  |.  8D55 F8       LEA EDX,[LOCAL.2]
  0049A9D8  |.  E8 C7DCF6FF   CALL MP3_RM_C.004086A4
  0049A9DD  |.  8D55 E8       LEA EDX,[LOCAL.6]
  0049A9E0  |.  8B45 F8       MOV EAX,[LOCAL.2]
  0049A9E3  |.  E8 F0DCF6FF   CALL MP3_RM_C.004086D8
  0049A9E8  |.  8B55 E8       MOV EDX,[LOCAL.6]
  0049A9EB  |.  8D45 F8       LEA EAX,[LOCAL.2]
  0049A9EE  |.  E8 2198F6FF   CALL MP3_RM_C.00404214
  0049A9F3  |.  837D FC 00    CMP [LOCAL.1],0                         
  0049A9F7  |.  0F84 F2000000 JE MP3_RM_C.0049AAEF
  0049A9FD  |.  837D F8 00    CMP [LOCAL.2],0                          ;  判断注册码是否为空,为空就跳
  0049AA01  |.  0F84 E8000000 JE MP3_RM_C.0049AAEF
  0049AA07  |.  8B45 F8       MOV EAX,[LOCAL.2]
  0049AA0A  |.  E8 2D9AF6FF   CALL MP3_RM_C.0040443C                   ;  计算注册码长度
  0049AA0F  |.  85C0          TEST EAX,EAX
  0049AA11  |.  7E 35         JLE SHORT MP3_RM_C.0049AA48
  0049AA13  |.  BA 01000000   MOV EDX,1
  0049AA18  |>  8B4D F8       /MOV ECX,[LOCAL.2]                       ;  注册码地址放到ECX
  0049AA1B  |.  0FB64C11 FF   |MOVZX ECX,BYTE PTR DS:[ECX+EDX-1]       ;  依次取一位注册码
  0049AA20  |.  83F9 30       |CMP ECX,30                              ;  与ASCII码30h比较,小于就失败
  0049AA23  |.  7C 05         |JL SHORT MP3_RM_C.0049AA2A
  0049AA25  |.  83F9 39       |CMP ECX,39                              ;  与ASCII码39h比较,大于就失败
  0049AA28  |.  7E 1A         |JLE SHORT MP3_RM_C.0049AA44             ; 
  0049AA2A  |>  6A 00         |PUSH 0                                  ; /Arg1 = 00000000
  0049AA2C  |.  66:8B0D 38AB4>|MOV CX,WORD PTR DS:[49AB38]             ; |
  0049AA33  |.  B2 02         |MOV DL,2                                ; |
  0049AA35  |.  B8 44AB4900   |MOV EAX,MP3_RM_C.0049AB44               ; |invalid register code! please retry!
  0049AA3A  |.  E8 1D7CF9FF   |CALL MP3_RM_C.0043265C                  ; \MP3_RM_C.0043265C
  0049AA3F  |.  E9 AB000000   |JMP MP3_RM_C.0049AAEF
  0049AA44  |>  42            |INC EDX
  0049AA45  |.  48            |DEC EAX
  0049AA46  |.^ 75 D0         \JNZ SHORT MP3_RM_C.0049AA18
  0049AA48  |>  33F6          XOR ESI,ESI                              ;  ESI清零
  0049AA4A  |.  8B45 FC       MOV EAX,[LOCAL.1]                        ;  用户名放到EAX
  0049AA4D  |.  E8 EA99F6FF   CALL MP3_RM_C.0040443C                   ;  计算用户名长度,作为下面的循环次数
  0049AA52  |.  85C0          TEST EAX,EAX
  0049AA54  |.  7E 13         JLE SHORT MP3_RM_C.0049AA69
  0049AA56  |.  BB 01000000   MOV EBX,1
  0049AA5B  |>  8B55 FC       /MOV EDX,[LOCAL.1]                       ;  用户名地址放到ECX
  0049AA5E  |.  0FB6541A FF   |MOVZX EDX,BYTE PTR DS:[EDX+EBX-1]
  0049AA63  |.  03F2          |ADD ESI,EDX                             ;  依次取用户名的每一位的ASCII码相加,和放到ESI
  0049AA65  |.  43            |INC EBX
  0049AA66  |.  48            |DEC EAX
  0049AA67  |.^ 75 F2         \JNZ SHORT MP3_RM_C.0049AA5B
  0049AA69  |>  69C6 26740700 IMUL EAX,ESI,77426                       ;  EAX=ESI*77426h
  0049AA6F  |.  83C0 52       ADD EAX,52                               ;  EAX+=52h
  0049AA72  |.  D1F8          SAR EAX,1                                ;  EAX算术右移一位,相当于EAX=EAX/2
  0049AA74  |.  79 03         JNS SHORT MP3_RM_C.0049AA79
  0049AA76  |.  83D0 00       ADC EAX,0
  0049AA79  |>  8BF0          MOV ESI,EAX                              ;  把EAX复制给ESI
  0049AA7B  |.  8B45 F8       MOV EAX,[LOCAL.2]                        ;  注册码放到EAX
  0049AA7E  |.  E8 DDDFF6FF   CALL MP3_RM_C.00408A60                   ;  关键CALL,跟进
  0049AA83  |.  3BF0          CMP ESI,EAX                              ;  判断EAX是否等于ESI,不等就跳
  0049AA85  |.  75 53         JNZ SHORT MP3_RM_C.0049AADA              ;  不能跳,一跳就失败
  0049AA87  |.  6A 00         PUSH 0                                   ; /Arg1 = 00000000
  0049AA89  |.  66:8B0D 38AB4>MOV CX,WORD PTR DS:[49AB38]              ; |
  0049AA90  |.  B2 02         MOV DL,2                                 ; |
  0049AA92  |.  B8 74AB4900   MOV EAX,MP3_RM_C.0049AB74                ; |congratulation! you have successfully registered!
  0049AA97  |.  E8 C07BF9FF   CALL MP3_RM_C.0043265C                   ; \MP3_RM_C.0043265C
  0049AA9C  |.  A1 341B4A00   MOV EAX,DWORD PTR DS:[4A1B34]
  0049AAA1  |.  C600 01       MOV BYTE PTR DS:[EAX],1
  0049AAA4  |.  A1 2C1C4A00   MOV EAX,DWORD PTR DS:[4A1C2C]
  0049AAA9  |.  8B00          MOV EAX,DWORD PTR DS:[EAX]
  0049AAAB  |.  33C9          XOR ECX,ECX
  0049AAAD  |.  BA 04000000   MOV EDX,4
  0049AAB2  |.  8B18          MOV EBX,DWORD PTR DS:[EAX]
  0049AAB4  |.  FF53 14       CALL DWORD PTR DS:[EBX+14]
  0049AAB7  |.  8B15 341B4A00 MOV EDX,DWORD PTR DS:[4A1B34]            ;  MP3_RM_C.004A2D1B
  0049AABD  |.  A1 2C1C4A00   MOV EAX,DWORD PTR DS:[4A1C2C]
  0049AAC2  |.  8B00          MOV EAX,DWORD PTR DS:[EAX]
  0049AAC4  |.  B9 01000000   MOV ECX,1
  0049AAC9  |.  E8 7E18F8FF   CALL MP3_RM_C.0041C34C
  0049AACE  |.  A1 082D4A00   MOV EAX,DWORD PTR DS:[4A2D08]
  0049AAD3  |.  E8 1CF8FDFF   CALL MP3_RM_C.0047A2F4
  0049AAD8  |.  EB 15         JMP SHORT MP3_RM_C.0049AAEF
  0049AADA  |>  6A 00         PUSH 0                                   ; /Arg1 = 00000000
  0049AADC  |.  66:8B0D 38AB4>MOV CX,WORD PTR DS:[49AB38]              ; |
  0049AAE3  |.  B2 02         MOV DL,2                                 ; |
  0049AAE5  |.  B8 44AB4900   MOV EAX,MP3_RM_C.0049AB44                ; |invalid register code! please retry!
  0049AAEA  |.  E8 6D7BF9FF   CALL MP3_RM_C.0043265C                   ; \MP3_RM_C.0043265C
  0049AAEF  |>  33C0          XOR EAX,EAX                              ;  (初始 cpu 选择)
  0049AAF1  |.  5A            POP EDX
  0049AAF2  |.  59            POP ECX
  0049AAF3  |.  59            POP ECX
  0049AAF4  |.  64:8910       MOV DWORD PTR FS:[EAX],EDX
  0049AAF7  |.  68 31AB4900   PUSH MP3_RM_C.0049AB31
  0049AAFC  |>  8D45 E8       LEA EAX,[LOCAL.6]
  0049AAFF  |.  E8 7896F6FF   CALL MP3_RM_C.0040417C
  0049AB04  |.  8D45 EC       LEA EAX,[LOCAL.5]
  0049AB07  |.  E8 7096F6FF   CALL MP3_RM_C.0040417C
  0049AB0C  |.  8D45 F0       LEA EAX,[LOCAL.4]
  0049AB0F  |.  E8 6896F6FF   CALL MP3_RM_C.0040417C
  0049AB14  |.  8D45 F4       LEA EAX,[LOCAL.3]
  0049AB17  |.  E8 6096F6FF   CALL MP3_RM_C.0040417C
  0049AB1C  |.  8D45 F8       LEA EAX,[LOCAL.2]
  0049AB1F  |.  BA 02000000   MOV EDX,2
  0049AB24  |.  E8 7796F6FF   CALL MP3_RM_C.004041A0
  0049AB29  \.  C3            RETN
  
  走到0049AA7E这一行,关键,跟进
  
  
  
  00408A60  /$  53            PUSH EBX
  00408A61  |.  56            PUSH ESI
  00408A62  |.  83C4 F4       ADD ESP,-0C
  00408A65  |.  8BD8          MOV EBX,EAX                              ;  注册码放到EBX
  00408A67  |.  8BD4          MOV EDX,ESP
  00408A69  |.  8BC3          MOV EAX,EBX
  00408A6B  |.  E8 F0A2FFFF   CALL MP3_RM_C.00402D60                   ;  关键,跟进
  00408A70  |.  8BF0          MOV ESI,EAX
  00408A72  |.  833C24 00     CMP DWORD PTR SS:[ESP],0
  00408A76  |.  74 19         JE SHORT MP3_RM_C.00408A91               ;  跳了
  00408A78  |.  895C24 04     MOV DWORD PTR SS:[ESP+4],EBX
  00408A7C  |.  C64424 08 0B  MOV BYTE PTR SS:[ESP+8],0B
  00408A81  |.  8D5424 04     LEA EDX,DWORD PTR SS:[ESP+4]
  00408A85  |.  A1 781A4A00   MOV EAX,DWORD PTR DS:[4A1A78]
  00408A8A  |.  33C9          XOR ECX,ECX
  00408A8C  |.  E8 CBF8FFFF   CALL MP3_RM_C.0040835C
  00408A91  |>  8BC6          MOV EAX,ESI
  00408A93  |.  83C4 0C       ADD ESP,0C
  00408A96  |.  5E            POP ESI                                  ;  ESI出栈
  00408A97  |.  5B            POP EBX
  00408A98  \.  C3            RETN
  
  走到  00408A6B  这一行,关键CALL,跟进
  
  00402D60  /$  53            PUSH EBX
  00402D61  |.  56            PUSH ESI
  00402D62  |.  57            PUSH EDI
  00402D63  |.  89C6          MOV ESI,EAX                              ;  注册码放到ESI
  00402D65  |.  50            PUSH EAX
  00402D66  |.  85C0          TEST EAX,EAX
  00402D68  |.  74 6C         JE SHORT MP3_RM_C.00402DD6
  00402D6A  |.  31C0          XOR EAX,EAX                              ;  EAX清空
  00402D6C  |.  31DB          XOR EBX,EBX                              ;  EBX清空
  00402D6E  |.  BF CCCCCC0C   MOV EDI,0CCCCCCC                         ;  EDI赋值0CCCCCCC
  00402D73  |>  8A1E          /MOV BL,BYTE PTR DS:[ESI]
  00402D75  |.  46            |INC ESI                                 ;  ESI自加
  00402D76  |.  80FB 20       |CMP BL,20                               ;  注册码的第一位与20h比较
  00402D79  |.^ 74 F8         \JE SHORT MP3_RM_C.00402D73
  00402D7B  |.  B5 00         MOV CH,0
  00402D7D  |.  80FB 2D       CMP BL,2D                                ;  注册码第一位与2Dh比较
  00402D80  |.  74 62         JE SHORT MP3_RM_C.00402DE4
  00402D82  |.  80FB 2B       CMP BL,2B                                ;  注册码第一位与2Bh比较
  00402D85  |.  74 5F         JE SHORT MP3_RM_C.00402DE6
  00402D87  |>  80FB 24       CMP BL,24                                ;  注册码第一位与24h比较
  00402D8A  |.  74 5F         JE SHORT MP3_RM_C.00402DEB
  00402D8C  |.  80FB 78       CMP BL,78                                ;  注册码第一位与78h比较
  00402D8F  |.  74 5A         JE SHORT MP3_RM_C.00402DEB
  00402D91  |.  80FB 58       CMP BL,58                                ;  注册码第一位与58h比较
  00402D94  |.  74 55         JE SHORT MP3_RM_C.00402DEB
  00402D96  |.  80FB 30       CMP BL,30                                ;  注册码第一位与30h比较
  00402D99  |.  75 13         JNZ SHORT MP3_RM_C.00402DAE              ;  跳了
  00402D9B  |.  8A1E          MOV BL,BYTE PTR DS:[ESI]
  00402D9D  |.  46            INC ESI
  00402D9E  |.  80FB 78       CMP BL,78
  00402DA1  |.  74 48         JE SHORT MP3_RM_C.00402DEB
  00402DA3  |.  80FB 58       CMP BL,58
  00402DA6  |.  74 43         JE SHORT MP3_RM_C.00402DEB
  00402DA8  |.  84DB          TEST BL,BL
  00402DAA  |.  74 20         JE SHORT MP3_RM_C.00402DCC
  00402DAC  |.  EB 04         JMP SHORT MP3_RM_C.00402DB2
  00402DAE  |>  84DB          TEST BL,BL                               ;  测试注册码第一位是否为0
  00402DB0  |.  74 2D         JE SHORT MP3_RM_C.00402DDF
  
  00402DB2  |>  80EB 30       /SUB BL,30                               ;  注册码-‘0’,把每一位注册码转换成数字
  00402DB5  |.  80FB 09       |CMP BL,9
  00402DB8  |.  77 25         |JA SHORT MP3_RM_C.00402DDF
  00402DBA  |.  39F8          |CMP EAX,EDI
  00402DBC  |.  77 21         |JA SHORT MP3_RM_C.00402DDF
  00402DBE  |.  8D0480        |LEA EAX,DWORD PTR DS:[EAX+EAX*4]
  00402DC1  |.  01C0          |ADD EAX,EAX                             ;  这句与上一句代码合起来等价与EAX*=10
  00402DC3  |.  01D8          |ADD EAX,EBX
  00402DC5  |.  8A1E          |MOV BL,BYTE PTR DS:[ESI]                ;这段代码的作用是把注册码由字符转换成数字放到EAX
  00402DC7  |.  46            |INC ESI
  00402DC8  |.  84DB          |TEST BL,BL
  00402DCA  |.^ 75 E6         \JNZ SHORT MP3_RM_C.00402DB2
  
  00402DCC  |>  FECD          DEC CH
  00402DCE  |.  74 09         JE SHORT MP3_RM_C.00402DD9
  00402DD0  |.  85C0          TEST EAX,EAX
  00402DD2  |.  7D 54         JGE SHORT MP3_RM_C.00402E28               ;跳了
  
  00402DD2跳了之后接着做了一些寄存器的出栈操作,返回到
  
  00408A70  |.  8BF0          MOV ESI,EAX  
  
  紧接着便执行到下面一行代码,把EAX放到ESI
  
  00408A70  |.  8BF0          MOV ESI,EAX
  
  接着跳到下面,然后返回。
  00408A91  |>  8BC6          MOV EAX,ESI
  00408A93  |.  83C4 0C       ADD ESP,0C
  00408A96  |.  5E            POP ESI                                  ;  ESI出栈
  00408A97  |.  5B            POP EBX
  00408A98  \.  C3            RETN

  最后比较EAX与ESI是否相等,不等就跳向失败。  
  
  
  

--------------------------------------------------------------------------------
【注册算法总结】
  该软件的用户注册名已经固化到程序里(上文我称之为程序“固有注册名”),用户输入的注册名只有与程序“固有注册名”相
  等才有可能注册成功。下面给出程序分别对用户名与注册码的处理方法。

  1.记用户名的ASCII码和为Bgn,用户名的处理结果为End,则End=(Bgn*77426h+52h)/2
  
  2.程序的注册码必须全为数字,否则注册失败。程序把用户的注册码由字符串转化为数字,比如字符串“123”转化称数字
  123.记转化好的数字为M。
  
  3.程序判断End是否与M相等,若不相等则跳向失败,明白了注册条件和注册算法就很容易写出该程序的算法注册机了。
  给出一对在我的机器上能正确注册的用户名和注册码:

  USER: VS88T6-Vs86
  CODE: 189311575
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

  • 标 题:答复
  • 作 者:xuecrack
  • 时 间:2008-10-06 20:41

附上用VC++写的注册算法吧。

#include<iostream>
#include<string>
using namespace std;
void main()
{
  string strRegName;
  int i;
  long j;
  j=0;
  cout<<"请输入注册名"<<endl;
  cin>>strRegName;
  for(i=0;i<strRegName.length();i++)
    j+=strRegName[i];
  j=(j*0x77426+0x52)/2;
  cout<<"注册码是"<<j<<endl;
}
上文有一点小错误,给予指正,正确的注册码我算出来了,但是复制上去的时候却不知怎么弄错了。在下面附上。
USER:VS88T6-Vs86
CODE:189288366