- UID
- 2
注册时间2004-12-1
阅读权限255
最后登录1970-1-1
总坛主
TA的每日心情 | 开心 2024-12-1 11:04 |
---|
签到天数: 12 天 [LV.3]偶尔看看II
|
【破文标题】某KeyGenMe 算法分析
【破文作者】飘云[PYG]
【作者邮箱】[email protected]
【作者主页】www.chinapyg.com
【破解工具】Peid0.94,[PYG]OD
【破解平台】Win9x/NT/2000/XP
【软件名称】KeyGenMe
【软件大小】20kb
【原版下载】https://www.chinapyg.com/viewthr ... &extra=page%3D1
【保护方式】用户名+注册码
【特别说明】应[PYG学员]wzwgp 要求,而写的鸟文,高手直接闪人~
------------------------------------------------------------------------
【分析过程】
OD载入程序,字符插件,找到如下:
输入注册信息,开始调试:
00401440 6A FF push -1
00401442 68 101C4000 push KeyGenMe.00401C10
00401447 64:A1 00000000 mov eax,dword ptr fs:[0]
0040144D 50 push eax
0040144E 64:8925 00000000 mov dword ptr fs:[0],esp
00401455 83EC 14 sub esp,14
00401458 53 push ebx
00401459 55 push ebp
0040145A 56 push esi
0040145B 8BF1 mov esi,ecx
0040145D 57 push edi
0040145E 8D4C24 1C lea ecx,dword ptr ss:[esp+1C]
00401462 E8 91040000 call <jmp.&MFC42.#540>
00401467 33ED xor ebp,ebp
00401469 6A 01 push 1
0040146B 8BCE mov ecx,esi
0040146D 896C24 30 mov dword ptr ss:[esp+30],ebp
00401471 896C24 1C mov dword ptr ss:[esp+1C],ebp
00401475 896C24 24 mov dword ptr ss:[esp+24],ebp
00401479 E8 B6040000 call <jmp.&MFC42.#6334>
0040147E 8D4424 10 lea eax,dword ptr ss:[esp+10]
00401482 8BCE mov ecx,esi
00401484 50 push eax
00401485 E8 56010000 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
00401496 C64424 2C 01 mov byte ptr ss:[esp+2C],1
0040149B F2:AE repne scas byte ptr es:[edi]
0040149D F7D1 not ecx
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 ; 累加用户名ascii值
004014A8 8BFB mov edi,ebx
004014AA 83C9 FF or ecx,FFFFFFFF
004014AD 33C0 xor eax,eax
004014AF 42 inc edx
004014B0 F2:AE repne scas byte ptr es:[edi]
004014B2 F7D1 not ecx
004014B4 49 dec ecx
004014B5 3BD1 cmp edx,ecx
004014B7 ^ 72 E9 jb short KeyGenMe.004014A2
004014B9 896C24 20 mov dword ptr ss:[esp+20],ebp ; 保存累加和,令它为sum1
004014BD 8D5424 14 lea edx,dword ptr ss:[esp+14]
004014C1 8BCE mov ecx,esi
004014C3 52 push edx
004014C4 33ED xor ebp,ebp
004014C6 E8 15010000 call KeyGenMe.004015E0 ; 算法call1===根据C盘序列号计算出一组字符串,F7跟进
{*****************************算法call1代码:*****************************
004015E0 6A FF push -1
004015E2 68 471C4000 push KeyGenMe.00401C47
004015E7 64:A1 00000000 mov eax,dword ptr fs:[0]
004015ED 50 push eax
004015EE 64:8925 00000000 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 0C lea ecx,dword ptr ss:[esp+C]
00401600 897424 14 mov dword ptr ss:[esp+14],esi
00401604 E8 EF020000 call <jmp.&MFC42.#540>
00401609 8D4C24 08 lea ecx,dword ptr ss:[esp+8]
0040160D C74424 20 01000000 mov dword ptr ss:[esp+20],1
00401615 E8 DE020000 call <jmp.&MFC42.#540>
0040161A 6A 0A push 0A
0040161C 56 push esi
0040161D 56 push esi
0040161E 8D4424 1C 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 40304000 push KeyGenMe.00403040 ; c:\
0040162C C64424 40 02 mov byte ptr ss:[esp+40],2
00401631 FF15 00204000 call dword ptr ds:[<&KERNEL32.>; kernel32.GetVolumeInformationA
00401637 8B4C24 10 mov ecx,dword ptr ss:[esp+10] ; 取C盘序列号
0040163B 8D5424 08 lea edx,dword ptr ss:[esp+8]
0040163F 51 push ecx
00401640 68 3C304000 push KeyGenMe.0040303C ; %x
00401645 52 push edx
00401646 E8 F5020000 call <jmp.&MFC42.#2818> ; 格式化成16进制字符串。令它为str1
0040164B 8B5424 14 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>; 逐位ascii送eax
00401664 0FAF4424 10 imul eax,dword ptr ss:[esp+10] ; [esp+10]C盘序列号的16进制
00401669 33D2 xor edx,edx
0040166B B9 1A000000 mov ecx,1A
00401670 F7F1 div ecx ; mod 1a 余数到dl
00401672 B0 7A mov al,7A ; al=7a
00401674 8D4C24 0C lea ecx,dword ptr ss:[esp+C]
00401678 2AC2 sub al,dl ; 7a-余数
0040167A 50 push eax
0040167B E8 AE020000 call <jmp.&MFC42.#940> ; 转换成对应的字符字符
00401680 8B5424 08 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.00401660 ;循环结束?
00401695 8B7424 28 mov esi,dword ptr ss:[esp+28]
00401699 8D4C24 0C lea ecx,dword ptr ss:[esp+C]
0040169D 51 push ecx
0040169E 8BCE mov ecx,esi
004016A0 E8 95020000 call <jmp.&MFC42.#535>
004016A5 C74424 14 01000000 mov dword ptr ss:[esp+14],1
004016AD 8D4C24 08 lea ecx,dword ptr ss:[esp+8]
004016B1 C64424 20 01 mov byte ptr ss:[esp+20],1
004016B6 E8 65010000 call <jmp.&MFC42.#800>
004016BB 8D4C24 0C lea ecx,dword ptr ss:[esp+C]
004016BF C64424 20 00 mov byte ptr ss:[esp+20],0
004016C4 E8 57010000 call <jmp.&MFC42.#800>
004016C9 8B4C24 18 mov ecx,dword ptr ss:[esp+18]
004016CD 8BC6 mov eax,esi
004016CF 5F pop edi
004016D0 5E pop esi
004016D1 64:890D 00000000 mov dword ptr fs:[0],ecx
004016D8 83C4 1C add esp,1C
004016DB C2 0400 retn 4
*****************************算法call1结束******************************
}
004014CB 8B38 mov edi,dword ptr ds:[eax] ; 返回的字符串送edi,令它为str2
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 14 lea ecx,dword ptr ss:[esp+14]
004014DB 0F95C3 setne bl
004014DE E8 3D030000 call <jmp.&MFC42.#800>
004014E3 84DB test bl,bl
004014E5 74 3D je short KeyGenMe.00401524
004014E7 8B4424 10 mov eax,dword ptr ss:[esp+10]
004014EB 8B5424 18 mov edx,dword ptr ss:[esp+18]
004014EF 0FBE0C28 movsx ecx,byte ptr ds:[eax+ebp>; 逐位取str2的ascii送ecx
004014F3 03D1 add edx,ecx ; 累加到edx
004014F5 8BCE mov ecx,esi
004014F7 895424 18 mov dword ptr ss:[esp+18],edx ; 最终保存到[esp+18]
004014FB 8D5424 14 lea edx,dword ptr ss:[esp+14]
004014FF 52 push edx
00401500 45 inc ebp
00401501 E8 DA000000 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 14 lea ecx,dword ptr ss:[esp+14]
00401518 0F92C3 setb bl
0040151B E8 00030000 call <jmp.&MFC42.#800>
00401520 84DB test bl,bl
00401522 ^ 75 C3 jnz short KeyGenMe.004014E7 //上面算法是累加str2的ascii值,令它为sum2
00401524 8B5424 10 mov edx,dword ptr ss:[esp+10]
00401528 83C9 FF or ecx,FFFFFFFF
0040152B 8BFA mov edi,edx
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] ; str2逐位ascii送bl
0040153B 8BCE mov ecx,esi
0040153D E8 9E010000 call KeyGenMe.004016E0 ; 取C盘序列号 转换成16进制后返回到eax
00401542 0FBECB movsx ecx,bl ; ecx=bl
00401545 0FAFC1 imul eax,ecx ; eax=eax×ecx
00401548 0FAF4424 18 imul eax,dword ptr ss:[esp+18] ; sum2×eax
0040154D 8B5C24 20 mov ebx,dword ptr ss:[esp+20] ; [esp+20]:用户名ascii累加和 sum1
00401551 33D2 xor edx,edx ; EDX清0
00401553 33C3 xor eax,ebx ; eax xor ebx
00401555 B9 1A000000 mov ecx,1A
0040155A F7F1 div ecx ; mod 1a
0040155C 8D4C24 1C lea ecx,dword ptr ss:[esp+1C]
00401560 80C2 41 add dl,41 ; 余数+41 保存到dl
00401563 52 push edx
00401564 E8 C5030000 call <jmp.&MFC42.#940> ; 将dl转换成对应的字符
00401569 8B5424 10 mov edx,dword ptr ss:[esp+10]
0040156D 83C9 FF or ecx,FFFFFFFF
00401570 8BFA mov edi,edx
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 1C 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 BC214000 call dword ptr ds:[<&MSVCRT._m>; msvcrt._mbscmp //比较call
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 2C304000 push KeyGenMe.0040302C ; 注册码不正确
0040159D EB 05 jmp short KeyGenMe.004015A4
0040159F 68 20304000 push KeyGenMe.00403020 ; 注册码正确
004015A4 8BCE mov ecx,esi
004015A6 E8 7D030000 call <jmp.&MFC42.#4224>
------------------------------------------------------------------------
【算法总结】
1.用户名ascii累加得到sum1
2.取C盘序列号转换成16进制字符串str1
3.对str1进行运算,得到str2
4.累加str2的ascii得到sum2
5.str2.sum1.sum2参与循环运算,最终得到RegKey
【注册机源码】
说明:没有做任何优化,保留注释;- //**********************************
- // KeyGen By PiaoYun[PYG]
- // 在 VC++6.0+winxp sp2 下调试通过
- // www.chinapyg.com
- // 2006.1.25
- //**********************************
- #include "iOStream.h"
- #include "windows.h"
- #include "stdio.h"
- void main()
- {
- DWORD dwIDESerial;
- char name[50],STR1[8],STR2[8],SN[50];
- int sum1=0,sum2=0;
- byte a; //定义一个字节变量,保存ascii码
- cout<<"\t\t**********************************\n";
- cout<<"\t\t* KeyGen By PiaoYun[PYG] *\n";
- cout<<"\t\t* www.chinapyg.com *\n";
- cout<<"\t\t* E-mail:[email protected] *\n";
- cout<<"\t\t**********************************\n";
- //BTW:有些数据不好处理,直接嵌入汇编了~~ 嘿嘿~~ ^_^
- cout<<"Please Input Your UserName:\n";
- cin>>name;
- //累加用户名ascii
- for(int i=0;i<int(strlen(name));i++)
- {
- //a = name[i]; //跟踪发现,原程序并没有对中文进行很好的处理,故不使用字节计算
- //sum1=sum1+a;
- sum1=sum1 + name[i];
- }
- //取C盘序列号
- GetVolumeInformation("C:\",NULL,0xC,&dwIDESerial,NULL,NULL,NULL,0xA);
- //|RootPathName = "C:"
- //|VolumeNameBuffer = NULL
- //|MaxVolumeNameSize = C (12.)
- //|pVolumeSerialNumber = 0012F7C4
- //|pMaxFilenameLength = NULL
- //|pFileSystemFlags = NULL
- //|pFileSystemNameBuffer = NULL
- //|pFileSystemNameSize = 0000000A
-
- //格式化成16进制字符串
- wsprintf(STR1,"%x",dwIDESerial);
- //计算由C盘序列号产生的一个字符串STR2
- for(i=0;i<int(strlen(STR1));i++)
- {
- a = STR1[i];
- __asm
- {
- movsx eax,a
- imul eax,dwIDESerial
- xor edx,edx
- mov ecx,0x1A
- div ecx
- mov al,0x7A
- sub al,dl
- mov a,al
- }
- STR2[i]=a; //每位字符保存到TZM2数组中
- STR2[i+1]='\0';
- }
- //累加由C盘得到的字符串ascii
- for(i=0;i<int(strlen(STR2));i++)
- sum2=sum2+STR2[i];
- //下面正式开始产生RegKey
- for(i=0;i<int(strlen(STR2));i++)
- {
- a = STR2[i];
- __asm
- {
- mov bl,a
- mov ecx,esi
- mov eax,dwIDESerial
- movsx ecx,bl
- imul eax,ecx
- imul eax,sum2
- mov ebx,sum1
- xor edx,edx
- xor eax,ebx
- mov ecx,0x1A
- div ecx
- add dl,0x41
- mov a,dl
- }
- SN[i]=a;
- SN[i+1]='\0';
- }
- cout<<"Your RegKey is:\n"<<SN<<endl;
- getchar();
- }
复制代码 ------------------------------------------------------------------------
【版权声明】本文纯属技术交流,转载请注明作者信息并保持文章的完整,谢谢! |
|