【软件介绍】:国产软件, Windows游戏工具, 简体中文, 317 KB
【软件下载】:http://notabdc.vip.sina.com/CnSoft/freecelltool.zip
【保护方式】:注册码 + 功能限制
【破解工具】:Win2000, PEiD, Ollydbg, W32DSM
【破解目的】:研究算法分析
【作者声明】:初学Crack,只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
—————————————————————————————————
【破解过程】:
侦测:用PEiD查壳,无壳,Microsoft Visual C++ 6.0
OllyDbg 打开软件, F9 运行, 帮助(H) -> 注册(R) 输入:
注册用户名: blackeyes
注册码:123456789
点击 OK, 没错误提示.
用 W32DSM 反汇编, 发现 UserName, RegisterCode, 以及
RegQueryValueExA().
Ctrl+F2重来, 下断点 bpx RegQueryValueExA, F9 运行, 拦截下来,
注意看右边堆栈中的提示, F9 几次后看到
RegQueryValueExA 在读UserName 与 RegisterCode,
Ctrl+F9 返回程序 0044157D处
00441560 |. 57 PUSH EDI
00441561 |. 50 PUSH EAX ; /pBufSize
00441562 |. 8D45 FC LEA EAX,DWORD PTR SS:[EBP-4] ; |
00441565 |. 50 PUSH EAX ; |Buffer
00441566 |. 8D45 F8 LEA EAX,DWORD PTR SS:[EBP-8] ; |
00441569 |. 50 PUSH EAX ; |pValueType
0044156A |. 6A 00 PUSH 0 ; |Reserved = NULL
0044156C |. FF75 0C PUSH DWORD PTR SS:[EBP+C] ; |ValueName
0044156F |. C745 08 04000>MOV DWORD PTR SS:[EBP+8],4 ; |
00441576 |. 56 PUSH ESI ; |hKey
00441577 |. FF15 0C604400 CALL DWORD PTR DS:[<&ADVAPI32.RegQueryVa>; \RegQueryValueExA
0044157D |. 56 PUSH ESI ; /hKey = 00000070 <==== 返回这
0044157E |. 8BF8 MOV EDI,EAX ; |
00441580 |. FF15 04604400 CALL DWORD PTR DS:[<&ADVAPI32.RegCloseKe>; \RegCloseKey
00441586 |. 85FF TEST EDI,EDI
00441588 |. 5F POP EDI
00441589 |.^ 75 CD JNZ SHORT Freecell.00441558
0044158B |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
0044158E |. EB 15 JMP SHORT Freecell.004415A5
00441590 |> FFB1 90000000 PUSH DWORD PTR DS:[ECX+90] ; /IniFileName
00441596 |. FF75 10 PUSH DWORD PTR SS:[EBP+10] ; |Default
00441599 |. FF75 0C PUSH DWORD PTR SS:[EBP+C] ; |Key
0044159C |. FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |Section
0044159F |. FF15 3C624400 CALL DWORD PTR DS:[<&KERNEL32.GetPrivate>; \GetPrivateProfileIntA
004415A5 |> 5E POP ESI
004415A6 |. C9 LEAVE
004415A7 \. C2 0C00 RETN 0C ; // 返回00406113
再F8单步几下, 返回00406113, 再F8单步跟, 很快就发现关键CALL及注册码比较的地方
00405FCC . 50 PUSH EAX
00405FCD . B9 B0994500 MOV ECX,Freecell.004599B0
00405FD2 . E8 F9170300 CALL Freecell.004377D0
00405FD7 . BB 01000000 MOV EBX,1 ; EBX=1
00405FDC . 8BCE MOV ECX,ESI
00405FDE . 53 PUSH EBX
...
004060D2 . 0F95C1 SETNE CL
004060D5 . 888E C0000000 MOV BYTE PTR DS:[ESI+C0],CL
004060DB . E8 B0FCFFFF CALL Freecell.00405D90
004060E0 . 68 CC414500 PUSH Freecell.004541CC ; ASCII "UnknownUser"
004060E5 . 68 B0414500 PUSH Freecell.004541B0 ; ASCII "UserName"
004060EA . 8D5424 18 LEA EDX,DWORD PTR SS:[ESP+18]
004060EE . 68 58414500 PUSH Freecell.00454158 ; ASCII "Options"
004060F3 . 52 PUSH EDX
004060F4 . 8BCE MOV ECX,ESI
004060F6 . 8BF8 MOV EDI,EAX
004060F8 . E8 ADB40300 CALL Freecell.004415AA
004060FD . 6A 00 PUSH 0
004060FF . 68 BC414500 PUSH Freecell.004541BC ; ASCII "RegisterCode"
00406104 . 68 58414500 PUSH Freecell.00454158 ; ASCII "Options"
00406109 . 8BCE MOV ECX,ESI
0040610B . C74424 2C 000>MOV DWORD PTR SS:[ESP+2C],0
00406113 . E8 26B40300 CALL Freecell.0044153E ; EAX = RegCode
00406118 . 8BE8 MOV EBP,EAX ; EBP = RegCode
0040611A . 51 PUSH ECX
0040611B . 8D4424 14 LEA EAX,DWORD PTR SS:[ESP+14]
0040611F . 8BCC MOV ECX,ESP
00406121 . 896424 18 MOV DWORD PTR SS:[ESP+18],ESP
00406125 . 50 PUSH EAX
00406126 . E8 E2F40200 CALL Freecell.0043560D
0040612B . 57 PUSH EDI
0040612C . E8 AFFCFFFF CALL Freecell.00405DE0 ; // 关键CALL, EAX=00405DE0(), F7跟进
00406131 . 83C4 08 ADD ESP,8
00406134 . 3BC5 CMP EAX,EBP ; EAX==EBP?
00406136 . 75 08 JNZ SHORT Freecell.00406140
00406138 . 889E C1000000 MOV BYTE PTR DS:[ESI+C1],BL ; BL=1, 已注册
0040613E . EB 07 JMP SHORT Freecell.00406147
00406140 > C686 C1000000>MOV BYTE PTR DS:[ESI+C1],0 ; 0 = 未注册
00406147 > 68 E0020000 PUSH 2E0
0040614C . E8 6DFA0200 CALL Freecell.00435BBE
// 详细的注册码计算, 入口参数为 系统信息码和注册用户名, 返回真的注册码
// 注册码计算与系统信息码无关!
00405DE0 /$ 8B4424 08 MOV EAX,DWORD PTR SS:[ESP+8] ; username
00405DE4 |. 56 PUSH ESI
00405DE5 |. 57 PUSH EDI
00405DE6 |. 33FF XOR EDI,EDI
00405DE8 |. 8B48 F8 MOV ECX,DWORD PTR DS:[EAX-8] ; len=strlen(username);
00405DEB |. BE 31D40000 MOV ESI,0D431 ; num=0x0D431;
00405DF0 |. 85C9 TEST ECX,ECX
00405DF2 |. 7E 34 JLE SHORT Freecell.00405E28 ; for(i=0;i<len;i++){
00405DF4 |> 0FBE0407 /MOVSX EAX,BYTE PTR DS:[EDI+EAX] ; ch = username[i];
00405DF8 |. 35 35211414 |XOR EAX,14142135 ; EAX = ch^0x14142135;
00405DFD |. 50 |PUSH EAX
00405DFE |. E8 E1AB0000 |CALL Freecell.004109E4 ; sub1(EAX);
00405E03 |. 83C4 04 |ADD ESP,4
00405E06 |. E8 E6AB0000 |CALL Freecell.004109F1 ; EAX=sub2();
00405E0B |. 8BCE |MOV ECX,ESI
00405E0D |. C1E9 10 |SHR ECX,10
00405E10 |. C1E6 10 |SHL ESI,10
00405E13 |. 0BCE |OR ECX,ESI ; ECX=(num<<16) | (num>>16);
00405E15 |. 03C1 |ADD EAX,ECX ; EAX=EAX+ECX;
00405E17 |. 35 28181827 |XOR EAX,27181828 ; EAX^=0x27181828;
00405E1C |. 47 |INC EDI
00405E1D |. 8BF0 |MOV ESI,EAX ; num=EAX
00405E1F |. 8B4424 10 |MOV EAX,DWORD PTR SS:[ESP+10]
00405E23 |. 3B78 F8 |CMP EDI,DWORD PTR DS:[EAX-8]
00405E26 |.^ 7C CC \JL SHORT Freecell.00405DF4 ; }
00405E28 |> 68 15CD5B07 PUSH 75BCD15
00405E2D |. E8 B2AB0000 CALL Freecell.004109E4 ; sub1(0x75BCD15);
00405E32 |. 83C4 04 ADD ESP,4
00405E35 |. BF 64000000 MOV EDI,64 ; for(i=0;i<100;i++) {
00405E3A |> E8 B2AB0000 /CALL Freecell.004109F1 ; EAX=sub2();
00405E3F |. 8BD6 |MOV EDX,ESI ; EDX=(num<<16) | (num>>16);
00405E41 |. C1EA 10 |SHR EDX,10
00405E44 |. C1E6 10 |SHL ESI,10
00405E47 |. 0BD6 |OR EDX,ESI
00405E49 |. 03C2 |ADD EAX,EDX ; EAX=EAX+EDX;
00405E4B |. 35 08053217 |XOR EAX,17320508 ; EAX^=0x17320508;
00405E50 |. 4F |DEC EDI
00405E51 |. 8BF0 |MOV ESI,EAX ; num = EAX;
00405E53 |.^ 75 E5 \JNZ SHORT Freecell.00405E3A ; }
00405E55 |. 8D4C24 10 LEA ECX,DWORD PTR SS:[ESP+10]
00405E59 |. E8 3AFA0200 CALL Freecell.00435898
00405E5E |. 8BC6 MOV EAX,ESI ; return num;
00405E60 |. 5F POP EDI
00405E61 |. 5E POP ESI
00405E62 \. C3 RETN
// 两个小的FUNCTION
004109E4 /$ E8 CA390000 CALL Freecell.004143B3 ; EAX = ...
004109E9 |. 8B4C24 04 MOV ECX,DWORD PTR SS:[ESP+4] ; para1
004109ED |. 8948 14 MOV DWORD PTR DS:[EAX+14],ECX ; [EAX+14] = para1
004109F0 \. C3 RETN
004109F1 /$ E8 BD390000 CALL Freecell.004143B3 ; EAX = ...
004109F6 |. 8B48 14 MOV ECX,DWORD PTR DS:[EAX+14] ; ECX = [EAX+14]
004109F9 |. 69C9 FD430300 IMUL ECX,ECX,343FD ; ECX *= 343FD
004109FF |. 81C1 C39E2600 ADD ECX,269EC3 ; ECX += 269EC3
00410A05 |. 8948 14 MOV DWORD PTR DS:[EAX+14],ECX ; [EAX+14] = ECX
00410A08 |. 8BC1 MOV EAX,ECX
00410A0A |. C1E8 10 SHR EAX,10
00410A0D |. 25 FF7F0000 AND EAX,7FFF ; ret (ECX>>16) & 7FFF
00410A12 \. C3 RETN
============注册机==========
#include <stdio.h>
#include <string.h>
static unsigned value;
void sub1(unsigned para)
{
value = para;
}
unsigned sub2(void)
{
value = value * 0x343FD + 0x269EC3;
return (value>>16) & 0x7fff;
}
void main(void) {
char UserName[100];
int i, len;
unsigned num;
printf("Input username:\n");
gets(UserName);
len = strlen(UserName);
num = 0x0D431;
for(i=0;i<len;i++)
{
sub1 ( (unsigned)(unsigned char)UserName[i] ^ 0x14142135 );
num = ( sub2() + ((num<<16)|(num>>16)) ) ^ 0x27181828;
}
sub1(0x75bCD15);
for(i=0;i<100;i++)
{
num = ( sub2() + ((num<<16)|(num>>16)) ) ^ 0x17320508;
}
printf("UserName=%s\n", UserName);
printf("RegisterCode=%ld\n", num);
}