首页
社区
课程
招聘
[原创]ty123的实用crackme- CPN Augur 破解详情
发表于: 2007-2-8 16:07 7321

[原创]ty123的实用crackme- CPN Augur 破解详情

2007-2-8 16:07
7321

【文章标题】: ty123的实用crackme- CPN Augur (新手飘过~~) 破解详情
【文章作者】: atomy
【作者邮箱】: http://2lin.net
--------------------------------------------------------------------------------
【详细过程】
  偶还是一个新手. 看到一个新手飘过的字样 不由的心痒痒想试一试.
  这个CrackMe 分析花了我好几天的时间
  第一次只破解了前四位 后来不甘心 最终被偶破解下来了.使我学到了不少东西 下面讲一下分析过程
  
  作者使用的软件防爆破方法真的不错. 以后可以多学习一下了
  这个CrackMe里面加了很多防爆破
  举个例
  一般大家爆破使用的方法就是修改爆破点. 但是作者使用内存动态解密的方法
  使用爆破点的数据进行加密 如果爆破点的数据改了 那解密出来的数据就是错误的 造成执行程序错误
  
  这种方法对OD的中断也有效 如果在爆破点设置断点 同样会发生异常
  
  好了 知道了这些 调试的时候只要不对爆破点下断点就可以了
  
  
  首先 试练码
  
  USER:ABCDEFG
  SN: 123456
  
  点击注册 提示重启验证
  
  重启 输入命令 bp RegQueryValueExA 运行
  
  被断后 一直按ALT + F9 或F9 直到进入 用户代码
  
  一直跟到下面代码
  
  004013BC    6A 00           push    0
  004013BE    8F45 88         pop     dword ptr [ebp-78]
  004013C1    68 E4304000     push    004030E4                                ; ASCII "BOY"
  004013C6    68 C3304000     push    004030C3                                ; ASCII "Software\CPN Augur\Licence\"
  004013CB    8D45 88         lea     eax, dword ptr [ebp-78]
  004013CE    50              push    eax
  004013CF    E8 8C050000     call    00401960
  004013D4    8B4D 88         mov     ecx, dword ptr [ebp-78]
  004013D7    85C9            test    ecx, ecx
  004013D9    0F84 8E020000   je      0040166D
  004013DF    68 13304000     push    00403013
  004013E4    68 AA204000     push    004020AA                                ; ASCII "Serial Number"
  004013E9    68 C3304000     push    004030C3                                ; ASCII "Software\CPN Augur\Licence\"
  004013EE    8D45 DB         lea     eax, dword ptr [ebp-25]
  004013F1    50              push    eax
  004013F2    E8 BF040000     call    004018B6
  004013F7    68 DF304000     push    004030DF                                ; ASCII "PLAY"
  004013FC    68 C3304000     push    004030C3                                ; ASCII "Software\CPN Augur\Licence\"
  00401401    8D45 8C         lea     eax, dword ptr [ebp-74]
  00401404    50              push    eax
  00401405    E8 56050000     call    00401960
  0040140A    68 13304000     push    00403013
  0040140F    68 A0204000     push    004020A0                                ; ASCII "User Name"
  00401414    68 A6304000     push    004030A6                                ; ASCII "Software\CPN Augur\User\"
  00401419    8D45 9B         lea     eax, dword ptr [ebp-65]
  0040141C    50              push    eax
  0040141D    E8 94040000     call    004018B6
  
  竟然有读四个值  PLAY BOY UserName SerialNumber
  继续往下看
  
  
  00401422    6A 00           push    0
  00401424    6A 00           push    0
  00401426    6A 00           push    0
  00401428    6A 00           push    0
  0040142A    8D45 FC         lea     eax, dword ptr [ebp-4]
  0040142D    50              push    eax
  0040142E    6A 00           push    0
  00401430    6A 00           push    0
  00401432    68 EE304000     push    004030EE                                ; ASCII "c:\"
  00401437    E8 90060000     call    <jmp.&kernel32.GetVolumeInformationA>   ;取磁盘序号
  0040143C    FF75 9B         push    dword ptr [ebp-65]
  0040143F    58              pop     eax                                     ; 用户名 前四位
  00401440    C1C0 08         rol     eax, 8                                  ; 循环左移8位
  00401443    3345 FC         xor     eax, dword ptr [ebp-4]                  ; 再异或C盘序列号
  00401446    2E:3305 7514400>xor     eax, dword ptr cs:[401475]              ; 再异或850F073A
  0040144D    8945 90         mov     dword ptr [ebp-70], eax
  00401450    8D75 90         lea     esi, dword ptr [ebp-70]
  00401453    8B45 DB         mov     eax, dword ptr [ebp-25]                 ; 序列号
  00401456    0FC8            bswap   eax                                     ; 交换顺序
  00401458    C1C8 08         ror     eax, 8                                  ; 循环右移8位
  0040145B    8945 DB         mov     dword ptr [ebp-25], eax
  0040145E    8D7D DB         lea     edi, dword ptr [ebp-25]
  00401461    6A 04           push    4
  00401463    59              pop     ecx
  00401464    6A 10           push    10
  00401466    5A              pop     edx
  00401467    8D1D 00304000   lea     ebx, dword ptr [403000]                 ; 字符 CodedByTy123-China
  0040146D    33C0            xor     eax, eax
  0040146F    AC              lods    byte ptr [esi]                          ; 取用户名算出来的字符第一个字节到al
  00401470    F6F2            div     dl                                      ; 将值 / 10
  00401472    86C4            xchg    ah, al                                  ; 交换 ah, al
  00401474    D7              xlat    byte ptr [ebx+al]                       ; 从字符 CodedByTy123-China 中取值
  00401475    3A07            cmp     al, byte ptr [edi]                      ; 对比
  00401477    0F85 F0010000   jnz     0040166D                                ; 不对 出错
  0040147D    47              inc     edi
  0040147E  ^ E2 ED           loopd   short 0040146D
  
  上面代码可以看出 这是对第一组序列号四个字符对比
  可以利用反推方法得出第一组序号
  关键在第二次对比 这个东东偶分析了好久的时间  下面看第二个对比
  
  
  00401498    8B45 88         mov     eax, dword ptr [ebp-78]                 ; BOY
  0040149B    2E:3305 7514400>xor     eax, dword ptr cs:[401475]              ; 异或 850F073A
  004014A2    3345 8C         xor     eax, dword ptr [ebp-74]                 ; 异或 PLAY
  004014A5    F7D0            not     eax                                     ; 取反
  004014A7    35 CA158B7D     xor     eax, 7D8B15CA                           ; 异或 7D8B15CA
  004014AC    0F85 BB010000   jnz     0040166D                                ; !=0 Over
  
  上面有两个数 一个PLAY BOY 可是不知道这两个数字是怎么来的. 
  这就需要跟踪到点击注册确定的时候做了些什么事情了.
  
  用上面的方法 下断 bp RegCreateKeyExA 按 ALT + F9 直到返回到用户代码 一直跟到下面代码
  
  00401072    50              push    eax
  00401073    68 D5070000     push    7D5
  00401078    FF75 08         push    dword ptr [ebp+8]
  0040107B    E8 DA090000     call    <jmp.&user32.GetDlgItemTextA>
  00401080    D1E0            shl     eax, 1                                  ; 序列号个数左移1位
  00401082    8945 C4         mov     dword ptr [ebp-3C], eax                 ; 放入内存
  00401085    DB45 C4         fild    dword ptr [ebp-3C]                      ; 放入st(0)
  00401088    D9EB            fldpi                                           ; 放入st(1) pi
  0040108A    DEC9            fmulp   st(1), st                               ; st(1) * st(0)
  0040108C    D95D CC         fstp    dword ptr [ebp-34]                      ; 放入变量 
  0040108F    8D75 D4         lea     esi, dword ptr [ebp-2C]                 ; 跳过前四位 取序列号后面的字符
  00401092    8D7D C8         lea     edi, dword ptr [ebp-38]
  00401095    6A 03           push    3
  00401097    59              pop     ecx                                     ; 3次
  00401098    A4              movs    byte ptr es:[edi], byte ptr [esi]
  00401099    83C6 04         add     esi, 4                                  ; 间隔4位字符取3个字符作序列号
  0040109C  ^ E2 FA           loopd   short 00401098
  0040109E    B8 47434644     mov     eax, 44464347
  004010A3    3145 C8         xor     dword ptr [ebp-38], eax                 ; 将挑出来的字符异或44464347
  004010A6    68 E8304000     push    004030E8                                ; ASCII "E-Mag"
  004010AB    68 C3304000     push    004030C3                                ; ASCII "Software\CPN Augur\Licence\"
  004010B0    68 6B304000     push    0040306B
  004010B5    E8 A6080000     call    00401960                                ; 获取 E-Mag 的值
  004010BA    60              pushad
  004010BB    8D05 D7104000   lea     eax, dword ptr [4010D7]                 ;
  004010C1    B9 2C000000     mov     ecx, 2C
  004010C6    8B15 06114000   mov     edx, dword ptr [401106]
  004010CC    3110            xor     dword ptr [eax], edx                    ; 动态解密
  004010CE    83C0 04         add     eax, 4
  004010D1    83E9 04         sub     ecx, 4
  004010D4  ^ 75 F6           jnz     short 004010CC
  
  上面代码可以看出 一花算出了两个值 
  一个是 将 SN shl 1 * pi  放入 ebp-34
  第二个是 将 序列号隔四位取一个字符 然后 xor 44464347H 放入 ebp-38 再动态解密一段代码 看看解出来的代码是什么样的
  
  004010D7    A1 6B304000     mov     eax, dword ptr [40306B]                 ; E-Mag 的值
  004010DC    85C0            test    eax, eax                                ; 为空跳走
  004010DE    74 32           je      short 00401112
  004010E0    35 71FF2CD7     xor     eax, D72CFF71                           ; EAX xor D72CFF71
  004010E5    C1E8 04         shr     eax, 4                                  ; 右移4位
  004010E8    8B35 06114000   mov     esi, dword ptr [401106]                 ; 4376073C
  004010EE    3335 03114000   xor     esi, dword ptr [401103]                 ; 3CE08A40
  004010F4    3335 0D114000   xor     esi, dword ptr [40110D]                 ; EBCC7531
  004010FA    3335 0A114000   xor     esi, dword ptr [40110A]                 ; 31C85531
  00401100    90              nop
  00401101    90              nop
  00401102    90              nop
  00401103    40              inc     eax                                     ; EAX ++
  00401104    8AE0            mov     ah, al
  00401106    3C 07           cmp     al, 7                                   ;  AL > 7
  00401108    76 43           jbe     short 0040114D                          ;  转移
  0040110A    3155 C8         xor     dword ptr [ebp-38], edx                 ;  EDX = 7C95ED54
  0040110D    3175 CC         xor     dword ptr [ebp-34], esi                 ;  ESI = xor 31C85531 xir EBCC7531 xor 3CE08A40 xor 4376073C
  00401110    EB 3B           jmp     short 0040114D
  
  00401113    8D05 2F114000   lea     eax, dword ptr [40112F]
  00401119    B9 1C000000     mov     ecx, 1C
  0040111E    8B15 03114000   mov     edx, dword ptr [401103]
  00401124    3110            xor     dword ptr [eax], edx                    ;防爆破 解密
  00401126    83C0 04         add     eax, 4
  00401129    83E9 04         sub     ecx, 4
  0040112C  ^ 75 F6           jnz     short 00401124
  0040112E    61              popad
  0040112F    40              inc     eax                                     ;
  00401130    8AE0            mov     ah, al                                  ;
  00401132    C1E0 04         shl     eax, 4                                  ; eax = 1010H
  00401135    2E:3305 0311400>xor     eax, dword ptr cs:[401103]              ; 3CE08A40
  0040113C    2E:3305 0D11400>xor     eax, dword ptr cs:[40110D]              ; EBCC7531
  00401143    A3 6B304000     mov     dword ptr [40306B], eax                 ; E-mag 
  
  这段代码大概意思就是将 E-Mag的值 进行一些计算 最后再看 al的值是否大于 7 如果大于就将
  上面计算的两个数 分别 xor 0A592AD7CH 和 7C95ED54H
  E-Mag的初始值是 0D72CEF61H 继续跟踪代码
  
  00401151    8D05 69114000   lea     eax, dword ptr [401169]
  00401157    B9 14000000     mov     ecx, 14
  0040115C    8BD6            mov     edx, esi                                ;
  0040115E    3110            xor     dword ptr [eax], edx
  00401160    83C0 04         add     eax, 4
  00401163    83E9 04         sub     ecx, 4
  00401166  ^ 75 F6           jnz     short 0040115E
  00401168    61              popad
  00401169    2E:3305 0311400>xor     eax, dword ptr cs:[401103]              ; 3CE08A40
  00401170    2E:3305 0D11400>xor     eax, dword ptr cs:[40110D]              ; EBCC7531
  00401177    A3 6B304000     mov     dword ptr [40306B], eax                 ; 重新给E-Mag 定值
  0040117C    90              nop
  0040117D    68 E8304000     push    004030E8                                ; ASCII "E-Mag"
  00401182    68 C3304000     push    004030C3                                ; ASCII "Software\CPN Augur\Licence\"
  00401187    68 6B304000     push    0040306B
  0040118C    E8 83070000     call    00401914                                ; 写入E-Bag
  00401191    6A 18           push    18
  00401193    8D45 E8         lea     eax, dword ptr [ebp-18]
  00401196    50              push    eax
  00401197    68 D3070000     push    7D3
  0040119C    FF75 08         push    dword ptr [ebp+8]
  0040119F    E8 B6080000     call    <jmp.&user32.GetDlgItemTextA>
  004011A4    83F8 04         cmp     eax, 4
  004011A7    72 05           jb      short 004011AE
  004011A9    83F8 10         cmp     eax, 10
  004011AC    76 02           jbe     short 004011B0
  004011AE    EB 50           jmp     short 00401200
  004011B0    6A 18           push    18
  004011B2    68 A0204000     push    004020A0                                ; ASCII "User Name"
  004011B7    68 A6304000     push    004030A6                                ; ASCII "Software\CPN Augur\User\"
  004011BC    8D45 E8         lea     eax, dword ptr [ebp-18]
  004011BF    50              push    eax
  004011C0    E8 A4060000     call    00401869
  004011C5    6A 18           push    18
  004011C7    68 AA204000     push    004020AA                                ; ASCII "Serial Number"
  004011CC    68 C3304000     push    004030C3                                ; ASCII "Software\CPN Augur\Licence\"
  004011D1    8D45 D0         lea     eax, dword ptr [ebp-30]
  004011D4    50              push    eax
  004011D5    E8 8F060000     call    00401869
  004011DA    68 DF304000     push    004030DF                                ; ASCII "PLAY"
  004011DF    68 C3304000     push    004030C3                                ; ASCII "Software\CPN Augur\Licence\"
  004011E4    8D45 CC         lea     eax, dword ptr [ebp-34]
  004011E7    50              push    eax
  004011E8    E8 27070000     call    00401914
  004011ED    68 E4304000     push    004030E4                                ; ASCII "BOY"
  004011F2    68 C3304000     push    004030C3                                ; ASCII "Software\CPN Augur\Licence\"
  004011F7    8D45 C8         lea     eax, dword ptr [ebp-38]
  004011FA    50              push    eax
  004011FB    E8 14070000     call    00401914
  
  可以看出 PLAY的值 = Count shl 1 * pi
  而 Boy 的值 就是序列号 每隔四个字符的值 再 xor 44464347H
  
  如果 E-Mag 算出的值 <= 7 还会 将这两个数字 再 xor 0A592AD7CH 和 7C95ED54H
  也就是说 第一次注册 是不会  xor 0A592AD7CH 和 7C95ED54H  的 所以调试的时候 每次都把 E-Mag这个键值删掉再重新注册
  
  而且 PLAY 的值 等于  Count shl 1 * pi  那么这是一个常数 现在的问题是怎么知道序列号是多少位的呢.
  利用反推法.
  
  首先反推第二个对比
  
  mov eax, 7D8B15CAH
  not eax                      ;先将 7D8B15CAH 取反 得到 8274EA35H
  xor eax, PLAY                ;再 xor PLAY
  xor eax, 850F073AH           ;得到BOY的值
  
  BOY 是 三个字符串 xor 44464347H 这么说 要得到正确的BOY 应该 第一个数字应该得到 44******H 这种数字才可以得到真正的 BOY 也就是三个字符
  最后一个 xor 的数字是 850F073AH 那么 就是说 PLAY 的值 应该是 850F073AH xor 44******H = 43******H
  
  于是写了下面一个过程 先假设 注册码为 16 位
  
  .data?       
     p        dd ?
         
  .CODE
  
  START:
  
    mov eax, 0FH
    shl eax, 1
     
    R:
     shr eax, 1
     inc eax
     shl eax, 1
     mov

