duelist crackme 2 破解(上) (6千字)

发布者:Editor
发布于:2000-10-17 15:08

duelist crackme 2 破解(上)      (希望转载的时候保持完整)

作者    丁丁虾  ddxia/[CCG]
目标     duelist crackme 2
目标URL    http:\\go.163.com\~ddxia\crackme\DueList\Due-cm2.zip
工具          SoftIce4.01 for NT  WinHex    winapi.hlp

    我们读一下它的readme.txt,就知道这是一道解keyfile类型crackme。

    keyfile类型解决方法:
        1、得到文件名
        2、通过分析代码来获得文件内容!

    首先运行它,看看有什么出错消息---->>"你的使用期限到了,请拷贝keyfile到

该目录下!"。它要读取文件一定用CreateFileA这个API函数。于是在目标程序运行前下

中断
    bpx CreateFileA
    被拦截下来,按F11回到程序代码中
001B:0040105C  6A00                    PUSH      00
001B:0040105E  686F214000    PUSH      0040216F
001B:00401063  6A03                    PUSH      03
001B:00401065  6A00          PUSH      00
001B:00401067  6A03                  PUSH      03
001B:00401069  68000000C0    PUSH      C0000000
001B:0040106E  6879204000      PUSH      00402079
001B:00401073  E80B020000    CALL      KERNEL32!CreateFileA
001B:00401078  83F8FF              CMP      EAX,-01
            ^^^^^^^^^^^^^^^^^^^^^^^^^^------>如果打开文件失败,eax=-01
001B:0040107B  751D                  JNZ      0040109A 
001B:0040107D  6A00                  PUSH      00
001B:0040107F  6801204000      PUSH      00402001
001B:00401084  6817204000      PUSH      00402017
001B:00401089  6A00                    PUSH      00
001B:0040108B  E8D7020000      CALL      USER32!MessageBoxA
            ^^^^^^^^^^^^^^^^^^^^^^^^^^------>出错信息
001B:00401090  E824020000      CALL      KERNEL32!ExitProcess       

    让我们看一下调用CreateFileA API的参数含义。

HANDLE CreateFile(

    LPCTSTR lpFileName,    // 指向文件名的指针
    DWORD dwDesiredAccess,    //读写模式
    DWORD dwShareMode,    // 共享模式
    LPSECURITY_ATTRIBUTES lpSecurityAttributes,    // 安全属性指针
    DWORD dwCreationDistribution,    // 创建标志
    DWORD dwFlagsAndAttributes,    // 文件属性
    HANDLE hTemplateFile     // 文件属性的复制句柄
  );    

    其中我们最关心的是    LPCTSTR lpFileName这个参数。需要注意的是在API

的调用中ASM和高级语言是有区别的,最先出现的参数,ASM中最后PUSH。然后我们

就看出是以下这行代码是文件名指针
     PUSH      00402079
    d  402079           
                  看到什么??-----due-cm2.dat----->>>keyfile的名字
    到目前我们就完成了第一步!

    接着我们进行下面一步进行挖掘文件的内容,好象有的点观看挖掘老山汉墓的

感觉 呵呵~~~~~~
    在目录下建一个文件名字为due-cm2.dat,再跟踪看一看是怎样的情形。
001B:00401073  E80B020000    CALL      KERNEL32!CreateFileA
001B:00401078  83F8FF              CMP      EAX,-01
            ^^^^^^^^^^^^^^^^^^^^^^^^^^------>如果打开文件失败,eax=-01
001B:0040107B  751D                  JNZ      0040109A 
            ^^^^^^^^^^^^^^^^^^^^^^^^^^------>如果成功,就跳到40109A

    然后看一看40109A的代码
001B:0040109A  6A00                  PUSH      00        //数据结构指针
001B:0040109C  6873214000    PUSH      00402173        //实际读取的字节数
001B:004010A1  6A46                    PUSH      46        //需要读取的字节数
001B:004010A3  681A214000    PUSH      0040211A        //存放内容的文件指针
001B:004010A8  50                    PUSH      EAX                                  //文件的句柄
001B:004010A9  E82F020000    CALL      KERNEL32!ReadFile
            ^^^^^^^^^^^^^^^^^^^^^^^^^^------>返回参数为非零,就成功
    ReadFile API中需要注意的三个参数:402173    46      40211A

