[原创]菜鸟 学注册机编写之 “sha1”
测试环境
系统: xp sp3
调试器 :od 1.10
高手莫要见笑,仅供小菜玩乐,有不对或不足的地方还请多多指教,不胜感激!
1. 首先运行程序随便输入用户与注册码如下图所示:

2.将程序载入OD, 下MessageBoxA函数断点, F9运行程序, 程序运行后随便输入用户名与注册码,点"OK"后断下,F8一直走,就会返回到如下的代码,我们在函数开头下好断点。(或者直接搜索字符串 "Thank you for registration!",也能快速定位到这里)
0041B190 55 push ebp 0041B191 8BEC mov ebp,esp 0041B193 6A FF push -0x1 0041B195 68 9B555900 push dvdiphon.0059559B 0041B19A 64:A1 00000000 mov eax,dword ptr fs:[0] 0041B1A0 50 push eax 0041B1A1 81EC 98010000 sub esp,0x198 0041B1A7 A1 F8E66000 mov eax,dword ptr ds:[0x60E6F8] 0041B1AC 33C5 xor eax,ebp 0041B1AE 8985 68FFFFFF mov dword ptr ss:[ebp-0x98],eax 0041B1B4 50 push eax 0041B1B5 8D45 F4 lea eax,dword ptr ss:[ebp-0xC] 0041B1B8 64:A3 00000000 mov dword ptr fs:[0],eax 0041B1BE 898D 60FEFFFF mov dword ptr ss:[ebp-0x1A0],ecx 0041B1C4 C745 F0 0000000>mov dword ptr ss:[ebp-0x10],0x0 0041B1CB 6A 00 push 0x0 0041B1CD 8D8D 6CFFFFFF lea ecx,dword ptr ss:[ebp-0x94] 0041B1D3 E8 38B1FEFF call dvdiphon.00406310 0041B1D8 C745 FC 0000000>mov dword ptr ss:[ebp-0x4],0x0 0041B1DF 8D8D 6CFFFFFF lea ecx,dword ptr ss:[ebp-0x94] 0041B1E5 E8 04570400 call dvdiphon.004608EE 0041B1EA 8945 F0 mov dword ptr ss:[ebp-0x10],eax 0041B1ED 837D F0 01 cmp dword ptr ss:[ebp-0x10],0x1 0041B1F1 0F85 F6000000 jnz dvdiphon.0041B2ED 0041B1F7 8D8D 6CFFFFFF lea ecx,dword ptr ss:[ebp-0x94] 0041B1FD E8 9ED6FFFF call dvdiphon.004188A0 0041B202 50 push eax 0041B203 8B8D 60FEFFFF mov ecx,dword ptr ss:[ebp-0x1A0] 0041B209 81C1 CCDC0200 add ecx,0x2DCCC 0041B20F E8 7C90FEFF call dvdiphon.00404290 0041B214 8D8D 6CFFFFFF lea ecx,dword ptr ss:[ebp-0x94] 0041B21A E8 A1D6FFFF call dvdiphon.004188C0 0041B21F 50 push eax 0041B220 8B8D 60FEFFFF mov ecx,dword ptr ss:[ebp-0x1A0] 0041B226 81C1 D0DC0200 add ecx,0x2DCD0 0041B22C E8 5F90FEFF call dvdiphon.00404290 0041B231 8B8D 60FEFFFF mov ecx,dword ptr ss:[ebp-0x1A0] 0041B237 81C1 D0DC0200 add ecx,0x2DCD0 0041B23D E8 3E470200 call dvdiphon.0043F980 ; 注册码 0041B242 50 push eax 0041B243 8B8D 60FEFFFF mov ecx,dword ptr ss:[ebp-0x1A0] 0041B249 81C1 CCDC0200 add ecx,0x2DCCC 0041B24F E8 2C470200 call dvdiphon.0043F980 ; 用户名 0041B254 50 push eax 0041B255 E8 C6FCFFFF call dvdiphon.0041AF20 0041B25A 83C4 08 add esp,0x8 0041B25D 8B85 60FEFFFF mov eax,dword ptr ss:[ebp-0x1A0] 0041B263 C780 D4DC0200 0>mov dword ptr ds:[eax+0x2DCD4],0x1 0041B26D 68 00010000 push 0x100 0041B272 6A 00 push 0x0 0041B274 8D8D 64FEFFFF lea ecx,dword ptr ss:[ebp-0x19C] 0041B27A 51 push ecx 0041B27B E8 F00B1500 call dvdiphon.0056BE70 0041B280 83C4 0C add esp,0xC 0041B283 B9 481E6200 mov ecx,dvdiphon.00621E48 ; tK^ 0041B288 E8 63BBFFFF call dvdiphon.00416DF0 0041B28D 8985 5CFEFFFF mov dword ptr ss:[ebp-0x1A4],eax 0041B293 8B95 5CFEFFFF mov edx,dword ptr ss:[ebp-0x1A4] 0041B299 8B02 mov eax,dword ptr ds:[edx] 0041B29B 8B8D 5CFEFFFF mov ecx,dword ptr ss:[ebp-0x1A4] 0041B2A1 8B50 18 mov edx,dword ptr ds:[eax+0x18] 0041B2A4 FFD2 call edx 0041B2A6 8BC8 mov ecx,eax 0041B2A8 E8 E398FFFF call dvdiphon.00414B90 0041B2AD 50 push eax 0041B2AE 68 988C5D00 push dvdiphon.005D8C98 ; Thank you for registration!\r\n%s will verify\r\nthe registration information after you restart it. 0041B2B3 68 FF000000 push 0xFF 0041B2B8 8D85 64FEFFFF lea eax,dword ptr ss:[ebp-0x19C] 0041B2BE 50 push eax 0041B2BF E8 A9FB1400 call dvdiphon.0056AE6D 0041B2C4 83C4 10 add esp,0x10 0041B2C7 6A 00 push 0x0 0041B2C9 8D8D 64FEFFFF lea ecx,dword ptr ss:[ebp-0x19C] 0041B2CF 51 push ecx 0041B2D0 8B8D 60FEFFFF mov ecx,dword ptr ss:[ebp-0x1A0] 0041B2D6 81C1 F8030000 add ecx,0x3F8 0041B2DC 8B95 60FEFFFF mov edx,dword ptr ss:[ebp-0x1A0] 0041B2E2 8B82 F8030000 mov eax,dword ptr ds:[edx+0x3F8] 0041B2E8 8B50 28 mov edx,dword ptr ds:[eax+0x28] 0041B2EB FFD2 call edx 0041B2ED C745 FC FFFFFFF>mov dword ptr ss:[ebp-0x4],-0x1 0041B2F4 8D8D 6CFFFFFF lea ecx,dword ptr ss:[ebp-0x94] 0041B2FA E8 D1B0FEFF call dvdiphon.004063D0 0041B2FF 8B4D F4 mov ecx,dword ptr ss:[ebp-0xC] 0041B302 64:890D 0000000>mov dword ptr fs:[0],ecx 0041B309 59 pop ecx 0041B30A 8B8D 68FFFFFF mov ecx,dword ptr ss:[ebp-0x98] 0041B310 33CD xor ecx,ebp 0041B312 E8 F4E31400 call dvdiphon.0056970B 0041B317 8BE5 mov esp,ebp 0041B319 5D pop ebp 0041B31A C3 retn
3. 我们重新载入程序来详细分析这些指令都做了什么?重新载入后,F9运行程序随便输入用户名与注册码。点击"OK"程序就会被断下。
输入用户与注册码为
用户名 test
注册码 123456789abcdefghijklmnopqlstuvwxyztrwm
获得用户名与注册码。
0041B23D E8 3E470200 call dvdiphon.0043F980 ; 注册码 0041B242 50 push eax 0041B243 8B8D 60FEFFFF mov ecx,dword ptr ss:[ebp-0x1A0] 0041B249 81C1 CCDC0200 add ecx,0x2DCCC 0041B24F E8 2C470200 call dvdiphon.0043F980 ; 用户名
4.加密注册码
0041B0C4 83C4 0C add esp,0xC 0041B0C7 8D8D 54FFFFFF lea ecx,dword ptr ss:[ebp-0xAC] 0041B0CD 898D 50FFFFFF mov dword ptr ss:[ebp-0xB0],ecx 0041B0D3 8B95 50FFFFFF mov edx,dword ptr ss:[ebp-0xB0] 0041B0D9 0FBE02 movsx eax,byte ptr ds:[edx] 0041B0DC 85C0 test eax,eax 0041B0DE 74 25 je short dvdiphon.0041B105 0041B0E0 8B8D 50FFFFFF mov ecx,dword ptr ss:[ebp-0xB0] ; 加密注册码 0041B0E6 0FBE11 movsx edx,byte ptr ds:[ecx] 0041B0E9 83EA 19 sub edx,0x19 ; 减0x19 0041B0EC 8B85 50FFFFFF mov eax,dword ptr ss:[ebp-0xB0] 0041B0F2 8810 mov byte ptr ds:[eax],dl ; 存放减后的值 0041B0F4 8B8D 50FFFFFF mov ecx,dword ptr ss:[ebp-0xB0] 0041B0FA 83C1 01 add ecx,0x1 0041B0FD 898D 50FFFFFF mov dword ptr ss:[ebp-0xB0],ecx 0041B103 ^ EB CE jmp short dvdiphon.0041B0D3 0041B105 33D2 xor edx,edx 0041B107 ^ 75 BE jnz short dvdiphon.0041B0C7 0041B109 B9 481E6200 mov ecx,dvdiphon.00621E48 ; tK^
加密前
123456789abcdefghijklmnopqlstuvwxyztrwm
加密后的值
18 19 1A 1B 1C 1D 1E 1F 20 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 53 5A 5B 5C 5D 5E 5F 60 61 5B 59 5E 54
5.将上面加密后的注册码写入注册表中(CLSID\{D2D219BC-BCE8-4249-8636-DE8BEFCD28C3}\ProgID)提示重启软件。
0012F8B0 004402B9 /CALL 到 RegSetValueExA 来自 dvdiphon.004402B3 0012F8B4 00000166 |hKey = 0x166 0012F8B8 00F979F8 |ValueName = "1" 0012F8BC 00000000 |Reserved = 0x0 0012F8C0 00000003 |ValueType = REG_BINARY 0012F8C4 0012F920 |Buffer = 0012F920 0012F8C8 00000027 \BufSize = 27 (39.)
6.可以确定是重启验证型式的, 它将我们输入的注册码与用户写入到了注册表项中,软件重启时会读取这些值来做验证,所以我们下好操作注册表的api函数,重新载入程序,F9运行,程序断在操作注册表的地方,打开存放加密后注册码的注册表键值。
0012FA34 0044005F /CALL 到 RegCreateKeyExA 来自 dvdiphon.00440059
0012FA38 80000000 |hKey = HKEY_CLASSES_ROOT
0012FA3C 00E67300 |Subkey = "CLSID\{D2D219BC-BCE8-4249-8636-DE8BEFCD28C3}\ProgID"
0012FA40 00000000 |Reserved = 0x0
0012FA44 00000000 |Class = NULL
0012FA48 00000000 |Options = REG_OPTION_NON_VOLATILE
0012FA4C 0002003F |Access = KEY_QUERY_VALUE|KEY_SET_VALUE|KEY_CREATE_SUB_KEY|KEY_ENUMERATE_SUB_KEYS|KEY_NOTIFY|KEY_CREATE_LINK|20000
0012FA50 00000000 |pSecurity = NULL
0012FA54 0012FB94 |pHandle = 0012FB94
0012FA58 0012FA68 \pDisposition = 0012FA68
查找CLSID\{D2D219BC-BCE8-4249-8636-DE8BEFCD28C3}\ProgID中的"1"是否存在
0012FA5C 00440309 /CALL 到 RegQueryValueExA 来自 dvdiphon.00440303 0012FA60 000000A6 |hKey = 0xA6 0012FA64 00E67350 |ValueName = "1" 0012FA68 00000000 |Reserved = NULL 0012FA6C 0012FA8C |pValueType = 0012FA8C 0012FA70 00000000 |Buffer = NULL 0012FA74 0012FA88 \pBufSize = 0012FA88
获取"1"中的值 (获取加密后的注册码)
0012FA5C 0044035D /CALL 到 RegQueryValueExA 来自 dvdiphon.00440357 0012FA60 000000A6 |hKey = 0xA6 0012FA64 00E67350 |ValueName = "1" 0012FA68 00000000 |Reserved = NULL 0012FA6C 00000000 |pValueType = NULL 0012FA70 00E67360 |Buffer = 00E67360 0012FA74 0012FA88 \pBufSize = 0012FA88
获取的值
18 19 1A 1B 1C 1D 1E 1F 20 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 53 5A 5B 5C 5D 5E 5F 60 61 5B 59 5E 54
7.解密从注册表读取出来的注册码
00417F2D /0F84 70020000 je dvdiphon.004181A3 00417F33 |C785 6CFFFFFF 0000000>mov dword ptr ss:[ebp-0x94],0x0 00417F3D |8D4D 84 lea ecx,dword ptr ss:[ebp-0x7C] 00417F40 |898D B0FEFFFF mov dword ptr ss:[ebp-0x150],ecx 00417F46 |8B95 B0FEFFFF mov edx,dword ptr ss:[ebp-0x150] 00417F4C |0FBE02 movsx eax,byte ptr ds:[edx] 00417F4F |85C0 test eax,eax ;判断是否为空 00417F51 |74 25 je short dvdiphon.00417F78 00417F53 |8B8D B0FEFFFF mov ecx,dword ptr ss:[ebp-0x150] 00417F59 |0FBE11 movsx edx,byte ptr ds:[ecx] ; 获得加密后的注册码1字节 00417F5C |83C2 19 add edx,0x19 ; 解密注册码(加上0x19) 00417F5F |8B85 B0FEFFFF mov eax,dword ptr ss:[ebp-0x150] 00417F65 |8810 mov byte ptr ds:[eax],dl ; 存放 00417F67 |8B8D B0FEFFFF mov ecx,dword ptr ss:[ebp-0x150] 00417F6D |83C1 01 add ecx,0x1 00417F70 |898D B0FEFFFF mov dword ptr ss:[ebp-0x150],ecx 00417F76 ^|EB CE jmp short dvdiphon.00417F46 00417F78 |33D2 xor edx,edx ; 完成 00417F7A ^|75 C1 jnz short dvdiphon.00417F3D
解密后
31 32 33 34 35 36 37 38 39 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 6C 73 74 75 76 77 78 79 7A 74 72 77 6D
8.将解密后的注册码分成2组,(其中第1组参与注册码计算,第2组为真实的注册码)
00418079 E8 B2FAFFFF call dvdiphon.00417B30 ; 将长度为0x27的注册码 分成2组
具体算法如下:
00417B30 55 push ebp 00417B31 8BEC mov ebp,esp 00417B33 83EC 10 sub esp,0x10 00417B36 C745 FC 00000000 mov dword ptr ss:[ebp-0x4],0x0 00417B3D C745 F8 00000000 mov dword ptr ss:[ebp-0x8],0x0 00417B44 C745 F0 00000000 mov dword ptr ss:[ebp-0x10],0x0 00417B4B C745 F4 00000000 mov dword ptr ss:[ebp-0xC],0x0 00417B52 837D 0C 27 cmp dword ptr ss:[ebp+0xC],0x27 ;判断注册码长度是否为0x27 00417B56 74 07 je short dvdiphon.00417B5F 00417B58 33C0 xor eax,eax 00417B5A E9 E8020000 jmp dvdiphon.00417E47 00417B5F C745 FC 00000000 mov dword ptr ss:[ebp-0x4],0x0 00417B66 EB 1B jmp short dvdiphon.00417B83 00417B68 8B45 FC mov eax,dword ptr ss:[ebp-0x4] 00417B6B 83C0 01 add eax,0x1 ; 计数加1 00417B6E 8945 FC mov dword ptr ss:[ebp-0x4],eax 00417B71 8B4D F8 mov ecx,dword ptr ss:[ebp-0x8] 00417B74 83C1 01 add ecx,0x1 ; 计数加1 00417B77 894D F8 mov dword ptr ss:[ebp-0x8],ecx 00417B7A 8B55 F0 mov edx,dword ptr ss:[ebp-0x10] 00417B7D 83C2 01 add edx,0x1 ; 计数加1 00417B80 8955 F0 mov dword ptr ss:[ebp-0x10],edx 00417B83 837D FC 03 cmp dword ptr ss:[ebp-0x4],0x3 ; 判断计数是否大于等于3 00417B87 7D 12 jge short dvdiphon.00417B9B 00417B89 8B45 10 mov eax,dword ptr ss:[ebp+0x10] ; 存放第1组注册码首地址 00417B8C 0345 F0 add eax,dword ptr ss:[ebp-0x10] ; 存放第1组注册码首地址加上计数 00417B8F 8B4D 08 mov ecx,dword ptr ss:[ebp+0x8] ; 注册码首地址 00417B92 034D F8 add ecx,dword ptr ss:[ebp-0x8] ; 注册码首地址加上计数 00417B95 8A11 mov dl,byte ptr ds:[ecx] ; 取注册码 00417B97 8810 mov byte ptr ds:[eax],dl ; 存放 00417B99 ^ EB CD jmp short dvdiphon.00417B68 00417B9B 8B45 F8 mov eax,dword ptr ss:[ebp-0x8] ; 取计数值 00417B9E 83C0 01 add eax,0x1 ; 计数加1 00417BA1 8945 F8 mov dword ptr ss:[ebp-0x8],eax 00417BA4 C745 FC 00000000 mov dword ptr ss:[ebp-0x4],0x0 ; 计数清0 00417BAB EB 1B jmp short dvdiphon.00417BC8 00417BAD 8B4D FC mov ecx,dword ptr ss:[ebp-0x4] 00417BB0 83C1 01 add ecx,0x1 ; 计数加1 00417BB3 894D FC mov dword ptr ss:[ebp-0x4],ecx 00417BB6 8B55 F8 mov edx,dword ptr ss:[ebp-0x8] 00417BB9 83C2 01 add edx,0x1 ; 计数加1 00417BBC 8955 F8 mov dword ptr ss:[ebp-0x8],edx 00417BBF 8B45 F4 mov eax,dword ptr ss:[ebp-0xC] 00417BC2 83C0 01 add eax,0x1 ; 计数加1 00417BC5 8945 F4 mov dword ptr ss:[ebp-0xC],eax 00417BC8 837D FC 03 cmp dword ptr ss:[ebp-0x4],0x3 ; 判断计数是否大于等于3 00417BCC 7D 12 jge short dvdiphon.00417BE0 00417BCE 8B4D 18 mov ecx,dword ptr ss:[ebp+0x18] ; 存放第2组注册码首地址 00417BD1 034D F4 add ecx,dword ptr ss:[ebp-0xC] ; 存放第2组注册码首地址加上计数 00417BD4 8B55 08 mov edx,dword ptr ss:[ebp+0x8] ; 注册码首地址 00417BD7 0355 F8 add edx,dword ptr ss:[ebp-0x8] ; 注册码首地址加上计数 00417BDA 8A02 mov al,byte ptr ds:[edx] ; 取注册码 00417BDC 8801 mov byte ptr ds:[ecx],al ; 存放 00417BDE ^ EB CD jmp short dvdiphon.00417BAD 00417BE0 C745 FC 00000000 mov dword ptr ss:[ebp-0x4],0x0 ; 计数清0 00417BE7 EB 1B jmp short dvdiphon.00417C04 00417BE9 8B4D FC mov ecx,dword ptr ss:[ebp-0x4] 00417BEC 83C1 01 add ecx,0x1 ; 计数加1 00417BEF 894D FC mov dword ptr ss:[ebp-0x4],ecx 00417BF2 8B55 F8 mov edx,dword ptr ss:[ebp-0x8] 00417BF5 83C2 01 add edx,0x1 ; 计数加1 00417BF8 8955 F8 mov dword ptr ss:[ebp-0x8],edx 00417BFB 8B45 F0 mov eax,dword ptr ss:[ebp-0x10] 00417BFE 83C0 01 add eax,0x1 ; 计数加1 00417C01 8945 F0 mov dword ptr ss:[ebp-0x10],eax 00417C04 837D FC 02 cmp dword ptr ss:[ebp-0x4],0x2 ; 判断计数是否大于等于3 00417C08 7D 12 jge short dvdiphon.00417C1C 00417C0A 8B4D 10 mov ecx,dword ptr ss:[ebp+0x10] ; 存放第1组注册码首地址 00417C0D 034D F0 add ecx,dword ptr ss:[ebp-0x10] ; 存放第1组注册码首地址加上计数 00417C10 8B55 08 mov edx,dword ptr ss:[ebp+0x8] ; 注册码首地址 00417C13 0355 F8 add edx,dword ptr ss:[ebp-0x8] ; 注册码首地址加上计数 00417C16 8A02 mov al,byte ptr ds:[edx] ; 取注册码 00417C18 8801 mov byte ptr ds:[ecx],al ; 存放 00417C1A ^ EB CD jmp short dvdiphon.00417BE9 00417C1C 8B4D F8 mov ecx,dword ptr ss:[ebp-0x8] ; 取计数值 00417C1F 83C1 01 add ecx,0x1 ; 计数值加1 00417C22 894D F8 mov dword ptr ss:[ebp-0x8],ecx 00417C25 C745 FC 00000000 mov dword ptr ss:[ebp-0x4],0x0 ; 计数清0 00417C2C EB 1B jmp short dvdiphon.00417C49 00417C2E 8B55 FC mov edx,dword ptr ss:[ebp-0x4] 00417C31 83C2 01 add edx,0x1 ; 计数值加1 00417C34 8955 FC mov dword ptr ss:[ebp-0x4],edx 00417C37 8B45 F8 mov eax,dword ptr ss:[ebp-0x8] 00417C3A 83C0 01 add eax,0x1 ; 计数值加1 00417C3D 8945 F8 mov dword ptr ss:[ebp-0x8],eax 00417C40 8B4D F4 mov ecx,dword ptr ss:[ebp-0xC] 00417C43 83C1 01 add ecx,0x1 ; 计数值加1 00417C46 894D F4 mov dword ptr ss:[ebp-0xC],ecx 00417C49 837D FC 03 cmp dword ptr ss:[ebp-0x4],0x3 ; 判断计数是否大于等于3 00417C4D 7D 12 jge short dvdiphon.00417C61 00417C4F 8B55 18 mov edx,dword ptr ss:[ebp+0x18] ; 存放第2组注册码首地址 00417C52 0355 F4 add edx,dword ptr ss:[ebp-0xC] ; 存放第2组注册码首地址加上计数 00417C55 8B45 08 mov eax,dword ptr ss:[ebp+0x8] ; 注册码首地址 00417C58 0345 F8 add eax,dword ptr ss:[ebp-0x8] ; 注册码首地址加上计数 00417C5B 8A08 mov cl,byte ptr ds:[eax] ; 取注册码 00417C5D 880A mov byte ptr ds:[edx],cl ; 存放 00417C5F ^ EB CD jmp short dvdiphon.00417C2E 00417C61 C745 FC 00000000 mov dword ptr ss:[ebp-0x4],0x0 ; 计数清0 00417C68 EB 1B jmp short dvdiphon.00417C85 00417C6A 8B55 FC mov edx,dword ptr ss:[ebp-0x4] 00417C6D 83C2 01 add edx,0x1 ; 计数值加1 00417C70 8955 FC mov dword ptr ss:[ebp-0x4],edx 00417C73 8B45 F8 mov eax,dword ptr ss:[ebp-0x8] 00417C76 83C0 01 add eax,0x1 ; 计数值加1 00417C79 8945 F8 mov dword ptr ss:[ebp-0x8],eax 00417C7C 8B4D F0 mov ecx,dword ptr ss:[ebp-0x10] 00417C7F 83C1 01 add ecx,0x1 ; 计数值加1 00417C82 894D F0 mov dword ptr ss:[ebp-0x10],ecx 00417C85 837D FC 02 cmp dword ptr ss:[ebp-0x4],0x2 ; 判断计数是否大于等于2 00417C89 7D 12 jge short dvdiphon.00417C9D 00417C8B 8B55 10 mov edx,dword ptr ss:[ebp+0x10] ; 存放第1组注册码首地址 00417C8E 0355 F0 add edx,dword ptr ss:[ebp-0x10] ; 存放第1组注册码首地址加上计数 00417C91 8B45 08 mov eax,dword ptr ss:[ebp+0x8] ; 注册码首地址 00417C94 0345 F8 add eax,dword ptr ss:[ebp-0x8] ; 注册码首地址加上计数 00417C97 8A08 mov cl,byte ptr ds:[eax] ; 取注册码 00417C99 880A mov byte ptr ds:[edx],cl ; 存放 00417C9B ^ EB CD jmp short dvdiphon.00417C6A 00417C9D 8B55 F8 mov edx,dword ptr ss:[ebp-0x8] ; 取计数值 00417CA0 83C2 01 add edx,0x1 ; 计数值加1 00417CA3 8955 F8 mov dword ptr ss:[ebp-0x8],edx 00417CA6 C745 FC 00000000 mov dword ptr ss:[ebp-0x4],0x0 ; 计数清0 00417CAD EB 1B jmp short dvdiphon.00417CCA 00417CAF 8B45 FC mov eax,dword ptr ss:[ebp-0x4] 00417CB2 83C0 01 add eax,0x1 ; 计数值加1 00417CB5 8945 FC mov dword ptr ss:[ebp-0x4],eax 00417CB8 8B4D F8 mov ecx,dword ptr ss:[ebp-0x8] 00417CBB 83C1 01 add ecx,0x1 ; 计数值加1 00417CBE 894D F8 mov dword ptr ss:[ebp-0x8],ecx 00417CC1 8B55 F4 mov edx,dword ptr ss:[ebp-0xC] 00417CC4 83C2 01 add edx,0x1 ; 计数值加1 00417CC7 8955 F4 mov dword ptr ss:[ebp-0xC],edx 00417CCA 837D FC 03 cmp dword ptr ss:[ebp-0x4],0x3 ; 判断计数是否大于等于3 00417CCE 7D 12 jge short dvdiphon.00417CE2 00417CD0 8B45 18 mov eax,dword ptr ss:[ebp+0x18] ; 存放第2组注册码首地址 00417CD3 0345 F4 add eax,dword ptr ss:[ebp-0xC] ; 存放第2组注册码首地址加上计数 00417CD6 8B4D 08 mov ecx,dword ptr ss:[ebp+0x8] ; 注册码首地址 00417CD9 034D F8 add ecx,dword ptr ss:[ebp-0x8] ; 注册码首地址加上计数 00417CDC 8A11 mov dl,byte ptr ds:[ecx] ; 取注册码 00417CDE 8810 mov byte ptr ds:[eax],dl ; 存放 00417CE0 ^ EB CD jmp short dvdiphon.00417CAF 00417CE2 C745 FC 00000000 mov dword ptr ss:[ebp-0x4],0x0 ; 计数清0 00417CE9 EB 1B jmp short dvdiphon.00417D06 00417CEB 8B45 FC mov eax,dword ptr ss:[ebp-0x4] 00417CEE 83C0 01 add eax,0x1 ; 计数值加1 00417CF1 8945 FC mov dword ptr ss:[ebp-0x4],eax 00417CF4 8B4D F8 mov ecx,dword ptr ss:[ebp-0x8] 00417CF7 83C1 01 add ecx,0x1 ; 计数值加1 00417CFA 894D F8 mov dword ptr ss:[ebp-0x8],ecx 00417CFD 8B55 F0 mov edx,dword ptr ss:[ebp-0x10] 00417D00 83C2 01 add edx,0x1 ; 计数值加1 00417D03 8955 F0 mov dword ptr ss:[ebp-0x10],edx 00417D06 837D FC 02 cmp dword ptr ss:[ebp-0x4],0x2 ; 判断计数是否大于等于2 00417D0A 7D 12 jge short dvdiphon.00417D1E 00417D0C 8B45 10 mov eax,dword ptr ss:[ebp+0x10] ; 存放第1组注册码首地址 00417D0F 0345 F0 add eax,dword ptr ss:[ebp-0x10] ; 存放第1组注册码首地址加上计数 00417D12 8B4D 08 mov ecx,dword ptr ss:[ebp+0x8] ; 注册码首地址 00417D15 034D F8 add ecx,dword ptr ss:[ebp-0x8] ; 注册码首地址加上计数 00417D18 8A11 mov dl,byte ptr ds:[ecx] ; 取注册码 00417D1A 8810 mov byte ptr ds:[eax],dl ; 存放 00417D1C ^ EB CD jmp short dvdiphon.00417CEB 00417D1E 8B45 F8 mov eax,dword ptr ss:[ebp-0x8] ; 取计数值 00417D21 83C0 01 add eax,0x1 ; 计数加1 00417D24 8945 F8 mov dword ptr ss:[ebp-0x8],eax 00417D27 C745 FC 00000000 mov dword ptr ss:[ebp-0x4],0x0 ; 计数清0 00417D2E EB 1B jmp short dvdiphon.00417D4B 00417D30 8B4D FC mov ecx,dword ptr ss:[ebp-0x4] 00417D33 83C1 01 add ecx,0x1 ; 计数加1 00417D36 894D FC mov dword ptr ss:[ebp-0x4],ecx 00417D39 8B55 F8 mov edx,dword ptr ss:[ebp-0x8] 00417D3C 83C2 01 add edx,0x1 ; 计数加1 00417D3F 8955 F8 mov dword ptr ss:[ebp-0x8],edx 00417D42 8B45 F4 mov eax,dword ptr ss:[ebp-0xC] 00417D45 83C0 01 add eax,0x1 ; 计数加1 00417D48 8945 F4 mov dword ptr ss:[ebp-0xC],eax 00417D4B 837D FC 03 cmp dword ptr ss:[ebp-0x4],0x3 ; 判断计数是否大于等于3 00417D4F 7D 12 jge short dvdiphon.00417D63 00417D51 8B4D 18 mov ecx,dword ptr ss:[ebp+0x18] ; 存放第2组注册码首地址 00417D54 034D F4 add ecx,dword ptr ss:[ebp-0xC] ; 存放第2组注册码首地址加上计数 00417D57 8B55 08 mov edx,dword ptr ss:[ebp+0x8] ; 注册码首地址 00417D5A 0355 F8 add edx,dword ptr ss:[ebp-0x8] ; 注册码首地址加上计数 00417D5D 8A02 mov al,byte ptr ds:[edx] ; 取注册码 00417D5F 8801 mov byte ptr ds:[ecx],al ; 存放 00417D61 ^ EB CD jmp short dvdiphon.00417D30 00417D63 C745 FC 00000000 mov dword ptr ss:[ebp-0x4],0x0 ; 计数清0 00417D6A EB 1B jmp short dvdiphon.00417D87 00417D6C 8B4D FC mov ecx,dword ptr ss:[ebp-0x4] 00417D6F 83C1 01 add ecx,0x1 ; 计数加1 00417D72 894D FC mov dword ptr ss:[ebp-0x4],ecx 00417D75 8B55 F8 mov edx,dword ptr ss:[ebp-0x8] 00417D78 83C2 01 add edx,0x1 ; 计数加1 00417D7B 8955 F8 mov dword ptr ss:[ebp-0x8],edx 00417D7E 8B45 F0 mov eax,dword ptr ss:[ebp-0x10] 00417D81 83C0 01 add eax,0x1 ; 计数加1 00417D84 8945 F0 mov dword ptr ss:[ebp-0x10],eax 00417D87 837D FC 02 cmp dword ptr ss:[ebp-0x4],0x2 ; 判断计数是否大于等于2 00417D8B 7D 12 jge short dvdiphon.00417D9F 00417D8D 8B4D 10 mov ecx,dword ptr ss:[ebp+0x10] ; 存放第1组注册码首地址 00417D90 034D F0 add ecx,dword ptr ss:[ebp-0x10] ; 存放第1组注册码首地址加上计数 00417D93 8B55 08 mov edx,dword ptr ss:[ebp+0x8] ; 注册码首地址 00417D96 0355 F8 add edx,dword ptr ss:[ebp-0x8] ; 注册码首地址加上计数 00417D99 8A02 mov al,byte ptr ds:[edx] ; 取注册码 00417D9B 8801 mov byte ptr ds:[ecx],al ; 存放 00417D9D ^ EB CD jmp short dvdiphon.00417D6C 00417D9F 8B4D F8 mov ecx,dword ptr ss:[ebp-0x8] ; 取计数值 00417DA2 83C1 01 add ecx,0x1 ; 计数加1 00417DA5 894D F8 mov dword ptr ss:[ebp-0x8],ecx 00417DA8 C745 FC 00000000 mov dword ptr ss:[ebp-0x4],0x0 ; 计数清0 00417DAF EB 1B jmp short dvdiphon.00417DCC 00417DB1 8B55 FC mov edx,dword ptr ss:[ebp-0x4] 00417DB4 83C2 01 add edx,0x1 ; 计数加1 00417DB7 8955 FC mov dword ptr ss:[ebp-0x4],edx 00417DBA 8B45 F8 mov eax,dword ptr ss:[ebp-0x8] 00417DBD 83C0 01 add eax,0x1 ; 计数加1 00417DC0 8945 F8 mov dword ptr ss:[ebp-0x8],eax 00417DC3 8B4D F4 mov ecx,dword ptr ss:[ebp-0xC] 00417DC6 83C1 01 add ecx,0x1 ; 计数加1 00417DC9 894D F4 mov dword ptr ss:[ebp-0xC],ecx 00417DCC 837D FC 05 cmp dword ptr ss:[ebp-0x4],0x5 ; 判断计数是否大于等于5 00417DD0 7D 12 jge short dvdiphon.00417DE4 00417DD2 8B55 18 mov edx,dword ptr ss:[ebp+0x18] ; 存放第2组注册码首地址 00417DD5 0355 F4 add edx,dword ptr ss:[ebp-0xC] ; 存放第2组注册码首地址加上计数 00417DD8 8B45 08 mov eax,dword ptr ss:[ebp+0x8] ; 注册码首地址 00417DDB 0345 F8 add eax,dword ptr ss:[ebp-0x8] ; 注册码首地址加上计数 00417DDE 8A08 mov cl,byte ptr ds:[eax] ; 取注册码 00417DE0 880A mov byte ptr ds:[edx],cl ; 存放 00417DE2 ^ EB CD jmp short dvdiphon.00417DB1 00417DE4 8B55 F8 mov edx,dword ptr ss:[ebp-0x8] ; 取计数值 00417DE7 83C2 01 add edx,0x1 ; 计数值加1 00417DEA 8955 F8 mov dword ptr ss:[ebp-0x8],edx 00417DED C745 FC 00000000 mov dword ptr ss:[ebp-0x4],0x0 ; 计数清0 00417DF4 EB 1B jmp short dvdiphon.00417E11 00417DF6 8B45 FC mov eax,dword ptr ss:[ebp-0x4] 00417DF9 83C0 01 add eax,0x1 ; 计数加1 00417DFC 8945 FC mov dword ptr ss:[ebp-0x4],eax 00417DFF 8B4D F8 mov ecx,dword ptr ss:[ebp-0x8] 00417E02 83C1 01 add ecx,0x1 ; 计数加1 00417E05 894D F8 mov dword ptr ss:[ebp-0x8],ecx 00417E08 8B55 F4 mov edx,dword ptr ss:[ebp-0xC] 00417E0B 83C2 01 add edx,0x1 ; 计数加1 00417E0E 8955 F4 mov dword ptr ss:[ebp-0xC],edx 00417E11 837D FC 05 cmp dword ptr ss:[ebp-0x4],0x5 ; 判断计数是否大于等于5 00417E15 7D 12 jge short dvdiphon.00417E29 00417E17 8B45 18 mov eax,dword ptr ss:[ebp+0x18] ; 存放第2组注册码首地址 00417E1A 0345 F4 add eax,dword ptr ss:[ebp-0xC] ; 存放第2组注册码首地址加上计数 00417E1D 8B4D 08 mov ecx,dword ptr ss:[ebp+0x8] ; 注册码首地址 00417E20 034D F8 add ecx,dword ptr ss:[ebp-0x8] ; 注册码首地址加上计数 00417E23 8A11 mov dl,byte ptr ds:[ecx] ; 取注册码 00417E25 8810 mov byte ptr ds:[eax],dl ; 存放 00417E27 ^ EB CD jmp short dvdiphon.00417DF6 00417E29 8B45 F8 mov eax,dword ptr ss:[ebp-0x8] ; 取计数值 00417E2C 83C0 01 add eax,0x1 ; 计数值加1 00417E2F 8945 F8 mov dword ptr ss:[ebp-0x8],eax 00417E32 8B4D 14 mov ecx,dword ptr ss:[ebp+0x14] 00417E35 8B55 F0 mov edx,dword ptr ss:[ebp-0x10] 00417E38 8911 mov dword ptr ds:[ecx],edx ; 第1组注册码长度 0xB 00417E3A 8B45 1C mov eax,dword ptr ss:[ebp+0x1C] 00417E3D 8B4D F4 mov ecx,dword ptr ss:[ebp-0xC] 00417E40 8908 mov dword ptr ds:[eax],ecx ; 第2组注册码长度 0x16 00417E42 B8 01000000 mov eax,0x1 00417E47 8BE5 mov esp,ebp 00417E49 5D pop ebp 00417E4A C3 retn
分组后为:
0012FAD8 31 32 33 38 39 65 66 6B 6C 71 6C 00 00 00 00 00 12389efklql.....
0012FAE8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3B 00 ..............;.
0012FAF8 35 36 37 62 63 64 68 69 6A 6E 6F 70 74 75 76 77 567bcdhijnoptuvw
0012FB08 78 7A 74 72 77 6D xztrwm
//-分组后与原始对照