, eax
     fild DWORD PTR


     fldpi
     fmulp st(1), st
     fstp DWORD PTR

   
     and DWORD PTR

,0FF000000H
     cmp DWORD PTR

,43000000H
     jnz R
     shr eax, 1
  
  这样 得出 eax 的值 = 21 就是 注册码的个数 然后再反推 BOY的值 为 /\>
  哈 其实这是错误的 真正的注册是23位的 追到后面看就知道了 但是这个数字可以通过第二关
  
  继续跟踪第三关
  
  004014B2    8D75 E0         lea     esi, dword ptr [ebp-20]                 ; 继续
  004014B5    8B06            mov     eax, dword ptr [esi]                    ; 取四位放入eax
  004014B7    3345 DB         xor     eax, dword ptr [ebp-25]                 ; 和序列号生成的前四位数异或
  004014BA    8906            mov     dword ptr [esi], eax
  004014BC    33C0            xor     eax, eax
  004014BE    33D2            xor     edx, edx
  004014C0    6A 04           push    4
  004014C2    59              pop     ecx
  004014C3    AC              lods    byte ptr [esi]                          ; 放入al
  004014C4    3203            xor     al, byte ptr [ebx]                      ; xor Code
  004014C6    03D0            add     edx, eax                                ; edx += eax
  004014C8    43              inc     ebx
  004014C9  ^ E2 F8           loopd   short 004014C3
  004014CB    52              push    edx                                     ; edx
  004014CC    8D75 9B         lea     esi, dword ptr [ebp-65]                 ; esi = 用户名
  004014CF    33C0            xor     eax, eax
  004014D1    33D2            xor     edx, edx
  004014D3    6A 04           push    4
  004014D5    59              pop     ecx
  004014D6    AC              lods    byte ptr [esi]
  004014D7    3203            xor     al, byte ptr [ebx]                      ; xor dByT
  004014D9    03D0            add     edx, eax                                ; edx += eax
  004014DB    43              inc     ebx
  004014DC  ^ E2 F8           loopd   short 004014D6
  004014DE    87CA            xchg    edx, ecx
  004014E0    5A              pop     edx
  004014E1    33CA            xor     ecx, edx                                ; edx1 != edx2 序列号不对 edx 要用到后面解压
  004014E3    0F85 84010000   jnz     0040166D
  
  这个算法把偶给搞了好久才明白
  其实就是 将 用户名前四位 xor 'dByT' 然后 再 xor 'Code' 就是第二组序列号了
  继续往下看
  
  00401506    A1 75144000     mov     eax, dword ptr [401475]                 ; 内存指定住不能下断点
  0040150B    3305 E1144000   xor     eax, dword ptr [4014E1]
  00401511    3305 AC144000   xor     eax, dword ptr [4014AC]
  00401517    8BF8            mov     edi, eax
  00401519    8945 90         mov     dword ptr [ebp-70], eax
  0040151C    60              pushad
  0040151D    8D05 35154000   lea     eax, dword ptr [401535]
  00401523    B9 34000000     mov     ecx, 34
  00401528    8BD7            mov     edx, edi
  0040152A    3110            xor     dword ptr [eax], edx
  0040152C    83C0 04         add     eax, 4
  0040152F    83E9 04         sub     ecx, 4
  00401532  ^ 75 F6           jnz     short 0040152A
  00401534    61              popad
  00401535    8D75 E5         lea     esi, dword ptr [ebp-1B]                 ; 继续计算第三组
  00401538    8D1D EB144000   lea     ebx, dword ptr [4014EB]                 ; nothing special, right? :)
  0040153E    6A 04           push    4
  00401540    59              pop     ecx
  00401541    33C0            xor     eax, eax
  00401543    AC              lods    byte ptr [esi]
  00401544    3203            xor     al, byte ptr [ebx]
  00401546    C1C0 08         rol     eax, 8
  00401549    43              inc     ebx
  0040154A  ^ E2 F7           loopd   short 00401543
  0040154C    50              push    eax                                     ; 保存Eax
  0040154D    8D75 9B         lea     esi, dword ptr [ebp-65]                 ; 用户名
  00401550    6A 04           push    4
  00401552    59              pop     ecx
  00401553    03D9            add     ebx, ecx                                ; special, right? :)
  00401555    33C0            xor     eax, eax
  00401557    AC              lods    byte ptr [esi]
  00401558    3203            xor     al, byte ptr [ebx]
  0040155A    C1C0 08         rol     eax, 8
  0040155D    43              inc     ebx
  0040155E  ^ E2 F7           loopd   short 00401557
  00401560    0FC8            bswap   eax                                     ; 交换 eax
  00401562    C1C8 08         ror     eax, 8                                  ; 循环右移
  00401565    91              xchg    eax, ecx
  00401566    58              pop     eax
  00401567    33C8            xor     ecx, eax                                ; 计算出来的值必须相等
  00401569    0F85 FE000000   jnz     0040166D
  
  
  第三组的算法也很是简单 不过也把偶的头搞的晕晕的.
  试了N次才得到这样一个算法
  
  mov eax, 'spec'
  xor eax, DWORD PTR [sUserName]   
  rol eax, 8H
  bswap eax
  xor eax, 'noth'
  
  eax 就是 第三组序列号了
  走到这里 可以说真是费了偶的九牛二虎之力 不容易呀..  
  继续看最后一组吧.
  
  004015A7    8D75 FC         lea     esi, dword ptr [ebp-4]                  ; 硬盘序号
  004015AA    6A 04           push    4
  004015AC    59              pop     ecx
  004015AD    33C0            xor     eax, eax
  004015AF    33D2            xor     edx, edx
  004015B1    AC              lods    byte ptr [esi]
  004015B2    03D0            add     edx, eax                                ; 四个字节的和
  004015B4  ^ E2 FB           loopd   short 004015B1
  004015B6    8955 90         mov     dword ptr [ebp-70], edx
  004015B9    DB45 90         fild    dword ptr [ebp-70]
  004015BC    8D75 9B         lea     esi, dword ptr [ebp-65]                 ; 用户名
  004015BF    8D45 9B         lea     eax, dword ptr [ebp-65]
  004015C2    50              push    eax
  004015C3    E8 78050000     call    00401B40                                ; 取用户名的长度
  004015C8    91              xchg    eax, ecx
  004015C9    33D2            xor     edx, edx
  004015CB    AC              lods    byte ptr [esi]
  004015CC    03D0            add     edx, eax                                ; 用户名 ASCII 和
  004015CE  ^ E2 FB           loopd   short 004015CB
  004015D0    0FAFD2          imul    edx, edx                                ; edx * edx
  004015D3    8955 90         mov     dword ptr [ebp-70], edx
  004015D6    DB45 90         fild    dword ptr [ebp-70]
  004015D9    DEC9            fmulp   st(1), st                               ;
  004015DB    D9EB            fldpi
  004015DD    DEC9            fmulp   st(1), st                               ; * pi
  004015DF    D9FC            frndint                                         ; 四舍五入
  004015E1    8D45 EA         lea     eax, dword ptr [ebp-16]                 ; 最后的序列号
  004015E4    50              push    eax
  004015E5    E8 FA040000     call    00401AE4                                ; 哈哈 和Crackme 5的算法一样 将字符串转换成数值
  004015EA    3345 88         xor     eax, dword ptr [ebp-78]                 ; xor boy 的值
  004015ED    8945 90         mov     dword ptr [ebp-70], eax
  004015F0    DB45 90         fild    dword ptr [ebp-70]
  004015F3    DB45 E5         fild    dword ptr [ebp-1B]                      ; 第三组序列号
  004015F6    DEE9            fsubp   st(1), st                               ; [ebp-70] - 第三组序列号的值
  004015F8    D8D9            fcomp   st(1)                                   ; 比较
  004015FA    9B              wait
  004015FB    DFE0            fstsw   ax
  004015FD    9E              sahf                                            ; ah 是否为 0
  004015FE    75 6D           jnz     short 0040166D                          ; 最后一次对比
  
  由于上次分析过 Crackme 5 发现这里竟然和那个一样 于是就猜测到最后一组的序列号应该是 8位
  所以注册码总数 = 23
  算法是根据用户名计算出一个值 然后再 将最后一组的值计算出一个数字 相等 就ok
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
   
  
  
