首页
社区
课程
招聘
[原创]Crackme 1.0 by DCrack-FOFF 破解分析[原创]
发表于: 2008-2-23 03:18 12255

[原创]Crackme 1.0 by DCrack-FOFF 破解分析[原创]

petnt 活跃值
12
2008-2-23 03:18
12255

【文章标题】: Crackme 1.0 by DCrack-FOFF 破解分析
【文章作者】: petnt
【作者邮箱】: petnt@sohu.com
【下载地址】: 见附件
【编写语言】: Delphi
【使用工具】: OD\记事本
【操作平台】: WinXP\sp2
【软件介绍】: 一个很意思的CrackMe
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  
  有些天没写东西了,壳的研究和手头的程序这几天均毫无进展,在论坛灌水的时候发现了sinlay同学发上来的一个CrackMe,打开初步

分析一下,其中思想非常合我的胃口,所以连夜奋战,终于有所收获,现把分析过程与大家共享。
 
  进入正题,Peid查壳,无壳,dephi编写。试运行,有错误提示。

  请出OD,载入,字符串查找,我们会发现“Error”,“Invalid Key”(共三处)这些敏感字符串,双击任意一处,我们将到达核心地

带。

0045C588   .  55               push    ebp
0045C589   .  8BEC             mov     ebp, esp
0045C58B   .  33C9             xor     ecx, ecx
0045C58D   .  51               push    ecx
0045C58E   .  51               push    ecx
0045C58F   .  51               push    ecx
0045C590   .  51               push    ecx
0045C591   .  53               push    ebx
0045C592   .  56               push    esi
0045C593   .  57               push    edi
0045C594   .  8BF0             mov     esi, eax
0045C596   .  33C0             xor     eax, eax
0045C598   .  55               push    ebp
0045C599   .  68 FDC64500      push    0045C6FD
0045C59E   .  64:FF30          push    dword ptr fs:[eax]
0045C5A1   .  64:8920          mov     dword ptr fs:[eax], esp
0045C5A4   .  8B86 68030000    mov     eax, dword ptr [esi+368]
0045C5AA   .  E8 0100FEFF      call    0043C5B0                         ;  获取Key长度
0045C5AF   .  83F8 0F          cmp     eax, 0F                          ;  长度==15?
0045C5B2   .  0F85 00010000    jnz     0045C6B8
0045C5B8   .  8B86 68030000    mov     eax, dword ptr [esi+368]
0045C5BE   .  E8 EDFFFDFF      call    0043C5B0             ;  获取Key长度
0045C5C3   .  50               push    eax
0045C5C4   .  8D45 F8          lea     eax, dword ptr [ebp-8]
0045C5C7   .  B9 01000000      mov     ecx, 1
0045C5CC   .  8B15 48C54500    mov     edx, dword ptr [45C548]          ;  Crackme_.0045C54C
0045C5D2   .  E8 0993FAFF      call    004058E0                         ;  清理空间,用于存放Key
0045C5D7   .  83C4 04          add     esp, 4
0045C5DA   .  68 98020000      push    298
0045C5DF   .  8D45 F4          lea     eax, dword ptr [ebp-C]
0045C5E2   .  B9 01000000      mov     ecx, 1
0045C5E7   .  8B15 68C54500    mov     edx, dword ptr [45C568]          ;  Crackme_.0045C56C
0045C5ED   .  E8 EE92FAFF      call    004058E0                         ;  清理空间,用于存放解密后的代码
0045C5F2   .  83C4 04          add     esp, 4
0045C5F5   .  33C9             xor     ecx, ecx
0045C5F7   .  55               push    ebp
0045C5F8   .  68 99C64500      push    0045C699
0045C5FD   .  64:FF31          push    dword ptr fs:[ecx]
0045C600   .  64:8921          mov     dword ptr fs:[ecx], esp     ;  安装SEH
0045C603   .  33DB             xor     ebx, ebx
0045C605   >  8D55 F0          lea     edx, dword ptr [ebp-10]
0045C608   .  8B86 68030000    mov     eax, dword ptr [esi+368]
0045C60E   .  E8 2D00FEFF      call    0043C640                         ;  获取Key
0045C613   .  8B45 F0          mov     eax, dword ptr [ebp-10]
0045C616   .  0FB64418 FF      movzx   eax, byte ptr [eax+ebx-1]
0045C61B   .  8B55 F8          mov     edx, dword ptr [ebp-8]
0045C61E   .  89049A           mov     dword ptr [edx+ebx*4], eax
0045C621   .  43               inc     ebx
0045C622   .  83FB 10          cmp     ebx, 10
0045C625   .^ 75 DE            jnz     short 0045C605          ;  利用循环按规律存放key
0045C627   .  BA 01000000      mov     edx, 1
0045C62C   .  33DB             xor     ebx, ebx
0045C62E   .  B8 A8F74500      mov     eax, 0045F7A8          ;  解密用数据存放处
0045C633   >  83FA 10          cmp     edx, 10
0045C636   .  75 05            jnz     short 0045C63D
0045C638   .  BA 01000000      mov     edx, 1
0045C63D   >  8B4D F8          mov     ecx, dword ptr [ebp-8]
0045C640   .  0FB60C91         movzx   ecx, byte ptr [ecx+edx*4]        ;  
0045C644   .  3208             xor     cl, byte ptr [eax]
0045C646   .  8B75 F4          mov     esi, dword ptr [ebp-C]
0045C649   .  880C1E           mov     byte ptr [esi+ebx], cl
0045C64C   .  42               inc     edx
0045C64D   .  43               inc     ebx
0045C64E   .  40               inc     eax
0045C64F   .  81FB 99020000    cmp     ebx, 299
0045C655   .^ 75 DC            jnz     short 0045C633          ;  用解密数据和key解密代码
0045C657   .  8B45 F4          mov     eax, dword ptr [ebp-C]
0045C65A   .  8945 FC          mov     dword ptr [ebp-4], eax
0045C65D   .  8B45 F4          mov     eax, dword ptr [ebp-C]
0045C660   .  8038 60          cmp     byte ptr [eax], 60        ;  比较解密后代码第1个字节
0045C663   .  75 17            jnz     short 0045C67C
0045C665   .  8B45 F4          mov     eax, dword ptr [ebp-C]
0045C668   .  8078 04 D0       cmp     byte ptr [eax+4], 0D0      ;  比较解密后代码第5个字节
0045C66C   .  75 0E            jnz     short 0045C67C
0045C66E   .  8B45 F4          mov     eax, dword ptr [ebp-C]
0045C671   .  8078 09 00       cmp     byte ptr [eax+9], 0              ;  比较解密后代码第10个字节
0045C675   .  75 05            jnz     short 0045C67C
0045C677   .  FF55 FC          call    dword ptr [ebp-4]        ;  进入解密后代码执行
0045C67A   .  EB 13            jmp     short 0045C68F
0045C67C   >  6A 00            push    0                                ; /Style = MB_OK|MB_APPLMODAL
0045C67E   .  68 0CC74500      push    0045C70C                         ; |Title = "Error"
0045C683   .  68 14C74500      push    0045C714                         ; |Text = "Invalid Key"
0045C688   .  6A 00            push    0                                ; |hOwner = NULL
0045C68A   .  E8 95A8FAFF      call    <jmp.&user32.MessageBoxA>        ; \MessageBoxA
0045C68F   >  33C0             xor     eax, eax
0045C691   .  5A               pop     edx
0045C692   .  59               pop     ecx
0045C693   .  59               pop     ecx
0045C694   .  64:8910          mov     dword ptr fs:[eax], edx
0045C697   .  EB 32            jmp     short 0045C6CB
0045C699   .^ E9 6678FAFF      jmp     00403F04
0045C69E   .  6A 00            push    0                                ; /Style = MB_OK|MB_APPLMODAL
0045C6A0   .  68 0CC74500      push    0045C70C                         ; |Title = "Error"
0045C6A5   .  68 14C74500      push    0045C714                         ; |Text = "Invalid Key"
0045C6AA   .  6A 00            push    0                                ; |hOwner = NULL
0045C6AC   .  E8 73A8FAFF      call    <jmp.&user32.MessageBoxA>        ; \MessageBoxA
0045C6B1   .  E8 5E7CFAFF      call    00404314
0045C6B6   .  EB 13            jmp     short 0045C6CB
0045C6B8   >  6A 00            push    0                                ; /Style = MB_OK|MB_APPLMODAL
0045C6BA   .  68 0CC74500      push    0045C70C                         ; |Title = "Error"
0045C6BF   .  68 14C74500      push    0045C714                         ; |Text = "Invalid Key"
0045C6C4   .  6A 00            push    0                                ; |hOwner = NULL
0045C6C6   .  E8 59A8FAFF      call    <jmp.&user32.MessageBoxA>        ; \MessageBoxA
0045C6CB   >  33C0             xor     eax, eax
0045C6CD   .  5A               pop     edx
0045C6CE   .  59               pop     ecx
0045C6CF   .  59               pop     ecx
0045C6D0   .  64:8910          mov     dword ptr fs:[eax], edx
0045C6D3   .  68 04C74500      push    0045C704
0045C6D8   >  8D45 F0          lea     eax, dword ptr [ebp-10]
0045C6DB   .  E8 7081FAFF      call    00404850
0045C6E0   .  8D45 F4          lea     eax, dword ptr [ebp-C]
0045C6E3   .  8B15 68C54500    mov     edx, dword ptr [45C568]          ;  Crackme_.0045C56C
0045C6E9   .  E8 FE91FAFF      call    004058EC
0045C6EE   .  8D45 F8          lea     eax, dword ptr [ebp-8]
0045C6F1   .  8B15 48C54500    mov     edx, dword ptr [45C548]          ;  Crackme_.0045C54C
0045C6F7   .  E8 F091FAFF      call    004058EC
0045C6FC   .  C3               retn
0045C6FD   .^ E9 B67AFAFF      jmp     004041B8
0045C702   .^ EB D4            jmp     short 0045C6D8
0045C704   .  5F               pop     edi
0045C705   .  5E               pop     esi
0045C706   .  5B               pop     ebx
0045C707   .  8BE5             mov     esp, ebp
0045C709   .  5D               pop     ebp
0045C70A   .  C3               retn

  
  整个注册流程并不复杂,主要如下:
 
 1. 判断key长度是否等于15,不等则失败。
  2. 申请空间并利用输入的key和固定数据解密出代码。
 3. 判断解密后的代码中指定字节是否符合要求,不符合则失败。
 4. 进入解密后的代码中执行,执行中异常则失败。

 解密算法也不复杂,循环利用Key的每一位与解密数据异或即得到解密后代码,解密用固定数据长度等于解密后代码长度。

 因为解密数据已知,解密算法简单可逆,所以只要知道解密后的代码,我们就能知道key。程序中有三处比较,所以我们很容易得到15

