- UID
- 67804
注册时间2010-5-30
阅读权限10
最后登录1970-1-1
周游历练
TA的每日心情 | 奋斗 2016-5-26 17:26 |
---|
签到天数: 17 天 [LV.4]偶尔看看III
|
【文章标题】: ReplayRadio5注册算法分析
【文章作者】: cyane
【下载地址】: 自己搜索下载
【加壳方式】: 无壳
【编写语言】: Microsoft Visual C++ 7.0
【使用工具】: OD
【破解平台】: Win9x/NT/2000/XP
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
【详细过程】
OD载入程序,输入注册码,弹出错误注册码提示,下MessageBoxA断点,通过回溯可以来到下面函数入口
004124D0 /. 55 push ebp
004124D1 |. 8BEC mov ebp, esp
004124D3 |. 83EC 54 sub esp, 54
.....
00412582 |. 81FA 66040000 cmp edx, 466
00412588 |. 75 0E jnz short 00412598
0041258A |. 6A 00 push 0 ; /Result = 0
0041258C |. 8B45 08 mov eax, dword ptr [ebp+8] ; |
0041258F |. 50 push eax ; |hWnd
00412590 |. FF15 18F54400 call dword ptr [<&USER32.EndDialog>] ; \EndDialog
00412596 |. EB 1E jmp short 004125B6
.....
0041270C |> \6A 40 push 40 ; /Count = 40 (64.)
0041270E |. 8B15 88F54600 mov edx, dword ptr [46F588] ; |
00412714 |. 52 push edx ; |Buffer => 0012F8AC
00412715 |. 68 F4030000 push 3F4 ; |ControlID = 3F4 (1012.)
0041271A |. 8B45 08 mov eax, dword ptr [ebp+8] ; |
0041271D |. 50 push eax ; |hWnd
0041271E |. FF15 30F54400 call dword ptr [<&USER32.GetDlgItemTe>; \GetDlgItemTextA
00412724 |. 8B0D 88F54600 mov ecx, dword ptr [46F588]
0041272A |. 51 push ecx
0041272B |. E8 00F9FFFF call 00412030
00412730 |. 83C4 04 add esp, 4
00412733 |. 8945 B0 mov dword ptr [ebp-50], eax
00412736 |. 837D B0 02 cmp dword ptr [ebp-50], 2
0041273A |. 75 42 jnz short 0041277E
0041273C |. 8B15 88F54600 mov edx, dword ptr [46F588]
00412742 |. 52 push edx
00412743 |. E8 08FBFFFF call 00412250
00412748 |. 83C4 04 add esp, 4
0041274B |. 6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL
0041274D |. 68 E4544500 push 004554E4 ; |Title = "Replay Radio"
00412752 |. 68 F4544500 push 004554F4 ; |Text = "Your code is accepted. Thanks for registering!"
00412757 |. 8B45 08 mov eax, dword ptr [ebp+8] ; |
0041275A |. 50 push eax ; |hOwner
0041275B |. FF15 C8F54400 call dword ptr [<&USER32.MessageBoxA>>; \MessageBoxA
00412761 |. C705 6CE74600>mov dword ptr [46E76C], 1
0041276B |. 6A 01 push 1 ; /Result = 1
0041276D |. 8B4D 08 mov ecx, dword ptr [ebp+8] ; |
00412770 |. 51 push ecx ; |hWnd
00412771 |. FF15 18F54400 call dword ptr [<&USER32.EndDialog>] ; \EndDialog
00412777 |. B8 01000000 mov eax, 1
0041277C |. EB 42 jmp short 004127C0
0041277E |> 6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL
00412780 |. 68 24554500 push 00455524 ; |Title = "Replay Radio"
00412785 |. 68 38554500 push 00455538 ; |Text = "Invalid Registration Code. Please check the code and try entering it again."
0041278A |. 8B55 08 mov edx, dword ptr [ebp+8] ; |
0041278D |. 52 push edx ; |hOwner
0041278E |. FF15 C8F54400 call dword ptr [<&USER32.MessageBoxA>>; \MessageBoxA
伪C码
GetDlgItemTextA(hDlg, 1012, lpString, 64);
if ( CheckSerial(serial) == 2 )
{
SetReg(serial);
MessageBoxA(hDlg, "Your code is accepted. Thanks for registering!", "Replay Radio", 0);
EndDialog(hDlg, 1);
result = 1;
}
else
{
MessageBoxA(hDlg,"Invalid Registration Code. Please check the code and try entering it again.","Replay Radio",0);
result = 0;
}
//重点分析call 00412030(CheckSerial伪函数)
00412030 /$ 55 push ebp
00412031 |. 8BEC mov ebp, esp
00412033 |. 81EC D8000000 sub esp, 0D8
00412039 |. 8B45 08 mov eax, dword ptr [ebp+8]
0041203C |. 50 push eax
0041203D |. E8 2E090000 call 00412970
00412042 |. 83C4 04 add esp, 4
00412045 |. 8B4D 08 mov ecx, dword ptr [ebp+8]
00412048 |. 894D FC mov dword ptr [ebp-4], ecx
0041204B |> 8B55 FC /mov edx, dword ptr [ebp-4]
0041204E |. 0FBE02 |movsx eax, byte ptr [edx]
00412051 |. 83F8 20 |cmp eax, 20
00412054 |. 75 15 |jnz short 0041206B
00412056 |. 8B4D FC |mov ecx, dword ptr [ebp-4]
00412059 |. 0FBE11 |movsx edx, byte ptr [ecx]
0041205C |. 85D2 |test edx, edx
0041205E |. 74 0B |je short 0041206B
00412060 |. 8B45 FC |mov eax, dword ptr [ebp-4]
00412063 |. 83C0 01 |add eax, 1
00412066 |. 8945 FC |mov dword ptr [ebp-4], eax
00412069 |.^ EB E0 \jmp short 0041204B
伪C代码
strcat(*tmp, *serial);
0041206B |> 8B4D FC mov ecx, dword ptr [ebp-4]
0041206E |. 898D 74FFFFFF mov dword ptr [ebp-8C], ecx
00412074 |> 8B55 FC /mov edx, dword ptr [ebp-4]
00412077 |. 0FBE02 |movsx eax, byte ptr [edx]
0041207A |. 85C0 |test eax, eax
0041207C |. 74 56 |je short 004120D4
0041207E |. 8B4D FC |mov ecx, dword ptr [ebp-4]
00412081 |. 0FBE11 |movsx edx, byte ptr [ecx]
00412084 |. 83FA 49 |cmp edx, 49
00412087 |. 75 06 |jnz short 0041208F
00412089 |. 8B45 FC |mov eax, dword ptr [ebp-4]
0041208C |. C600 31 |mov byte ptr [eax], 31
0041208F |> 8B4D FC |mov ecx, dword ptr [ebp-4]
00412092 |. 0FBE11 |movsx edx, byte ptr [ecx]
00412095 |. 83FA 4F |cmp edx, 4F
00412098 |. 75 06 |jnz short 004120A0
0041209A |. 8B45 FC |mov eax, dword ptr [ebp-4]
0041209D |. C600 30 |mov byte ptr [eax], 30
004120A0 |> 8B4D FC |mov ecx, dword ptr [ebp-4]
004120A3 |. 0FBE11 |movsx edx, byte ptr [ecx]
004120A6 |. 83FA 20 |cmp edx, 20
004120A9 |. 74 16 |je short 004120C1
004120AB |. 8B45 FC |mov eax, dword ptr [ebp-4]
004120AE |. 0FBE08 |movsx ecx, byte ptr [eax]
004120B1 |. 83F9 0A |cmp ecx, 0A
004120B4 |. 74 0B |je short 004120C1
004120B6 |. 8B55 FC |mov edx, dword ptr [ebp-4]
004120B9 |. 0FBE02 |movsx eax, byte ptr [edx]
004120BC |. 83F8 0D |cmp eax, 0D
004120BF |. 75 08 |jnz short 004120C9
004120C1 |> 8B4D FC |mov ecx, dword ptr [ebp-4]
004120C4 |. C601 00 |mov byte ptr [ecx], 0
004120C7 |. EB 0B |jmp short 004120D4
004120C9 |> 8B55 FC |mov edx, dword ptr [ebp-4]
004120CC |. 83C2 01 |add edx, 1
004120CF |. 8955 FC |mov dword ptr [ebp-4], edx
004120D2 |.^ EB A0 \jmp short 00412074
伪C代码
while(*serial!='\0')
{
if(serial == 'I')
serial = 1;
else if(serial == 'O')
serial = 0;
else if(serial == ' ' || serial == '\n' || serial == '\r')
{
i=0;
break;
}
++i;
}
.....
004120FA |. 83C4 08 add esp, 8
004120FD |. 68 34534500 push 00455334 ; /String = "RAD"
00412102 |. FF15 C8F24400 call dword ptr [<&KERNEL32.lstrlenA>] ; \lstrlenA
00412108 |. 50 push eax
00412109 |. 68 38534500 push 00455338 ; ASCII "RAD"
0041210E |. 8D8D 30FFFFFF lea ecx, dword ptr [ebp-D0]
00412114 |. 51 push ecx
00412115 |. E8 36080000 call 00412950 ; strncmp
0041211A |. 83C4 0C add esp, 0C
0041211D |. 85C0 test eax, eax
0041211F |. 0F85 18010000 jnz 0041223D
00412125 |. 8D95 30FFFFFF lea edx, dword ptr [ebp-D0]
0041212B |. 52 push edx ; /String2
0041212C |. 8D85 78FFFFFF lea eax, dword ptr [ebp-88] ; |
00412132 |. 50 push eax ; |String1
00412133 |. FF15 88F24400 call dword ptr [<&KERNEL32.lstrcpyA>] ; \lstrcpyA
00412139 |. 6A 2D push 2D
0041213B |. 8D8D 78FFFFFF lea ecx, dword ptr [ebp-88]
00412141 |. 51 push ecx
00412142 |. E8 C9070000 call 00412910 ; strchr
伪C代码
if (!strncmp(*serial, "RAD"))
return 0;
else
strcat(*serial, '-');
00412147 |. 83C4 08 add esp, 8
0041214A |. 8945 FC mov dword ptr [ebp-4], eax
0041214D |. 837D FC 00 cmp dword ptr [ebp-4], 0
00412151 |. 75 07 jnz short 0041215A
00412153 |. 33C0 xor eax, eax
00412155 |. E9 F0000000 jmp 0041224A
0041215A |> 8B55 FC mov edx, dword ptr [ebp-4]
0041215D |. C602 00 mov byte ptr [edx], 0
00412160 |. 8D45 B8 lea eax, dword ptr [ebp-48]
00412163 |. 50 push eax
00412164 |. 8D8D 78FFFFFF lea ecx, dword ptr [ebp-88]
0041216A |. 51 push ecx
0041216B |. E8 90FEFFFF call 00412000
伪C代码(call 00412000内的代码直接逆过来)RAD+0xBD
na=0xBD;
for(i=0; i<n; i++)
{
if(serial!='-')
na += hex(serial);
else
break;
}
//这里解释一下,上面介绍了I=1,O=0;若输入的注册码为RADI-,则此函数会把0xBD+0x'R'+0x'A'+0x'D'+0x'1'存为临时变量na
//并将na转为十进制数据,比如RADI-就转化为453
00412170 |. 83C4 08 add esp, 8
00412173 |. 8D95 30FFFFFF lea edx, dword ptr [ebp-D0]
00412179 |. 52 push edx
0041217A |. 8D45 B8 lea eax, dword ptr [ebp-48]
0041217D |. 50 push eax
0041217E |. E8 AD070000 call 00412930
伪C代码
strcmp(HexToInt(na), '-'后面的数据);
//比如RADI-453就符合要求
00412183 |. 83C4 08 add esp, 8
00412186 |. 85C0 test eax, eax
00412188 |. 0F85 A0000000 jnz 0041222E
0041218E |. 8B4D FC mov ecx, dword ptr [ebp-4]
00412191 |. 83E9 01 sub ecx, 1
00412194 |. 894D FC mov dword ptr [ebp-4], ecx
00412197 |. 8B55 FC mov edx, dword ptr [ebp-4]
0041219A |. C602 00 mov byte ptr [edx], 0
0041219D |. 8B45 FC mov eax, dword ptr [ebp-4]
004121A0 |. 83E8 04 sub eax, 4
004121A3 |. 8945 FC mov dword ptr [ebp-4], eax
004121A6 |. 8B4D FC mov ecx, dword ptr [ebp-4]
004121A9 |. 0FBE11 movsx edx, byte ptr [ecx]
004121AC |. 83FA 47 cmp edx, 47
004121AF |. 74 0C je short 004121BD
004121B1 |. 8B45 FC mov eax, dword ptr [ebp-4]
004121B4 |. 0FBE48 02 movsx ecx, byte ptr [eax+2]
004121B8 |. 83F9 47 cmp ecx, 47
004121BB |. 75 0A jnz short 004121C7
004121BD |> B8 02000000 mov eax, 2
004121C2 |. E9 83000000 jmp 0041224A
004121C7 |> 8D95 78FFFFFF lea edx, dword ptr [ebp-88]
004121CD |. 8955 FC mov dword ptr [ebp-4], edx
004121D0 |> 8B45 FC /mov eax, dword ptr [ebp-4]
004121D3 |. 0FBE08 |movsx ecx, byte ptr [eax]
004121D6 |. 83F9 30 |cmp ecx, 30
004121D9 |. 7C 0B |jl short 004121E6
004121DB |. 8B55 FC |mov edx, dword ptr [ebp-4]
004121DE |. 0FBE02 |movsx eax, byte ptr [edx]
004121E1 |. 83F8 39 |cmp eax, 39
004121E4 |. 7E 0B |jle short 004121F1
004121E6 |> 8B4D FC |mov ecx, dword ptr [ebp-4]
004121E9 |. 83C1 01 |add ecx, 1
004121EC |. 894D FC |mov dword ptr [ebp-4], ecx
004121EF |.^ EB DF \jmp short 004121D0
004121F1 |> 8B55 FC mov edx, dword ptr [ebp-4]
伪C代码
strcmp(*serial[0], 'G')
strcmp(*serial[1], 'G')
//表示前两位字符不能为G,否则无效,然后循环到'-'后的数据,然后压入堆栈
004121F4 |. 52 push edx
004121F5 |. E8 4FBD0100 call 0042DF49
004121FA |. 83C4 04 add esp, 4
004121FD |. 8985 28FFFFFF mov dword ptr [ebp-D8], eax
00412203 |. 8995 2CFFFFFF mov dword ptr [ebp-D4], edx
00412209 |. 83BD 2CFFFFFF>cmp dword ptr [ebp-D4], 2
00412210 |. 7C 15 jl short 00412227
00412212 |. 7F 0C jg short 00412220
00412214 |. 81BD 28FFFFFF>cmp dword ptr [ebp-D8], 8435FFF9
0041221E |. 76 07 jbe short 00412227
00412220 |> B8 02000000 mov eax, 2
00412225 |. EB 23 jmp short 0041224A
00412227 |> B8 01000000 mov eax, 1
0041222C |. EB 1C jmp short 0041224A
伪C代码
atoi64('-'后的数据);
if(进位大于2 & total > 0x8435FFF9)
result = 2
else
result = 1
//从上面的分析可以看出,只有返回数值为2才会注册成功,所以只要构造出了就可以了。
//这是很容易构造的,先給两组注册码吧。
注册码1: RADIIIIIIIIIIOOO-1038
注册码2: RADIIIIIIIIIIIIOOO-1136
|
评分
-
查看全部评分
|