--------------------------------------------------------------------------------
【经验总结】
  破解分析完后 感受颇深 使我更坚信,只要你有足够的耐心 没有什么事能难到你. 当然前提是你有充足的时间
  下面是注册机代码 汇编写的 偶汇编不太好 大家将就着看吧.
  如果有什么错误 请大家指正~ 谢谢!
  
  .486
  .model flat, stdcall
  option casemap :none
  
  include windows.inc
  include user32.inc
  include kernel32.inc
  include masm32.inc
  include gdi32.inc
  include advapi32.inc
  
  includelib gdi32.lib
  includelib user32.lib
  includelib kernel32.lib
  includelib masm32.lib
  includelib advapi32.lib
  include macro.asm
  .data
          sMsg                     db "请输入用户名:",0
          sDriver       db "C:\", 0
          sFormat       db "序列号是:%s",0
          sFormat1      db "%08X",0
          sKey          db "CodedByTy123-China", 0
          sKey1         db "nothing special, right? :)", 0
          sKEYPath      db "SOFTWARE\CPN Augur\Licence\", 0
          dBoy          dd 446B6E6AH
  
  .data?
          sUserName           db MAX_PATH dup(?)
          sRegKey        db MAX_PATH dup(?)
          sShowKey       db MAX_PATH dup(?)
          dSerial        dd ?       
          dPlay          dd ?               
          p              dd ?               
         
  .CODE
  START:
     ;删除注册表的键
     invoke RegDeleteKey, HKEY_LOCAL_MACHINE, addr sKEYPath
     
  
          invoke StdOut,offset sMsg       
          invoke StdIn, addr sUserName, sizeof sUserName       
          ;获取硬盘序列号
          invoke GetVolumeInformation, addr sDriver, 0, 0, addr dSerial, 0, 0, 0, 0
         
          ;计算第一组序列号
          mov eax, DWORD PTR [sUserName]
          rol eax, 8 ;
          xor eax, DWORD PTR [dSerial]    ; eax xor 硬盘序列号
          xor eax, 850F073AH
          mov