9.计算sha1值(参与计算的有如下数据)
a.软件中的常量数据
常量数据 长度为0x20
CD 25 BA 43 73 ED 72 80 EF 82 B1 41 10 B1 71 81 25 CC BB B4 CC CC B7 B8 37 92 92 9B 98 AA 96 97
b.第1组注册码
0012FAD8 31 32 33 38 39 65 66 6B 6C 71 6C "12389efklql"
首先是0x20字节的常量与0x36 xor 产生一个0x40长度的buffer数据
00417727 8B95 70EFFFFF mov edx,dword ptr ss:[ebp-0x1090] 0041772D 83C2 01 add edx,0x1 00417730 8995 70EFFFFF mov dword ptr ss:[ebp-0x1090],edx 00417736 83BD 70EFFFFF 40 cmp dword ptr ss:[ebp-0x1090],0x40 0041773D 7D 26 jge short dvdiphon.00417765 0041773F 8B85 70EFFFFF mov eax,dword ptr ss:[ebp-0x1090] 00417745 0FB68C05 30EFFFFF movzx ecx,byte ptr ss:[ebp+eax-0x10D0] 0041774D 0FB695 76EFFFFF movzx edx,byte ptr ss:[ebp-0x108A] 00417754 33CA xor ecx,edx ; 常量与0x36 xor 00417756 8B85 70EFFFFF mov eax,dword ptr ss:[ebp-0x1090] 0041775C 888C05 D0EDFFFF mov byte ptr ss:[ebp+eax-0x1230],cl ; 存放xor后的值 00417763 ^ EB C2 jmp short dvdiphon.00417727 00417765 C785 70EFFFFF 00000000 mov dword ptr ss:[ebp-0x1090],0x0
结果为:
FB 13 8C 75 45 DB 44 B6 D9 B4 87 77 26 87 47 B7 13 FA 8D 82 FA FA 81 8E 01 A4 A4 AD AE 9C A0 A136 36 36 36 36 36 36 36 36 36 36 36 36 36 36 36 36 36 36 36 36 36 36 36 36 36 36 36 36 36 36 36
将第1组注册码与xor后的数据组合在一起
0012E9E0 FB 13 8C 75 45 DB 44 B6 D9 B4 87 77 26 87 47 B7 ?寀E跠顿磭w&嘒
0012E9F0 13 FA 8D 82 FA FA 81 8E 01 A4 A4 AD AE 9C A0 A1 鷯傶鷣?い湢
0012EA00 36 36 36 36 36 36 36 36 36 36 36 36 36 36 36 36 6666666666666666
0012EA10 36 36 36 36 36 36 36 36 36 36 36 36 36 36 36 36 6666666666666666
0012EA20 31 32 33 38 39 65 66 6B 6C 71 6C 12389efklql
计算组合后数据sha1值
004177FA FF95 CCEDFFFF call dword ptr ss:[ebp-0x1234] ; sha1算法 (计算组合后的数据 长度为0x4b)
如何确定是sha1函数(该函数有如下常量特征, 应当是sha1算法)
00417048 8B55 08 mov edx,dword ptr ss:[ebp+0x8] 0041704B 0355 0C add edx,dword ptr ss:[ebp+0xC] 0041704E C602 80 mov byte ptr ds:[edx],0x80 00417051 8B85 0CEEFFFF mov eax,dword ptr ss:[ebp-0x11F4] 00417057 25 FF000000 and eax,0xFF 0041705C 8B8D 14EEFFFF mov ecx,dword ptr ss:[ebp-0x11EC] 00417062 C1E1 06 shl ecx,0x6 00417065 8B55 08 mov edx,dword ptr ss:[ebp+0x8] 00417068 88440A FF mov byte ptr ds:[edx+ecx-0x1],al 0041706C 8B85 0CEEFFFF mov eax,dword ptr ss:[ebp-0x11F4] 00417072 C1E8 08 shr eax,0x8 00417075 25 FF000000 and eax,0xFF 0041707A 8B8D 14EEFFFF mov ecx,dword ptr ss:[ebp-0x11EC] 00417080 C1E1 06 shl ecx,0x6 00417083 8B55 08 mov edx,dword ptr ss:[ebp+0x8] 00417086 88440A FE mov byte ptr ds:[edx+ecx-0x2],al 0041708A 8B85 0CEEFFFF mov eax,dword ptr ss:[ebp-0x11F4] 00417090 C1E8 10 shr eax,0x10 00417093 25 FF000000 and eax,0xFF 00417098 8B8D 14EEFFFF mov ecx,dword ptr ss:[ebp-0x11EC] 0041709E C1E1 06 shl ecx,0x6 004170A1 8B55 08 mov edx,dword ptr ss:[ebp+0x8] 004170A4 88440A FD mov byte ptr ds:[edx+ecx-0x3],al 004170A8 8B85 0CEEFFFF mov eax,dword ptr ss:[ebp-0x11F4] 004170AE C1E8 18 shr eax,0x18 004170B1 25 FF000000 and eax,0xFF 004170B6 8B8D 14EEFFFF mov ecx,dword ptr ss:[ebp-0x11EC] 004170BC C1E1 06 shl ecx,0x6 004170BF 8B55 08 mov edx,dword ptr ss:[ebp+0x8] 004170C2 88440A FC mov byte ptr ds:[edx+ecx-0x4],al [COLOR="red"]004170C6 C785 ACFEFFFF 0>mov dword ptr ss:[ebp-0x154],0x67452301 004170D0 C785 B0FEFFFF 8>mov dword ptr ss:[ebp-0x150],0xEFCDAB89 004170DA C785 B4FEFFFF F>mov dword ptr ss:[ebp-0x14C],0x98BADCFE 004170E4 C785 B8FEFFFF 7>mov dword ptr ss:[ebp-0x148],0x10325476 004170EE C785 BCFEFFFF F>mov dword ptr ss:[ebp-0x144],0xC3D2E1F0[/COLOR] 004170F8 C785 A0FEFFFF 0>mov dword ptr ss:[ebp-0x160],0x0 00417102 EB 0F jmp short dvdiphon.00417113
计算的结果为:
23 91 90 CD 1D C6 63 3E 3F 81 EA 9E 9D 24 4A C4 99 03 9E B0
再次将0x20字节常量值与0x5c xor 产生一个0x40长度的buffer数据
常量数据 长度0x20
CD 25 BA 43 73 ED 72 80 EF 82 B1 41 10 B1 71 81 25 CC BB B4 CC CC B7 B8 37 92 92 9B 98 AA 96 97
0041782D 0FB68415 30EFFFFF movzx eax,byte ptr ss:[ebp+edx-0x10D0] ; 取常量 00417835 0FB68D 77EFFFFF movzx ecx,byte ptr ss:[ebp-0x1089] ; 0x5c 0041783C 33C1 xor eax,ecx ; xor 0041783E 8B95 70EFFFFF mov edx,dword ptr ss:[ebp-0x1090] 00417844 888415 10EEFFFF mov byte ptr ss:[ebp+edx-0x11F0],al ; 存放 0041784B ^ EB C2 jmp short dvdiphon.0041780F
xor后的结果与上面计算的sha1值组合在一起
0012E8C0 91 79 E6 1F 2F B1 2E DC B3 DE ED 1D 4C ED 2D DD 憏?/?艹揄L?
0012E8D0 79 90 E7 E8 90 90 EB E4 6B CE CE C7 C4 F6 CA CB y愮钀愲鋕挝悄鍪
0012E8E0 5C 5C 5C 5C 5C 5C 5C 5C 5C 5C 5C 5C 5C 5C 5C 5C \\\\\\\\\\\\\\\\
0012E8F0 5C 5C 5C 5C 5C 5C 5C 5C 5C 5C 5C 5C 5C 5C 5C 5C \\\\\\\\\\\\\\\\
0012E900 23 91 90 CD 1D C6 63 3E 3F 81 EA 9E 9D 24 4A C4 #憪?芻>?侁灊$J
0012E910 99 03 9E B0
对组合在一起的数据再次进行sha1计算 长度为0x54
004178CB 8B55 1C mov edx,dword ptr ss:[ebp+0x1C] 004178CE 52 push edx 004178CF 8B85 54EEFFFF mov eax,dword ptr ss:[ebp-0x11AC] 004178D5 83C0 14 add eax,0x14 004178D8 50 push eax 004178D9 8D8D 58EEFFFF lea ecx,dword ptr ss:[ebp-0x11A8] 004178DF 51 push ecx 004178E0 FF95 CCEDFFFF call dword ptr ss:[ebp-0x1234] ; sha1算法
结果为
68 51 1C E5 09 94 70 95 53 97 82 C9 E7 3F 0F 8D C8 C6 CD 93
10. 根据反回的sha1值来查找字符(注册码)
004180AD 83C4 14 add esp,0x14 004180B0 8D85 3CFFFFFF lea eax,dword ptr ss:[ebp-0xC4] 004180B6 50 push eax 004180B7 6A 14 push 0x14 ; 长度 004180B9 8D8D 28FFFFFF lea ecx,dword ptr ss:[ebp-0xD8] 004180BF 51 push ecx ; sha1值 004180C0 E8 6BF8FFFF call dvdiphon.00417930 ; 查找字符串算法(取sha值的每3个字节做为一个整数进行运算做为字符表的下标值)
字符表
00613B78 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 ABCDEFGHIJKLMNOP
00613B88 51 52 53 54 55 56 57 58 59 5A 61 62 63 64 65 66 QRSTUVWXYZabcdef
00613B98 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 ghijklmnopqrstuv
00613BA8 77 78 79 7A 30 31 32 33 34 35 36 37 38 39 2B 2F wxyz0123456789+/
具体算法如下:
00417930 55 push ebp 00417931 8BEC mov ebp,esp 00417933 83EC 24 sub esp,0x24 00417936 8B45 10 mov eax,dword ptr ss:[ebp+0x10] 00417939 8945 F4 mov dword ptr ss:[ebp-0xC],eax 0041793C 8B4D F4 mov ecx,dword ptr ss:[ebp-0xC] 0041793F 894D FC mov dword ptr ss:[ebp-0x4],ecx 00417942 8B55 08 mov edx,dword ptr ss:[ebp+0x8] 00417945 8955 F0 mov dword ptr ss:[ebp-0x10],edx 00417948 C745 F8 0000000>mov dword ptr ss:[ebp-0x8],0x0 0041794F C745 F8 0000000>mov dword ptr ss:[ebp-0x8],0x0 00417956 8B45 F8 mov eax,dword ptr ss:[ebp-0x8] 00417959 3B45 0C cmp eax,dword ptr ss:[ebp+0xC] 0041795C 0F8D EF000000 jge dvdiphon.00417A51 ; 判断是否结束 00417962 8B4D F0 mov ecx,dword ptr ss:[ebp-0x10] 00417965 034D F8 add ecx,dword ptr ss:[ebp-0x8] 00417968 0FB611 movzx edx,byte ptr ds:[ecx] 0041796B 8955 EC mov dword ptr ss:[ebp-0x14],edx 0041796E 8B45 F8 mov eax,dword ptr ss:[ebp-0x8] 00417971 83C0 01 add eax,0x1 00417974 8945 F8 mov dword ptr ss:[ebp-0x8],eax 00417977 8B4D EC mov ecx,dword ptr ss:[ebp-0x14] 0041797A C1E1 08 shl ecx,0x8 ; 第1字节左移8位 0041797D 894D EC mov dword ptr ss:[ebp-0x14],ecx 00417980 8B55 F8 mov edx,dword ptr ss:[ebp-0x8] 00417983 3B55 0C cmp edx,dword ptr ss:[ebp+0xC] 00417986 7D 0F jge short dvdiphon.00417997 00417988 8B45 F0 mov eax,dword ptr ss:[ebp-0x10] 0041798B 0345 F8 add eax,dword ptr ss:[ebp-0x8] 0041798E 0FB608 movzx ecx,byte ptr ds:[eax] 00417991 034D EC add ecx,dword ptr ss:[ebp-0x14] ; 第2字节加上前面左移8位后的值 00417994 894D EC mov dword ptr ss:[ebp-0x14],ecx ; 存放 00417997 8B55 F8 mov edx,dword ptr ss:[ebp-0x8] 0041799A 83C2 01 add edx,0x1 0041799D 8955 F8 mov dword ptr ss:[ebp-0x8],edx 004179A0 8B45 EC mov eax,dword ptr ss:[ebp-0x14] 004179A3 C1E0 08 shl eax,0x8 ; 左移8位 004179A6 8945 EC mov dword ptr ss:[ebp-0x14],eax 004179A9 8B4D F8 mov ecx,dword ptr ss:[ebp-0x8] 004179AC 3B4D 0C cmp ecx,dword ptr ss:[ebp+0xC] 004179AF 7D 0F jge short dvdiphon.004179C0 004179B1 8B55 F0 mov edx,dword ptr ss:[ebp-0x10] 004179B4 0355 F8 add edx,dword ptr ss:[ebp-0x8] 004179B7 0FB602 movzx eax,byte ptr ds:[edx] 004179BA 0345 EC add eax,dword ptr ss:[ebp-0x14] ; 第3字节加上前面左移8位后的值 004179BD 8945 EC mov dword ptr ss:[ebp-0x14],eax 004179C0 8B4D F8 mov ecx,dword ptr ss:[ebp-0x8] 004179C3 83C1 01 add ecx,0x1 004179C6 894D F8 mov dword ptr ss:[ebp-0x8],ecx 004179C9 8B55 EC mov edx,dword ptr ss:[ebp-0x14] 004179CC 81E2 0000FC00 and edx,0xFC0000 ; 将上面计算得到的整数值进逻辑运算 004179D2 C1FA 12 sar edx,0x12 ; 算术右移0x12 (逻辑运算后的值做为下标取字符) 004179D5 8B45 FC mov eax,dword ptr ss:[ebp-0x4] 004179D8 8A8A 783B6100 mov cl,byte ptr ds:[edx+0x613B78] ; ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ 004179DE 8808 mov byte ptr ds:[eax],cl ; 存放查找到的字符 004179E0 8B55 EC mov edx,dword ptr ss:[ebp-0x14] 004179E3 81E2 00F00300 and edx,0x3F000 004179E9 C1FA 0C sar edx,0xC 004179EC 8B45 FC mov eax,dword ptr ss:[ebp-0x4] 004179EF 8A8A 783B6100 mov cl,byte ptr ds:[edx+0x613B78] ; ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ 004179F5 8848 01 mov byte ptr ds:[eax+0x1],cl ; 存放查找到的字符 004179F8 8B55 EC mov edx,dword ptr ss:[ebp-0x14] 004179FB 81E2 C00F0000 and edx,0xFC0 00417A01 C1FA 06 sar edx,0x6 00417A04 8B45 FC mov eax,dword ptr ss:[ebp-0x4] 00417A07 8A8A 783B6100 mov cl,byte ptr ds:[edx+0x613B78] ; ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ 00417A0D 8848 02 mov byte ptr ds:[eax+0x2],cl ; 存放查找到的字符 00417A10 8B55 EC mov edx,dword ptr ss:[ebp-0x14] 00417A13 83E2 3F and edx,0x3F 00417A16 8B45 FC mov eax,dword ptr ss:[ebp-0x4] 00417A19 8A8A 783B6100 mov cl,byte ptr ds:[edx+0x613B78] ; ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ 00417A1F 8848 03 mov byte ptr ds:[eax+0x3],cl ; 存放查找到的字符 00417A22 8B55 F8 mov edx,dword ptr ss:[ebp-0x8] 00417A25 3B55 0C cmp edx,dword ptr ss:[ebp+0xC] 00417A28 7E 07 jle short dvdiphon.00417A31 00417A2A 8B45 FC mov eax,dword ptr ss:[ebp-0x4] 00417A2D C640 03 3D mov byte ptr ds:[eax+0x3],0x3D 00417A31 8B4D 0C mov ecx,dword ptr ss:[ebp+0xC] 00417A34 83C1 01 add ecx,0x1 00417A37 394D F8 cmp dword ptr ss:[ebp-0x8],ecx 00417A3A 7E 07 jle short dvdiphon.00417A43 00417A3C 8B55 FC mov edx,dword ptr ss:[ebp-0x4] 00417A3F C642 02 3D mov byte ptr ds:[edx+0x2],0x3D 00417A43 8B45 FC mov eax,dword ptr ss:[ebp-0x4] 00417A46 83C0 04 add eax,0x4 00417A49 8945 FC mov dword ptr ss:[ebp-0x4],eax 00417A4C ^ E9 05FFFFFF jmp dvdiphon.00417956 00417A51 8B4D FC mov ecx,dword ptr ss:[ebp-0x4] ; 结束 00417A54 C601 00 mov byte ptr ds:[ecx],0x0 00417A57 8B55 F4 mov edx,dword ptr ss:[ebp-0xC] 00417A5A 8955 E8 mov dword ptr ss:[ebp-0x18],edx 00417A5D 8B45 E8 mov eax,dword ptr ss:[ebp-0x18] 00417A60 83C0 01 add eax,0x1 00417A63 8945 E4 mov dword ptr ss:[ebp-0x1C],eax 00417A66 8B4D E8 mov ecx,dword ptr ss:[ebp-0x18] 00417A69 8A11 mov dl,byte ptr ds:[ecx] 00417A6B 8855 E3 mov byte ptr ss:[ebp-0x1D],dl 00417A6E 8345 E8 01 add dword ptr ss:[ebp-0x18],0x1 00417A72 807D E3 00 cmp byte ptr ss:[ebp-0x1D],0x0 00417A76 ^ 75 EE jnz short dvdiphon.00417A66 00417A78 8B45 E8 mov eax,dword ptr ss:[ebp-0x18] 00417A7B 2B45 E4 sub eax,dword ptr ss:[ebp-0x1C] 00417A7E 8945 DC mov dword ptr ss:[ebp-0x24],eax 00417A81 8B45 DC mov eax,dword ptr ss:[ebp-0x24] 00417A84 8BE5 mov esp,ebp 00417A86 5D pop ebp
11.将查找到的字符中小写字母转换成大写并判断是否有字符 '/' '+', 如果有就替换成 'O' 'E'
004180C8 C785 ACFEFFFF 0>mov dword ptr ss:[ebp-0x154],0x0 004180D2 EB 0F jmp short dvdiphon.004180E3 004180D4 8B95 ACFEFFFF mov edx,dword ptr ss:[ebp-0x154] ; 转换成大写 004180DA 83C2 01 add edx,0x1 004180DD 8995 ACFEFFFF mov dword ptr ss:[ebp-0x154],edx 004180E3 83BD ACFEFFFF 1>cmp dword ptr ss:[ebp-0x154],0x16 004180EA 0F8D 8F000000 jge dvdiphon.0041817F 004180F0 8B85 ACFEFFFF mov eax,dword ptr ss:[ebp-0x154] 004180F6 0FBE8C05 3CFFFF>movsx ecx,byte ptr ss:[ebp+eax-0xC4] 004180FE 83F9 61 cmp ecx,0x61 00418101 7C 33 jl short dvdiphon.00418136 00418103 8B95 ACFEFFFF mov edx,dword ptr ss:[ebp-0x154] 00418109 0FBE8415 3CFFFF>movsx eax,byte ptr ss:[ebp+edx-0xC4] 00418111 83F8 7A cmp eax,0x7A 00418114 7F 20 jg short dvdiphon.00418136 00418116 8B8D ACFEFFFF mov ecx,dword ptr ss:[ebp-0x154] 0041811C 0FBE940D 3CFFFF>movsx edx,byte ptr ss:[ebp+ecx-0xC4] 00418124 83EA 20 sub edx,0x20 00418127 8B85 ACFEFFFF mov eax,dword ptr ss:[ebp-0x154] 0041812D 889405 3CFFFFFF mov byte ptr ss:[ebp+eax-0xC4],dl 00418134 EB 44 jmp short dvdiphon.0041817A 00418136 8B8D ACFEFFFF mov ecx,dword ptr ss:[ebp-0x154] 0041813C 0FBE940D 3CFFFF>movsx edx,byte ptr ss:[ebp+ecx-0xC4] 00418144 83FA 2B cmp edx,0x2B ; 是否为 '+' 00418147 75 10 jnz short dvdiphon.00418159 00418149 8B85 ACFEFFFF mov eax,dword ptr ss:[ebp-0x154] 0041814F C68405 3CFFFFFF>mov byte ptr ss:[ebp+eax-0xC4],0x45 ; 替换成 'E' 00418157 EB 21 jmp short dvdiphon.0041817A 00418159 8B8D ACFEFFFF mov ecx,dword ptr ss:[ebp-0x154] 0041815F 0FBE940D 3CFFFF>movsx edx,byte ptr ss:[ebp+ecx-0xC4] 00418167 83FA 2F cmp edx,0x2F ; 是否为 '/' 0041816A 75 0E jnz short dvdiphon.0041817A 0041816C 8B85 ACFEFFFF mov eax,dword ptr ss:[ebp-0x154] 00418172 C68405 3CFFFFFF>mov byte ptr ss:[ebp+eax-0xC4],0x4F ; 替换成 'O' 0041817A ^ E9 55FFFFFF jmp dvdiphon.004180D4
12.比较注册码是否相同, 长度为0x16(比较上面查找到的字符串是否与第2组注册码相同)
0041817F 6A 16 push 0x16 00418181 8D8D DCFEFFFF lea ecx,dword ptr ss:[ebp-0x124] 00418187 51 push ecx 00418188 8D95 3CFFFFFF lea edx,dword ptr ss:[ebp-0xC4] 0041818E 52 push edx 0041818F E8 3CF9FFFF call dvdiphon.00417AD0 ; 判断注册码是否相同(输入的注册码分组后第2组注册码与根据sha1值查找的字符串进行比较 长度为0x16字节) 00418194 83C4 0C add esp,0xC 00418197 F7D8 neg eax 00418199 1BC0 sbb eax,eax 0041819B 83C0 01 add eax,0x1 0041819E A3 D81B6200 mov dword ptr ds:[0x621BD8],eax ; 注册码相同则给全局变量值为1,否则为0 004181A3 8B85 6CFFFFFF mov eax,dword ptr ss:[ebp-0x94] 004181A9 8985 A0FEFFFF mov dword ptr ss:[ebp-0x160],eax 004181AF C745 FC FFFFFFF>mov dword ptr ss:[ebp-0x4],-0x1 004181B6 8D8D 70FFFFFF lea ecx,dword ptr ss:[ebp-0x90] 004181BC E8 3F7D0200 call dvdiphon.0043FF00
13.分析总结
a) 将用户输入的注册码加密(减0x19)写入注册表(CLSID\{D2D219BC-BCE8-4249-8636- DE8BEFCD28C3}\ProgID),提示重启软件。
b) 重启软件时从注册表中读取注册码将其解密(加上0x19),并将解密后的注册码分成2组。
c) 用第1组注册码参与sha1计算得到sha1值
d) 根据sha1值查找字符,得到注册码。
e) 比较查找到的字符是否与第2组注册码相同, 相同则注册成功,否则失败。
14. 算法分析明白,就开始写注册机。
#include "stdafx.h"
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <time.h>
#include <Windows.h>
#include "sha1.h"
//随机数
int genrand(long num, char * outrand)
{
BYTE *dat = (BYTE *)malloc(num * sizeof(BYTE));
BYTE *p = dat, i;
if (0 == num)
{
return -1;
}
if (dat == NULL){
printf("malloc error, memory not enough!\n");
return -1;
}
srand( (unsigned int)time(0) );
for (i = 0; i < num; i += 3){
dat[i] = 'A'+ rand()%4;
dat[i+1] = 'a'+rand()%4;
dat[i+2] = '0'+rand()%10;
}
memcpy(outrand, dat, num);
return 0;
}
//根据sha1值获取字符
void FindLicense(BYTE* sha1data, int len, char* outLicense)
{
unsigned long offset = 0;
unsigned long temp = 0x0;
char tempLong[3] = {0};
char szTable[256] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int index = 0;
if (NULL == sha1data || 0 == len)
{
return;
}
for (int i=0; i<len; i+=3)
{
//取3位sha1值为一个整数
for (int j=0; j<3; j++)
{
if (0 == j)
{
temp = sha1data[i+j];
temp <<= 8;
offset = temp;
}
if (1 == j)
{
temp = sha1data[i+j];
offset += temp;
}
if (2 == j)
{
temp = sha1data[i+j];
offset <<=8;
offset += temp;
}
}
temp = offset;
temp &= 0xFC0000;
temp >>= 0x12;
outLicense[index] = szTable[temp];
index++;
temp = offset;
temp &= 0x3F000;
temp >>= 0xc;
outLicense[index] = szTable[temp];
index++;
temp = offset;
temp &= 0xFC0;
temp >>= 0x6;
outLicense[index] = szTable[temp];
index++;
temp = offset;
temp &= 0x3F;
outLicense[index] = szTable[temp];
index++;
}
outLicense[index] = '=';
}
void GenerateLicense(char* License,int Licenselen, char* randchar, int randlen, char* outLincenes)
{
/*
//-分组后与原始对照
123456789abcdefghijklmnopqlstuvwxyztrwm
123 89 ef kl ql
567 bcd hij nop tuvwx ztrwm
1234 AFE89a C5Qefg MUCklm JVTqlsL4LJ5y Z8PJCjGzZM
//--正确的注册码
1234AFE89aC5QefgMUCklmJVTqlsL4LJ5yZ8PJC
*/
char randchartemp[5] = {0};
char randchartemp1[4] = {0};
char randchartemp2[4] = {0};
char randchartemp3[4] = {0};
char randchartemp4[4] = {0};
char Licensetemp[5] = {0};
char Licensetemp1[5] = {0};
char Licensetemp2[5] = {0};
char Licensetemp3[5] = {0};
char Licensetemp4[7] = {0};
char Licensetemp5[20] = {0};
char stastr[256] = {0};
if (NULL == License || 0 == Licenselen || NULL == randchar || 0 == randlen)
{
return;
}
//-先将随机数分组
strncpy(randchartemp, randchar, 3);
randchartemp[3] = '8';
strncpy(randchartemp1, randchar+3, 2);
randchartemp1[2] = '8';
strncpy(randchartemp2, randchar+5, 2);
randchartemp2[2] = '8';
strncpy(randchartemp3, randchar+7, 2);
randchartemp3[2] = '8';
strncpy(randchartemp4, randchar+9, 2);
randchartemp4[2] = '8';
//--注册码分组
strncpy(Licensetemp, License, 3);
strncpy(Licensetemp1, License+3, 3);
strncpy(Licensetemp2, License+6, 3);
strncpy(Licensetemp3, License+9, 3);
strncpy(Licensetemp4, License+12, 5);
Licensetemp4[5] = '8';
strncpy(Licensetemp5, License+17, Licenselen-17);
//组合注册码
strncpy(stastr, randchartemp, 4);
strncpy(stastr+4, Licensetemp, 3);
strncpy(stastr+7, randchartemp1, 3);
strncpy(stastr+10, Licensetemp1, 3);
strncpy(stastr+13, randchartemp2, 3);
strncpy(stastr+16, Licensetemp2, 3);
strncpy(stastr+19, randchartemp3, 3);
strncpy(stastr+22, Licensetemp3, 3);
strncpy(stastr+25, randchartemp4, 3);
strncpy(stastr+28, Licensetemp4, 6);
strncpy(stastr+34, Licensetemp5, strlen(Licensetemp5));
strncpy(outLincenes, stastr, 0x27);
}
int _tmain(int argc, _TCHAR* argv[])
{
//软件中的常量数据,参与计算注册码
const BYTE data[0x100] = {0xCD, 0x25, 0xBA, 0x43, 0x73, 0xED, 0x72, 0x80, 0xEF, 0x82, 0xB1, 0x41, 0x10, 0xB1, 0x71, 0x81,
0x25, 0xCC, 0xBB, 0xB4, 0xCC, 0xCC, 0xB7, 0xB8, 0x37, 0x92, 0x92, 0x9B, 0x98, 0xAA,
0x96, 0x97};
BYTE XorData[0x100] = {0x00};
BYTE XorData1[0x100] = {0x00};
char randdata[16] = {0x31, 0x32, 0x33, 0x38, 0x39, 0x65, 0x66, 0x6B, 0x6C, 0x71, 0x6C};
char License[256] = {0};
char TempLicense[256] = {0};
int ret = 0;
int len = 0;
unsigned char sha1output[30] = {0x00};
unsigned char sha1output1[30] = {0x00};
ret = genrand(11,randdata);
if (-1 == ret)
{
printf("生成注册码出错!\n");
return -1;
}
//软件中的常量数据与0x36 进行xor
for (int i=0; i <= 0x40; i++)
{
XorData[i] = data[i] ^ 0x36;
len = i;
}
//将xor后的数据与随机数组合
memcpy(XorData+len, randdata, 11);
//计算组合后数据的sha1值
sha1(XorData, len+11,sha1output);
//软件中的常量数据与0x5c 进行xor
for (int i=0; i <= 0x40; i++)
{
XorData1[i] = data[i] ^ 0x5c;
len = i;
}
//将上面计算出来的sha1值与XorData1数据组合
memcpy(XorData1+len, sha1output, 20);
//计算组合后数据的sha1值
sha1(XorData1, len+20,sha1output1);
FindLicense(sha1output1, 20, TempLicense);
//--将字符转换成大写,并将其中的字符'/'与'+'替换成 'O'与'E'
for (int n=0; n<strlen(TempLicense); n++)
{
//--判断大小写并转换成大写
if(TempLicense[n]>='a'&& TempLicense[n]<='z')
{
TempLicense[n] -= 32;
continue;
}
if (TempLicense[n] == '/')
{
TempLicense[n] = 'O';
}
if (TempLicense[n] == '+')
{
TempLicense[n] = 'E';
}
}
//--生成注册码
GenerateLicense(TempLicense, strlen(TempLicense), randdata, strlen(randdata), License);
printf("用户名注册时随便输入\n");
printf("注册码: %s\n",License);
getchar();
return 0;
}
15.测试注册机

16.输入用户名test 输入注册码码,成功注册

bin.zip
src.zip
样本.part1.rar
样本.part2.rar
样本.part3.rar
样本.part4.rar
样本.part5.rar
