中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 看雪学院专区 > CrackMe
KEYFILE分析实例
作者:佚名 时间:2006-12-14 21:27 出处:pediy.com 责编:月夜寒箫
              摘要:KEYFILE分析实例
【破文标题】KEYFILE实例分析(简单)
【破文作者】逍遥风
【作者邮箱】tc-xb@163.com
【破解工具】OD winHex
【破解平台】winXp
【软件名称】FaNt0m's CrackMe #6
【原版下载】www.crackmes.de
----------------------------------------------------------------------
最近有好多CRACKME的分析但很少见KF类型的.
所以写一个简单的KEYFILE的CRACKMEDE的分析。过程比较典型,拿来与广大菜鸟享。
高手见笑。
话不多说。直接开始。
对付这类简单的KEYFILE,可以按找两个大的步骤进行
1)找出KEY文件的文件名
用OD载入这个CRACKME。
先用字符串查找看看能不能得到些有用的信息。打开字符串参考(如图1)。成功与失败的提示都有,看来重要的线索已经找到了。
双击任意一个提示,就来到了相对应的代码处。
0040116C  |> \6A 10         PUSH 10                                  ; /Style = MB_OK|MB_ICONHAND|MB_APPLMODAL
0040116E  |.  68 23304000   PUSH CRACKME6.00403023                   ; |error!
00401173  |.  68 52304000   PUSH CRACKME6.00403052                   ; |invalid key!
00401178  |.  6A 00         PUSH 0                                   ; |hOwner = NULL
0040117A  |.  E8 2F000000   CALL <JMP.&USER32.MessageBoxA>           ; \MessageBoxA
0040117F  |.  EB 15         JMP SHORT CRACKME6.00401196
00401181  |>  6A 40         PUSH 40                                  ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
00401183  |.  68 76304000   PUSH CRACKME6.00403076                   ; |correct!!!
00401188  |.  68 5F304000   PUSH CRACKME6.0040305F                   ; |correct key! good job!
0040118D  |.  6A 00         PUSH 0                                   ; |hOwner = NULL
0040118F  |.  E8 1A000000   CALL <JMP.&USER32.MessageBoxA>           ; \MessageBoxA
我们的目标不是这些,而是根据这些提示找到验证开始的地方。从这段代码开始向上找,由于这个CRACKME是KEYFILE型的
所以一般情况下我们的目标就是要找到CreateFileA这个函数。一路向上找到这里。
004010E1  /$  6A 00         PUSH 0                                   ; /hTemplateFile = NULL(下断点)
004010E3  |.  68 80000000   PUSH 80                                  ; |Attributes = NORMAL
004010E8  |.  6A 03         PUSH 3                                   ; |Mode = OPEN_EXISTING
004010EA  |.  6A 00         PUSH 0                                   ; |pSecurity = NULL
004010EC  |.  6A 01         PUSH 1                                   ; |ShareMode = FILE_SHARE_READ
004010EE  |.  68 00000080   PUSH 80000000                            ; |Access = GENERIC_READ
004010F3  |.  68 17304000   PUSH CRACKME6.00403017                   ; |keyfile.dat (注意这个)
004010F8  |.  E8 BD000000   CALL <JMP.&KERNEL32.CreateFileA>         ; \CreateFileA
找到这个函数了,注意它的上面有一个keyfile.dat。没错这就是我们要找的KEY文件的文件名了。
第一个目标已经完成了。现在打开WINHEX新建一个文件,字节数先随便输入一个但要记住。已10个字节为例建立
一个名位keyfile.dat的文件(如图2),保存。在004010E1处下断点,用OD重新载入。
2)开始跟踪,
在CRACKME中点击CHECK后程序中断了。
下面就开始了一个典型的KEYFILE验证过程。这个过程可以分为三个步骤
第一步:查找KEY文件。
004010F8  |.  E8 BD000000   CALL <JMP.&KERNEL32.CreateFileA>         ; \CreateFileA
004010FD  |.  A3 88304000   MOV DWORD PTR DS:[403088],EAX            ;  开始读文件
00401102  |.  83F8 FF       CMP EAX,-1                               ;  文件存在吗
00401105  |.  75 14         JNZ SHORT CRACKME6.0040111B              ;  KEY文件已存在就继续验证,不存在就跳出错误提示
00401107  |.  6A 10         PUSH 10                                  ; /Style = MB_OK|MB_ICONHAND|MB_APPLMODAL
00401109  |.  68 23304000   PUSH CRACKME6.00403023                   ; |error!
0040110E  |.  68 2A304000   PUSH CRACKME6.0040302A                   ; |key file not found!
00401113  |.  6A 00         PUSH 0                                   ; |hOwner = NULL
00401115  |.  E8 94000000   CALL <JMP.&USER32.MessageBoxA>           ; \MessageBoxA
如果没有一个名为“keyfile.dat”的文件,那么就会出现key file not found。
第二步:检验KEY文件
联系上一段代码中的“JNZ SHORT CRACKME6.0040111B”如果KEY文件存在就会来到这里
0040111B  |> \6A 00         PUSH 0                                   ; /pOverlapped = NULL
0040111D  |.  68 96304000   PUSH CRACKME6.00403096                   ; |pBytesRead = CRACKME6.00403096
00401122  |.  6A 0A         PUSH 0A                                  ; |BytesToRead = A (10.)
00401124  |.  68 8C304000   PUSH CRACKME6.0040308C                   ; |Buffer = CRACKME6.0040308C
00401129  |.  FF35 88304000 PUSH DWORD PTR DS:[403088]               ; |hFile = 00000080 (window)
0040112F  |.  E8 98000000   CALL <JMP.&KERNEL32.ReadFile>            ; \ReadFile
00401134  |.  83F8 00       CMP EAX,0                                ; 
00401137  |.  75 15         JNZ SHORT CRACKME6.0040114E              ;
00401139  |.  6A 10         PUSH 10                                  ; /Style = MB_OK|MB_ICONHAND|MB_APPLMODAL
0040113B  |.  68 23304000   PUSH CRACKME6.00403023                   ; |error!
00401140  |.  68 3E304000   PUSH CRACKME6.0040303E                   ; |error reading file!
00401145  |.  6A 00         PUSH 0                                   ; |hOwner = NULL
00401147  |.  E8 62000000   CALL <JMP.&USER32.MessageBoxA>           ; \MessageBoxA
这可以看作是对KEY文件的一个检验过程。可以理解为“这个KEY文件可读吗?”。不同的CRACKME对KEY文件的要求是不一样的。大多数KEYFILE型的CRACKME都会用
GetFileSize这个函数来检验文件的字节数是否符合要求。
例:http://bbs.pediy.com/showthread.php?s=&threadid=23785
    http://bbs.pediy.com/showthread.php?s=&threadid=25086