, eax
          lea esi,


         
          mov ecx, 4H
          mov edx, 10H
          lea ebx, [sKey]       
          lea edi,


         
   R:  
     xor eax, eax
          lods BYTE PTR [esi]
          div dl
     xchg ah, al
          xlat
          stosb
     loopd R
     
     mov eax, DWORD PTR


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 7
支持
分享
最新回复 (12)
雪    币: 226
活跃值: (30)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
2
这个注册机只能算使用数字的用户名。。 字母的用户名
好像有些问题
关键在这里 
  004015EA    3345 88         xor     eax, dword ptr [ebp-78]                 ; xor boy 的值
  004015ED    8945 90         mov     dword ptr [ebp-70], eax
  004015F0    DB45 90         fild    dword ptr [ebp-70]

这里用的是 dword
如果使用我的这种算法 

faddp st(1),st
fistp DWORD PTR


mov eax, DWORD PTR



出来的数字再压进去 就会 是一个负数

这里不太明白 请老神树指教~

2007-2-8 19:03
0
雪    币: 297
活跃值: (21)
能力值: ( LV9,RANK:330 )
在线值:
发帖
回帖
粉丝
3
还有就是算出的注册码的第二组很多是不可输入和显示的字符。有了注册码也输不进去啊
2007-2-8 19:14
0
雪    币: 461
活跃值: (93)
能力值: ( LV9,RANK:1170 )
在线值:
发帖
回帖
粉丝
4
楼主牛人啊,我搞了好久都没弄出来!支持!
2007-2-8 19:24
0
雪    币: 226
活跃值: (30)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
5
最初由 dewar 发布
还有就是算出的注册码的第二组很多是不可输入和显示的字符。有了注册码也输不进去啊


