首页
社区
课程
招聘
[原创]MD2CrackMe算法分析
发表于: 2008-2-20 09:28 6446

[原创]MD2CrackMe算法分析

2008-2-20 09:28
6446

【文章标题】: MD2CrackMe算法分析
【文章作者】: dttom
【作者邮箱】: dttom2006@126.com
【软件名称】: MD2CrackMe
【软件大小】: 48Kb
【下载地址】: http://bbs.pediy.com/attachment.php?attachmentid=6635&d=1183881201
【保护方式】: 无
【编写语言】: Delphi
【使用工具】: Ollydbg,RadASM,Peid
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
      首先我们先来了解一下什么是MD2算法,MD2是一种单向散列加密算法,根据RFC1319可以查得MD2算法的描述,基本算法流程如下:
      (1)用i字节对消息进行填充,使填充后消息长度为(N=N+i)为16字节的整数倍。
      (2)在256字节的随机打乱的数表中,通过XOR运算,获得一个16字节的附加检查和,附加到步骤一的结尾。N'=N+16
      (3)初始化48字节的分组。将x的前16字节置为0,接下去的16字节对应消息的前16字节,第三个16字节是x的前16字节
           与x的第二个16字节XOR结果。
      (4)通过一段加密函数块实现加密。
           t = 0;
           for (i = 0; i < 18; i++)
           {
              for (j = 0; j < 48; j++)
                 t = x[j] ^= S[t];
            t = (t + i) & 0xff;
           }
       (5)将消息块填入x的第二个16字节,x第三个16字节x是第一个16字节与第二个16字节XOR结果。重复这一过程,重复
  次数为N'/16-1次。即最后16字节校验和不参与加密运算。
       (6)最后输出x的前16字节为加密结果。
  
      了解了上面的流程,我们可以来调试了,下面我说说我的操作过程,不一定正确,欢迎批评指正。我们来打开od,载入MD2CrackMe,F9运行,输入用户名dttom和试练码55556666,接着摆在我们面前
  的就是下断,下bp GetDlgItemTextA断点。点注册认证,接着断在下面的代码处。
  
  77D6AE36 >  8BFF            mov     edi, edi                    //断在这里
  77D6AE38    55              push    ebp
  77D6AE39    8BEC            mov     ebp, esp
  77D6AE3B    FF75 0C         push    dword ptr [ebp+C]
  77D6AE3E    FF75 08         push    dword ptr [ebp+8]
  77D6AE41    E8 888FFBFF     call    GetDlgItem                       //获得控件的handle,为取数做准备
  77D6AE46    85C0            test    eax, eax
  77D6AE48    74 0E           je      short 77D6AE58
  77D6AE4A    FF75 14         push    dword ptr [ebp+14]
  77D6AE4D    FF75 10         push    dword ptr [ebp+10]
  77D6AE50    50              push    eax
  77D6AE51    E8 D572FCFF     call    GetWindowTextA                     //取控件内的字符串
  77D6AE56    EB 0E           jmp     short 77D6AE66
  77D6AE58    837D 14 00      cmp     dword ptr [ebp+14], 0
  77D6AE5C    74 06           je      short 77D6AE64
  77D6AE5E    8B45 10         mov     eax, dword ptr [ebp+10]
  77D6AE61    C600 00         mov     byte ptr [eax], 0
  77D6AE64    33C0            xor     eax, eax
  77D6AE66    5D              pop     ebp
  77D6AE67    C2 1000         retn    10
  ......
  ctrl+F9来到下面的代码处:
  