001B:004010AE  85C0                TEST      EAX,EAX
001B:004010B0  7502                  JNZ      004010B4
001B:004010B2  EB43                JMP      004010F7
            ^^^^^^^^^^^^^^^^^^^^^^^^^^------>出错跳远
001B:004010B4  33DB                XOR      EBX,EBX
001B:004010B6  33F6                  XOR      ESI,ESI
001B:004010B8  833D7321400012      CMP      DWORD PTR [00402173],12
            ^^^^^^^^^^^^^^^^^^^^^^^^^^------>文件的字节数是否大于12,

注意12是十六进制=18,小于18个字节就出错!
001B:004010BF  7C36                JL        004010F7
001B:004010C1  8A831A214000        MOV      AL,[EBX+0040211A]
            ^^^^^^^^^^^^^^^^^^^^^^^^^^------>取每一个字节进行比较
001B:004010C7  3C00                CMP      AL,00
001B:004010C9  7408                JZ        004010D3
001B:004010CB  3C01              CMP      AL,01
001B:004010CD  7501                JNZ      004010D0
001B:004010CF  46                    INC      ESI
            ^^^^^^^^^^^^^^^^^^^^^^^^^^------>ESI是累计01的个数
001B:004010D0  43                    INC      EBX
            ^^^^^^^^^^^^^^^^^^^^^^^^^^------>文件偏移指针
001B:004010D1  EBEE              JMP      004010C1
001B:004010D3  83FE02            CMP      ESI,02
            ^^^^^^^^^^^^^^^^^^^^^^^^^^------>01的个数要大于等于2
001B:004010D6  7C1F                JL        004010F7
001B:004010D8  33F6                XOR      ESI,ESI
001B:004010DA  33DB                XOR      EBX,EBX
001B:004010DC  8A831A214000        MOV      AL,[EBX+0040211A]
001B:004010E2  3C00                CMP      AL,00
001B:004010E4  7409                JZ        004010EF
            ^^^^^^^^^^^^^^^^^^^^^^^^^^------>判断是否到文件尾部
001B:004010E6  3C01                CMP      AL,01
001B:004010E8  7405                JZ        004010EF
001B:004010EA  03F0                ADD      ESI,EAX
            ^^^^^^^^^^^^^^^^^^^^^^^^^^------>当不等于01和00的时候进行

累加
001B:004010EC  43                    INC      EBX
001B:004010ED  EBED              JMP      004010DC
001B:004010EF  81FED5010000        CMP      ESI,000001D5
            ^^^^^^^^^^^^^^^^^^^^^^^^^^------>当累加到1D5时,就跳转,

否则出错!!!
001B:004010F5  741D                JZ        00401114

001B:004010F7  6A00                PUSH      00
001B:004010F9  6801204000  PUSH      00402001
001B:004010FE  6886204000  PUSH      00402086
001B:00401103  6A00                PUSH      00
001B:00401105  E85D020000  CALL      USER32!MessageBoxA
             ^^^^^^^^^^^^^^^^^^^^^^^^^^------>错误信息。
001B:0040110A  E8AA010000 CALL      KERNEL32!ExitProcess
    到这里我们中场休息10分钟,看看目前战果如何?^_^
    1、文件的长度至少18个字节。
    2、文件中01的字节至少有2个。
    3、文件中再遇到01字节前,至少累加和为1D5。
    aa+aa+81=1d5 (十六进制数字顺便取)
    文件内容至少是这样 AA AA 81 01 01 00 00......凑够18个字节就行了

    下课了,3点俺要上班了,下回接着讲啊!呵呵~~~~~~~~~~~~
    啊哦!!迟到了,没有关系,领导不在!!呵呵~~~~~~~~~~~~
                时间:2000.10.17 15:02:33


声明:该文观点仅代表作者本人,转载请注明来自看雪