是有可能。 第二组的算法 不只一种 

可能是我那算法不太好 
2007-2-8 19:32
0
雪    币: 297
活跃值: (21)
能力值: ( LV9,RANK:330 )
在线值:
发帖
回帖
粉丝
6
理论上第二组注册码有无穷种可能,可以手工凑出一些能显示和输入的字符来
作者的防爆做得很好,爆破应该是不可能的。
写注册机也很不好写,特别是第2部分,第4部分也有问题,如楼主所说转为浮点数时如果生成负数大概就没注册码了
2007-2-8 19:53
0
雪    币: 242
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
首先祝贺流动的情感关注并破解我的crackme 4!再替新手感谢你写出这么详细的的好文章。文章我会找时间细细阅读...

关于各位大侠提到的问题,我抽时间逐一解答。

正在写crackme7,还是keyfile的,until next time...
2007-2-9 08:50
0
雪    币: 242
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
首先再次祝贺流动的情感大侠将Crackme4成功破解!对他辛苦写出破解教程表示感谢!

一般大家爆破使用的方法就是修改爆破点,但是作者使用内存动态解密的方法,使用爆破点的数据进行加密。如果爆破点的数据改了,那解密出来的数据就是错误的,造成执行程序错误。


是的,我用了一点SMC (Self-modifying code)技术。SMC动态解码,可以对抗一些静态分析工具,对抗OllyDBG等动态分析工具效果就不明显了。我们都是爆破手出身的,但总停留在改JNZ、JZ、NOP阶段也真的没有什么趣味,于是我在一般爆破手关注的对方放了监测点,迫使他们得提升自己,呵呵。

