这个KeyGenMe(作者反复强调说不是CrackMe,^_^)原则上是一机一码(如果谁能不爆破而找到通用码,
欢迎联系AGanNo2@163.com.),主要是由C盘的序列号而产生的不同(调用GetVolumeInformation得到的)。
下面是对整个算法的分析过程:
算法的大体过程是由C盘的序列号(dwVolumeSerialNumber)得到一个字符串(szProduceByDisk),当然
到这里算法并未结束,然后由szProduceByDisk得到最终的szRegKey.
中间用的只是UserName的各位加起来的和dwSumName,当然还用到了szProduceByDisk的各位加起来的和dwSumProduceByDisk。
下边是详细的分析过程:
00401459 55 push ebp
0040145A 56 push esi
0040145B 8BF1 mov esi,ecx
0040145D 57 push edi
0040145E 8D4C24 1>lea ecx,dword ptr ss:[esp+1C]
00401462 E8 91040>call <jmp.&MFC42.#540_CString::CString>
00401467 33ED xor ebp,ebp
00401469 6A 01 push 1
0040146B 8BCE mov ecx,esi
0040146D 896C24 3>mov dword ptr ss:[esp+30],ebp
00401471 896C24 1>mov dword ptr ss:[esp+1C],ebp
00401475 896C24 2>mov dword ptr ss:[esp+24],ebp
00401479 E8 B6040>call <jmp.&MFC42.#6334_CWnd::UpdateData>
0040147E 8D4424 1>lea eax,dword ptr ss:[esp+10]
00401482 8BCE mov ecx,esi
00401484 50 push eax
00401485 E8 56010>call KeyGenMe.004015E0
0040148A 8B5E 60 mov ebx,dword ptr ds:[esi+60]
0040148D 83C9 FF or ecx,FFFFFFFF
00401490 8BFB mov edi,ebx
00401492 33C0 xor eax,eax
00401494 33D2 xor edx,edx ; MFC42.73E0E578
00401496 C64424 2>mov byte ptr ss:[esp+2C],1 _
0040149B F2:AE repne scas byte ptr es:[edi] |
0040149D F7D1 not ecx | ; 得到RegName的长度
0040149F 49 dec ecx
004014A0 74 1B je short KeyGenMe.004014BD
004014A2 0FBE0C13 movsx ecx,byte ptr ds:[ebx+edx]
004014A6 03E9 add ebp,ecx ; 取每一个字符加到ebp中
004014A8 8BFB mov edi,ebx
004014AA 83C9 FF or ecx,FFFFFFFF
004014AD 33C0 xor eax,eax
004014AF 42 inc edx ; MFC42.73E0E578
004014B0 F2:AE repne scas byte ptr es:[edi]
004014B2 F7D1 not ecx
004014B4 49 dec ecx
004014B5 3BD1 cmp edx,ecx ; Name有没有结束?
004014B7 ^ 72 E9 jb short KeyGenMe.004014A2
004014B9 <> 896C24 2>mov dword ptr ss:[esp+20],ebp ; ebp=26F
004014BD 8D5424 1>lea edx,dword ptr ss:[esp+14]
004014C1 8BCE mov ecx,esi
004014C3 52 push edx ; MFC42.73E0E578
004014C4 33ED xor ebp,ebp
004014C6 E8 15010>call KeyGenMe.004015E0
004014CB 8B38 mov edi,dword ptr ds:[eax] ; eax="vjtxfthh",这个字符串是由C盘的序列号得到的,
004014CD 83C9 FF or ecx,FFFFFFFF ;每台机器一般不一样,这是在我机器上得到的,关于
004014D0 33C0 xor eax,eax ;如何得到的,后面有分析
004014D2 F2:AE repne scas byte ptr es:[edi]
004014D4 F7D1 not ecx
004014D6 49 dec ecx
004014D7 8D4C24 1>lea ecx,dword ptr ss:[esp+14]
004014DB 0F95C3 setne bl
004014DE E8 3D030>call <jmp.&MFC42.#800_CString::~CString>
004014E3 84DB test bl,bl
004014E5 74 3D je short KeyGenMe.00401524
004014E7 8B4424 1>mov eax,dword ptr ss:[esp+10]
004014EB 8B5424 1>mov edx,dword ptr ss:[esp+18]
004014EF 0FBE0C28 movsx ecx,byte ptr ds:[eax+ebp]
004014F3 03D1 add edx,ecx ; 取“vjtxfthh”中的每一个字符加到edx中
004014F5 8BCE mov ecx,esi
004014F7 895424 1>mov dword ptr ss:[esp+18],edx ; MFC42.73E0E578
004014FB 8D5424 1>lea edx,dword ptr ss:[esp+14]
004014FF 52 push edx ; MFC42.73E0E578
00401500 45 inc ebp
00401501 E8 DA000>call KeyGenMe.004015E0
00401506 8B38 mov edi,dword ptr ds:[eax]
00401508 83C9 FF or ecx,FFFFFFFF
0040150B 33C0 xor eax,eax
0040150D F2:AE repne scas byte ptr es:[edi]
0040150F F7D1 not ecx
00401511 49 dec ecx
00401512 3BE9 cmp ebp,ecx
00401514 8D4C24 1>lea ecx,dword ptr ss:[esp+14]
00401518 0F92C3 setb bl
0040151B E8 00030>call <jmp.&MFC42.#800_CString::~CString>
00401520 84DB test bl,bl
00401522 ^ 75 C3 jnz short KeyGenMe.004014E7
00401524 8B5424 1>mov edx,dword ptr ss:[esp+10]
00401528 83C9 FF or ecx,FFFFFFFF
0040152B 8BFA mov edi,edx ; MFC42.73E0E578
0040152D 33C0 xor eax,eax
0040152F 33ED xor ebp,ebp
00401531 F2:AE repne scas byte ptr es:[edi]
00401533 F7D1 not ecx
00401535 49 dec ecx
00401536 74 46 je short KeyGenMe.0040157E
00401538 8A1C2A mov bl,byte ptr ds:[edx+ebp] ; 取“vjtxfthh”(每台机器不一样)
0040153B 8BCE mov ecx,esi
0040153D E8 9E010>call KeyGenMe.004016E0 ; 取得C盘的序列号,存在eax中
00401542 0FBECB movsx ecx,bl ;从“vjtxfthh”中逐位取出字符
00401545 0FAFC1 imul eax,ecx ; eax=485ec5b0,C盘的序列号
00401548 0FAF4424>imul eax,dword ptr ss:[esp+18] ; 376,(“vjtxfthh”相加的和)
0040154D 8B5C24 2>mov ebx,dword ptr ss:[esp+20] ; 26F,(RegName相加的和)
00401551 33D2 xor edx,edx |
00401553 33C3 xor eax,ebx |
00401555 <> B9 1A000>mov ecx,1A |
0040155A F7F1 div ecx |__这几步是由C盘的序列号产生RegKey的过程
0040155C 8D4C24 1>lea ecx,dword ptr ss:[esp+1C] |
00401560 80C2 41 add dl,41 |
00401563 52 push edx |
00401564 E8 C5030>call <jmp.&MFC42.#940_CString::operator+=>
00401569 8B5424 1>mov edx,dword ptr ss:[esp+10]
0040156D 83C9 FF or ecx,FFFFFFFF
00401570 8BFA mov edi,edx ; MFC42.73E0E578
00401572 33C0 xor eax,eax
00401574 45 inc ebp
00401575 F2:AE repne scas byte ptr es:[edi]
00401577 F7D1 not ecx
00401579 49 dec ecx
0040157A 3BE9 cmp ebp,ecx
0040157C ^ 72 BA jb short KeyGenMe.00401538
0040157E 8B5424 1>mov edx,dword ptr ss:[esp+1C]
00401582 8B46 64 mov eax,dword ptr ds:[esi+64]
00401585 52 push edx ;这一步是比较
00401586 50 push eax
00401587 FF15 BC2>call near dword ptr ds:[<&MSVCRT._mbscmp>] ; msvcrt._mbscmp
0040158D 83C4 08 add esp,8
00401590 85C0 test eax,eax
00401592 6A 00 push 0
00401594 6A 00 push 0
00401596 74 07 je short KeyGenMe.0040159F ;爆破在这边,^_^
00401598 68 2C304>push KeyGenMe.0040302C
0040159D EB 05 jmp short KeyGenMe.004015A4
0040159F 68 20304>push KeyGenMe.00403020
004015A4 8BCE mov ecx,esi
004015A6 E8 7D030>call <jmp.&MFC42.#4224_CWnd::MessageBoxA>
;下边是由C盘的序列号产生字符串“vjtxfthh”的过程,
;在每台机器上这个字符串会不一样
004015E0 6A FF push -1
004015E2 68 471C4>push KeyGenMe.00401C47
004015E7 64:A1 00>mov eax,dword ptr fs:[0]
004015ED 50 push eax
004015EE 64:8925 >mov dword ptr fs:[0],esp
004015F5 83EC 10 sub esp,10
004015F8 56 push esi
004015F9 33F6 xor esi,esi
004015FB 57 push edi
004015FC 8D4C24 0>lea ecx,dword ptr ss:[esp+C]
00401600 897424 1>mov dword ptr ss:[esp+14],esi
00401604 E8 EF020>call <jmp.&MFC42.#540_CString::CString>
00401609 8D4C24 0>lea ecx,dword ptr ss:[esp+8]
0040160D C74424 2>mov dword ptr ss:[esp+20],1
00401615 E8 DE020>call <jmp.&MFC42.#540_CString::CString>
0040161A 6A 0A push 0A
0040161C 56 push esi
0040161D 56 push esi
0040161E 8D4424 1>lea eax,dword ptr ss:[esp+1C]
00401622 56 push esi
00401623 50 push eax
00401624 6A 0C push 0C
00401626 56 push esi
00401627 68 40304>push KeyGenMe.00403040 ; ASCII "C:\"
0040162C C64424 4>mov byte ptr ss:[esp+40],2
00401631 FF15 002>call near dword ptr ds:[<&KERNEL32.GetVolume>; kernel32.GetVolumeInformationA
00401637 8B4C24 1>mov ecx,dword ptr ss:[esp+10]
0040163B 8D5424 0>lea edx,dword ptr ss:[esp+8]
0040163F 51 push ecx
00401640 68 3C304>push KeyGenMe.0040303C ; ASCII "%x"
00401645 52 push edx
00401646 E8 F5020>call <jmp.&MFC42.#2818_CString::Format>
0040164B 8B5424 1>mov edx,dword ptr ss:[esp+14]
0040164F 83C9 FF or ecx,FFFFFFFF
00401652 8BFA mov edi,edx
00401654 33C0 xor eax,eax
00401656 83C4 0C add esp,0C
00401659 F2:AE repne scas byte ptr es:[edi]
0040165B F7D1 not ecx
0040165D 49 dec ecx
0040165E 74 35 je short KeyGenMe.00401695
00401660 <> 0FBE0416 movsx eax,byte ptr ds:[esi+edx] | ;取序列号的每一位
00401664 0FAF4424>imul eax,dword ptr ss:[esp+10] | ;乘以序列号本生
00401669 33D2 xor edx,edx |
0040166B B9 1A000>mov ecx,1A |___这是关键的几步
00401670 F7F1 div ecx | ;除1A
00401672 B0 7A mov al,7A |
00401674 8D4C24 0>lea ecx,dword ptr ss:[esp+C] |
00401678 2AC2 sub al,dl | ;减dl,得到字符串的每一位(al中)
0040167A 50 push eax
0040167B E8 AE020>call <jmp.&MFC42.#940_CString::operator+=>
00401680 8B5424 0>mov edx,dword ptr ss:[esp+8] |
00401684 83C9 FF or ecx,FFFFFFFF |
00401687 8BFA mov edi,edx |
00401689 33C0 xor eax,eax |
0040168B 46 inc esi |
0040168C F2:AE repne scas byte ptr es:[edi] |___用来测试是否到了序列号的最后一位的
0040168E F7D1 not ecx |
00401690 49 dec ecx |
00401691 3BF1 cmp esi,ecx |
00401693 ^ 72 CB jb short <KeyGenMe.401660> |
00401695 8B7424 2>mov esi,dword ptr ss:[esp+28]
00401699 8D4C24 0>lea ecx,dword ptr ss:[esp+C]
0040169D 51 push ecx
0040169E 8BCE mov ecx,esi
004016A0 E8 95020>call <jmp.&MFC42.#535_CString::CString>
004016A5 C74424 1>mov dword ptr ss:[esp+14],1
004016AD 8D4C24 0>lea ecx,dword ptr ss:[esp+8]
004016B1 C64424 2>mov byte ptr ss:[esp+20],1
004016B6 E8 65010>call <jmp.&MFC42.#800_CString::~CString>
004016BB 8D4C24 0>lea ecx,dword ptr ss:[esp+C]
004016BF C64424 2>mov byte ptr ss:[esp+20],0
004016C4 E8 57010>call <jmp.&MFC42.#800_CString::~CString>
004016C9 8B4C24 1>mov ecx,dword ptr ss:[esp+18]
004016CD 8BC6 mov eax,esi
004016CF 5F pop edi ; KeyGenMe.0040148A
004016D0 5E pop esi ; KeyGenMe.0040148A
004016D1 64:890D >mov dword ptr fs:[0],ecx
004016D8 83C4 1C add esp,1C
004016DB C2 0400 retn 4
最后是我写的注册机,用的是VC++嵌入汇编,感觉比较好用,可以“偷”反汇编中的代码^_^。
我声明我只是在两台机器上测试过,如果有问题和我联系(AGanNo2@163.com).
#include<windows.h>
#include<iostream>
char szHexVolumeSerialNumber[8]; //十六二进制的硬盘序列号
char szProduceByDisk[8]; //由硬盘序列号产生的一个字符串
int main()
{
std::cout<<"我只测试过两台机器,有问题和aganno2@163.com联系\n\n";
char szUserName[256];
std::cout<<"请输入UserName: ";
std::cin.getline(szUserName,256);
char szRegKey[256];
//得到逻辑盘C:的序列号
char szVolumeNameBuffer[MAX_PATH];
DWORD dwVolumeSerialNumber;
DWORD dwMaximumComponentLength;
DWORD dwFileSystemFlags;
char szFileSystemNameBuffer[MAX_PATH];
::GetVolumeInformation("C:\\",szVolumeNameBuffer,sizeof(szVolumeNameBuffer),
&dwVolumeSerialNumber,&dwMaximumComponentLength,
&dwFileSystemFlags,szFileSystemNameBuffer,sizeof(szFileSystemNameBuffer));
//格式化为十六二进制的硬盘序列号
wsprintf(szHexVolumeSerialNumber,"%08x",dwVolumeSerialNumber);
//**********************************************
//下面这个循环用来产生由硬盘序列号产生的一个字符串szProduceByDisk
byte bChar;
for(int i=0;i<8;i++)
{
bChar=szHexVolumeSerialNumber[i];
__asm
{
mov edx, dwVolumeSerialNumber
movsx eax, bChar
imul eax,dwVolumeSerialNumber
xor edx,edx
mov ecx,0x1A
div ecx
mov al,0x7A
sub al,dl
mov bChar,al
}
szProduceByDisk[i]=bChar; //由硬盘序列号产生的一个字符串的每一位
}
//dwSumProduceByDisk为szProduceByDisk中的每一位相加和
DWORD dwSumProduceByDisk=0;
for(i=0;szProduceByDisk[i]!='\0';i++)
dwSumProduceByDisk+=szProduceByDisk[i];
//dwSumName为szUserName中每一位相加和
DWORD dwSumName=0;
for(i=0;szUserName[i]!='\0';i++)
dwSumName+=szUserName[i];
//由szProduceByDisk产生注册码szRegKey的过程
for(i=0;i<8;i++)
{
bChar=szProduceByDisk[i];
__asm
{
mov eax,dwVolumeSerialNumber
movsx ecx,bChar
imul eax,ecx
imul eax,dwSumProduceByDisk
mov ebx,dwSumName
xor edx,edx
xor eax,ebx
mov ecx,0x1A
div ecx
add dl,0x41
mov bChar,dl
}
szRegKey[i]=bChar;
}
szRegKey[8]='\0';
std::cout<<"注册码RegKey为: "<<szRegKey<<std::endl;
std::cout<<"Good Luck!\n";
system("pause");
return 0;
}
这是原文件及我写的注册机。附件:keygen.rar
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!