飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 12533|回复: 10

[原创] 某KeyGenMe 算法分析【应[PYG学员]wzwgp 要求,而写】

[复制链接]
  • TA的每日心情
    开心
    2024-12-1 11:04
  • 签到天数: 12 天

    [LV.3]偶尔看看II

    发表于 2006-1-25 18:47:37 | 显示全部楼层 |阅读模式
    【破文标题】某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


    注册机源码】
    说明:没有做任何优化,保留注释;
    1. //**********************************
    2. //       KeyGen By PiaoYun[PYG]
    3. //  在 VC++6.0+winxp sp2 下调试通过
    4. //          www.chinapyg.com
    5. //             2006.1.25
    6. //**********************************



    7. #include "iOStream.h"
    8. #include "windows.h"
    9. #include "stdio.h"
    10. void main()
    11. {
    12. DWORD dwIDESerial;
    13. char name[50],STR1[8],STR2[8],SN[50];
    14. int sum1=0,sum2=0;
    15. byte a;    //定义一个字节变量,保存ascii码
    16. cout<<"\t\t**********************************\n";
    17. cout<<"\t\t*     KeyGen By PiaoYun[PYG]     *\n";
    18. cout<<"\t\t*        www.chinapyg.com        *\n";
    19. cout<<"\t\t*    E-mail:[email protected]    *\n";
    20. cout<<"\t\t**********************************\n";
    21.      //BTW:有些数据不好处理,直接嵌入汇编了~~ 嘿嘿~~ ^_^

    22. cout<<"Please Input Your UserName:\n";
    23. cin>>name;

    24. //累加用户名ascii
    25. for(int i=0;i<int(strlen(name));i++)
    26. {   
    27. //a = name[i];    //跟踪发现,原程序并没有对中文进行很好的处理,故不使用字节计算
    28. //sum1=sum1+a;
    29. sum1=sum1 + name[i];
    30. }

    31. //取C盘序列号
    32. GetVolumeInformation("C:\",NULL,0xC,&dwIDESerial,NULL,NULL,NULL,0xA);

    33. //|RootPathName = "C:"
    34. //|VolumeNameBuffer = NULL
    35. //|MaxVolumeNameSize = C (12.)
    36. //|pVolumeSerialNumber = 0012F7C4
    37. //|pMaxFilenameLength = NULL
    38. //|pFileSystemFlags = NULL
    39. //|pFileSystemNameBuffer = NULL
    40. //|pFileSystemNameSize = 0000000A

    41. //格式化成16进制字符串
    42. wsprintf(STR1,"%x",dwIDESerial);

    43. //计算由C盘序列号产生的一个字符串STR2
    44. for(i=0;i<int(strlen(STR1));i++)        
    45. {
    46. a = STR1[i];
    47. __asm
    48. {
    49. movsx eax,a
    50. imul eax,dwIDESerial
    51. xor edx,edx
    52. mov ecx,0x1A
    53. div ecx         
    54. mov al,0x7A
    55. sub al,dl  
    56. mov a,al
    57. }
    58. STR2[i]=a;         //每位字符保存到TZM2数组中
    59. STR2[i+1]='\0';
    60. }

    61. //累加由C盘得到的字符串ascii
    62. for(i=0;i<int(strlen(STR2));i++)
    63. sum2=sum2+STR2[i];

    64. //下面正式开始产生RegKey
    65. for(i=0;i<int(strlen(STR2));i++)
    66. {
    67. a = STR2[i];
    68. __asm
    69. {
    70. mov bl,a
    71. mov ecx,esi
    72. mov eax,dwIDESerial
    73. movsx ecx,bl         
    74. imul eax,ecx        
    75. imul eax,sum2      
    76. mov ebx,sum1     
    77. xor edx,edx      
    78. xor eax,ebx     
    79. mov ecx,0x1A
    80. div ecx      
    81. add dl,0x41   
    82. mov a,dl
    83. }
    84. SN[i]=a;
    85. SN[i+1]='\0';
    86. }
    87. cout<<"Your RegKey is:\n"<<SN<<endl;
    88. getchar();
    89. }
    复制代码
    ------------------------------------------------------------------------
    【版权声明】本文纯属技术交流,转载请注明作者信息并保持文章的完整,谢谢!
    PYG19周年生日快乐!
  • TA的每日心情
    擦汗
    2019-3-20 20:06
  • 签到天数: 258 天

    [LV.8]以坛为家I

    发表于 2006-1-25 19:02:47 | 显示全部楼层
    又一学习教材!~~~
    PYG19周年生日快乐!
  • TA的每日心情
    擦汗
    2017-9-28 11:05
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    发表于 2006-1-25 20:13:04 | 显示全部楼层
    不错~
    学习了
    我昨天看了一下
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2018-2-26 08:32
  • 签到天数: 19 天

    [LV.4]偶尔看看III

    发表于 2006-1-25 20:38:23 | 显示全部楼层
    谢谢老大!太感谢了。
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2006-1-25 21:16:58 | 显示全部楼层
    强,努力学习中
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2018-1-6 14:28
  • 签到天数: 6 天

    [LV.2]偶尔看看I

    发表于 2006-1-26 06:54:26 | 显示全部楼层
    学习下```晕呼呼的```
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2006-1-27 03:01:12 | 显示全部楼层
    算法学习起来真的感觉费力,看来自己还需要加把劲啊!
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2006-2-18 16:46:04 | 显示全部楼层
    看不懂~
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2006-3-3 11:43:38 | 显示全部楼层
    牛,太牛了
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2006-3-5 20:10:13 | 显示全部楼层
    牛人,看的不是很明白!
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表