这种方法对OD的中断也有效 如果在爆破点设置断点 同样会发生异常


想想为什么会这样呢?对于像OllyDBG这样的Ring3级调试器,设置断点就是在下断处放一个INT3 (0CCh),那么监测点的数据将发生变化,导致解码异常。

一个是 将 SN shl 1 * pi 放入 ebp-34; 第二个是 将 序列号隔四位取一个字符 然后 xor 44464347H 放入 ebp-38 再动态解密一段代码


这里是在检测注册码的长度和规格。以注册码的长度为半径,圆的周长就是play的键值;顺序取注册码5、10、15位的三个分隔符“-”,然后再XOR “DFCG”就是boy的键值。原本想的是这里有问题,就不让过第二关。流动的情感大侠测试21位注册码也可以通过,这是后话。

这段代码大概意思就是将 E-Mag的值 进行一些计算 最后再看 al的值是否大于 7 如果不大于就将上面计算的两个数 分别 xor 0A592AD7CH 和 7C95ED54H


跟过这个程序的朋友知道,play和boy键值会参与注册码的计算和校验。E-Mag键值用于检测注册次数,如果输入注册信息超过8次,将play和boy键值彻底搞乱。

如果 E-Mag 算出的值 <= 7 还会 将这两个数字 再 xor 0A592AD7CH 和 7C95ED54H 也就是说 第一次注册是不会 xor 0A592AD7CH 和 7C95ED54H 的 所以调试的时候 每次都把 E-Mag这个键值删掉再重新注册


