某音频处理软件算法
【文章标题】: 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 ; |
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 ; |
00412714|.52 push edx ; |Buffer => 0012F8AC
00412715|.68 F4030000 push 3F4 ; |ControlID = 3F4 (1012.)
0041271A|.8B45 08 mov eax, dword ptr ; |
0041271D|.50 push eax ; |hWnd
0041271E|.FF15 30F54400 call dword ptr [<&USER32.GetDlgItemTe>; \GetDlgItemTextA
00412724|.8B0D 88F54600 mov ecx, dword ptr
0041272A|.51 push ecx
0041272B|.E8 00F9FFFF call 00412030
00412730|.83C4 04 add esp, 4
00412733|.8945 B0 mov dword ptr , eax
00412736|.837D B0 02 cmp dword ptr , 2
0041273A|.75 42 jnz short 0041277E
0041273C|.8B15 88F54600 mov edx, dword ptr
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 ; |
0041275A|.50 push eax ; |hOwner
0041275B|.FF15 C8F54400 call dword ptr [<&USER32.MessageBoxA>>; \MessageBoxA
00412761|.C705 6CE74600>mov dword ptr , 1
0041276B|.6A 01 push 1 ; /Result = 1
0041276D|.8B4D 08 mov ecx, dword ptr ; |
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 ; |
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
0041203C|.50 push eax
0041203D|.E8 2E090000 call 00412970
00412042|.83C4 04 add esp, 4
00412045|.8B4D 08 mov ecx, dword ptr
00412048|.894D FC mov dword ptr , ecx
0041204B|>8B55 FC /mov edx, dword ptr
0041204E|.0FBE02 |movsx eax, byte ptr
00412051|.83F8 20 |cmp eax, 20
00412054|.75 15 |jnz short 0041206B
00412056|.8B4D FC |mov ecx, dword ptr
00412059|.0FBE11 |movsx edx, byte ptr
0041205C|.85D2 |test edx, edx
0041205E|.74 0B |je short 0041206B
00412060|.8B45 FC |mov eax, dword ptr
00412063|.83C0 01 |add eax, 1
00412066|.8945 FC |mov dword ptr , eax
00412069|.^ EB E0 \jmp short 0041204B
伪C代码
strcat(*tmp, *serial);
0041206B|>8B4D FC mov ecx, dword ptr
0041206E|.898D 74FFFFFF mov dword ptr , ecx
00412074|>8B55 FC /mov edx, dword ptr
00412077|.0FBE02 |movsx eax, byte ptr
0041207A|.85C0 |test eax, eax
0041207C|.74 56 |je short 004120D4
0041207E|.8B4D FC |mov ecx, dword ptr
00412081|.0FBE11 |movsx edx, byte ptr
00412084|.83FA 49 |cmp edx, 49
00412087|.75 06 |jnz short 0041208F
00412089|.8B45 FC |mov eax, dword ptr
0041208C|.C600 31 |mov byte ptr , 31
0041208F|>8B4D FC |mov ecx, dword ptr
00412092|.0FBE11 |movsx edx, byte ptr
00412095|.83FA 4F |cmp edx, 4F
00412098|.75 06 |jnz short 004120A0
0041209A|.8B45 FC |mov eax, dword ptr
0041209D|.C600 30 |mov byte ptr , 30
004120A0|>8B4D FC |mov ecx, dword ptr
004120A3|.0FBE11 |movsx edx, byte ptr
004120A6|.83FA 20 |cmp edx, 20
004120A9|.74 16 |je short 004120C1
004120AB|.8B45 FC |mov eax, dword ptr
004120AE|.0FBE08 |movsx ecx, byte ptr
004120B1|.83F9 0A |cmp ecx, 0A
004120B4|.74 0B |je short 004120C1
004120B6|.8B55 FC |mov edx, dword ptr
004120B9|.0FBE02 |movsx eax, byte ptr
004120BC|.83F8 0D |cmp eax, 0D
004120BF|.75 08 |jnz short 004120C9
004120C1|>8B4D FC |mov ecx, dword ptr
004120C4|.C601 00 |mov byte ptr , 0
004120C7|.EB 0B |jmp short 004120D4
004120C9|>8B55 FC |mov edx, dword ptr
004120CC|.83C2 01 |add edx, 1
004120CF|.8955 FC |mov dword ptr , 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
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
0041212B|.52 push edx ; /String2
0041212C|.8D85 78FFFFFF lea eax, dword ptr ; |
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
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 , eax
0041214D|.837D FC 00 cmp dword ptr , 0
00412151|.75 07 jnz short 0041215A
00412153|.33C0 xor eax, eax
00412155|.E9 F0000000 jmp 0041224A
0041215A|>8B55 FC mov edx, dword ptr
0041215D|.C602 00 mov byte ptr , 0
00412160|.8D45 B8 lea eax, dword ptr
00412163|.50 push eax
00412164|.8D8D 78FFFFFF lea ecx, dword ptr
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
00412179|.52 push edx
0041217A|.8D45 B8 lea eax, dword ptr
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
00412191|.83E9 01 sub ecx, 1
00412194|.894D FC mov dword ptr , ecx
00412197|.8B55 FC mov edx, dword ptr
0041219A|.C602 00 mov byte ptr , 0
0041219D|.8B45 FC mov eax, dword ptr
004121A0|.83E8 04 sub eax, 4
004121A3|.8945 FC mov dword ptr , eax
004121A6|.8B4D FC mov ecx, dword ptr
004121A9|.0FBE11 movsx edx, byte ptr
004121AC|.83FA 47 cmp edx, 47
004121AF|.74 0C je short 004121BD
004121B1|.8B45 FC mov eax, dword ptr
004121B4|.0FBE48 02 movsx ecx, byte ptr
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
004121CD|.8955 FC mov dword ptr , edx
004121D0|>8B45 FC /mov eax, dword ptr
004121D3|.0FBE08 |movsx ecx, byte ptr
004121D6|.83F9 30 |cmp ecx, 30
004121D9|.7C 0B |jl short 004121E6
004121DB|.8B55 FC |mov edx, dword ptr
004121DE|.0FBE02 |movsx eax, byte ptr
004121E1|.83F8 39 |cmp eax, 39
004121E4|.7E 0B |jle short 004121F1
004121E6|>8B4D FC |mov ecx, dword ptr
004121E9|.83C1 01 |add ecx, 1
004121EC|.894D FC |mov dword ptr , ecx
004121EF|.^ EB DF \jmp short 004121D0
004121F1|>8B55 FC mov edx, dword ptr
伪C代码
strcmp(*serial, 'G')
strcmp(*serial, 'G')
//表示前两位字符不能为G,否则无效,然后循环到'-'后的数据,然后压入堆栈
004121F4|.52 push edx
004121F5|.E8 4FBD0100 call 0042DF49
004121FA|.83C4 04 add esp, 4
004121FD|.8985 28FFFFFF mov dword ptr , eax
00412203|.8995 2CFFFFFF mov dword ptr , edx
00412209|.83BD 2CFFFFFF>cmp dword ptr , 2
00412210|.7C 15 jl short 00412227
00412212|.7F 0C jg short 00412220
00412214|.81BD 28FFFFFF>cmp dword ptr , 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
页:
[1]