00408A2A   .  8D45 B4       lea     eax, dword ptr [ebp-4C]
  00408A2D   .  BA AC934000   mov     edx, 004093AC                    ;  ASCII "dttom"
  00408A32   .  B9 FF000000   mov     ecx, 0FF
  00408A37   .  E8 3CAEFFFF   call    00403878                         ;  计算用户名长度
  00408A3C   .  837D B4 00    cmp     dword ptr [ebp-4C], 0
  00408A40   .  75 1C         jnz     short 00408A5E
  00408A42   .  6A 40         push    40                               ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
  00408A44   .  68 788C4000   push    00408C78                         ; |Title = ""D7,"",A2,"",B2,"崽崾?
  00408A49   .  68 848C4000   push    00408C84                         ; |Text = "用",BB,"?,B2,"",BB,"能为空请输入?,A1,""
  00408A4E   .  8B45 08       mov     eax, dword ptr [ebp+8]           ; |
  00408A51   .  50            push    eax                              ; |hOwner
  00408A52   .  E8 3DBDFFFF   call    <jmp.&user32.MessageBoxA>        ; \MessageBoxA
  00408A57   .  33DB          xor     ebx, ebx
  00408A59   .  E9 A2010000   jmp     00408C00
  00408A5E   >  68 FF000000   push    0FF                              ; /Count = FF (255.)
  00408A63   .  68 AC944000   push    004094AC                         ; |Buffer = MD2Crack.004094AC
  00408A68   .  68 F3030000   push    3F3                              ; |ControlID = 3F3 (1011.)
  00408A6D   .  8B45 08       mov     eax, dword ptr [ebp+8]           ; |
  00408A70   .  50            push    eax                              ; |hWnd
  00408A71   .  E8 E6BCFFFF   call    <jmp.&user32.GetDlgItemTextA>    ; \GetDlgItemTextA
  00408A76   .  8D45 B0       lea     eax, dword ptr [ebp-50]
  00408A79   .  BA AC944000   mov     edx, 004094AC                    ;  ASCII "55556666"
  00408A7E   .  B9 FF000000   mov     ecx, 0FF
  00408A83   .  E8 F0ADFFFF   call    00403878                         ;  计算假注册码长度
  00408A88   .  837D B0 00    cmp     dword ptr [ebp-50], 0
  00408A8C   .  75 1C         jnz     short 00408AAA
  00408A8E   .  6A 40         push    40                               ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
  00408A90   .  68 788C4000   push    00408C78                         ; |Title = ""D7,"",A2,"",B2,"崽崾?
  00408A95   .  68 9C8C4000   push    00408C9C                         ; |Text = ""D7,"",A2,"",B2,"崧?,B2,"",BB,"能为空请输入?,A1,""
  00408A9A   .  8B45 08       mov     eax, dword ptr [ebp+8]           ; |
  00408A9D   .  50            push    eax                              ; |hOwner
  00408A9E   .  E8 F1BCFFFF   call    <jmp.&user32.MessageBoxA>        ; \MessageBoxA
  00408AA3   .  33DB          xor     ebx, ebx
  00408AA5   .  E9 56010000   jmp     00408C00
  00408AAA   >  33C0          xor     eax, eax
  00408AAC   .  55            push    ebp
  00408AAD   .  68 2C8B4000   push    00408B2C
  00408AB2   .  64:FF30       push    dword ptr fs:[eax]
  00408AB5   .  64:8920       mov     dword ptr fs:[eax], esp
  00408AB8   .  8D45 A8       lea     eax, dword ptr [ebp-58]
  00408ABB   .  BA AC934000   mov     edx, 004093AC                    ;  ASCII "dttom"
  00408AC0   .  B9 FF000000   mov     ecx, 0FF
  00408AC5   .  E8 AEADFFFF   call    00403878                         ;计算用户名长度
  00408ACA   .  8B45 A8       mov     eax, dword ptr [ebp-58]
  00408ACD   .  8D55 AC       lea     edx, dword ptr [ebp-54]
  00408AD0   .  E8 EBFCFFFF   call    004087C0                         ;关键CALL,注册码的计算子过程
  00408AD5   .  8B45 AC       mov     eax, dword ptr [ebp-54]
  00408AD8   .  50            push    eax
  00408AD9   .  8D45 A4       lea     eax, dword ptr [ebp-5C]
  00408ADC   .  BA AC944000   mov     edx, 004094AC                    ;  ASCII "55556666"
  00408AE1   .  B9 FF000000   mov     ecx, 0FF
  00408AE6   .  E8 8DADFFFF   call    00403878
  00408AEB   .  8B55 A4       mov     edx, dword ptr [ebp-5C]
  00408AEE   .  58            pop     eax
  00408AEF   .  E8 FCAEFFFF   call    004039F0
  00408AF4   .  75 17         jnz     short 00408B0D
  ......
  
  00408AD0  处点F7跟进分析,省掉一些字符长度检查,结构化异常安装等代码,找到关键计算408840,F7跟进
  
  0040883E   .  8BD3          mov     edx, ebx
  00408840   .  E8 03FBFFFF   call    00408348                        ;  注册计算函数 F7跟进
  00408845   .  8B55 F8       mov     edx, dword ptr [ebp-8]
  .......
  来到下面一段函数
  ......
  00408371  |.  8B55 08       mov     edx, dword ptr [ebp+8]
  00408374  |.  8D45 F0       lea     eax, dword ptr [ebp-10]
  00408377  |.  E8 50FFFFFF   call    004082CC                        ;  call后出现注册码  F7跟进
  .........
  004082FD  |.  8D55 FC       lea     edx, dword ptr [ebp-4]
  00408300  |.  8B03          mov     eax, dword ptr [ebx]
  00408302  |.  E8 6DFEFFFF   call    00408174                        ;  计算出注册码   F7跟进
  
  来到下面一段函数,这一块函数到了我们的加密函数的核地带
  
  00408174  /$  55            push    ebp
  00408175  |.  8BEC          mov     ebp, esp
  00408177  |.  83C4 F8       add     esp, -8
  0040817A  |.  53            push    ebx
  0040817B  |.  56            push    esi
  0040817C  |.  57            push    edi
  0040817D  |.  33C9          xor     ecx, ecx
  0040817F  |.  894D F8       mov     dword ptr [ebp-8], ecx
  00408182  |.  8BFA          mov     edi, edx
  00408184  |.  8BF0          mov     esi, eax
  00408186  |.  33C0          xor     eax, eax
  00408188  |.  55            push    ebp
  00408189  |.  68 07824000   push    00408207                        ;  安装结构化异常处理程序
  0040818E  |.  64:FF30       push    dword ptr fs:[eax]
  00408191  |.  64:8920       mov     dword ptr fs:[eax], esp
  00408194  |.  33C0          xor     eax, eax
  00408196  |.  8A46 40       mov     al, byte ptr [esi+40]           ;  将用户名长度传入al
  00408199  |.  BA 10000000   mov     edx, 10
  0040819E  |.  2BD0          sub     edx, eax                        ;  计算出需要附加字符长度(padLen)
  004081A0  |.  8955 FC       mov     dword ptr [ebp-4], edx
  004081A3  |.  8B5D FC       mov     ebx, dword ptr [ebp-4]
  004081A6  |.  4B            dec     ebx
  004081A7  |.  85DB          test    ebx, ebx
  004081A9  |.  72 0E         jb      short 004081B9
  004081AB  |.  43            inc     ebx
  004081AC  |>  8A55 FC       /mov     dl, byte ptr [ebp-4]
  004081AF  |.  8BC6          |mov     eax, esi
  004081B1  |.  E8 A2FEFFFF   |call    00408058                       ;  输入数据内存copy及附加字符串,保证字串MOD 16=0
  004081B6  |.  4B            |dec     ebx
  004081B7  |.^ 75 F3         \jnz     short 004081AC
  004081B9  |>  33DB          xor     ebx, ebx
  004081BB  |>  8A541E 30     /mov     dl, byte ptr [esi+ebx+30]
  004081BF  |.  8BC6          |mov     eax, esi
  004081C1  |.  E8 92FEFFFF   |call    00408058                       ;  附加checksum处理
  004081C6  |.  43            |inc     ebx
  004081C7  |.  83FB 10       |cmp     ebx, 10
  004081CA  |.^ 75 EF         \jnz     short 004081BB
  004081CC  |.  33DB          xor     ebx, ebx
  004081CE  |>  33C0          /xor     eax, eax
  004081D0  |.  8A041E        |mov     al, byte ptr [esi+ebx]
  004081D3  |.  33D2          |xor     edx, edx
  004081D5  |.  52            |push    edx
  004081D6  |.  50            |push    eax
  004081D7  |.  8D55 F8       |lea     edx, dword ptr [ebp-8]
  004081DA  |.  B0 02         |mov     al, 2
  004081DC  |.  E8 BFFDFFFF   |call    00407FA0                       ;  更新checksum
  004081E1  |.  8B55 F8       |mov     edx, dword ptr [ebp-8]
  004081E4  |.  8BC7          |mov     eax, edi
  ......
  
  在4081B1处F7可以来到下面一段加密块计算过程如下,在加密块前有载入静态表的一些准备工作,代码不贴了大家自己跟吧
  004080D5  |.  33C0          xor     eax, eax
  004080D7  |.  C64424 04 00  mov     byte ptr [esp+4], 0
  004080DC  |>  8B1424        /mov     edx, dword ptr [esp]           ;  加密块计算过程
  004080DF  |.  B1 08         |mov     cl, 8
  004080E1  |>  25 FF000000   |/and     eax, 0FF
  004080E6  |.  8A0406        ||mov     al, byte ptr [esi+eax]
  004080E9  |.  3002          ||xor     byte ptr [edx], al
  004080EB  |.  8A02          ||mov     al, byte ptr [edx]
  004080ED  |.  42            ||inc     edx
  004080EE  |.  25 FF000000   ||and     eax, 0FF
  004080F3  |.  8A0406        ||mov     al, byte ptr [esi+eax]
  004080F6  |.  3002          ||xor     byte ptr [edx], al
  004080F8  |.  8A02          ||mov     al, byte ptr [edx]
  004080FA  |.  42            ||inc     edx
  004080FB  |.  25 FF000000   ||and     eax, 0FF
  00408100  |.  8A0406        ||mov     al, byte ptr [esi+eax]
  00408103  |.  3002          ||xor     byte ptr [edx], al
  00408105  |.  8A02          ||mov     al, byte ptr [edx]
  00408107  |.  42            ||inc     edx
  00408108  |.  25 FF000000   ||and     eax, 0FF
  0040810D  |.  8A0406        ||mov     al, byte ptr [esi+eax]
  00408110  |.  3002          ||xor     byte ptr [edx], al
  00408112  |.  8A02          ||mov     al, byte ptr [edx]
  00408114  |.  42            ||inc     edx
  00408115  |.  25 FF000000   ||and     eax, 0FF
  0040811A  |.  8A0406        ||mov     al, byte ptr [esi+eax]
  0040811D  |.  3002          ||xor     byte ptr [edx], al
  0040811F  |.  8A02          ||mov     al, byte ptr [edx]
  00408121  |.  42            ||inc     edx
  00408122  |.  25 FF000000   ||and     eax, 0FF
  00408127  |.  8A0406        ||mov     al, byte ptr [esi+eax]
  0040812A  |.  3002          ||xor     byte ptr [edx], al
  0040812C  |.  8A02          ||mov     al, byte ptr [edx]
  0040812E  |.  42            ||inc     edx
  0040812F  |.  FEC9          ||dec     cl
  00408131  |.^ 75 AE         |\jnz     short 004080E1
  00408133  |.  024424 04     |add     al, byte ptr [esp+4]
  00408137  |.  FE4424 04     |inc     byte ptr [esp+4]
  0040813B  |.  807C24 04 12  |cmp     byte ptr [esp+4], 12
  00408140  |.^ 75 9A         \jnz     short 004080DC
  
  对应c语言如下:
    t = 0;
    for (i = 0; i < 18; i++) {
      for (j = 0; j < 48; j++)
        t = x[j] ^= PI_SUBST[t];
      t = (t + i) & 0xff;
    }
  其它则是一些收尾工作,具体代码就不贴出来了。
  下面就是写汇编注册机,最近工作比较忙,这个等我有时间学会了再写,现在256个数的数组在汇编里怎么设置还不会,等学会了再写,先把算法
  分析发上。
  
  
--------------------------------------------------------------------------------
【经验总结】
  汇编带码里函数的嵌套比较多,但是对着C语言代码来看相对要容易多了。
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2008年02月20日 上午 09:35:00


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

收藏
免费 7
支持
分享
最新回复 (3)
雪    币: 485
活跃值: (12)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
2
算法分析的很棒,学习。。。
2008-2-20 10:01
0
雪    币: 479
活跃值: (25)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
3
petnt过奖了我也是刚刚入门,自己分析了,留点笔记方便一下后来人。
2008-2-20 15:15
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
学习了.强顶.
2008-2-21 07:31
0
游客
登录 | 注册 方可回帖
返回
//