这里说的有问题,应该是大于7时,将会....。每次删E-Mag键值方法是可行的,写程序时曾想每次启动程序时锁闭注册表,后来想那样有些霸道,就放弃了。但不意味者软件作者像我这样心慈,记得3、4年前跟过一个程序,无意中带过一个CALL,结果人家把我的注册表全删除了,到现在每到一个不熟悉的call,先F7进去看看,我是一朝被蛇咬,十年怕井绳啊,呵呵。

走到这里 可以说真是费了偶的九牛二虎之力 不容易呀.. 继续看最后一组吧


我最初的意思是一关要比一关难一些,第四组原本采用SMC + 3×3行列式确定注册码,后来去掉了SMC,再后来去掉了3×3矩阵计算换成目前的简单算法。

破解分析完后 感受颇深 使我更坚信,只要你有足够的耐心 没有什么事能难到你.


的确是这样,reversing本来就是力气活,没有足够的耐心和信心,到老只能是一个JZer或者NOPer...

理论上第二组注册码有无穷种可能,可以手工凑出一些能显示和输入的字符来


dewar大侠说的在理!可以简单写一段Bruter,等找到可显示的字符后再进行第三组注册码计算。

如楼主所说转为浮点数时如果生成负数大概就没注册码了


我们讨论一个比较极端的例子:
假设用户名是:~~~~~~~~~~~~~~~~ =>sum(Name)  =07E0h
C:\ 序列号是:0FFFFFFFFh       =>sum(VOL_ID)=03FCh
那么,圆柱体体积 V=pi*07E0h^2*03FCh = 0308446378h