第三步:读取KEY文件。
经过了前面两步,程序就开始读取KEY文件的内容了。程序是按怎样的顺序读取文件的内容呢?
0040114E  |> \8D15 8C304000 LEA EDX,DWORD PTR DS:[40308C]            ;  取KEY文件的内容放进EDX中
为什么说这句代码就是取KEY文件的内容的?
在F8单步到这一句时,在命令行输入命令:d 40308C.显示的结果(如图3)。地址40308C处的内容就是KEY文件的内容
所以程序在这里将KEY文件的内容放进了EDX中
00401154  |.  83C2 05       ADD EDX,5                                ;  EDX=EDX+5(即:取文件的第6个字节的内容)
为什么说是取文件的第6个字节的内容呢?
在执行这段代码前注意EDX的值(如图4) ,执行过ADD EDX,5后EDX的值(如图5)
在命令行输入命令:d 403091结果(如图6)。地址403091处的内容正是KEY文件中第6字节的内容,所以程序在这里读取了文件第6字节的内容。
00401157  |.  803A 31       CMP BYTE PTR DS:[EDX],31                 ;  第六个字节的内容与0x31相比较
0040115A  |.  75 10         JNZ SHORT CRACKME6.0040116C              ;  不相等就跳向失败
0040115C  |.  83C2 03       ADD EDX,3                                ;  EDX=EDX+3(即:取KEY文件第9个字节的内容)
执行过这一句后在一次注意EDX的值,(如图7)。在命令行输入d 403094
结果(如图8) 
0040115F  |.  803A 33       CMP BYTE PTR DS:[EDX],33                 ;  第9个字节的内容与0x33相比较
00401162  |.  75 08         JNZ SHORT CRACKME6.0040116C              ;  不相等就跳向失败
00401164  |.  42            INC EDX                                  ;  EDX+1(即:取KEY文件的第10个字节的内容)
这里方法和上面一样,动手试一下。
00401165  |.  803A 30       CMP BYTE PTR DS:[EDX],30                 ;  第10个字节的内容与0x30相比较
00401168  |.  74 02         JE SHORT CRACKME6.0040116C               ;  相等就跳向失败
0040116A  |.  EB 15         JMP SHORT CRACKME6.00401181              ;  第10个字节的内容不等于0x30就成功
经过了一个简单的算法验证,如果符合算法要求就成功。
0040116C  |> \6A 10         PUSH 10                                  ; /Style = MB_OK|MB_ICONHAND|MB_APPLMODAL
0040116E  |.  68 23304000   PUSH CRACKME6.00403023                   ; |error!
00401173  |.  68 52304000   PUSH CRACKME6.00403052                   ; |invalid key!
00401178  |.  6A 00         PUSH 0                                   ; |hOwner = NULL
0040117A  |.  E8 2F000000   CALL <JMP.&USER32.MessageBoxA>           ; \MessageBoxA
0040117F  |.  EB 15         JMP SHORT CRACKME6.00401196
00401181  |>  6A 40         PUSH 40                                  ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
00401183  |.  68 76304000   PUSH CRACKME6.00403076                   ; |correct!!!
00401188  |.  68 5F304000   PUSH CRACKME6.0040305F                   ; |correct key! good job!
0040118D  |.  6A 00         PUSH 0                                   ; |hOwner = NULL
0040118F  |.  E8 1A000000   CALL <JMP.&USER32.MessageBoxA>           ; \MessageBoxA
总结一下
1)KEY文件的文件名必须是keyfile.dat
2)KEY文件的字节数必须大于9
3)KEY文件第6字节内容必须为31,第9字节内容必须为33,第10字节内容不能为30
所以用WINHEX建立的文件(如图9) 
----------------------------------------------------------------------
一点心得,希望对大家有所帮助
----------------------------------------------------------------------
【版权声明】本文只为交流,转载请保留作者及文章完整性
所上传文件
crackme6.rar (上传时间2006-07-21,12:28,99.8 KB,77 次点击)
关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有