首页
社区
课程
招聘
[原创]HappyTown的第21个CrackMe分析
2006-10-13 10:01 6727

[原创]HappyTown的第21个CrackMe分析

2006-10-13 10:01
6727
【文章标题】: HappyTown的第21个CrackMe分析
【文章作者】: Horst Stein
【作者邮箱】: [email]horststein@hotmail.com[/email]
【软件名称】: HappyTown's CrackMe_0021
【下载地址】: http://bbs.pediy.com/showthread.php?s=&threadid=32213
【保护方式】: 序列号
【使用工具】: OD,PEiD,Kanal,IDA,W32DSAM,DAMN_HashCalc,OpenSSL库
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  首先感谢HappyTown为我们带来这么好的CrackMe。
  用到了OpenSSL库。
  
  一、基本情况分析:
      1. 用PEiD分析,发现未加壳;
      2. 用Kanal查看得知使用了MD5,用IDA加载openssl的sig文件后,导出MAP文件;
      3. 随便输入信息,发现未有出错提示;
      4. 但用W32DASM发现了Congratulations。它的前面有个je的跳转,再往前有个call 00401130在00401081处。
  
  二、正式开工:
      1. OD载入,用bp 401081下断点,并加载刚才生成的MAP文件;
      2. 运行程序,输入假码:
      name: HorstStein
      sn:9876543210ABCDEF (为什么是16个字符,请看下面)
      3. 点击Check被断,进入00401130:
  
  00401130  />sub     esp, 3CC
  00401136  |>push    ebx
  00401137  |>push    ebp
  00401138  |>push    esi
  00401139  |>push    edi
  0040113A  |>mov     ecx, 31
  0040113F  |>xor     eax, eax
  00401141  |>lea     edi, [esp+165]
  00401148  |>mov     byte ptr [esp+164], 0
  00401150  |>rep     stos dword ptr es:[edi]
  00401152  |>stos    word ptr es:[edi]
  00401154  |>stos    byte ptr es:[edi]
  00401155  |>mov     ecx, 31
  0040115A  |>xor     eax, eax
  0040115C  |>lea     edi, [esp+41]
  00401160  |>mov     byte ptr [esp+40], 0
  00401165  |>rep     stos dword ptr es:[edi]
  00401167  |>stos    word ptr es:[edi]
  00401169  |>stos    byte ptr es:[edi]
  0040116A  |>mov     esi, [esp+3E0]
  00401171  |>xor     eax, eax
  00401173  |>mov     edi, [<&USER32.GetDlgItemTextA>]          ;  USER32.GetDlgItemTextA
  00401179  |>mov     [esp+29], eax
  0040117D  |>mov     [esp+2D], eax
  00401181  |>xor     ecx, ecx
  00401183  |>lea     edx, [esp+164]
  0040118A  |>mov     [esp+31], eax
  0040118E  |>mov     [esp+21], ecx
  00401192  |>push    0C9                                       ; /Count = C9 (201.)
  00401197  |>push    edx                                       ; |Buffer
  00401198  |>mov     [esp+3D], ax                              ; |
  0040119D  |>mov     ebx, 4                                    ; |
  004011A2  |>mov     [esp+2D], cx                              ; |
  004011A7  |>push    3E8                                       ; |ControlID = 3E8 (1000.)
  004011AC  |>push    esi                                       ; |hWnd
  004011AD  |>mov     byte ptr [esp+38], 0                      ; |
  004011B2  |>mov     [esp+47], al                              ; |
  004011B6  |>mov     [esp+20], bl                              ; |//密钥从[esp+20]开始;bl=04
  004011BA  |>mov     byte ptr [esp+21], 0B5                    ; |
  004011BF  |>mov     byte ptr [esp+22], 52                     ; |
  004011C4  |>mov     byte ptr [esp+23], 6C                     ; |
  004011C9  |>mov     byte ptr [esp+24], 0DC                    ; |
  004011CE  |>mov     byte ptr [esp+25], 6                      ; |
  004011D3  |>mov     byte ptr [esp+26], 0C4                    ; |
  004011D8  |>mov     byte ptr [esp+27], 0DF                    ; |
  004011DD  |>mov     byte ptr [esp+28], 87                     ; |
  004011E2  |>mov     byte ptr [esp+29], 0C2                    ; |
  004011E7  |>mov     byte ptr [esp+2A], 0AA                    ; |
  004011EC  |>mov     byte ptr [esp+2B], 75                     ; |
  004011F1  |>mov     byte ptr [esp+2C], 0DE                    ; |
  004011F6  |>mov     byte ptr [esp+2D], 7                      ; |
  004011FB  |>mov     [esp+2E], bl                              ; |bl=04
  004011FF  |>mov     byte ptr [esp+2F], 8                      ; |\\密钥到[esp+2F]结束,长度16
  00401204  |>mov     [esp+30], al                              ; |
  00401208  |>mov     [esp+37], cl                              ; |
  0040120C  |>call    edi                                       ; \GetDlgItemTextA
  0040120E  |>mov     ebp, eax                                  ;  len(name)
  00401210  |>cmp     ebp, ebx                                  ;  name长度不小于4
  00401212  |>jge     short 00401221
  00401214  |>pop     edi
  00401215  |>pop     esi
  00401216  |>pop     ebp
  00401217  |>xor     eax, eax
  00401219  |>pop     ebx
  0040121A  |>add     esp, 3CC
  00401220  |>retn
  00401221  |>lea     eax, [esp+40]
  00401225  |>push    0C9
  0040122A  |>push    eax
  0040122B  |>push    3E9
  00401230  |>push    esi
  00401231  |>call    edi                                       ;  取输入的sn
  00401233  |>cmp     eax, 10                                   ;  注册码长度必须为16
  00401236  |>je      short 00401245
  00401238  |>pop     edi
  00401239  |>pop     esi
  0040123A  |>pop     ebp
  0040123B  |>xor     eax, eax
  0040123D  |>pop     ebx
  0040123E  |>add     esp, 3CC
  00401244  |>retn
  00401245  |>xor     esi, esi
  00401247  |>/cmp     dword ptr [4082E8], 1                    ;  // 检查输入的序列号sn是否为16进制数,同时转化为小写
  0040124E  |>|jle     short 00401265
  00401250  |>|movsx   ecx, byte ptr [esp+esi+40]
  00401255  |>|push    80
  0040125A  |>|push    ecx
  0040125B  |>|call    <__isctype>
  00401260  |>|add     esp, 8
  00401263  |>|jmp     short 00401277
  00401265  |>|movsx   edx, byte ptr [esp+esi+40]
  0040126A  |>|mov     eax, [4080DC]
  0040126F  |>|mov     al, [eax+edx*2]
  00401272  |>|and     eax, 80
  00401277  |>|test    eax, eax
  00401279  |>|je      short 00401214
  0040127B  |>|movsx   ecx, byte ptr [esp+esi+40]
  00401280  |>|push    ecx
  00401281  |>|call    <_tolower>
  00401286  |>|add     esp, 4
  00401289  |>|mov     [esp+esi+40], al
  0040128D  |>|inc     esi
  0040128E  |>|cmp     esi, 10
  00401291  |>\jl      short 00401247                           ;  \\
  00401293  |>xor     edi, edi
  00401295  |>lea     esi, [esp+41]
  00401299  |>/cmp     dword ptr [4082E8], 1                    ;  //把sn转化成对应的十六进制
  004012A0  |>|jle     short 004012B3
  004012A2  |>|movsx   edx, byte ptr [esi-1]
  004012A6  |>|push    2
  004012A8  |>|push    edx
  004012A9  |>|call    <__isctype>
  004012AE  |>|add     esp, 8
  004012B1  |>|jmp     short 004012C3
  004012B3  |>|movsx   eax, byte ptr [esi-1]
  004012B7  |>|mov     ecx, [4080DC]                            ;  CrackMe_.004080E6
  004012BD  |>|mov     al, [ecx+eax*2]
  004012C0  |>|and     eax, 2
  004012C3  |>|mov     bl, [esi-1]
  004012C6  |>|test    eax, eax
  004012C8  |>|jnz     short 004012CF
  004012CA  |>|sub     bl, 30
  004012CD  |>|jmp     short 004012D2
  004012CF  |>|sub     bl, 57
  004012D2  |>|cmp     dword ptr [4082E8], 1
  004012D9  |>|jle     short 004012EB
  004012DB  |>|movsx   edx, byte ptr [esi]
  004012DE  |>|push    2
  004012E0  |>|push    edx
  004012E1  |>|call    <__isctype>
  004012E6  |>|add     esp, 8
  004012E9  |>|jmp     short 004012FA
  004012EB  |>|movsx   eax, byte ptr [esi]
  004012EE  |>|mov     ecx, [4080DC]                            ;  CrackMe_.004080E6
  004012F4  |>|mov     al, [ecx+eax*2]
  004012F7  |>|and     eax, 2
  004012FA  |>|test    eax, eax
  004012FC  |>|mov     al, [esi]
  004012FE  |>|jnz     short 00401304
  00401300  |>|sub     al, 30
  00401302  |>|jmp     short 00401306
  00401304  |>|sub     al, 57
  00401306  |>|shl     bl, 4
  00401309  |>|or      bl, al
  0040130B  |>|add     esi, 2
  0040130E  |>|mov     [esp+edi+20], bl
  00401312  |>|inc     edi
  00401313  |>|cmp     edi, 8
  00401316  |>\jl      short 00401299                           ;  \\
  00401318  |>lea     edx, [esp+108]
  0040131F  |>push    edx
  00401320  |>call    <MD5_Init>
  
  //MD5_Init:
      00401B80 >/>mov     eax, [esp+4]                              ;  MD5_Init
      00401B84  |>xor     ecx, ecx
      00401B86  |>mov     dword ptr [eax], 67452301                 ;  //MD5的4个常数
      00401B8C  |>mov     dword ptr [eax+4], EFCDAB89
      00401B93  |>mov     dword ptr [eax+8], 98BADCFE
      00401B9A  |>mov     dword ptr [eax+C], 10325476               ;  \\
      00401BA1  |>mov     [eax+10], ecx
      00401BA4  |>mov     [eax+14], ecx
      00401BA7  |>mov     [eax+58], ecx
      00401BAA  |>mov     eax, 1
      00401BAF  \>retn
  \\
      
  00401325  |>lea     eax, [esp+168]
  0040132C  |>push    ebp                                       ;  len(name)
  0040132D  |>lea     ecx, [esp+110]
  00401334  |>push    eax                                       ;  name
  00401335  |>push    ecx
  00401336  |>call    <MD5_Update>
  0040133B  |>lea     edx, [esp+118]
  00401342  |>lea     eax, [esp+38]
  00401346  |>push    edx
  00401347  |>push    eax                                       ;  //在这里先d eax
  00401348  |>call    <MD5_Final>
  0040134D  |>lea     ecx, [esp+244]                            ;  \\看内存区,MD5(HorstStein)=82E0134547E6AF1C4D677811201710E7
  00401354  |>lea     edx, [esp+28]
  00401358  |>push    ecx                                       ;  由openssl库idea.h头文件可知此乃IDEA_KEY_SCHEDULE结构,即存放子密钥的地方
  00401359  |>push    edx                                       ;  用于IDEA的key:04 B5 52 6C...向上翻翻看:D
  0040135A  |>call    <_idea_set_encrypt_key>                   ;  设置IDEA加密密钥
  0040135F  |>lea     eax, [esp+324]
  00401366  |>lea     ecx, [esp+24C]
  0040136D  |>push    eax
  0040136E  |>push    ecx
  0040136F  |>call    <idea_set_decrypt_key>                    ;  设置IDEA解密密钥
  00401374  |>lea     edx, [esp+32C]
  0040137B  |>lea     eax, [esp+60]
  0040137F  |>push    edx
  00401380  |>lea     ecx, [esp+4C]
  00401384  |>push    eax
  00401385  |>push    ecx                                       ;  sn
  00401386  |>call    <_idea_ecb_encrypt>                       ;  解密sn(ecb模式)
  0040138B  |>add     esp, 34
  0040138E  |>mov     ecx, 2
  00401393  |>lea     edi, [esp+28]
  00401397  |>lea     esi, [esp+38]
  0040139B  |>xor     edx, edx
  0040139D  |>repe    cmps dword ptr es:[edi], dword ptr [esi]
  0040139F  |>pop     edi
  004013A0  |>mov     eax, edx
  004013A2  |>pop     esi
  004013A3  |>pop     ebp
  004013A4  |>sete    al
  004013A7  |>pop     ebx
  004013A8  |>add     esp, 3CC
  004013AE  \>retn
  
  三、其验证算法:
      1. h=MD5(name);
      2. x=IDEA(sn,Decrypt);
      3. 判断h=x否,相等则成功,不等则失败
  
  两组可用的注册码:
  name:HorstStein
  sn:03CDCA61C437218C
  
  name:pediy
  sn:6A46FF71FCCAAC76
  
  四、注册机算法及其代码:
      1. 算法:IDEA(MD5(name),Encrypt)。
      2. 代码(用到了OpenSSL库):
  
  int main()
  {
          int i;
          int nLenName;                                //name长度
        char szName[150] = {0};                 //存放name
        MD5_CTX md5;
          unsigned char MD5Name[16] = {0};        //存放MD5(szName)的消息摘要
          unsigned char cSerial_test[8] = {0};        //临时存放注册码
          unsigned char outEn[8];                        //存放IDEA的输出
          unsigned char szBuffer[150]={0};        //存放注册码
          IDEA_KEY_SCHEDULE key;                        //存放IDEA加密子密钥
          unsigned char k[16] = {        0x04,0xB5,0x52,0x6C,0xDC,0x06,0xC4,0xDF,
                                  0x87,0xC2,0xAA,0x75,0xDE,0x07,0x04,0x08};//IDEA密钥
  
        printf("Enter your name:");
        scanf("%s",szName);
  
          //MD5(szName)
          MD5_Init( &md5);
          MD5_Update( &md5, szName, nLenName);
          MD5_Final( MD5Name, &md5);
  
          //设置IDEA加密密钥
          idea_set_encrypt_key(k,&key);
  
          for (i=0; i<8; i++)
          {
                  cSerial_test[i] = MD5Name[i];       
          }
  
        //加密MD5(name)
          idea_ecb_encrypt(cSerial_test,outEn,&key);
  
          for (i=0; i<8; i++)
          {
                  wsprintf(&szBuffer[i*2], "%02X", *(byte*)(outEn+i));
          }
        printf("\nSN:%s\n",szBuffer);
        return 0;
  }
  
