飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 2769|回复: 2

[原创] 分析KeygenMe(KM)2014#001——山重水复疑无路,柳暗花明又一村。 【上篇】

  [复制链接]
  • TA的每日心情
    开心
    2019-3-17 22:44
  • 签到天数: 132 天

    [LV.7]常住居民III

    发表于 2014-9-10 22:29:15 | 显示全部楼层 |阅读模式
    本帖最后由 tree_fly 于 2015-8-19 23:11 编辑
    评委:GGLHY、月之精灵
    观战:飘云

    特此声明:
    A.不得利用CM自身任何BUG绕过注册机
    B.算法程序。请勿爆破
    C.分析好的文章评优秀、精华,奖励PYB
    D.记住:没什么值得炫耀的!


    1.请提交一组合法KEY信息[设置阅读权限]
    2.请提交胜利截图[部分信息隐藏]
    3.请提交算法分析[另外开贴,设置阅读权限]
    4.请提交注册机及源码详细内容,跳转:https://www.chinapyg.com/thread-72326-1-1.html

    分析KeyGenMe(KM)2014#001——山重水复疑无路,柳暗花明又一村。 【上篇】  
    链接 [url=https://www.chinapyg.com/thread-74486-1-1.html]分析KeygenMe2014#001——山重水复疑无路,柳暗花明又一村 【下篇】 算法注册机源码[/url]

    今天我们来分析KeygenMe2014#001,这款软件破解难度略高,不过各位如果仔细、认真的分析代码,问题均会迎刃而解。
    让我想起陆游的一首《游西山村》,可谓是:山重水复疑无路,柳暗花明又一村!


    下面进入主题:
    0x01 基础篇*****************************************************************************************************
      PEiD检测Keygenme001.exe,被识别加壳软件:ASPack 2.12 -> Alexey Solodovnikov.
      为了调试方便,这里我们脱壳后保存程序:KG_Unpack.exe.









      
    0x02 机器码篇**************************************************************************************************
      很容易,我们来到这里
    [Asm] 纯文本查看 复制代码
    004042D0  /$  81EC 4C020000 SUB     ESP, 24C
    004042D6  |.  A1 78244100   MOV     EAX, DWORD PTR DS:[412478]
    004042DB  |.  53            PUSH    EBX
    004042DC  |.  55            PUSH    EBP
    004042DD  |.  56            PUSH    ESI
    004042DE  |.  57            PUSH    EDI                              ;  ntdll.7C930228
    004042DF  |.  6A 68         PUSH    68                               ; /RsrcName = 104.
    004042E1  |.  50            PUSH    EAX                              ; |hInst = NULL
    004042E2  |.  FF15 8C914000 CALL    NEAR DWORD PTR DS:[<&USER32.Load>; \LoadIconA
    004042E8  |.  8BB424 600200>MOV     ESI, DWORD PTR SS:[ESP+260]
    004042EF  |.  50            PUSH    EAX                              ; /lParam = 0
    004042F0  |.  6A 01         PUSH    1                                ; |wParam = 1
    004042F2  |.  68 80000000   PUSH    80                               ; |Message = WM_SETICON
    004042F7  |.  56            PUSH    ESI                              ; |hWnd = FFFFFFFF
    004042F8  |.  FF15 80914000 CALL    NEAR DWORD PTR DS:[<&USER32.Send>; \SendMessageA
    004042FE  |.  8B0D 681E4100 MOV     ECX, DWORD PTR DS:[411E68]       ;  C:\
    00404304  |.  8D5424 34     LEA     EDX, DWORD PTR SS:[ESP+34]
    00404308  |.  894C24 28     MOV     DWORD PTR SS:[ESP+28], ECX
    0040430C  |.  68 FF000000   PUSH    0FF                              ; /pFileSystemNameSize = 000000FF
    00404311  |.  8D4424 34     LEA     EAX, DWORD PTR SS:[ESP+34]       ; |
    00404315  |.  52            PUSH    EDX                              ; |pFileSystemNameBuffer = ntdll.KiFastSystemCallRet
    00404316  |.  8D4C24 34     LEA     ECX, DWORD PTR SS:[ESP+34]       ; |
    0040431A  |.  50            PUSH    EAX                              ; |pFileSystemFlags = NULL
    0040431B  |.  8D5424 2C     LEA     EDX, DWORD PTR SS:[ESP+2C]       ; |
    0040431F  |.  51            PUSH    ECX                              ; |pMaxFilenameLength = 
    00404320  |.  52            PUSH    EDX                              ; |pVolumeSerialNumber = ntdll.KiFastSystemCallRet
    00404321  |.  8D4424 54     LEA     EAX, DWORD PTR SS:[ESP+54]       ; |
    00404325  |.  68 FF000000   PUSH    0FF                              ; |MaxVolumeNameSize = FF (255.)
    0040432A  |.  8D4C24 40     LEA     ECX, DWORD PTR SS:[ESP+40]       ; |
    0040432E  |.  50            PUSH    EAX                              ; |VolumeNameBuffer = NULL
    0040432F  |.  51            PUSH    ECX                              ; |RootPathName 
    00404330  |.  FF15 7C904000 CALL    NEAR DWORD PTR DS:[<&KERNEL32.Ge>; \GetVolumeInformationA
    00404336  |.  B9 40000000   MOV     ECX, 40                          ;  获取C盘卷的序列号
    0040433B  |.  33C0          XOR     EAX, EAX
    0040433D  |.  8D7C24 55     LEA     EDI, DWORD PTR SS:[ESP+55]
    00404341  |.  B3 34         MOV     BL, 34
    00404343  |.  F3:AB         REP     STOS DWORD PTR ES:[EDI]
    00404345  |.  66:AB         STOS    WORD PTR ES:[EDI]
    00404347  |.  AA            STOS    BYTE PTR ES:[EDI]
    00404348  |.  8B4424 20     MOV     EAX, DWORD PTR SS:[ESP+20]       ;   
    0040434C  |.  C64424 54 50  MOV     BYTE PTR SS:[ESP+54], 50
    00404351  |.  C1E0 29       SHL     EAX, 29
    00404354  |.  99            CDQ
    00404355  |.  33C2          XOR     EAX, EDX                         ;  ntdll.KiFastSystemCallRet
    00404357  |.  C64424 55 59  MOV     BYTE PTR SS:[ESP+55], 59
    0040435C  |.  2BC2          SUB     EAX, EDX                         ;  ntdll.KiFastSystemCallRet
    0040435E  |.  8D5424 5B     LEA     EDX, DWORD PTR SS:[ESP+5B]
    00404362  |.  50            PUSH    EAX                              ; /<%d> = 0
    00404363  |.  68 641E4100   PUSH    KG_Unpac.00411E64                ; |%d
    00404368  |.  52            PUSH    EDX                              ; |s = ntdll.KiFastSystemCallRet
    00404369  |.  C64424 62 47  MOV     BYTE PTR SS:[ESP+62], 47         ; |
    0040436E  |.  C64424 63 32  MOV     BYTE PTR SS:[ESP+63], 32         ; |
    00404373  |.  C64424 64 30  MOV     BYTE PTR SS:[ESP+64], 30         ; |
    00404378  |.  C64424 65 31  MOV     BYTE PTR SS:[ESP+65], 31         ; |
    0040437D  |.  885C24 66     MOV     BYTE PTR SS:[ESP+66], BL         ; |
    00404381  |.  FF15 9C914000 CALL    NEAR DWORD PTR DS:[<&USER32.wspr>; \wsprintfA
    00404387  |.  8B2D 84914000 MOV     EBP, DWORD PTR DS:[<&USER32.SetD>;  USER32.SetDlgItemTextA



    这里使用了这个函数,GetVolumeInformationA 函数解释如下:


      RootPathName String,欲获取信息的那个卷的根路径,KM提供的是C:\
      VolumeNameBuffer String,用于装载卷名(卷标)的一个字串
      VolumeNameSize Long,lpVolumeNameBuffer字串的长度
      VolumeSerialNumber Long,用于装载磁盘卷序列号的变量
      MaximumComponentLength Long,指定一个变量,用于装载文件名每一部分的长度。


    堆栈 SS:[0012F9B8]=FC2363B9   ,这里就是C盘的序列号
    EAX=00000001

       


    注意这里
    00404348  |.  8B4424 20     MOV     EAX, DWORD PTR SS:[ESP+20]       ;   
    0040434C  |.  C64424 54 50  MOV     BYTE PTR SS:[ESP+54], 50
    00404351  |.  C1E0 29       SHL     EAX, 29
    C盘卷标被再次读取给EAX,SHL 0x29 = SHL 0x9
    0xFC2363B9 * 2^0x9 = 0x46C77200(1187475968)     ;这个就是机器码的后部分。 PYG2014 + 1187475968


    0012F9EC  50 59 47 32 30 31 34 31 31 38 37 34 37 35 39 36  PYG2014118747596
    0012F9FC  38                                               8










    0x03 文件篇******************************************************************************************************
    函数原型:FILE * fopen(const char * path,const char * mode);


    1.程序查找目录内是否有 PYG2014.dat文件,如果不存在,随机生成一串字符写入内存,文件存在即读取。
    [Asm] 纯文本查看 复制代码
    004043E7  |.  68 5C1E4100   PUSH    KG_Unpac.00411E5C                ; /rb
    004043EC  |.  50            PUSH    EAX                              ; |path = ".\\PYG2014.dat"
    004043ED  |.  C64424 1C 59  MOV     BYTE PTR SS:[ESP+1C], 59         ; |
    004043F2  |.  C64424 1D 47  MOV     BYTE PTR SS:[ESP+1D], 47         ; |
    004043F7  |.  C64424 1E 32  MOV     BYTE PTR SS:[ESP+1E], 32         ; |
    004043FC  |.  C64424 1F 30  MOV     BYTE PTR SS:[ESP+1F], 30         ; |
    00404401  |.  C64424 20 31  MOV     BYTE PTR SS:[ESP+20], 31         ; |
    00404406  |.  885C24 21     MOV     BYTE PTR SS:[ESP+21], BL         ; |
    0040440A  |.  884C24 22     MOV     BYTE PTR SS:[ESP+22], CL         ; |
    0040440E  |.  C64424 23 64  MOV     BYTE PTR SS:[ESP+23], 64         ; |
    00404413  |.  C64424 24 61  MOV     BYTE PTR SS:[ESP+24], 61         ; |
    00404418  |.  C64424 25 74  MOV     BYTE PTR SS:[ESP+25], 74         ; |
    0040441D  |.  885424 26     MOV     BYTE PTR SS:[ESP+26], DL         ; |
    00404421  |.  FF15 E4904000 CALL    NEAR DWORD PTR DS:[<&msvcrt.fope>; \fopen
    00404427  |.  8BD8          MOV     EBX, EAX
    00404429  |.  83C4 08       ADD     ESP, 8
    0040442C  |.  85DB          TEST    EBX, EBX



    2.文件流内存地址:77C2FCE0
    向地址:004123F4 写入文件内容
    对地址:004123FF 写入字节0结束符,提示将读取 F4->FE,这0xB个字符。
    00404475  |.  C605 FF234100>MOV     BYTE PTR DS:[4123FF], 0            


      读文件:
    [Asm] 纯文本查看 复制代码
    0040442E  |.  74 1C         JE      SHORT KG_Unpac.0040444C
    00404430  |.  53            PUSH    EBX                              ; /stream = 00050234
    00404431  |.  6A 0A         PUSH    0A                               ; |n = A (10.)
    00404433  |.  6A 01         PUSH    1                                ; |size = 1
    00404435  |.  68 F4234100   PUSH    KG_Unpac.004123F4                ; |ptr = KG_Unpac.004123F4
    0040443A  |.  FF15 EC904000 CALL    NEAR DWORD PTR DS:[<&msvcrt.frea>; \fread
    00404440  |.  53            PUSH    EBX                              ; /stream = 00050234
    00404441  |.  FF15 F0904000 CALL    NEAR DWORD PTR DS:[<&msvcrt.fclo>; \fclose



      否则随机生成0xB字节数据:
    [Asm] 纯文本查看 复制代码
    00404447  |.  83C4 14       ADD     ESP, 14
    0040444A  |.  EB 1A         JMP     SHORT KG_Unpac.00404466
    0040444C  |>  33DB          XOR     EBX, EBX
    0040444E  |>  FF15 00914000 /CALL    NEAR DWORD PTR DS:[<&msvcrt.ran>; [rand
    00404454  |.  02C0          |ADD     AL, AL
    00404456  |.  B1 01         |MOV     CL, 1
    00404458  |.  2AC8          |SUB     CL, AL
    0040445A  |.  888B F4234100 |MOV     BYTE PTR DS:[EBX+4123F4], CL
    00404460  |.  43            |INC     EBX
    00404461  |.  83FB 0B       |CMP     EBX, 0B
    00404464  |.^ 72 E8         \JB      SHORT KG_Unpac.0040444E



    3.获取当前文件的完整路径,存放在地址:12FAF0
    kernel32.GetModuleFileNameA
    [Asm] 纯文本查看 复制代码
    00404466  |>  8D9424 580100>LEA     EDX, DWORD PTR SS:[ESP+158]
    0040446D  |.  68 04010000   PUSH    104                              ; /BufSize = 
    00404472  |.  52            PUSH    EDX                              ; |PathBuffer = NULL
    00404473  |.  6A 00         PUSH    0                                ; |hModule = NULL
    00404475  |.  C605 FF234100>MOV     BYTE PTR DS:[4123FF], 0          ; |
    0040447C  |.  FF15 78904000 CALL    NEAR DWORD PTR DS:[<&KERNEL32.Ge>; \GetModuleFileNameA



    4.打开当前文件,执行READ操作
    kernel32.CreateFileA
    [Asm] 纯文本查看 复制代码
    00404482  |.  6A 00         PUSH    0                                ; /hTemplateFile = NULL
    00404484  |.  6A 00         PUSH    0                                ; |Attributes = 0
    00404486  |.  6A 03         PUSH    3                                ; |Mode = OPEN_EXISTING
    00404488  |.  6A 00         PUSH    0                                ; |pSecurity = NULL
    0040448A  |.  6A 01         PUSH    1                                ; |ShareMode = FILE_SHARE_READ
    0040448C  |.  8D8424 6C0100>LEA     EAX, DWORD PTR SS:[ESP+16C]      ; |
    00404493  |.  6A 08         PUSH    8                                ; |Access = 8
    00404495  |.  50            PUSH    EAX                              ; |FileName = 
    00404496  |.  FF15 74904000 CALL    NEAR DWORD PTR DS:[<&KERNEL32.Cr>; \CreateFileA
    0040449C  |.  8BD8          MOV     EBX, EAX
    0040449E  |.  83FB FF       CMP     EBX, -1
    004044A1  |.  74 3C         JE      SHORT KG_Unpac.004044DF



    5.获取文件大小,以字节为单位 294912(0x48000)
    kernel32.GetFileSize
    004044A3  |.  6A 00         PUSH    0                                ; /pFileSizeHigh = NULL
    004044A5  |.  53            PUSH    EBX                              ; |hFile =
    004044A6  |.  FF15 70904000 CALL    NEAR DWORD PTR DS:[<&KERNEL32.Ge>; \GetFileSize


    6.向地址: 0012FAF0 写入当前文件大小,且十进制表示,如:ASCII "294912"
    USER32.wsprintfA
    [Asm] 纯文本查看 复制代码
    004044AC  |.  50            PUSH    EAX                              ; /<%d> = 
    004044AD  |.  8D8C24 5C0100>LEA     ECX, DWORD PTR SS:[ESP+15C]      ; |
    004044B4  |.  68 641E4100   PUSH    KG_Unpac.00411E64                ; |%d
    004044B9  |.  51            PUSH    ECX                              ; |s = 
    004044BA  |.  894424 30     MOV     DWORD PTR SS:[ESP+30], EAX       ; |
    004044BE  |.  FF15 9C914000 CALL    NEAR DWORD PTR DS:[<&USER32.wspr>; \wsprintfA
    004044C4  |.  83C4 0C       ADD     ESP, 0C
    004044C7  |.  53            PUSH    EBX                              ; /hObject = 00050234
    004044C8  |.  FF15 6C904000 CALL    NEAR DWORD PTR DS:[<&KERNEL32.Cl>; \CloseHandle



    7.这里比较文件大小,是否小于等于 0x11170,校验是否被脱壳,并对全局变量值[40A010]修改,这里很关键,关系到后面算法分析:
    004044CE  |.  817C24 24 701>CMP     DWORD PTR SS:[ESP+24], 11170     ;  比较文件大小断点
    004044D6  |.  77 07         JA      SHORT KG_Unpac.004044DF
    004044D8  |.  C605 10A04000>MOV     BYTE PTR DS:[40A010], 7E


    *.为了我们伟大的胜利,修改一下吧。
    004044CE      817C24 24 701>CMP     DWORD PTR SS:[ESP+24], 11170
    004044D6      76 07         JBE     SHORT KG_Unpac.004044DF
    修改成大于跳转,即  JA(76改77),并另存为新文件:KG_Unpack_Patch.exe




    分析KeygenMe2014#001——山重水复疑无路,柳暗花明又一村 【下篇】 算法注册机源码




    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?加入我们

    x

    评分

    参与人数 3威望 +12 飘云币 +16 收起 理由
    一梦千年缘 + 4 很给力!
    crackvip + 8 + 8 膜拜,师付收了我吧
    heizihui + 8 很给力!

    查看全部评分

    PYG19周年生日快乐!
  • TA的每日心情
    慵懒
    2015-8-14 00:08
  • 签到天数: 25 天

    [LV.4]偶尔看看III

    发表于 2014-9-11 21:59:09 | 显示全部楼层
    沙发。。。终于坐到了
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2022-1-20 17:13
  • 签到天数: 291 天

    [LV.8]以坛为家I

    发表于 2015-6-7 16:21:49 | 显示全部楼层
    这篇分析分析的很详细透彻,学习了
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

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