这时,如果第三组注册码小于0308446378h,则没有第四组注册码。问题来了,第三组注册码会不会小于这个数呢(注意:0308446378h已经不是一个dword了)?

这个注册机只能算使用数字的用户名。字母的用户名好像有些问题

关键在这里 
004015EA 3345 88 xor eax, dword ptr [ebp-78] ; xor boy 的值
004015ED 8945 90 mov dword ptr [ebp-70], eax
004015F0 DB45 90 fild dword ptr [ebp-70]

这里用的是 dword,如果使用我的这种算法 

faddp st(1),st
fistp DWORD PTR


mov eax, DWORD PTR



出来的数字再压进去 就会 是一个负数

这里不太明白 请老神树指教~



客气了。你写的这段可以,目前没有看出什么问题,请各位大侠再看看。当st(1)+st>002147483647d (07FFFFFFFh)出来再进去就会是负值了。

上面的一些话可以说是望文生义,肯定有说的不对的地方,请各位大侠批评指正,以免误人子弟。

给流动的情感大侠一个建议:这种注册机应该将注册信息直接写入注册表或者自动生成.key文件,供用户使用。
2007-2-10 14:55
0
雪    币: 226
活跃值: (30)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
9
 多谢老神指正 。算法太深奥了,
偶数学没学好。汇编没学好~~
希望不会误人子弟....
2007-2-10 15:41
0
雪    币: 253
活跃值: (25)
能力值: ( LV9,RANK:290 )
在线值:
发帖
回帖
粉丝
10
支持~~~~~
2007-2-11 11:33
0
雪    币: 538
活跃值: (460)
能力值: ( LV9,RANK:290 )
在线值:
发帖
回帖
粉丝
11
上次搞了好一会没搞出来,因为要考试了也没时间,支持!!!
2007-2-11 14:32
0
雪    币: 220
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
12
最初由 老神树 发布
正在写crackme7,还是keyfile的,until next time...


期待老神树的CM7
2007-2-11 17:52
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
学习学习一下。
支持。
2007-2-11 21:18
0
游客
登录 | 注册 方可回帖
返回
//