首页
社区
课程
招聘
[原创]kiTo's keygenme破解分析(Base64+md5)
发表于: 2006-8-20 16:30 7530

[原创]kiTo's keygenme破解分析(Base64+md5)

2006-8-20 16:30
7530

【文章标题】: CRACKME破解分析
【文章作者】: 逍遥风
【下载地址】: crackmes.de
【使用工具】: OD
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
----------------------------------------------------------------------
【详细过程】
  
  CRACKME简介
  Keygen this little baby and submit your solution.
  
  Difficulty: 2 - Needs a little brain (or luck)
  Platform: Windows
  Language: Assembler
  
  
  PEID检查发现没有加壳,用OD载入后在命令行下断点
  BP GetDlgItemTextA。任意输入注册名和注册码后,程序中断了。
  
  提示:
  这个CRACKME用到了Base64和MD5两种算法,分析的时候要注意。
  
  0040110B  /$  55            push    ebp                   ;  从这里开始
  0040110C  |.  8BEC          mov     ebp, esp
  0040110E  |.  C605 D4324000>mov     byte ptr [4032D4], 0
  00401115  |.  6A 32         push    32                    ; /Count = 32 (50.)
  00401117  |.  68 70324000   push    00403270              ; |Buffer = kiToKGNm.00403270
  0040111C  |.  68 E9030000   push    3E9                   ; |ControlID = 3E9 (1001.)
  00401121  |.  FF75 08       push    dword ptr [ebp+8]     ; |hWnd
  00401124  |.  E8 E3080000   call    <jmp.&user32.GetDlgIt>; \GetDlgItemTextA
  00401129  |.  68 A2324000   push    004032A2              ;  取注册名
  0040112E  |.  50            push    eax                   ;  使EAX等于注册名位数
  0040112F  |.  68 70324000   push    00403270              ;  ASCII "lovetc"
  00401134  |.  E8 67070000   call    004018A0              ;  Base64(注册名)
  00401139  |.  68 A2324000   push    004032A2              ; /StringToAdd = "bG92ZXRj"
  0040113E  |.  68 D4324000   push    004032D4              ;
  00401143  |.  E8 A0080000   call    <jmp.&kernel32.lstrca>; \取Base64(注册名)的结果,设为字符串B
  
  
  先取注册名进行计算
  将注册名进行 Base64转换后,得到的结果设为  “字符串B”
  例如:注册名lovetc
  Base64(lovetc) = bG92ZXRj = 字符串B
  
  00401148  |.  68 3E324000   push    0040323E              ; /StringToAdd = "NTE0MDA4MjhOVEUwTURBNE=="
  0040114D  |.  68 D4324000   push    004032D4              ; |ConcatString = "bG92ZXRjNTE0MDA4MjhOVEUwTURBNE=="
  00401152  |.  E8 91080000   call    <jmp.&kernel32.lstrca>; \取字符串A(即显示的机器码)
  00401157  |.  68 D4324000   push    004032D4              ; /String = "bG92ZXRjNTE0MDA4MjhOVEUwTURBNE=="
  0040115C  |.  E8 93080000   call    <jmp.&kernel32.lstrle>; \合并字符串A与字符串B,得到字符串C
  
  将 “字符串A”(机器码)与“字符串B“(Base64[注册名])合并,得到字符串C
  
  字符串A(机器码) = NTE0MDA4MjhOVEUwTURBNE==
  字符串B(Base64[lovetc]) = bG92ZXRj
  所以:
  字符串C = bG92ZXRjNTE0MDA4MjhOVEUwTURBNE==
  
  00401161  |.  A3 A0314000   mov     [4031A0], eax         ;  使EAX等于字符串C的位数
  00401166  |.  E8 3D060000   call    004017A8              ;  MD5(字符串C)
  0040116B  |.  FF35 A0314000 push    dword ptr [4031A0]
  00401171  |.  68 D4324000   push    004032D4              ;  ASCII "bG92ZXRjNTE0MDA4MjhOVEUwTURBNE=="
  00401176  |.  E8 6D060000   call    004017E8
  0040117B  |.  E8 C8060000   call    00401848
  00401180  |.  33DB          xor     ebx, ebx              ;  MD5(字符串3)的结果被分成4个部分
  00401182  |.  0318          add     ebx, [eax]            ;  第一部分
  00401184  |.  0358 04       add     ebx, [eax+4]          ;  第二部分
  00401187  |.  0358 08       add     ebx, [eax+8]          ;  第三部分
  0040118A  |.  0358 0C       add     ebx, [eax+C]          ;  第四部分
  0040118D  |.  53            push    ebx                   ; /<%X>
  0040118E  |.  68 00304000   push    00403000              ; |将4部分的值相加后,得到结果设为A
  00401193  |.  68 38334000   push    00403338              ; |s = kiToKGNm.00403338
  00401198  |.  E8 5D080000   call    <jmp.&user32.wsprintf>; \wsprintfA
  
  将字符串C进行MD5计算,并将计算的结果分成4部分进行累加。
  
  是如何看出将MD5计算的结果进累加的呢?
  注册这里:
  00401182  |.  0318          add     ebx, [eax]            ;  第一部分
  00401184  |.  0358 04       add     ebx, [eax+4]          ;  第二部分
  00401187  |.  0358 08       add     ebx, [eax+8]          ;  第三部分
  0040118A  |.  0358 0C       add     ebx, [eax+C]          ;  第四部分
  发现,都是对EAX中的内容进行计算的。
  
  所以:在命令行下输入命令 “D EAX”
  
  显示结果如下:
  
  004033F0  BE 4F 32 EE 9A C0 2F 11 5C 1A C8 7A 11 71 3D 6D
  
  而MD5(bG92ZXRjNTE0MDA4MjhOVEUwTURBNE==) =  BE4F32EE9AC02F115C1AC87A11713D6D
  
  第一部分:EE324FBE
               +
  第二部分:112FC09A
               +
  第三部分:7AC81A5C
               +
  第四部分:6D3D7111
               =
  得到结果:E7679BC5 即:A=E7679BC5(这个值设为A)
  
  0040119D  |.  83C4 0C       add     esp, 0C
  004011A0  |.  C605 3C334000>mov     byte ptr [40333C], 2D ;  将结果A的第五位字母用符号“-”替换。得到新的结果设为B
  004011A7  |.  6A 32         push    32                    ; /Count = 32 (50.)
  004011A9  |.  68 6A334000   push    0040336A              ; |Buffer = kiToKGNm.0040336A
  004011AE  |.  68 EA030000   push    3EA                   ; |ControlID = 3EA (1002.)
  004011B3  |.  FF75 08       push    dword ptr [ebp+8]     ; |取输入的注册码
  004011B6  |.  E8 51080000   call    <jmp.&user32.GetDlgIt>; \GetDlgItemTextA
  004011BB  |.  68 6A334000   push    0040336A              ; /String2 = "1234567"
  004011C0  |.  68 38334000   push    00403338              ; |String1 = "E767-BC5"
  004011C5  |.  E8 24080000   call    <jmp.&kernel32.lstrcm>; \结果B与输入的注册码进行比较。
  
  最后一步处理:
  
  将A=E7679BC5 中的第五位 即9,用符号“-”替换
  
  得到的结果 E767-BC5 就是注册码
  
  所以:
  注册名:lovetc
  机器码:NTE0MDA4MjhOVEUwTURBNE==
  对应的注册码就是:E767-BC5
  
  
----------------------------------------------------------------------【算法总结】
1)合并机器码与BASE64(注册名)
2)将得到的字符串进行MD5计算
3)累加MD5计算的结果,并将累加结果的第5位用符号"-"替换,替换后的结果就是注册码
  
----------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2006年08月20日 16:21:49


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 7
支持
分享
最新回复 (2)
雪    币: 443
活跃值: (200)
能力值: ( LV9,RANK:1140 )
在线值:
发帖
回帖
粉丝
2
精彩,又有好文学习了!

2006-8-20 22:23
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
哈哈,逍遥兄强啊.....好教材学习了,,,,
2006-8-23 08:11
0
游客
登录 | 注册 方可回帖
返回
//