My FAQ,最新最全的IT技术FAQ
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 未整理篇 | 技术讨论
  当前位置:> 看雪学院专区 > CrackMe
对《我做的一个简单的Keygenme》的分析及注册机
作者:smarter 时间:2005-11-17 12:44 出处:pediy 责编:My FAQ
              摘要:暂无
这个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;
}
这是原文件及我写的注册机。[COLOR=blue]
[COLOR=darkblue]附件:keygen.rar

 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 myfaq.com.cn All rights reserved. www.myfaq.com.cn 版权所有