--------------------------------------------------------------------------------
【经验总结】
  这个CrackMe的验证方式和很多使用RSA的CrackMe的验证方式类似,所以,值得我等菜鸟一学。
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2005年10月09日 19:28:08

[培训]科锐软件逆向50期预科班报名即将截止,速来!!! 50期正式班报名火爆招生中!!!

收藏
免费 7
打赏
分享
最新回复 (7)
雪    币: 270
活跃值: (176)
能力值: ( LV12,RANK:370 )
在线值:
发帖
回帖
粉丝
ikki 9 2006-10-13 12:20
2
0
HappyTown的Crackme
HorstStein的帖子都写的很好,学习。
雪    币: 405
活跃值: (10)
能力值: ( LV9,RANK:1130 )
在线值:
发帖
回帖
粉丝
binbinbin 28 2006-10-13 12:53
3
0
佩服佩服,学习学习。这个加密方法我没懂
雪    币: 309
活跃值: (15)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
网游难民 15 2006-10-14 10:59
4
0

偶发现这个好难,算法一出来偶就听说了~~
认真学习 下啊~~
雪    币: 233
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
DCracker 2 2006-10-14 13:21
5
0
支持!!!
雪    币: 342
活跃值: (318)
能力值: ( LV12,RANK:740 )
在线值:
发帖
回帖
粉丝
aalloverred 18 2006-10-14 18:05
6
0
嗯,不错,学习了。
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
lnhfng 2006-10-14 21:45
7
0
楼主是如何判断使用了OpenSSL函数的?有何特征?
雪    币: 35
能力值: (RANK:210 )
在线值:
发帖
回帖
粉丝
HorstStein 5 2006-10-17 20:56
8
0
最初由 lnhfng 发布
楼主是如何判断使用了OpenSSL函数的?有何特征?


原贴有人提示过。
游客
登录 | 注册 方可回帖
返回