cyane 发表于 2011-2-22 21:00:24

某音频处理软件算法

【文章标题】: 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]
查看完整版本: 某音频处理软件算法