位是的三位。格式应该如下:

 “/***F****A*****” (引号内数据,*代表任意字符)

 上面的分析很简单,下面我们将遇到问题,利用已知的三位Key,我们仅能知道解密后的第一字节是60(pushad),最后一个字节是

C3(ret)及其中零散的一些正确的字节,我们凭这些如何确定长度为298hBYTE代码,又如何来确定我们的正确的key呢?

 从程序中我们很难得出正确答案,此时我们只能先揣摩一下作者的想法。

 1. 可能他只是想在那段代码中产生指定的异常,然后在SEH中进行处理。
 2. 运行解密后的代码即可给出注册正确的提示(这种可能性比较大,因为解密后的代码很长,可以做很多事情)。

 为保险起见,我们要先查看一下SEH,怎么查就不多说了,查后知道那里没有我们关心的东西,他只会让注册失败。

 现在我们可以有95%的把握确定他的注册正确提示在解密后的代码里。正如humourkyo 兄所说,我们连注册成功是什么样子都不知道,

而且我们只知道其中不连贯的1/5的代码,怎么办?

 去猜测他关键地方的代码?难度很大。那么长的代码,他做什么都有可能,我们又凭什么来确定他固定位置上的代码呢?
 
 我们从算法入手看看有没有别的方法,毕竟这个算法只是个简单的xor。

  我想大家也一定注意过平时的代码中,经常出现一个字节的00,有时甚至连续出现几个字节的00,如引用[004XXXXX]中就一定有一个

字节的0,而且这种方式还很常用。要是碰上 push 0(有可能是68 00 00 00 00),这样我们就有连续4个字节的0。有零有什么用?大

家可以和xor联系起来,再什么情况下才能让结果为0啊?xor eax,eax就为零,对了!这说明什么?想想。。。相信你已经想到了,就是

加密数据中应该存在 key 中字符的明码,甚至可能是连续几个字符的明码。快去看我们的加密数据:

0045F7A8  4F 12 85 7C 96 2E 29 54 45 41 15 10 F1 12 87 1C  O厊?)TEA??
0045F7B8  F3 27 27 46 56 2D 54 2D 41 5D 23 31 49 5C 2F 21  ?'FV-T-A]#1I\/!
0045F7C8  46 F6 92 2E 6D 54 BA 90 25 23 36 21 5C 47 21 46  F鰭.mT簮%#6!\G!F
0045F7D8  4F 46 16 94 98 2D 01 4D DC E0 E7 5C 76 E7 C6 4E  OF敇-M茑鏫v缙N
0045F7E8  46 46 2D 3B 83 C1 4F 23 31 21 29 E9 A1 45 4F 46  FF-;兞O#1!)椤EOF
0045F7F8  46 0D 92 C5 45 4D 23 31 45 9A AF 24 46 4F 46 2F  F.捙EM#1E毌$FOF/
0045F808  EB D4 43 41 4D 23 55 E7 DC 28 21 46 4F 66 80 AD  朐CAM#U畿(!FOf€
0045F818  5C 45 41 4D 4A F7 A1 55 2F 21 46 3B 80 C6 27 54  \EAMJ鳌U/!F;€?T
0045F828  45 41 6C E5 B1 2A 5C 2F 21 46 89 C6 56 2D 54 45  EAl灞*\/!F壠V-TE
0045F838  09 8B A3 20 21 5C 2F 40 80 CF 54 46 2D 54 31 87  .嫞 !\/@€蟃F-T1
0045F848  CD 30 31 21 5C 5C E7 C6 5B 46 46 2D 74 83 C1 58  ?1!\\缙[FF-t兞X
0045F858  23 31 21 33 E9 A1 50 4F 46 46 4B 92 C5 56 4D 23  #1!3椤POFFK捙VM#
0045F868  31 47 9A AF 39 46 4F 46 66 EB D4 5C 41 4D 23 45  1G毌9FOFf朐\AM#E
0045F878  E7 DC 35 21 46 4F 29 80 AD 4F 45 41 4D 03 F7 A1  畿5!FO)€璒EAM鳌
0045F888  40 2F 21 46 36 80 C6 30 54 45 41 22 E5 B1 3F 5C  @/!F6€?TEA"灞?\
0045F898  2F 21 33 89 C6 59 2D 54 45 61 8B A3 11 21 5C 2F  /!3壠Y-TEa嫞!\/
0045F8A8  4C 80 CF 67 46 2D 54 24 87 CD 01 31 21 5C 5B E7  L€蟝F-T$囃1!\[
0045F8B8  C6 6C 46 46 2D 31 83 C1 69 23 31 21 72 E9 A1 63  苐FF-1兞i#1!r椤c
0045F8C8  4F 46 46 0D 92 C5 67 4D 23 31 71 9A AF 06 46 4F  OFF.捙gM#1q毌FO
0045F8D8  46 2A EB D4 6D 41 4D 23 54 E7 DC 06 21 46 4F 27  F*朐mAM#T畿!FO'
0045F8E8  80 AD 7E 45 41 4D 50 F7 A1 77 2F 21 46 2A 80 C6  €瓇EAMP鳌w/!F*€
0045F8F8  01 54 45 41 6D E5 B1 0C 5C 2F 21 35 89 C6 68 2D  TEAm灞.\/!5壠h-
0045F908  54 45 24 8B A3 1E 21 5C 2F 4F 80 CF 76 46 2D 54  TE$嫞!\/O€蟰F-T
0045F918  21 87 CD 12 31 21 5C 0F E7 C6 7D 46 46 2D 2D 83  !囃1!\缙}FF--
0045F928  C1 7E 23 31 21 33 E9 A1 72 4F 46 46 58 92 C5 74  羱#1!3椤rOFFX捙t
0045F938  4D 23 31 53 9A AF 17 46 4F 46 66 EB D4 72 41 4D  M#1S毌FOFf朐rAM
0045F948  23 42 E7 DC 17 21 46 4F 29 80 AD 6D 45 41 4D 4F  #B畿!FO)€璵EAMO
0045F958  F7 A1 66 2F 21 46 3A 80 C6 16 54 45 41 39 E5 B1  鳌f/!F:€?TEA9灞
0045F968  1D 5C 2F 21 2F 89 C6 7B 2D 54 45 2E 8B A3 0F 21  \/!/壠{-TE.嫞!
0045F978  5C 2F 4F 80 CF 79 46 2D 54 65 87 CD 63 31 21 5C  \/O€蟳F-Te囃c1!\
0045F988  5B E7 C6 0E 46 46 2D 3B 83 C1 0F 23 31 21 7C E9  [缙FF-;兞#1!|
0045F998  A1 05 4F 46 46 49 92 C5 05 4D 23 31 42 9A AF 64  ?OFFI捙M#1B毌d
0045F9A8  46 4F 46 34 EB D4 03 41 4D 23 50 E7 DC 68 21 46  FOF4朐AM#P畿h!F
0045F9B8  4F 25 80 AD 1C 45 41 4D 48 F7 A1 15 2F 21 46 7D  O%€?EAMH鳌/!F}
0045F9C8  80 C6 67 54 45 41 7D E5 B1 6A 5C 2F 21 76 89 C6  €苂TEA}灞j\/!v壠
0045F9D8  0A 2D 54 45 76 8B A3 7C 21 5C 2F 61 80 CF 08 46  .-TEv嫞|!\/a€?F
0045F9E8  2D 54 22 87 CD 6C 31 21 5C 42 E7 C6 1F 46 46 2D  -T"囃l1!\B缙FF-
0045F9F8  35 83 C1 1C 23 31 21 35 E9 A1 14 4F 46 46 41 92  5兞#1!5椤OFFA
0045FA08  C5 12 4D 23 31 0F 9A AF 75 46 4F 46 25 EB D4 10  ?M#1毌uFOF%朐
0045FA18  41 4D 23 5E E7 DC 79 21 46 4F 2B 80 AD 03 45 41  AM#^畿y!FO+€?EA
0045FA28  4D 23 59 21 5C 2F 21 16 CC 86 56 7D 3C 45 41 4D  M#Y!\/!虇V}<EAM
0045FA38  23 88 05 33 6F 21 B9 9E 85                       #?3o!篂厤 

 
 我们已经知道其中的3位,而且key中的字符和加密数据是有对应关系的,我们很明确的知道key中的哪个字符和加密数据中的哪一位进

行xor运算,如果恰巧地解密后相对应的位是0的话,那么在那个位置上加密数据就是我们key中的字符。我们知道第一位字符是“/”,在

数据中找找看,幸运的是我们发现了好多“/”,而且,我们还能发现,在“/”两边出现频率很高的字符是“\”和“!”。同理,我们

可以发现“F”的两边出现最高的是“O”和“F”,“A”两边的是“E”和“M”。我们还可以发现,出来在“-”后“E”前最多的是“T

”,同理,我们会发现更多。好了把我们的这些猜测变成现实去试一试,当我们输入key “/!FOFF-TEAMlm!\”时,我们会发现:

00E2EE39    B9 D4684000          mov     ecx, 4068D4   ; jmp 到 kernel32.HeapCreate
00E2EE3E    FFD1                 call    ecx


 出现这样的代码足以验证我们猜测的可以性,并进一步证实其中连续几位的正确性。好了不多说了,看着解密数据,试几次就会发现

正确的注册码是“/!FOFF-TEAM#1!\”。

 整个过程有点投机,其实这样的用key来进行解密的注册方法应该是很可取的一种保护方法。只要算法稍微复杂一点,在没有一组正确

key的情况下,是很难解密其中代码的。

 好了,投机取巧的注册过程就到这里吧,没什么技术含量,失礼之处,请大侠莫笑。如有分析不当之处,敬请指出。

--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2008年02月23日 03:10:31


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (22)
雪    币: 1844
活跃值: (35)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
2
好久没搞过CM了,顶一下
2008-2-23 09:10
0
雪    币: 609
活跃值: (237)
能力值: ( LV12,RANK:441 )
在线值:
发帖
回帖
粉丝
3
膜拜一个……又一个精华……
汗……早上3点多写的……
2008-2-23 09:39
0
雪    币: 485
活跃值: (12)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
4
谢谢支持,刚开学就又休息了?
2008-2-23 09:42
0
雪    币: 609
活跃值: (237)
能力值: ( LV12,RANK:441 )
在线值:
发帖
回帖
粉丝
5
嘿嘿……改革春分吹进门……今天不上课了……嘿嘿……不过还有作业的……
2008-2-23 09:43
0
雪    币: 1346
活跃值: (2331)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
顶!看来我们三个是常来的啊!
2008-2-24 10:18
0
雪    币: 485
活跃值: (12)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
7
是啊,我们三个常来。
但估计还有常来的,只是不像我们三个这样爱灌水,好多大牛喜欢潜水。
曾见过好多04年就注册的号发帖数却没你多的。呵呵。。

写的有什么不对的地方或是分析有不足的地方,欢迎指出啊。
2008-2-24 10:25
0
雪    币: 609
活跃值: (237)
能力值: ( LV12,RANK:441 )
在线值:
发帖
回帖
粉丝
8
额……汇编比较烂……Studying……
2008-2-24 10:56
0
雪    币: 2256
活跃值: (941)
能力值: (RANK:2210 )
在线值:
发帖
回帖
粉丝
9
呵呵
分析的不错哦
2008-2-24 18:01
0
雪    币: 443
活跃值: (200)
能力值: ( LV9,RANK:1140 )
在线值:
发帖
回帖
粉丝
10
这篇写得好,支持一个!!!!!!
2008-2-24 18:03
0
雪    币: 2316
活跃值: (129)
能力值: (RANK:410 )
在线值:
发帖
回帖
粉丝
11
分析的好!
我研究半天,没搞定,只好来学习petnt的破文了.,学了一招.
2008-2-24 21:46
0
雪    币: 485
活跃值: (12)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
12
谢谢各位支持。
楼上客气了,共同学习进步。。
2008-2-24 21:52
0
雪    币: 321
活跃值: (271)
能力值: ( LV13,RANK:1050 )
在线值:
发帖
回帖
粉丝
13
petnt连夜奋战,支持。
2008-2-24 22:46
0
雪    币: 134
活跃值: (84)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
14
这么神速。太快了,哦呵呵
这两天正在玩这个,有个问题:查出3位后后面就有点无奈了,call里错误的直接调用seh,然后就我详细检查了下seh代码,跟对比无关,然后就跳到错误key上了。不过确实call内的代码和密码解码有关。但到最后也不能用试来解决整个问题吧?还有更好的解决办法没了?
debug030:00E2EE18 pusha ; Push all General Registers
debug030:00E2EE19 xor eax, ebx ; Logical Exclusive OR
debug030:00E2EE1B xor edx, eax ; Logical Exclusive OR
debug030:00E2EE1D push 4
debug030:00E2EE22 pop eax
debug030:00E2EE23 xor eax, eax ; Logical Exclusive OR
debug030:00E2EE25 xor ebx, ebx ; Logical Exclusive OR
debug030:00E2EE27 xor edx, edx ; Logical Exclusive OR
debug030:00E2EE29 popa ; Pop all General Registers
debug030:00E2EE2A push 1000h
debug030:00E2EE2F push 1000h
debug030:00E2EE34 push 0
debug030:00E2EE39 mov ecx, offset HeapCreate
debug030:00E2EE3E call ecx ; HeapCreate ; Indirect Call Near Procedure
debug030:00E2EE40 push 700h
debug030:00E2EE45 push 0
debug030:00E2EE4A push eax
debug030:00E2EE4B mov ecx, offset HeapAlloc
debug030:00E2EE50 call ecx ; HeapAlloc ; Indirect Call Near Procedure
debug030:00E2EE52 mov byte ptr [eax], 59h
debug030:00E2EE55 db 0C6h,80h,1,0,0,0,6Fh ; <BAD>mov byte ptr [eax+1], 6Fh
debug030:00E2EE5C db 0C6h,80h,2,0,0,0,75h ; <BAD>mov byte ptr [eax+2], 75h
debug030:00E2EE63 db 0C6h,80h,3,0,0,0,20h ; <BAD>mov byte ptr [eax+3], 20h
debug030:00E2EE6A db 0C6h,80h,4,0,0,0,64h ; <BAD>mov byte ptr [eax+4], 64h
debug030:00E2EE71 db 0C6h,80h,5,0,0,0,69h ; <BAD>mov byte ptr [eax+5], 69h
debug030:00E2EE78 db 0C6h,80h,6,0,0,0,64h ; <BAD>mov byte ptr [eax+6], 64h
debug030:00E2EE7F db 0C6h,80h,7,0,0,0,20h ; <BAD>mov byte ptr [eax+7], 20h
debug030:00E2EE86 db 0C6h,80h,8,0,0,0,69h ; <BAD>mov byte ptr [eax+8], 69h
debug030:00E2EE8D db 0C6h,80h,9,0,0,0,74h ; <BAD>mov byte ptr [eax+9], 74h
debug030:00E2EE94 db 0C6h,80h,0Ah,0,0,0,21h ; <BAD>mov byte ptr [eax+0Ah], 21h
debug030:00E2EE9B db 0C6h,80h,0Bh,0,0,0,0 ; <BAD>mov byte ptr [eax+0Bh], 0
debug030:00E2EEA2 db 0C6h,80h,10h,0,0,0,48h ; <BAD>mov byte ptr [eax+10h], 48h
debug030:00E2EEA9 db 0C6h,80h,11h,0,0,0,61h ; <BAD>mov byte ptr [eax+11h], 61h
debug030:00E2EEB0 db 0C6h,80h,12h,0,0,0,74h ; <BAD>mov byte ptr [eax+12h], 74h
debug030:00E2EEB7 db 0C6h,80h,13h,0,0,0,73h ; <BAD>mov byte ptr [eax+13h], 73h
debug030:00E2EEBE db 0C6h,80h,14h,0,0,0,20h ; <BAD>mov byte ptr [eax+14h], 20h
debug030:00E2EEC5 db 0C6h,80h,15h,0,0,0,6Fh ; <BAD>mov byte ptr [eax+15h], 6Fh
debug030:00E2EECC db 0C6h,80h,16h,0,0,0,66h ; <BAD>mov byte ptr [eax+16h], 66h
debug030:00E2EED3 db 0C6h,80h,17h,0,0,0,66h ; <BAD>mov byte ptr [eax+17h], 66h
debug030:00E2EEDA db 0C6h,80h,18h,0,0,0,20h ; <BAD>mov byte ptr [eax+18h], 20h
debug030:00E2EEE1 db 0C6h,80h,19h,0,0,0,74h ; <BAD>mov byte ptr [eax+19h], 74h
debug030:00E2EEE8 db 0C6h,80h,1Ah,0,0,0,6Fh ; <BAD>mov byte ptr [eax+1Ah], 6Fh
debug030:00E2EEEF db 0C6h,80h,1Bh,0,0,0,20h ; <BAD>mov byte ptr [eax+1Bh], 20h
debug030:00E2EEF6 db 0C6h,80h,1Ch,0,0,0,79h ; <BAD>mov byte ptr [eax+1Ch], 79h
debug030:00E2EEFD db 0C6h,80h,1Dh,0,0,0,6Fh ; <BAD>mov byte ptr [eax+1Dh], 6Fh
debug030:00E2EF04 db 0C6h,80h,1Eh,0,0,0,75h ; <BAD>mov byte ptr [eax+1Eh], 75h
debug030:00E2EF0B db 0C6h,80h,1Fh,0,0,0,20h ; <BAD>mov byte ptr [eax+1Fh], 20h
debug030:00E2EF12 db 0C6h,80h,20h,0,0,0,6Dh ; <BAD>mov byte ptr [eax+20h], 6Dh
debug030:00E2EF19 db 0C6h,80h,21h,0,0,0,61h ; <BAD>mov byte ptr [eax+21h], 61h
debug030:00E2EF20 db 0C6h,80h,22h,0,0,0,74h ; <BAD>mov byte ptr [eax+22h], 74h
debug030:00E2EF27 db 0C6h,80h,23h,0,0,0,65h ; <BAD>mov byte ptr [eax+23h], 65h
debug030:00E2EF2E db 0C6h,80h,24h,0,0,0,2Eh ; <BAD>mov byte ptr [eax+24h], 2Eh
debug030:00E2EF35 db 0C6h,80h,25h,0,0,0,20h ; <BAD>mov byte ptr [eax+25h], 20h
debug030:00E2EF3C db 0C6h,80h,26h,0,0,0,50h ; <BAD>mov byte ptr [eax+26h], 50h
debug030:00E2EF43 db 0C6h,80h,27h,0,0,0,6Ch ; <BAD>mov byte ptr [eax+27h], 6Ch
debug030:00E2EF4A db 0C6h,80h,28h,0,0,0,65h ; <BAD>mov byte ptr [eax+28h], 65h
debug030:00E2EF51 db 0C6h,80h,29h,0,0,0,61h ; <BAD>mov byte ptr [eax+29h], 61h
debug030:00E2EF58
debug030:00E2EF58 loc_E2EF58:
debug030:00E2EF58 db 0C6h,80h,2Ah,0,0,0,73h ; <BAD>mov byte ptr [eax+2Ah], 73h
debug030:00E2EF5F db 0C6h,80h,2Bh,0,0,0,65h ; <BAD>mov byte ptr [eax+2Bh], 65h
debug030:00E2EF66 db 0C6h,80h,2Ch,0,0,0,20h ; <BAD>mov byte ptr [eax+2Ch], 20h
debug030:00E2EF6D db 0C6h,80h,2Dh,0,0,0,73h ; <BAD>mov byte ptr [eax+2Dh], 73h
debug030:00E2EF74 db 0C6h,80h,2Eh,0,0,0,65h ; <BAD>mov byte ptr [eax+2Eh], 65h
debug030:00E2EF7B db 0C6h,80h,2Fh,0,0,0,6Eh ; <BAD>mov byte ptr [eax+2Fh], 6Eh
debug030:00E2EF82 db 0C6h,80h,30h,0,0,0,64h ; <BAD>mov byte ptr [eax+30h], 64h
debug030:00E2EF89 db 0C6h,80h,31h,0,0,0,20h ; <BAD>mov byte ptr [eax+31h], 20h
debug030:00E2EF90 db 0C6h,80h,32h,0,0,0,79h ; <BAD>mov byte ptr [eax+32h], 79h
debug030:00E2EF97 db 0C6h,80h,33h,0,0,0,6Fh ; <BAD>mov byte ptr [eax+33h], 6Fh
debug030:00E2EF9E db 0C6h,80h,34h,0,0,0,75h ; <BAD>mov byte ptr [eax+34h], 75h
debug030:00E2EFA5 db 0C6h,80h,35h,0,0,0,72h ; <BAD>mov byte ptr [eax+35h], 72h
debug030:00E2EFAC db 0C6h,80h,36h,0,0,0,20h ; <BAD>mov byte ptr [eax+36h], 20h
debug030:00E2EFB3 db 0C6h,80h,37h,0,0,0,73h ; <BAD>mov byte ptr [eax+37h], 73h
debug030:00E2EFBA db 0C6h,80h,38h,0,0,0,6Fh ; <BAD>mov byte ptr [eax+38h], 6Fh
debug030:00E2EFC1 db 0C6h,80h,39h,0,0,0,6Ch ; <BAD>mov byte ptr [eax+39h], 6Ch
debug030:00E2EFC8 db 0C6h,80h,3Ah,0,0,0,75h ; <BAD>mov byte ptr [eax+3Ah], 75h
debug030:00E2EFCF db 0C6h,80h,3Bh,0,0,0,74h ; <BAD>mov byte ptr [eax+3Bh], 74h
debug030:00E2EFD6 db 0C6h,80h,3Ch,0,0,0,69h ; <BAD>mov byte ptr [eax+3Ch], 69h
debug030:00E2EFDD db 0C6h,80h,3Dh,0,0,0,6Fh ; <BAD>mov byte ptr [eax+3Dh], 6Fh
debug030:00E2EFE4 db 0C6h,80h,3Eh,0,0,0,6Eh ; <BAD>mov byte ptr [eax+3Eh], 6Eh
debug030:00E2EFEB db 0C6h,80h,3Fh,0,0,0,20h ; <BAD>mov byte ptr [eax+3Fh], 20h
debug030:00E2EFF2 db 0C6h,80h,40h,0,0,0,74h ; <BAD>mov byte ptr [eax+40h], 74h
debug030:00E2EFF9 db 0C6h,80h,41h,0,0,0,6Fh ; <BAD>mov byte ptr [eax+41h], 6Fh
debug030:00E2F000 db 0C6h,80h,42h,0,0,0,20h ; <BAD>mov byte ptr [eax+42h], 20h
debug030:00E2F007 db 0C6h,80h,43h,0,0,0,64h ; <BAD>mov byte ptr [eax+43h], 64h
debug030:00E2F00E db 0C6h,80h,44h,0,0,0,63h ; <BAD>mov byte ptr [eax+44h], 63h
debug030:00E2F015 db 0C6h,80h,45h,0,0,0,72h ; <BAD>mov byte ptr [eax+45h], 72h
debug030:00E2F01C db 0C6h,80h,46h,0,0,0,61h ; <BAD>mov byte ptr [eax+46h], 61h
debug030:00E2F023 db 0C6h,80h,47h,0,0,0,63h ; <BAD>mov byte ptr [eax+47h], 63h
debug030:00E2F02A db 0C6h,80h,48h,0,0,0,6Bh ; <BAD>mov byte ptr [eax+48h], 6Bh
debug030:00E2F031 db 0C6h,80h,49h,0,0,0,32h ; <BAD>mov byte ptr [eax+49h], 32h
debug030:00E2F038 db 0C6h,80h,4Ah,0,0,0,30h ; <BAD>mov byte ptr [eax+4Ah], 30h
debug030:00E2F03F db 0C6h,80h,4Bh,0,0,0,30h ; <BAD>mov byte ptr [eax+4Bh], 30h
debug030:00E2F046 db 0C6h,80h,4Ch,0,0,0,37h ; <BAD>mov byte ptr [eax+4Ch], 37h
debug030:00E2F04D db 0C6h,80h,4Dh,0,0,0,40h ; <BAD>mov byte ptr [eax+4Dh], 40h
debug030:00E2F054 db 0C6h,80h,4Eh,0,0,0,67h ; <BAD>mov byte ptr [eax+4Eh], 67h
debug030:00E2F05B db 0C6h,80h,4Fh,0,0,0,6Dh ; <BAD>mov byte ptr [eax+4Fh], 6Dh
debug030:00E2F062 db 0C6h,80h,50h,0,0,0,61h ; <BAD>mov byte ptr [eax+50h], 61h
debug030:00E2F069 db 0C6h,80h,51h,0,0,0,69h ; <BAD>mov byte ptr [eax+51h], 69h
debug030:00E2F070 db 0C6h,80h,52h,0,0,0,6Ch ; <BAD>mov byte ptr [eax+52h], 6Ch
debug030:00E2F077 db 0C6h,80h,53h,0,0,0,2Eh ; <BAD>mov byte ptr [eax+53h], 2Eh
debug030:00E2F07E db 0C6h,80h,54h,0,0,0,63h ; <BAD>mov byte ptr [eax+54h], 63h
debug030:00E2F085 db 0C6h,80h,55h,0,0,0,6Fh ; <BAD>mov byte ptr [eax+55h], 6Fh
debug030:00E2F08C db 0C6h,80h,56h,0,0,0,6Dh ; <BAD>mov byte ptr [eax+56h], 6Dh
debug030:00E2F093 db 0C6h,80h,57h,0,0,0,0 ; <BAD>mov byte ptr [eax+57h], 0
debug030:00E2F09A push 0
debug030:00E2F09F push eax
debug030:00E2F0A0 add eax, 10h ; Add
debug030:00E2F0A3 push eax
debug030:00E2F0A4 push 0
debug030:00E2F0A9 mov ecx, offset MessageBoxA_0
debug030:00E2F0AE call ecx ; MessageBoxA_0 ; Indirect Call Near Procedure
debug030:00E2F0B0 retn ; Return Near from Procedure

顺便把你没帖出的代码帖出。呵呵  哥们我在线等  qq:414211565
2008-2-25 09:17
0
雪    币: 423
活跃值: (11)
能力值: ( LV9,RANK:230 )
在线值:
发帖
回帖
粉丝
15
年年岁岁人相似
岁岁年年事不同
一声蛙鸣拂晓白
算法漏洞解两难

恭喜Petnt兄,蛤蟆功更见深厚,西毒之名不久了!破解工具里多了个记事本,好习惯啊。

引用:
其实这样的用key来进行解密的注册方法应该是很可取的一种保护方法。只要算法稍微复杂一点,在没有一组正确key的情况下,是很难解密其中代码的。

这种说法有待商榷。
这种加密的方法难点在于加密的原代码和KEY两种都不清晰。但对于汇编高手而言,KEY和加密的原代码只要存在着某种规律,就存在着破解的可能,差别只是时间问题。

这个CRACK ME的构思是相当精巧的。体现的细节有:
1:语言选择。Delphi的CALL对堆栈的处理不象其他语言,开头规律并不为一般人熟悉。其他的语言开头有

  push    ebp                        
  mov     ebp, esp
  sub     esp, 8
经典的堆栈处理语句。

2:子程序开头的初始化独具匠心:
00DB7AE8    60              pushad
00DB7AE9    33C3          xor     eax, ebx
00DB7AEB    33D0          xor     edx, eax
作为一个汇编高手,存在着XOR 赋零的良好习惯。PUSHAD的指令暗示着开头部分是环境初始化,第二句的可能性最大的有:
xor     eax, eax
xor     eax, ebx
xor     eax, ecx
xor     ecx, edx
四种可能性,这四种开头的字节都是33,推算出第二个KEY字符是!。汇编高手可以根据散在的三个正确字符,利用在子程序较有规律的开头和结尾段推测出数种可能的编程语句反复实验,半靠运气半靠对汇编语句的精湛理解,理论上存在着破解的概率。
而作者没有用常见的xor     eax, eax
                           xor     edx, edx
是精心设置的,增加了破解的尝试量。看雪老大的书里说过,大意如下:这种加密法关键是KEY的长度,只要足够长,虽然理论上存在着破解的可能性,但在实际运用中破解的成功率极低。加密的算法再巧妙,由于加密的子程序受语言、编程流程和编程规律等等的限制,存在着诸多约束,在KEY长度有限的情况下,都有机会破解。结尾肯定是RET,对应KEY第五位的F,令人对作者的严密设防由衷地佩服。

3.作者在细节上的巧思妙构,为什么留下算法上的漏洞呢?作者做这个CRACK ME是对KEY的加密性的测试,了解这种加密法的缺陷,是探讨性的。我猜测作者留下的这漏洞是作者心中的正解,增加破解的趣味性和普及性、传播性。

  我对这种加密法的联想是:
1.KEY的长度是最关键的。
2.被加密的数据要进行特殊的修饰和处理,避免过多的重复数据,避免过多的常用语法。
3.算法的精密度也很重要,加大逆向的难度。
2008-2-26 16:28
0
雪    币: 2316
活跃值: (129)
能力值: (RANK:410 )
在线值:
发帖
回帖
粉丝
16
我想大家也一定注意过平时的代码中,经常出现一个字节的00,有时甚至连续出现几个字节的00

这一点很关键,知道这一点后,可以很容易根据统计的方法,迅速得处正确的注册码。
将290h个字节,15个一组排列如下:
[FONT="Fixedsys"]
4F 12 85 7C 96 2E 29 54 45 41 15 10 F1 12 87 
1C F3 27 27 46 56 2D 54 2D 41 5D 23 31 49 5C 
2F 21 46 F6 92 2E 6D 54 BA 90 25 23 36 21 5C 
47 21 46 4F 46 16 94 98 2D 01 4D DC E0 E7 5C 
76 E7 C6 4E 46 46 2D 3B 83 C1 4F 23 31 21 29 
E9 A1 45 4F 46 46 0D 92 C5 45 4D 23 31 45 9A 
AF 24 46 4F 46 2F EB D4 43 41 4D 23 55 E7 DC
28 21 46 4F 66 80 AD 5C 45 41 4D 4A F7 A1 55
2F 21 46 3B 80 C6 27 54 45 41 6C E5 B1 2A 5C 
2F 21 46 89 C6 56 2D 54 45 09 8B A3 20 21 5C 
2F 40 80 CF 54 46 2D 54 31 87 CD 30 31 21 5C 
5C E7 C6 5B 46 46 2D 74 83 C1 58 23 31 21 33 
E9 A1 50 4F 46 46 4B 92 C5 56 4D 23 31 47 9A 
AF 39 46 4F 46 66 EB D4 5C 41 4D 23 45 E7 DC 
35 21 46 4F 29 80 AD 4F 45 41 4D 03 F7 A1 40 
2F 21 46 36 80 C6 30 54 45 41 22 E5 B1 3F 5C 
2F 21 33 89 C6 59 2D 54 45 61 8B A3 11 21 5C 
2F 4C 80 CF 67 46 2D 54 24 87 CD 01 31 21 5C 
5B E7 C6 6C 46 46 2D 31 83 C1 69 23 31 21 72 
E9 A1 63 4F 46 46 0D 92 C5 67 4D 23 31 71 9A 
AF 06 46 4F 46 2A EB D4 6D 41 4D 23 54 E7 DC 
06 21 46 4F 27 80 AD 7E 45 41 4D 50 F7 A1 77 
2F 21 46 2A 80 C6 01 54 45 41 6D E5 B1 0C 5C 
2F 21 35 89 C6 68 2D 54 45 24 8B A3 1E 21 5C 
2F 4F 80 CF 76 46 2D 54 21 87 CD 12 31 21 5C 
0F E7 C6 7D 46 46 2D 2D 83 C1 7E 23 31 21 33 
E9 A1 72 4F 46 46 58 92 C5 74 4D 23 31 53 9A 
AF 17 46 4F 46 66 EB D4 72 41 4D 23 42 E7 DC 
17 21 46 4F 29 80 AD 6D 45 41 4D 4F F7 A1 66 
2F 21 46 3A 80 C6 16 54 45 41 39 E5 B1 1D 5C 
2F 21 2F 89 C6 7B 2D 54 45 2E 8B A3 0F 21 5C 
2F 4F 80 CF 79 46 2D 54 65 87 CD 63 31 21 5C 
5B E7 C6 0E 46 46 2D 3B 83 C1 0F 23 31 21 7C
E9 A1 05 4F 46 46 49 92 C5 05 4D 23 31 42 9A 
AF 64 46 4F 46 34 EB D4 03 41 4D 23 50 E7 DC 
68 21 46 4F 25 80 AD 1C 45 41 4D 48 F7 A1 15 
2F 21 46 7D 80 C6 67 54 45 41 7D E5 B1 6A 5C 
2F 21 76 89 C6 0A 2D 54 45 76 8B A3 7C 21 5C 
2F 61 80 CF 08 46 2D 54 22 87 CD 6C 31 21 5C 
42 E7 C6 1F 46 46 2D 35 83 C1 1C 23 31 21 35 
E9 A1 14 4F 46 46 41 92 C5 12 4D 23 31 0F 9A 
AF 75 46 4F 46 25 EB D4 10 41 4D 23 5E E7 DC 
79 21 46 4F 2B 80 AD 03 45 41 4D 23 59 21 5C
2F 21 16 CC 86 56 7D 3C 45 41 4D 23 88 05 33 
6F 21 B9 9E 85 
[/FONT]

将每列中出现频率最高的顺序排列出来如下:
[FONT="Fixedsys"]2F 21 46 4f 46 46 2D 54 45 41 4d 23 31 21 5C[/FONT]

对应ASCII码为“/!FOFF-TEAM#1!\”

统计的方法,不需要最开始获得的那3个字节,也不需要了解是何种编译器和何种语言,更迅速直观些。
2008-2-26 18:37
0
雪    币: 479
活跃值: (25)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
17
petnt分析的很好。
我看过这篇文章我觉得,将代码加密,通过key或注册码即密钥来解密代码,然后再运行代码,如果运用高强度密码学算法加密,解密代码的可能性很小。选择核心代码进行加密即可,这样在效率上有个折衷考虑。
2008-2-26 18:55
0
雪    币: 223
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
rst
18
向高手学习,呵呵
2008-2-26 19:15
0
雪    币: 485
活跃值: (12)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
19
有道理。。

同时感谢nba2005等各位老兄意见,谢谢
2008-2-26 21:12
0
雪    币: 485
活跃值: (12)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
20
这么神速。太快了,哦呵呵
这两天正在玩这个,有个问题:查出3位后后面就有点无奈了,call里错误的直接调用seh,然后就我详细检查了下seh代码,跟对比无关,然后就跳到错误key上了。不过确实call内的代码和密码解码有关。但到最后也不能用试来解决整个问题吧?还有更好的解决办法没了?


我想应该是没有什么正规的办法,只能去猜,可能高手会猜特殊部位的指令,我有点投机,实际上算法稍微复杂一点,我就没办法了
2008-2-26 23:28
0
雪    币: 206
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
大鬼原来是个狠角色,不错不错
2008-2-28 12:31
0
雪    币: 203
活跃值: (21)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
拜读了楼主的分析及各位精辟的回复...差距啊!路漫漫其修远,吾将上下而求索......
2008-2-29 14:09
0
雪    币: 227
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
学习!努力地学习!
2008-2-29 14:32
0
游客
登录 | 注册 方可回帖
返回
//