昨天刚下载了一个想要了很久的PS2光碟ISO文件,但是又没有PS2,听说Cube Media Player可以播放PS2光碟里面的video和audio,就上网顺手找了个1.04.0702版的CubeMedia Player.发现是要注册的,想想自己也N久没有解密了,就来试试手,如有不足,请高手指导.废话不多说了,开始吧.
使用工具:OD,32bit Calulator v1.7,W32DASM,Windows计算器
CubeMedia Player无壳,用PEid查一下,是Visual C++ 7.0编写的,用OD反汇编.
它有机器码,所以我想它肯定与硬件有关的,一般来说硬盘序列号是很常见的,所以查GetVolumeInfomationA(),来到这里.
0043FA60 /$ 51 push ecx
0043FA61 |. 8B4424 08 mov eax,dword ptr ss:[esp+8]
0043FA65 |. 53 push ebx
0043FA66 |. 56 push esi
0043FA67 |. 57 push edi
0043FA68 |. A3 5C022E01 mov dword ptr ds:[12E025C],eax
0043FA6D |. FF15 DC724500 call dword ptr ds:[<&WINMM.timeGetTime>] ; WINMM.timeGetTime
0043FA73 |. 50 push eax
0043FA74 |. E8 D8DE0000 call CubeMedi.0044D951
0043FA79 |. 83C4 04 add esp,4
0043FA7C |. 6A 00 push 0 ; /pFileSystemNameSize = NULL
0043FA7E |. 6A 00 push 0 ; |pFileSystemNameBuffer = NULL
0043FA80 |. 8D4C24 1C lea ecx,dword ptr ss:[esp+1C] ; |
0043FA84 |. 51 push ecx ; |pFileSystemFlags
0043FA85 |. 8BD1 mov edx,ecx ; |
0043FA87 |. 52 push edx ; |pMaxFilenameLength
0043FA88 |. 68 B0B7D802 push CubeMedi.02D8B7B0 ; |pVolumeSerialNumber = CubeMedi.02D8B7B0
0043FA8D |. 6A 00 push 0 ; |MaxVolumeNameSize = 0
0043FA8F |. 6A 00 push 0 ; |VolumeNameBuffer = NULL
0043FA91 |. 68 E09B4500 push CubeMedi.00459BE0 ; |RootPathName = "C:\"
0043FA96 |. FF15 30714500 call dword ptr ds:[<&KERNEL32.GetVolumeI>; \GetVolumeInformationA 得到C盘的序列号
0043FA9C |. 33C0 xor eax,eax
0043FA9E |. A3 68415C02 mov dword ptr ds:[25C4168],eax ;嗯,开始分配内存空间了
0043FAA3 |. A3 6C415C02 mov dword ptr ds:[25C416C],eax
0043FAA8 |. A3 70415C02 mov dword ptr ds:[25C4170],eax
0043FAAD |. A2 74415C02 mov byte ptr ds:[25C4174],al
0043FAB2 |. 33C0 xor eax,eax ;清理寄存器了
0043FAB4 |. 33DB xor ebx,ebx
0043FAB6 |. 33C9 xor ecx,ecx
0043FAB8 |. 33D2 xor edx,edx
0043FABA |. 0FA2 cpuid ;哈哈,CPUID,得到CPU的参数,这是得到CPU的字符串
;AMD的CPU就是AuthenticAMD
;Intel的CPU就是GenuineIntel
0043FABC |. 891D 68415C02 mov dword ptr ds:[25C4168],ebx ;CPU字符串放入这些内存空间里面
0043FAC2 |. 8915 6C415C02 mov dword ptr ds:[25C416C],edx
0043FAC8 |. 890D 70415C02 mov dword ptr ds:[25C4170],ecx
0043FACE |. 8B35 B0B7D802 mov esi,dword ptr ds:[2D8B7B0] ;C盘序列号
0043FAD4 |. 33C9 xor ecx,ecx
0043FAD6 |. 890D 20598B01 mov dword ptr ds:[18B5920],ecx ;又来分配内存了
0043FADC |. 890D 24598B01 mov dword ptr ds:[18B5924],ecx
0043FAE2 |. 890D 28598B01 mov dword ptr ds:[18B5928],ecx
0043FAE8 |. 880D 2C598B01 mov byte ptr ds:[18B592C],cl
0043FAEE |. 8BFF mov edi,edi ;请教高手:这条是不是冗余指令啊? 当时的EDI是User32.LoadStringA
0043FAF0 |> 0FB681 68415C>/movzx eax,byte ptr ds:[ecx+25C4168] ;CpuString每一个字符
0043FAF7 |. 33D2 |xor edx,edx
0043FAF9 |. 03C6 |add eax,esi ;与C盘序列号相加
0043FAFB |. BF 1A000000 |mov edi,1A
0043FB00 |. F7F7 |div edi;EAX/0x1A
0043FB02 |. 80C2 41 |add dl,41 ;余数+0x41
0043FB05 |. 8891 20598B01 |mov byte ptr ds:[ecx+18B5920],dl ;生成机器码
0043FB0B |. 41 |inc ecx
0043FB0C |. 83F9 0C |cmp ecx,0C
0043FB0F |.^ 7C DF \jl short CubeMedi.0043FAF0;loop
0043FB11 |. E8 2AE5FCFF call CubeMedi.0040E040 ;关键,注册码生成过程 call进
0043FB16 |. 85C0 test eax,eax
0043FB18 |. BF 01000000 mov edi,1
0043FB1D 74 0C je short CubeMedi.0043FB2B
0043FB1F |. 893D B4B7D802 mov dword ptr ds:[2D8B7B4],edi
0043FB25 |. 893D B8B7D802 mov dword ptr ds:[2D8B7B8],edi
Call进注册码的生成过程后:
0040E040 $ 83EC 2C sub esp,2C
0040E043 . A1 C4DD4500 mov eax,dword ptr ds:[45DDC4]
0040E048 . 53 push ebx
0040E049 . 56 push esi
0040E04A . 57 push edi
0040E04B . 894424 34 mov dword ptr ss:[esp+34],eax
0040E04F . 33C0 xor eax,eax
0040E051 . B9 40000000 mov ecx,40
0040E056 . BF 80E84500 mov edi,CubeMedi.0045E880
0040E05B . F3:AB rep stos dword ptr es:[edi]
0040E05D . 8D4424 10 lea eax,dword ptr ss:[esp+10]
0040E061 . 50 push eax ; /pHandle
0040E062 . 68 3F000F00 push 0F003F ; |Access = KEY_ALL_ACCESS
0040E067 . 6A 00 push 0 ; |Reserved = 0
0040E069 . 68 7C754500 push CubeMedi.0045757C ; |Subkey = "Software\CubeMediaPlayer"
0040E06E . 68 01000080 push 80000001 ; |hKey = HKEY_CURRENT_USER
0040E073 . C74424 20 040>mov dword ptr ss:[esp+20],4 ; |
0040E07B . FF15 10704500 call dword ptr ds:[<&ADVAPI32.RegOpenKey>; \RegOpenKeyExA
0040E081 . 85C0 test eax,eax
0040E083 . 75 4C jnz short CubeMedi.0040E0D1
0040E08B . 8D4C24 0C lea ecx,dword ptr ss:[esp+C]
0040E08F . 51 push ecx ; /pBufSize
0040E090 . 68 80E84500 push CubeMedi.0045E880 ; |Buffer = CubeMedi.0045E880
0040E095 . 8D5424 1C lea edx,dword ptr ss:[esp+1C] ; |
0040E099 . 52 push edx ; |pvalueType
0040E09A . 50 push eax ; |Reserved
0040E09B . 8B4424 20 mov eax,dword ptr ss:[esp+20] ; |
0040E09F . 68 70754500 push CubeMedi.00457570 ; |valueName = "User Name" //读注册表里面的用户名
0040E0A4 . BF 00010000 mov edi,100 ; |
0040E0A9 . 50 push eax ; |hKey
0040E0AA . 897C24 24 mov dword ptr ss:[esp+24],edi ; |
0040E0AE . FFD6 call esi ; \RegQueryvalueExA
0040E0B0 . 8B4424 10 mov eax,dword ptr ss:[esp+10]
0040E0B4 . 8D4C24 0C lea ecx,dword ptr ss:[esp+C]
0040E0B8 . 51 push ecx ; /pBufSize
0040E0B9 . 68 68BB9001 push CubeMedi.0190BB68 ; |Buffer = CubeMedi.0190BB68
0040E0BE . 8D5424 1C lea edx,dword ptr ss:[esp+1C] ; |
0040E0C2 . 52 push edx ; |pvalueType
0040E0C3 . 6A 00 push 0 ; |Reserved = NULL
0040E0C5 . 68 60754500 push CubeMedi.00457560 ; |valueName = "Register Code" //读注册表里面的注册码
0040E0CA . 50 push eax ; |hKey
0040E0CB . 897C24 24 mov dword ptr ss:[esp+24],edi ; |
0040E0CF . FFD6 call esi ; \RegQueryvalueExA
0040E0D1 > 33C9 xor ecx,ecx
0040E0D3 . 894C24 18 mov dword ptr ss:[esp+18],ecx ;开始分配内存空间,可能是像C++的new()操作符
0040E0D7 . 894C24 1C mov dword ptr ss:[esp+1C],ecx
0040E0DB . 894C24 20 mov dword ptr ss:[esp+20],ecx
0040E0DF . 894C24 24 mov dword ptr ss:[esp+24],ecx
0040E0E3 . 894C24 28 mov dword ptr ss:[esp+28],ecx
0040E0E7 . 894C24 2C mov dword ptr ss:[esp+2C],ecx
0040E0EB . B8 80E84500 mov eax,CubeMedi.0045E880 ; ASCII "Pr0Zel"
0040E0F0 . 33F6 xor esi,esi
0040E0F2 . 884C24 30 mov byte ptr ss:[esp+30],cl
0040E0F6 . 33D2 xor edx,edx
0040E0F8 . 8D78 01 lea edi,dword ptr ds:[eax+1]
0040E0FB . EB 03 jmp short CubeMedi.0040E100
0040E0FD 8D49 00 lea ecx,dword ptr ds:[ecx]
0040E100 > 8A08 mov cl,byte ptr ds:[eax]
0040E102 . 40 inc eax ;计算Username的ASCII码个数
0040E103 . 84C9 test cl,cl
0040E105 .^ 75 F9 jnz short CubeMedi.0040E100
0040E107 . 2BC7 sub eax,edi ;ASCII码个数放入EAX,这里EAX永远为0 是mov eax,edi的变形
0040E109 . 894424 14 mov dword ptr ss:[esp+14],eax
0040E10D . 74 20 je short CubeMedi.0040E12F
0040E10F . 90 nop
0040E110 > 0FBE82 80E845>movsx eax,byte ptr ds:[edx+45E880]
0040E117 . 03F0 add esi,eax ;esi是ascii码累加值
0040E119 . B8 80E84500 mov eax,CubeMedi.0045E880 ; ASCII "Pr0Zel"
0040E11E . 42 inc edx
0040E11F . 8D78 01 lea edi,dword ptr ds:[eax+1]
0040E122 > 8A08 mov cl,byte ptr ds:[eax]
0040E124 . 40 inc eax
0040E125 . 84C9 test cl,cl
0040E127 .^ 75 F9 jnz short CubeMedi.0040E122
0040E129 . 2BC7 sub eax,edi
0040E12B . 3BD0 cmp edx,eax
0040E12D .^ 72 E1 jb short CubeMedi.0040E110
0040E12F > 33C9 xor ecx,ecx
0040E131 > 0FB681 20598B>movzx eax,byte ptr ds:[ecx+18B5920] ;第1位机器码
0040E138 . 0FB6B9 21598B>movzx edi,byte ptr ds:[ecx+18B5921] ;第2位机器码
0040E13F . 0FAFC6 imul eax,esi ;第1位机器码*0x1AA
0040E142 . 03C7 add eax,edi ;再加上第2位机器码
0040E144 . 33D2 xor edx,edx
0040E146 . BB 1A000000 mov ebx,1A
0040E14B . F7F3 div ebx ;eax为商,edx为余数 Eax/EBX /1A
0040E14D . 0FB699 22598B>movzx ebx,byte ptr ds:[ecx+18B5922] ;第3位机器码
0040E154 . 8BC7 mov eax,edi ;edi->第2位的机器码
0040E156 . 0FAFC6 imul eax,esi ;第2位机器码*0x1AA
0040E159 . 03C3 add eax,ebx ;ebx->第3位机器码
0040E15B . BF 1A000000 mov edi,1A
0040E160 . 83C1 06 add ecx,6 ;ECX+6
0040E163 . 80C2 41 add dl,41 ;dl->40e14b的余数
0040E166 . 88540C 12 mov byte ptr ss:[esp+ecx+12],dl ;dl+0x41放入内存里
0040E16A . 33D2 xor edx,edx
0040E16C . F7F7 div edi ;eax/edi 商:eax, 余数:edx /1A
0040E16E . 0FB6B9 1D598B>movzx edi,byte ptr ds:[ecx+18B591D] ;第4位机器码
0040E175 . 8BC3 mov eax,ebx ;ebx->第3位机器码
0040E177 . 0FAFC6 imul eax,esi ;ESI=0
0040E17A . 03C7 add eax,edi ;第4位机器码+EAX
0040E17C . BB 1A000000 mov ebx,1A
0040E181 . 80C2 41 add dl,41 ;dl->40e16c的余数
0040E184 . 88540C 13 mov byte ptr ss:[esp+ecx+13],dl
0040E188 . 33D2 xor edx,edx
0040E18A . F7F3 div ebx
0040E18C . 0FB699 1E598B>movzx ebx,byte ptr ds:[ecx+18B591E]
0040E193 . 8BC7 mov eax,edi
0040E195 . 0FAFC6 imul eax,esi
0040E198 . 03C3 add eax,ebx
0040E19A . BF 1A000000 mov edi,1A
0040E19F . 80C2 41 add dl,41
0040E1A2 . 88540C 14 mov byte ptr ss:[esp+ecx+14],dl
0040E1A6 . 33D2 xor edx,edx
0040E1A8 . F7F7 div edi
0040E1AA . 0FB6B9 1F598B>movzx edi,byte ptr ds:[ecx+18B591F]
0040E1B1 . 8BC3 mov eax,ebx
0040E1B3 . 0FAFC6 imul eax,esi
0040E1B6 . 03C7 add eax,edi
0040E1B8 . BB 1A000000 mov ebx,1A
0040E1BD . 80C2 41 add dl,41
0040E1C0 . 88540C 15 mov byte ptr ss:[esp+ecx+15],dl
0040E1C4 . 33D2 xor edx,edx
0040E1C6 . F7F3 div ebx
0040E1C8 . 8BC7 mov eax,edi
0040E1CA . 0FAFC6 imul eax,esi
0040E1CD . 8BFB mov edi,ebx
0040E1CF . 80C2 41 add dl,41
0040E1D2 . 88540C 16 mov byte ptr ss:[esp+ecx+16],dl
0040E1D6 . 0FB691 20598B>movzx edx,byte ptr ds:[ecx+18B5920]
0040E1DD . 03C2 add eax,edx
0040E1DF . 33D2 xor edx,edx
0040E1E1 . F7F7 div edi
0040E1E3 . 80C2 41 add dl,41
0040E1E6 . 83F9 0C cmp ecx,0C
0040E1E9 . 88540C 17 mov byte ptr ss:[esp+ecx+17],dl
0040E1ED .^ 0F8C 3EFFFFFF jl CubeMedi.0040E131 //loop
0040E1F3 . 46 inc esi ;ESI+1 //ESI是Username的ASCII码累加值
0040E1F4 . 33C9 xor ecx,ecx
0040E1F6 . BF 0C000000 mov edi,0C ;作下面循环的计数器,循环0xC次,即12次
0040E1FB . EB 03 jmp short CubeMedi.0040E200
0040E1FD 8D49 00 lea ecx,dword ptr ds:[ecx]
0040E200 > 0FB681 20598B>movzx eax,byte ptr ds:[ecx+18B5920] ;第1位机器码
0040E207 . 0FAFC6 imul eax,esi ;第1位机器码*ESI
0040E20A . 33D2 xor edx,edx
0040E20C . BB 1A000000 mov ebx,1A
0040E211 . F7F3 div ebx ;又是取余
0040E213 . 80C2 41 add dl,41 ;取余后+0x41
0040E216 . 88540C 24 mov byte ptr ss:[esp+ecx+24],dl ;加在以前面生成的注册码后
0040E21A . 41 inc ecx
0040E21B . 4F dec edi ;计数器-1
0040E21C .^ 75 E2 jnz short CubeMedi.0040E200
0040E21E . 5F pop edi
0040E21F . 5E pop esi
0040E220 . 33C0 xor eax,eax
0040E222 . 5B pop ebx
0040E223 . EB 0B jmp short CubeMedi.0040E230
0040E225 . 8DA424 000000>lea esp,dword ptr ss:[esp]
0040E22C . 8D6424 00 lea esp,dword ptr ss:[esp]
0040E230 > 0FBE88 68BB90>movsx ecx,byte ptr ds:[eax+190BB68]
0040E237 . 0FB65404 0C movzx edx,byte ptr ss:[esp+eax+C]
0040E23C . 3BD1 cmp edx,ecx
0040E23E . 75 18 jnz short CubeMedi.0040E258
0040E240 . 40 inc eax
0040E241 . 83F8 19 cmp eax,19
0040E244 .^ 7C EA jl short CubeMedi.0040E230
0040E246 . B8 01000000 mov eax,1
0040E24B . 8B4C24 28 mov ecx,dword ptr ss:[esp+28]
0040E24F . E8 9EF20300 call CubeMedi.0044D4F2
0040E254 . 83C4 2C add esp,2C
0040E257 . C3 retn
0040E258 > 8B4C24 28 mov ecx,dword ptr ss:[esp+28]
0040E25C . 33C0 xor eax,eax
0040E25E . E8 8FF20300 call CubeMedi.0044D4F2
0040E263 . 83C4 2C add esp,2C
0040E266 . C3 retn
现在明白了,它的序列号是这样算成的:
前12位的注册码是: (( (机器码(N)*用户名ASCII码累加值)+机器码(N+1))%0x1A)
后12位的注册码是: ((机器码(N)*(用户名ASCII码累加值+1))%0x1A+0x41)
而它的机器码的生成方式则是:
(硬盘序列号+CPU字符串(N))%0x1A+0x41 //N是0-11
明白了算法后,开始写注册机:
CString CKeyGun::MakeMachineCode() //Make MachineCode
{
CString MachineCode;
DWORD Disk_Vol;
char CPUStr[12];
int i;
GetVolumeInformation("C:\\",NULL,12,&Disk_Vol,NULL,NULL,NULL,10);
_asm{
mov eax,0
cpuid
mov DWORD ptr CPUStr , ebx
mov DWORD ptr CPUStr+4 , edx
mov DWORD ptr CPUStr+8 , ecx
}
for(i=0;i<12;i++)
{
MachineCode+=char((Disk_Vol+int(CPUStr[i]))%0x1A+0x41);
}
return MachineCode;
}
CString CKeyGun::MakeKey(CString MaCode,CString Username) //Make Reg key
{
int i,Usr;
Usr=0;
for(i=0;i<Username.GetLength();i++)
{
Usr+=int(Username.GetAt(i));
}
CString Key;
for(i=0;i<11;i++)
{
Key+=char(((MaCode.GetAt(i)*Usr)+MaCode.GetAt(i+1))%0x1A+0x41);
}
Key+=char((MaCode.GetAt(i)*Usr)%0x1A+0x41);
for(i=0;i<12;i++)
{
Key+=char((MaCode.GetAt(i)*(Usr+1))%0x1A+0x41);
}
return Key;
}
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!