程序的界面如下:
比较郁闷的是,不管我怎么点击它,就是没有任何反应,也就是说在注册码输入错误的情况下是没有任何反应的。通过查壳发现是Delphi程序,没有壳,由于对Delphi不了解,先打开OD搜索关键字,看有没有突破
通过智能搜索,得到了一个“注册成功”字符串,定位到此处:
00458031 |. 81BE 0C030000>cmp dword ptr ds:[esi+0x30C],0x85
0045803B |. 75 76 jnz short CKme.004580B3 ; 关键跳,不能跳
0045803D |. 33DB xor ebx,ebx
0045803F |> 8D55 E4 /lea edx,[local.7]
00458042 |. 8B86 D4020000 |mov eax,dword ptr ds:[esi+0x2D4]
00458048 |. E8 FBB2FCFF |call CKme.00423348
0045804D |. 8B45 E4 |mov eax,[local.7]
00458050 |. E8 27BBFAFF |call CKme.00403B7C
00458055 |. 83C0 03 |add eax,0x3
00458058 |. 8D55 E8 |lea edx,[local.6]
0045805B |. E8 A4FAFAFF |call CKme.00407B04
00458060 |. FF75 E8 |push [local.6]
00458063 |. 8D55 E0 |lea edx,[local.8]
00458066 |. 8B86 D4020000 |mov eax,dword ptr ds:[esi+0x2D4]
0045806C |. E8 D7B2FCFF |call CKme.00423348
00458071 |. FF75 E0 |push [local.8]
00458074 |. 8D55 DC |lea edx,[local.9]
00458077 |. 8BC3 |mov eax,ebx
00458079 |. E8 86FAFAFF |call CKme.00407B04
0045807E |. FF75 DC |push [local.9]
00458081 |. 8D45 FC |lea eax,[local.1]
00458084 |. BA 03000000 |mov edx,0x3
00458089 |. E8 AEBBFAFF |call CKme.00403C3C
0045808E |. 43 |inc ebx
0045808F |. 83FB 13 |cmp ebx,0x13
00458092 |.^ 75 AB \jnz short CKme.0045803F
00458094 |. 33D2 xor edx,edx ; CKme.
00458096 |. 8B86 F0020000 mov eax,dword ptr ds:[esi+0x2F0]
0045809C |. E8 BFB1FCFF call CKme.00423260
004580A1 |. A1 20B84500 mov eax,dword ptr ds:[0x45B820]
004580A6 |. 83C0 70 add eax,0x70
004580A9 |. BA 14814500 mov edx,CKme.00458114 ; 恭喜恭喜!注册成功
004580AE |. E8 9DB8FAFF call CKme.00403950
在过程选项中,发现程序有五个事件,第一个窗体创建与输入的字符应该无关,而后面的键盘按键放下、面板单击和面板双击、还有检查密码,应该就和用户名/注册码的获取和检测有关了,还可以看到“注册成功”的代码段就是面板单击事件中。通过测试发现,KeyUp事件是为了获取输入的用户名,chkcode事件是为了获取输入的注册码并检测我们对这个四个事件下断点,当输入注册码时断在了此处:
00457C40 /. 55 push ebp
00457C41 |. 8BEC mov ebp,esp
00457C43 |. 51 push ecx
00457C44 |. B9 05000000 mov ecx,0x5
00457C49 |> 6A 00 /push 0x0
00457C4B |. 6A 00 |push 0x0
00457C4D |. 49 |dec ecx
00457C4E |.^ 75 F9 \jnz short CKme.00457C49
00457C50 |. 51 push ecx
00457C51 |. 874D FC xchg [local.1],ecx
00457C54 |. 53 push ebx
00457C55 |. 56 push esi
00457C56 |. 8BD8 mov ebx,eax
00457C58 |. 33C0 xor eax,eax
00457C5A |. 55 push ebp
00457C5B |. 68 3D7E4500 push CKme.00457E3D
00457C60 |. 64:FF30 push dword ptr fs:[eax]
00457C63 |. 64:8920 mov dword ptr fs:[eax],esp
00457C66 |. 8BB3 F8020000 mov esi,dword ptr ds:[ebx+0x2F8]
00457C6C |. 83C6 05 add esi,0x5
00457C6F |. FFB3 10030000 push dword ptr ds:[ebx+0x310] ; 黑头Sun Bird
00457C75 |. 8D55 F8 lea edx,[local.2]
00457C78 |. 8BC6 mov eax,esi
00457C7A |. E8 85FEFAFF call CKme.00407B04 ; 整数转字符串
00457C7F |. FF75 F8 push [local.2] ; 字符串长度+5
00457C82 |. FFB3 14030000 push dword ptr ds:[ebx+0x314] ; dseloffc-012-OK
00457C88 |. 8D55 F4 lea edx,[local.3]
00457C8B |. 8B83 D4020000 mov eax,dword ptr ds:[ebx+0x2D4]
00457C91 |. E8 B2B6FCFF call CKme.00423348
00457C96 |. FF75 F4 push [local.3] ; 输入的用户名
00457C99 |. 8D83 18030000 lea eax,dword ptr ds:[ebx+0x318]
00457C9F |. BA 04000000 mov edx,0x4
00457CA4 |. E8 93BFFAFF call CKme.00403C3C
00457CA9 |. 33D2 xor edx,edx
00457CAB |. 8B83 F4020000 mov eax,dword ptr ds:[ebx+0x2F4]
00457CB1 |. E8 AAB5FCFF call CKme.00423260
00457CB6 |. 8B93 18030000 mov edx,dword ptr ds:[ebx+0x318] ; 疑似正确的序列号
00457CBC |. 8B83 F4020000 mov eax,dword ptr ds:[ebx+0x2F4]
00457CC2 |. E8 B1B6FCFF call CKme.00423378
00457CC7 |. 33F6 xor esi,esi
00457CC9 |> 8D55 EC /lea edx,[local.5]
00457CCC |. 8B83 D4020000 |mov eax,dword ptr ds:[ebx+0x2D4]
00457CD2 |. E8 71B6FCFF |call CKme.00423348
00457CD7 |. 8B45 EC |mov eax,[local.5] ; 输入的用户名
00457CDA |. E8 9DBEFAFF |call CKme.00403B7C
00457CDF |. 83C0 03 |add eax,0x3
00457CE2 |. 8D55 F0 |lea edx,[local.4]
00457CE5 |. E8 1AFEFAFF |call CKme.00407B04
00457CEA |. FF75 F0 |push [local.4]
00457CED |. 8D55 E8 |lea edx,[local.6]
00457CF0 |. 8B83 D4020000 |mov eax,dword ptr ds:[ebx+0x2D4]
00457CF6 |. E8 4DB6FCFF |call CKme.00423348
00457CFB |. FF75 E8 |push [local.6]
00457CFE |. 8D55 E4 |lea edx,[local.7]
00457D01 |. 8BC6 |mov eax,esi
00457D03 |. E8 FCFDFAFF |call CKme.00407B04
00457D08 |. FF75 E4 |push [local.7]
00457D0B |. 8D45 FC |lea eax,[local.1]
00457D0E |. BA 03000000 |mov edx,0x3
00457D13 |. E8 24BFFAFF |call CKme.00403C3C
00457D18 |. 46 |inc esi
00457D19 |. 83FE 13 |cmp esi,0x13
00457D1C |.^ 75 AB \jnz short CKme.00457CC9
00457D1E |. 8D55 E0 lea edx,[local.8]
00457D21 |. 8B83 D8020000 mov eax,dword ptr ds:[ebx+0x2D8] ; CKme.004428F8
00457D27 |. E8 1CB6FCFF call CKme.00423348
00457D2C |. 8B45 E0 mov eax,[local.8] ; 输入的序列号
00457D2F |. 8B93 18030000 mov edx,dword ptr ds:[ebx+0x318] ; 正确的序列号
00457D35 |. E8 52BFFAFF call CKme.00403C8C ; 比较
00457D3A |. 75 0A jnz short CKme.00457D46
然后返回来看最开始的“注册成功”的地方:
00458021 |. BA 03000000 |mov edx,0x3
00458026 |. E8 11BCFAFF |call CKme.00403C3C
0045802B |. 43 |inc ebx
0045802C |. 83FB 13 |cmp ebx,0x13
0045802F |.^ 75 AB \jnz short CKme.00457FDC
00458031 |. 81BE 0C030000>cmp dword ptr ds:[esi+0x30C],0x85
0045803B |. 75 76 jnz short CKme.004580B3 ; 关键跳,不能跳
0045803D |. 33DB xor ebx,ebx
0045803F |> 8D55 E4 /lea edx,[local.7]
00458042 |. 8B86 D4020000 |mov eax,dword ptr ds:[esi+0x2D4]
00458048 |. E8 FBB2FCFF |call CKme.00423348
0045804D |. 8B45 E4 |mov eax,[local.7]
00458050 |. E8 27BBFAFF |call CKme.00403B7C
接着来看面板双击事件代码如下:
00457E7C /. 55 push ebp
00457E7D |. 8BEC mov ebp,esp
00457E7F |. B9 04000000 mov ecx,0x4
00457E84 |> 6A 00 /push 0x0
00457E86 |. 6A 00 |push 0x0
00457E88 |. 49 |dec ecx ; wow64cpu.776E2AD2
00457E89 |.^ 75 F9 \jnz short CKme.00457E84
00457E8B |. 51 push ecx ; wow64cpu.776E2AD2
00457E8C |. 53 push ebx
00457E8D |. 56 push esi
00457E8E |. 8BF0 mov esi,eax
00457E90 |. 33C0 xor eax,eax
00457E92 |. 55 push ebp
00457E93 |. 68 A97F4500 push CKme.00457FA9
00457E98 |. 64:FF30 push dword ptr fs:[eax]
00457E9B |. 64:8920 mov dword ptr fs:[eax],esp
00457E9E |. 33DB xor ebx,ebx
00457EA0 |> 8D55 F4 /lea edx,[local.3]
00457EA3 |. 8B86 D4020000 |mov eax,dword ptr ds:[esi+0x2D4]
00457EA9 |. E8 9AB4FCFF |call CKme.00423348
00457EAE |. 8B45 F4 |mov eax,[local.3] ; 用户名
00457EB1 |. E8 C6BCFAFF |call CKme.00403B7C
00457EB6 |. 83C0 09 |add eax,0x9
00457EB9 |. 8D55 F8 |lea edx,[local.2]
00457EBC |. E8 43FCFAFF |call CKme.00407B04
00457EC1 |. FF75 F8 |push [local.2]
00457EC4 |. 8D55 F0 |lea edx,[local.4]
00457EC7 |. 8B86 D4020000 |mov eax,dword ptr ds:[esi+0x2D4]
00457ECD |. E8 76B4FCFF |call CKme.00423348
00457ED2 |. FF75 F0 |push [local.4]
00457ED5 |. 8D55 EC |lea edx,[local.5]
00457ED8 |. 8BC3 |mov eax,ebx
00457EDA |. E8 25FCFAFF |call CKme.00407B04
00457EDF |. FF75 EC |push [local.5] ; CKme.0040D6BD
00457EE2 |. 8D45 FC |lea eax,[local.1]
00457EE5 |. BA 03000000 |mov edx,0x3
00457EEA |. E8 4DBDFAFF |call CKme.00403C3C
00457EEF |. 43 |inc ebx
00457EF0 |. 83FB 13 |cmp ebx,0x13
00457EF3 |.^ 75 AB \jnz short CKme.00457EA0
00457EF5 |. 83BE 0C030000>cmp dword ptr ds:[esi+0x30C],0x3E
00457EFC |. 75 0A jnz short CKme.00457F08
00457EFE |. C786 0C030000>mov dword ptr ds:[esi+0x30C],0x85
00457F08 |> 33DB xor ebx,ebx
00457F0A |> 8D55 E4 /lea edx,[local.7]
每次输入用户名的时候,事件KeyUp都会获取用户输入的字符,并保存起来,并获取输入的用户名的长度保存起来,每次输入序列号的时候,事件chkcode都会获取输入的字符并保存起来,在生成正确的字符串(正确的序列号时代码中出现字符串的拼接)并与之对比,如果正确,就向地址[esi+0x3C] 中写入 0x3E。
在面板双击事件中会检测地址[esi+0x3C] 的值是否为0x3E,是的话就向地址[esi+0x3C] 写入0x85 ,在面板单击事件中检测地址[esi+0x3C] 的值是否为0x85是的话顺序执行到注册成功处,否则跳过注册成功。