【文章标题】: 菜鸟的第一个注册机
【文章作者】: Root
【作者邮箱】: cppcoffee@gmail.com
【软件名称】: 国内某mp4视频格式转换器
【下载地址】: 自己搜索下载
【编写语言】: delphi
【软件介绍】: 一款功能强大的MP4视频转换器。
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  纯属菜鸟作品,高手请无视:).最近电脑上电影有好多还没看完,而且冬天了,想转成MP4格式放到iTouch中躲到被窝里慢慢欣赏.就去网上找了个MP4转换软件,结果需要注册.嘿嘿刚好拿来练习下.
  就不废话了,进入正题:
  用peid查壳 Borland Delphi 6.0 - 7.0 .没有加壳,嘿嘿.用DEDE载入,看下模块名"U_reg"里面的事件"Btn_RegClick"的RVA地址: 004C20F8.接着载入OD,下断 bp 004C20F8.运行,在注册窗口输入假码,点击"注册",OD断下在如下代码中:
  
  004C20F8  /.  55            PUSH EBP                                 ;  注册按钮点击入口地址
  004C20F9  |.  8BEC          MOV EBP,ESP
  004C20FB  |.  6A 00         PUSH 0x0
  004C20FD  |.  6A 00         PUSH 0x0
  004C20FF  |.  53            PUSH EBX
  004C2100  |.  8BD8          MOV EBX,EAX
  004C2102  |.  33C0          XOR EAX,EAX
  004C2104  |.  55            PUSH EBP
  004C2105  |.  68 B8214C00   PUSH mp4.004C21B8
  004C210A  |.  64:FF30       PUSH DWORD PTR FS:[EAX]
  004C210D  |.  64:8920       MOV DWORD PTR FS:[EAX],ESP
  004C2110  |.  8D55 FC       LEA EDX,DWORD PTR SS:[EBP-0x4]
  004C2113  |.  8B83 04030000 MOV EAX,DWORD PTR DS:[EBX+0x304]         ;  Edit_RegName
  004C2119  |.  E8 0251FAFF   CALL <mp4.GetText>                       ;  获取用户名字符串
  004C211E  |.  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-0x4]
  004C2121  |.  E8 C624F4FF   CALL <mp4.System.LStrLen>                ;  得到用户名的长度
  004C2126  |.  85C0          TEST EAX,EAX                             ;  用户名是否空
  004C2128  |.  75 29         JNZ SHORT mp4.004C2153
  004C212A  |.  6A 40         PUSH 0x40
  004C212C  |.  68 C4214C00   PUSH mp4.004C21C4
  004C2131  |.  68 CC214C00   PUSH mp4.004C21CC
  004C2136  |.  8BC3          MOV EAX,EBX
  004C2138  |.  E8 CBB8FAFF   CALL <mp4.GetHandle>
  004C213D  |.  50            PUSH EAX                                 ; |hOwner
  004C213E  |.  E8 7952F4FF   CALL <JMP.&user32.MessageBoxA>           ; \MessageBoxA
  004C2143  |.  8B83 04030000 MOV EAX,DWORD PTR DS:[EBX+0x304]
  004C2149  |.  8B10          MOV EDX,DWORD PTR DS:[EAX]
  004C214B  |.  FF92 C4000000 CALL DWORD PTR DS:[EDX+0xC4]
  004C2151  |.  EB 4A         JMP SHORT mp4.004C219D
  004C2153  |>  8D55 F8       LEA EDX,DWORD PTR SS:[EBP-0x8]           ;  Edit_RegCode
  004C2156  |.  8B83 08030000 MOV EAX,DWORD PTR DS:[EBX+0x308]
  004C215C  |.  E8 BF50FAFF   CALL <mp4.GetText>                       ;  获取假吗
  004C2161  |.  8B45 F8       MOV EAX,DWORD PTR SS:[EBP-0x8]
  004C2164  |.  E8 8324F4FF   CALL <mp4.System.LStrLen>                ;  LStrLen
  004C2169  |.  85C0          TEST EAX,EAX                             ;  注册码是否空
  004C216B  |.  75 29         JNZ SHORT mp4.004C2196
  004C216D  |.  6A 40         PUSH 0x40
  004C216F  |.  68 C4214C00   PUSH mp4.004C21C4
  004C2174  |.  68 E8214C00   PUSH mp4.004C21E8
  004C2179  |.  8BC3          MOV EAX,EBX
  004C217B  |.  E8 88B8FAFF   CALL <mp4.GetHandle>
  004C2180  |.  50            PUSH EAX                                 ; |hOwner
  004C2181  |.  E8 3652F4FF   CALL <JMP.&user32.MessageBoxA>           ; \MessageBoxA
  004C2186  |.  8B83 08030000 MOV EAX,DWORD PTR DS:[EBX+0x308]
  004C218C  |.  8B10          MOV EDX,DWORD PTR DS:[EAX]
  004C218E  |.  FF92 C4000000 CALL DWORD PTR DS:[EDX+0xC4]
  004C2194  |.  EB 07         JMP SHORT mp4.004C219D
  004C2196  |>  8BC3          MOV EAX,EBX
  004C2198  |.  E8 FBFCFFFF   CALL mp4.004C1E98                        ;  关键的注册函数
  004C219D  |>  33C0          XOR EAX,EAX
  
  进入关键的注册函数 004C2198  |.  E8 FBFCFFFF   CALL mp4.004C1E98
  
  004C1E98   $  55            PUSH EBP                                 ;  注册函数入口
  004C1E99   .  8BEC          MOV EBP,ESP
  004C1E9B   .  33C9          XOR ECX,ECX
  004C1E9D   .  51            PUSH ECX
  004C1E9E   .  51            PUSH ECX
  004C1E9F   .  51            PUSH ECX
  004C1EA0   .  51            PUSH ECX
  004C1EA1   .  51            PUSH ECX
  004C1EA2   .  53            PUSH EBX
  004C1EA3   .  56            PUSH ESI
  004C1EA4   .  57            PUSH EDI
  004C1EA5   .  8945 FC       MOV DWORD PTR SS:[EBP-0x4],EAX
  004C1EA8   .  33C0          XOR EAX,EAX
  004C1EAA   .  55            PUSH EBP
  004C1EAB   .  68 E91F4C00   PUSH mp4.004C1FE9
  004C1EB0   .  64:FF30       PUSH DWORD PTR FS:[EAX]
  004C1EB3   .  64:8920       MOV DWORD PTR FS:[EAX],ESP
  004C1EB6   .  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-0x4]
  004C1EB9   .  E8 B2FEFFFF   CALL mp4.004C1D70                        ;  关键CALL
  004C1EBE   .  84C0          TEST AL,AL                               ;  是否是正确的注册码
  004C1EC0   .  0F84 DB000000 JE mp4.004C1FA1                          ;  错误的注册码则跳
  004C1EC6   .  33C0          XOR EAX,EAX
  004C1EC8   .  55            PUSH EBP
  004C1EC9   .  68 851F4C00   PUSH mp4.004C1F85
  004C1ECE   .  64:FF30       PUSH DWORD PTR FS:[EAX]
  004C1ED1   .  64:8920       MOV DWORD PTR FS:[EAX],ESP
  004C1ED4   .  B2 01         MOV DL,0x1
  004C1ED6   .  A1 20B54300   MOV EAX,DWORD PTR DS:[0x43B520]
  004C1EDB   .  E8 4097F7FF   CALL <mp4.TReistry.Create>               ;  创建注册表项
  004C1EE0   .  8BD8          MOV EBX,EAX
  004C1EE2   .  BA 02000080   MOV EDX,0x80000002
  004C1EE7   .  8BC3          MOV EAX,EBX
  004C1EE9   .  E8 D297F7FF   CALL <mp4.SetRootKey>
  004C1EEE   .  B1 01         MOV CL,0x1
  004C1EF0   .  BA 00204C00   MOV EDX,mp4.004C2000                     ;  ASCII "Software\jisusoft\mp4"
  004C1EF5   .  8BC3          MOV EAX,EBX
  004C1EF7   .  E8 2898F7FF   CALL <mp4.OpenKey>
  004C1EFC   .  8D55 F4       LEA EDX,DWORD PTR SS:[EBP-0xC]           ;  Edit_RegName
  004C1EFF   .  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-0x4]
  004C1F02   .  8B80 04030000 MOV EAX,DWORD PTR DS:[EAX+0x304]
  004C1F08   .  E8 1353FAFF   CALL <mp4.GetText>                       ;  获取用户名
  004C1F0D   .  8B45 F4       MOV EAX,DWORD PTR SS:[EBP-0xC]
  004C1F10   .  8D55 F8       LEA EDX,DWORD PTR SS:[EBP-0x8]
  004C1F13   .  E8 BC6BF4FF   CALL <mp4.SysUtils.Trim>
  004C1F18   .  8B4D F8       MOV ECX,DWORD PTR SS:[EBP-0x8]
  004C1F1B   .  BA 20204C00   MOV EDX,mp4.004C2020                     ;  ASCII "Name"
  004C1F20   .  8BC3          MOV EAX,EBX
  004C1F22   .  E8 9999F7FF   CALL <mp4.Registry.WriteString>          ;  写入用户名
  004C1F27   .  8D55 EC       LEA EDX,DWORD PTR SS:[EBP-0x14]          ;  Edit_RegCode
  004C1F2A   .  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-0x4]
  004C1F2D   .  8B80 08030000 MOV EAX,DWORD PTR DS:[EAX+0x308]
  004C1F33   .  E8 E852FAFF   CALL <mp4.GetText>                       ;  获取注册码
  004C1F38   .  8B45 EC       MOV EAX,DWORD PTR SS:[EBP-0x14]
  004C1F3B   .  8D55 F0       LEA EDX,DWORD PTR SS:[EBP-0x10]
  004C1F3E   .  E8 916BF4FF   CALL <mp4.SysUtils.Trim>
  004C1F43   .  8B4D F0       MOV ECX,DWORD PTR SS:[EBP-0x10]
  004C1F46   .  BA 30204C00   MOV EDX,mp4.004C2030                     ;  ASCII "Pass"
  004C1F4B   .  8BC3          MOV EAX,EBX
  004C1F4D   .  E8 6E99F7FF   CALL <mp4.Registry.WriteString>          ;  写入注册码
  004C1F52   .  8BC3          MOV EAX,EBX
  004C1F54   .  E8 6715F4FF   CALL <mp4.System.TObject.Free(TObject)>  ;  System.TObject.Free
  004C1F59   .  6A 40         PUSH 0x40
  004C1F5B   .  68 38204C00   PUSH mp4.004C2038
  004C1F60   .  68 44204C00   PUSH mp4.004C2044
  004C1F65   .  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-0x4]
  004C1F68   .  E8 9BBAFAFF   CALL <mp4.GetHandle>                     ;  得到窗口句柄
  004C1F6D   .  50            PUSH EAX                                 ; |hOwner
  004C1F6E   .  E8 4954F4FF   CALL <JMP.&user32.MessageBoxA>           ; \MessageBoxA
  004C1F73   .  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-0x4]
  004C1F76   .  E8 2520FCFF   CALL <mp4.Forms.TCustomForm.Close>       ;  关闭注册窗口
  004C1F7B   .  33C0          XOR EAX,EAX
  004C1F7D   .  5A            POP EDX
  004C1F7E   .  59            POP ECX
  004C1F7F   .  59            POP ECX
  004C1F80   .  64:8910       MOV DWORD PTR FS:[EAX],EDX
  004C1F83   .  EB 36         JMP SHORT mp4.004C1FBB
  004C1F85   .^ E9 161AF4FF   JMP mp4.004039A0
  004C1F8A   .  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-0x4]
  004C1F8D   .  E8 0E20FCFF   CALL <mp4.Forms.TCustomForm.Close>
  004C1F92   .  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-0x4]
  004C1F95   .  E8 1AFDFFFF   CALL mp4.004C1CB4
  004C1F9A   .  E8 691DF4FF   CALL mp4.00403D08
  004C1F9F   .  EB 1A         JMP SHORT mp4.004C1FBB
  004C1FA1   >  6A 40         PUSH 0x40                                ;  弹出错误注册码提示框
  004C1FA3   .  68 C4204C00   PUSH mp4.004C20C4                        ;  ASCII "Register"
  004C1FA8   .  68 D0204C00   PUSH mp4.004C20D0
  004C1FAD   .  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-0x4]
  004C1FB0   .  E8 53BAFAFF   CALL <mp4.GetHandle>                     ;  得到窗口句柄
  004C1FB5   .  50            PUSH EAX                                 ; |hOwner
  004C1FB6   .  E8 0154F4FF   CALL <JMP.&user32.MessageBoxA>           ; \MessageBoxA
  004C1FBB   >  33C0          XOR EAX,EAX
  
  进入关键 004C1EB9   .  E8 B2FEFFFF   CALL mp4.004C1D70
  
  004C1D70  /$  55            PUSH EBP                                 ;  关键CALL入口
  004C1D71  |.  8BEC          MOV EBP,ESP
  004C1D73  |.  B9 04000000   MOV ECX,0x4
  004C1D78  |>  6A 00         /PUSH 0x0
  004C1D7A  |.  6A 00         |PUSH 0x0
  004C1D7C  |.  49            |DEC ECX
  004C1D7D  |.^ 75 F9         \JNZ SHORT mp4.004C1D78
  004C1D7F  |.  51            PUSH ECX
  004C1D80  |.  53            PUSH EBX
  004C1D81  |.  56            PUSH ESI
  004C1D82  |.  8BF0          MOV ESI,EAX
  004C1D84  |.  33C0          XOR EAX,EAX
  004C1D86  |.  55            PUSH EBP
  004C1D87  |.  68 871E4C00   PUSH mp4.004C1E87
  004C1D8C  |.  64:FF30       PUSH DWORD PTR FS:[EAX]
  004C1D8F  |.  64:8920       MOV DWORD PTR FS:[EAX],ESP
  004C1D92  |.  8D55 F8       LEA EDX,DWORD PTR SS:[EBP-0x8]           ;  Edit_RegCode
  004C1D95  |.  8B86 08030000 MOV EAX,DWORD PTR DS:[ESI+0x308]
  004C1D9B  |.  E8 8054FAFF   CALL <mp4.GetText>                       ;  获取用户输入的注册码明文
  004C1DA0  |.  8B45 F8       MOV EAX,DWORD PTR SS:[EBP-0x8]
  004C1DA3  |.  8D55 FC       LEA EDX,DWORD PTR SS:[EBP-0x4]
  004C1DA6  |.  E8 296DF4FF   CALL <mp4.SysUtils.Trim>                 ;  去掉注册码空格
  004C1DAB  |.  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-0x4]
  004C1DAE  |.  50            PUSH EAX
  004C1DAF  |.  8D55 EC       LEA EDX,DWORD PTR SS:[EBP-0x14]          ;  Edit_RegName
  004C1DB2  |.  8B86 04030000 MOV EAX,DWORD PTR DS:[ESI+0x304]
  004C1DB8  |.  E8 6354FAFF   CALL <mp4.GetText>                       ;  获取用户名
  004C1DBD  |.  8B45 EC       MOV EAX,DWORD PTR SS:[EBP-0x14]
  004C1DC0  |.  8D55 F0       LEA EDX,DWORD PTR SS:[EBP-0x10]
  004C1DC3  |.  E8 0C6DF4FF   CALL <mp4.SysUtils.Trim>                 ;  去掉用户名中包含的空格
  004C1DC8  |.  8B55 F0       MOV EDX,DWORD PTR SS:[EBP-0x10]
  004C1DCB  |.  8D4D F4       LEA ECX,DWORD PTR SS:[EBP-0xC]
  004C1DCE  |.  8BC6          MOV EAX,ESI
  004C1DD0  |.  E8 EBFCFFFF   CALL <mp4.MakeKey>                       ;  生成注册码
  004C1DD5  |.  8B55 F4       MOV EDX,DWORD PTR SS:[EBP-0xC]
  004C1DD8  |.  58            POP EAX
  004C1DD9  |.  E8 5A29F4FF   CALL <mp4.System.LStrCmp>                ;  注册码比较(关键)
  004C1DDE  |.  75 52         JNZ SHORT mp4.004C1E32
  004C1DE0  |.  B3 01         MOV BL,0x1
  004C1DE2  |.  8D55 E4       LEA EDX,DWORD PTR SS:[EBP-0x1C]          ;  Edit_RegName
  004C1DE5  |.  8B86 04030000 MOV EAX,DWORD PTR DS:[ESI+0x304]
  004C1DEB  |.  E8 3054FAFF   CALL <mp4.GetText>                       ;  获取用户名
  004C1DF0  |.  8B45 E4       MOV EAX,DWORD PTR SS:[EBP-0x1C]
  004C1DF3  |.  8D55 E8       LEA EDX,DWORD PTR SS:[EBP-0x18]
  004C1DF6  |.  E8 D96CF4FF   CALL <mp4.SysUtils.Trim>
  004C1DFB  |.  8B55 E8       MOV EDX,DWORD PTR SS:[EBP-0x18]
  004C1DFE  |.  8D86 1C030000 LEA EAX,DWORD PTR DS:[ESI+0x31C]
  004C1E04  |.  E8 5B25F4FF   CALL <mp4.System.LStrAsg>                ;  System.LStrAsg
  004C1E09  |.  8D55 DC       LEA EDX,DWORD PTR SS:[EBP-0x24]          ;  Edit_RegCode
  004C1E0C  |.  8B86 08030000 MOV EAX,DWORD PTR DS:[ESI+0x308]
  004C1E12  |.  E8 0954FAFF   CALL <mp4.GetText>                       ;  获取注册码
  004C1E17  |.  8B45 DC       MOV EAX,DWORD PTR SS:[EBP-0x24]
  004C1E1A  |.  8D55 E0       LEA EDX,DWORD PTR SS:[EBP-0x20]
  004C1E1D  |.  E8 B26CF4FF   CALL <mp4.SysUtils.Trim>
  004C1E22  |.  8B55 E0       MOV EDX,DWORD PTR SS:[EBP-0x20]
  004C1E25  |.  8D86 20030000 LEA EAX,DWORD PTR DS:[ESI+0x320]
  004C1E2B  |.  E8 3425F4FF   CALL <mp4.System.LStrAsg>
  004C1E30  |.  EB 02         JMP SHORT mp4.004C1E34
  
  这里看到 004C1DD0  |.  E8 EBFCFFFF   CALL <mp4.MakeKey> 生成注册码,再与输入的伪码进行比较,然后将比较结果返回,进入 004C1DD0 看看
  
  <mp4.Make>/$  55            PUSH EBP                                 ;  生成注册码CALL
  004C1AC1  |.  8BEC          MOV EBP,ESP
  004C1AC3  |.  51            PUSH ECX
  004C1AC4  |.  B9 04000000   MOV ECX,0x4
  004C1AC9  |>  6A 00         /PUSH 0x0
  004C1ACB  |.  6A 00         |PUSH 0x0
  004C1ACD  |.  49            |DEC ECX
  004C1ACE  |.^ 75 F9         \JNZ SHORT mp4.004C1AC9                  ;  准备堆栈变量空间
  004C1AD0  |.  51            PUSH ECX
  004C1AD1  |.  874D FC       XCHG DWORD PTR SS:[EBP-0x4],ECX
  004C1AD4  |.  53            PUSH EBX
  004C1AD5  |.  56            PUSH ESI
  004C1AD6  |.  57            PUSH EDI
  004C1AD7  |.  8BF9          MOV EDI,ECX
  004C1AD9  |.  8955 FC       MOV DWORD PTR SS:[EBP-0x4],EDX
  004C1ADC  |.  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-0x4]
  004C1ADF  |.  E8 F82CF4FF   CALL <mp4.System.LStrAddRef>
  004C1AE4  |.  33C0          XOR EAX,EAX
  004C1AE6  |.  55            PUSH EBP
  004C1AE7  |.  68 811C4C00   PUSH mp4.004C1C81
  004C1AEC  |.  64:FF30       PUSH DWORD PTR FS:[EAX]
  004C1AEF  |.  64:8920       MOV DWORD PTR FS:[EAX],ESP
  004C1AF2  |.  8BC7          MOV EAX,EDI
  004C1AF4  |.  E8 1728F4FF   CALL <mp4.System.LStrClr>
  004C1AF9  |.  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-0x4]
  004C1AFC  |.  E8 EB2AF4FF   CALL <mp4.System.LStrLen>                ;  计算用户名长度
  004C1B01  |.  8BF0          MOV ESI,EAX
  004C1B03  |.  85F6          TEST ESI,ESI                             ;  用户名为空则跳
  004C1B05  |.  7E 26         JLE SHORT mp4.004C1B2D
  004C1B07  |.  BB 01000000   MOV EBX,0x1                              ;  i=1
  004C1B0C  |>  8D4D EC       /LEA ECX,DWORD PTR SS:[EBP-0x14]
  004C1B0F  |.  8B45 FC       |MOV EAX,DWORD PTR SS:[EBP-0x4]
  004C1B12  |.  0FB64418 FF   |MOVZX EAX,BYTE PTR DS:[EAX+EBX-0x1]     ;  name[i-1]
  004C1B17  |.  33D2          |XOR EDX,EDX
  004C1B19  |.  E8 3273F4FF   |CALL <mp4.IntToHex>                     ;  IntToHex
  004C1B1E  |.  8B55 EC       |MOV EDX,DWORD PTR SS:[EBP-0x14]         ;  将用户名转换成16进制
  004C1B21  |.  8D45 F8       |LEA EAX,DWORD PTR SS:[EBP-0x8]
  004C1B24  |.  E8 CB2AF4FF   |CALL <mp4.System.LStrCat>               ;  转换后的16进制字符串存入缓冲区
  004C1B29  |.  43            |INC EBX
  004C1B2A  |.  4E            |DEC ESI                                 ;  遍历用户名结束??
  004C1B2B  |.^ 75 DF         \JNZ SHORT mp4.004C1B0C
  004C1B2D  |>  8B45 F8       MOV EAX,DWORD PTR SS:[EBP-0x8]
  004C1B30  |.  E8 B72AF4FF   CALL <mp4.System.LStrLen>                ;  计算转换后缓冲区的长度
  004C1B35  |.  8BF0          MOV ESI,EAX
  004C1B37  |.  85F6          TEST ESI,ESI                             ;  缓冲区长度为0则跳
  004C1B39  |.  7E 2C         JLE SHORT mp4.004C1B67
  004C1B3B  |.  BB 01000000   MOV EBX,0x1                              ;  i=1
  004C1B40  |>  8B45 F8       /MOV EAX,DWORD PTR SS:[EBP-0x8]
  004C1B43  |.  E8 A42AF4FF   |CALL <mp4.System.LStrLen>               ;  计算16进制缓冲区长度
  004C1B48  |.  2BC3          |SUB EAX,EBX                             ;  len-i
  004C1B4A  |.  8B55 F8       |MOV EDX,DWORD PTR SS:[EBP-0x8]
  004C1B4D  |.  8A1402        |MOV DL,BYTE PTR DS:[EDX+EAX]            ;  nameBuf[len-i]
  004C1B50  |.  8D45 E8       |LEA EAX,DWORD PTR SS:[EBP-0x18]
  004C1B53  |.  E8 A029F4FF   |CALL <mp4.System.LStrFromChar>
  004C1B58  |.  8B55 E8       |MOV EDX,DWORD PTR SS:[EBP-0x18]
  004C1B5B  |.  8D45 F4       |LEA EAX,DWORD PTR SS:[EBP-0xC]
  004C1B5E  |.  E8 912AF4FF   |CALL <mp4.System.LStrCat>               ;  保存16进制用户名倒序
  004C1B63  |.  43            |INC EBX                                 ;  ++i
  004C1B64  |.  4E            |DEC ESI
  004C1B65  |.^ 75 D9         \JNZ SHORT mp4.004C1B40
  004C1B67  |>  8D45 F8       LEA EAX,DWORD PTR SS:[EBP-0x8]           ;  16进制转换的缓冲区地址
  004C1B6A  |.  50            PUSH EAX
  004C1B6B  |.  B9 04000000   MOV ECX,0x4
  004C1B70  |.  BA 01000000   MOV EDX,0x1
  004C1B75  |.  8B45 F4       MOV EAX,DWORD PTR SS:[EBP-0xC]
  004C1B78  |.  E8 CF2CF4FF   CALL <mp4.System.LStrCopy>               ;  复制倒序缓冲区前4个数据 Buf1
  004C1B7D  |.  8D45 F4       LEA EAX,DWORD PTR SS:[EBP-0xC]
  004C1B80  |.  50            PUSH EAX
  004C1B81  |.  B9 04000000   MOV ECX,0x4
  004C1B86  |.  BA 05000000   MOV EDX,0x5
  004C1B8B  |.  8B45 F4       MOV EAX,DWORD PTR SS:[EBP-0xC]
  004C1B8E  |.  E8 B92CF4FF   CALL <mp4.System.LStrCopy>               ;  复制倒序缓冲区第4个位置后面的5个数据 Buf2
  004C1B93  |.  8B45 F8       MOV EAX,DWORD PTR SS:[EBP-0x8]
  004C1B96  |.  E8 512AF4FF   CALL <mp4.System.LStrLen>
  004C1B9B  |.  83F8 04       CMP EAX,0x4                              ;  Buf1 缓冲区长度是否大于等于4
  004C1B9E  |.  7D 2F         JGE SHORT mp4.004C1BCF
  004C1BA0  |.  8B45 F8       MOV EAX,DWORD PTR SS:[EBP-0x8]
  004C1BA3  |.  E8 442AF4FF   CALL <mp4.System.LStrLen>                ;  计算Buf1长度
  004C1BA8  |.  8BD8          MOV EBX,EAX
  004C1BAA  |.  83FB 03       CMP EBX,0x3                              ;  是否小于3?
  004C1BAD  |.  7F 20         JG SHORT mp4.004C1BCF
  004C1BAF  |>  8D4D E4       /LEA ECX,DWORD PTR SS:[EBP-0x1C]
  004C1BB2  |.  8BC3          |MOV EAX,EBX
  004C1BB4  |.  C1E0 02       |SHL EAX,0x2                             ;  长度左移2位
  004C1BB7  |.  33D2          |XOR EDX,EDX
  004C1BB9  |.  E8 9272F4FF   |CALL <mp4.IntToHex>                     ;  转换成16进制
  004C1BBE  |.  8B55 E4       |MOV EDX,DWORD PTR SS:[EBP-0x1C]
  004C1BC1  |.  8D45 F8       |LEA EAX,DWORD PTR SS:[EBP-0x8]
  004C1BC4  |.  E8 2B2AF4FF   |CALL <mp4.System.LStrCat>
  004C1BC9  |.  43            |INC EBX                                 ;  增加长度变量
  004C1BCA  |.  83FB 04       |CMP EBX,0x4
  004C1BCD  |.^ 75 E0         \JNZ SHORT mp4.004C1BAF                  ;  是否大于等于4
  004C1BCF  |>  8B45 F4       MOV EAX,DWORD PTR SS:[EBP-0xC]
  004C1BD2  |.  E8 152AF4FF   CALL <mp4.System.LStrLen>
  004C1BD7  |.  83F8 04       CMP EAX,0x4                              ;  Buf2 缓冲区长度是否大于等于4
  004C1BDA  |.  7D 2F         JGE SHORT mp4.004C1C0B
  004C1BDC  |.  8B45 F4       MOV EAX,DWORD PTR SS:[EBP-0xC]
  004C1BDF  |.  E8 082AF4FF   CALL <mp4.System.LStrLen>                ;  计算 Buf2 缓冲区长度
  004C1BE4  |.  8BD8          MOV EBX,EAX
  004C1BE6  |.  83FB 03       CMP EBX,0x3                              ;  Buf2缓冲区是否大于3?
  004C1BE9  |.  7F 20         JG SHORT mp4.004C1C0B
  004C1BEB  |>  8D4D E0       /LEA ECX,DWORD PTR SS:[EBP-0x20]
  004C1BEE  |.  8BC3          |MOV EAX,EBX
  004C1BF0  |.  C1E0 02       |SHL EAX,0x2                             ;  Buf2长度左移2位
  004C1BF3  |.  33D2          |XOR EDX,EDX
  004C1BF5  |.  E8 5672F4FF   |CALL <mp4.IntToHex>
  004C1BFA  |.  8B55 E0       |MOV EDX,DWORD PTR SS:[EBP-0x20]
  004C1BFD  |.  8D45 F4       |LEA EAX,DWORD PTR SS:[EBP-0xC]
  004C1C00  |.  E8 EF29F4FF   |CALL <mp4.System.LStrCat>
  004C1C05  |.  43            |INC EBX                                 ;  增加长度变量
  004C1C06  |.  83FB 04       |CMP EBX,0x4
  004C1C09  |.^ 75 E0         \JNZ SHORT mp4.004C1BEB
  004C1C0B  |>  8D45 F0       LEA EAX,DWORD PTR SS:[EBP-0x10]
  004C1C0E  |.  BA 981C4C00   MOV EDX,mp4.004C1C98                     ;  ASCII "mp46687i686c"
  004C1C13  |.  E8 9027F4FF   CALL <mp4.System.LStrLAsg>               ;  复制字符串
  004C1C18  |.  8D45 DC       LEA EAX,DWORD PTR SS:[EBP-0x24]
  004C1C1B  |.  50            PUSH EAX
  004C1C1C  |.  B9 04000000   MOV ECX,0x4
  004C1C21  |.  BA 01000000   MOV EDX,0x1
  004C1C26  |.  8B45 F0       MOV EAX,DWORD PTR SS:[EBP-0x10]
  004C1C29  |.  E8 1E2CF4FF   CALL <mp4.System.LStrCopy>               ;  保存字符串的前4个数据
  004C1C2E  |.  FF75 DC       PUSH DWORD PTR SS:[EBP-0x24]
  004C1C31  |.  68 B01C4C00   PUSH mp4.004C1CB0                        ;  "-"
  004C1C36  |.  FF75 F8       PUSH DWORD PTR SS:[EBP-0x8]              ;  Buf1
  004C1C39  |.  8D45 D8       LEA EAX,DWORD PTR SS:[EBP-0x28]
  004C1C3C  |.  50            PUSH EAX
  004C1C3D  |.  B9 05000000   MOV ECX,0x5
  004C1C42  |.  BA 05000000   MOV EDX,0x5
  004C1C47  |.  8B45 F0       MOV EAX,DWORD PTR SS:[EBP-0x10]
  004C1C4A  |.  E8 FD2BF4FF   CALL <mp4.System.LStrCopy>               ;  复制字符串"687i6"到缓冲区
  004C1C4F  |.  FF75 D8       PUSH DWORD PTR SS:[EBP-0x28]
  004C1C52  |.  68 B01C4C00   PUSH mp4.004C1CB0
  004C1C57  |.  FF75 F4       PUSH DWORD PTR SS:[EBP-0xC]              ;  Buf2
  004C1C5A  |.  8BC7          MOV EAX,EDI
  004C1C5C  |.  BA 06000000   MOV EDX,0x6
  004C1C61  |.  E8 462AF4FF   CALL <mp4.System.LStrCatN>               ;  复制正确的注册码到缓冲区中
  004C1C66  |.  33C0          XOR EAX,EAX
  004C1C68  |.  5A            POP EDX
  004C1C69  |.  59            POP ECX
  004C1C6A  |.  59            POP ECX
  004C1C6B  |.  64:8910       MOV DWORD PTR FS:[EAX],EDX
  004C1C6E  |.  68 881C4C00   PUSH mp4.004C1C88
  004C1C73  |>  8D45 D8       LEA EAX,DWORD PTR SS:[EBP-0x28]
  004C1C76  |.  BA 0A000000   MOV EDX,0xA
  004C1C7B  |.  E8 B426F4FF   CALL <mp4.System.LStrArrayClr>
  004C1C80  \.  C3            RETN
  
  有了上面的代码,自己写了个注册机.附C代码
  =================================华丽的分隔线=================================
  #include <iostream>
  #include <cstdlib>
  #include <string>
  using namespace std;
  
  const char* Key = "mp46687i686c";
  #define MAX_LENGTH    512
  
  // 注册码不足位数时候则填充
  void FillValue( char* pBuf, int nBufSize )
  {
    int len;
    char szTemp[MAX_LENGTH];
  
    while ( (len = strlen(pBuf)) < 4 )
    {
      sprintf_s( szTemp, MAX_LENGTH, "%X", len <<= 2 );
      strcat_s( pBuf, nBufSize, szTemp );
    }
  }
  
  int main(void)
  {
    string strName;
  
    cout << "用户名: ";
    cin >> strName;
  
    // 将用户名转换成16进制
    char szTemp[MAX_LENGTH];
    string strHex;
    string::iterator it = strName.begin();
    while ( it != strName.end() )
    {
      sprintf_s( szTemp, MAX_LENGTH, "%X", *it++ );
      strHex += szTemp;
    }
  
    // 倒序
    string strReverse;
    for ( int n = strHex.length() - 1; n >= 0; n-- )
    {
      strReverse += strHex.at(n);
    }
  
    // 缓冲区的前4个数据存放到Buf1中
    char Buf1[5];
    strncpy_s( Buf1, 5, strReverse.c_str(), 4 );
  
    // 拷贝后4个数据到缓冲区中
    char Buf2[5];
    strncpy_s( Buf2, 5, strReverse.c_str() + 4, strReverse.length() > 4 ? 4 : 0 );
  
    // 计算Buf1长度,不够则左移长度填充
    if ( strlen(Buf1) < 4 )
    {
      FillValue( Buf1, 5 );
    }
    // 计算Buf2长度,不够则左移长度填充
    if ( strlen(Buf2) < 4 )
    {
      FillValue( Buf2, 5 );
    }
  
    // 拷贝KEY前4位数据
    string strCode;
    strncpy_s( szTemp, MAX_LENGTH, Key, 4 );
    szTemp[4] = 0x00;
    strCode += szTemp;
    strCode += "-";
    strCode += Buf1;
    strncpy_s( szTemp, MAX_LENGTH, Key + 4, 5);
    szTemp[5] = 0x00;
    strCode += szTemp;
    strCode += "-";
    strCode += Buf2;
  
    cout << "注册码: " << strCode << endl;
  
    system("PAUSE");
    return 0;
  }
  
  附一个可用的注册号码:
  用户名: Root
  注册码: mp46-47F6687i6-F625
  
  谢谢你看完了本菜鸟的文章,嘿嘿.
  
--------------------------------------------------------------------------------
【经验总结】
  由于的第一次写注册机,有不足之处请大家指出.
  
--------------------------------------------------------------------------------

                                                       2010年12月07日 20:23:40