看雪CTF2016CrackMe第一题分析

Author Avatar
leo00000 7月 04, 2018

看雪CTF刷题系列,PEDIY-CTF2016-CM1。

前言

能力不足,基本上是对着前辈的Writeup逐步跟下来的,记录一些心得。

知识点

  • OD、IDA基础知识
  • Windows反调试

详细步骤

发现反调试

  1. OD加载程序,单步执行到 0x1C2BC9 call 0x1CC111; call _initterm 挂掉了,跟进 _initerm 函数执行到 0x1CC151 call dword ptr [ebp-8]; call 0x1C1000 第二次挂掉,继续跟进在 0x1C000 跳转到 0x1C1340 处,在 sub_1C1340 中执行到 0x1C1530 会有一个判断直接退出程序,这里我们直接NOP掉,之后来到0x1C2C44 call 0x1C1560进入WinMain函数。进入WinMain之前的函数栈 start->scrt_common_main_seh->WinMain,在 scrt_common_main_seh 中调用 _initterm
  2. 进入WinMain之后,界面程序起来之前,会遇到超时检测。通过交叉引用查看clock函数,能发现三处超时检测,如图:

    我们直接NOP掉跳转指令,这样就能让CM在OD中跑起来了。

  3. 给出程序调试过程中的反调试patch:

分析注册过程

  1. 进入WinMain函数以后,这里有一个技巧对GetWindowTextW函数下断,执行到返回 0x1C232B ,落在 sub_1C2120 函数中,ida分析 sub_1C2120 是窗口处理消息的程序,只有当消息值为 0x40B 时才注册成功。继续运行之后, 程序会创建新线程进入 sub_1C20E0 ,继而进入 sub_1C1CB0 ,可以看出 sub_1C1CB0 就是注册码检测逻辑的主函数。

  2. 第一次进入 sub_1C1CB0 ,调用了 sub_1C1C00sub_1C2A50 ,分别要求注册码含有 ‘b’‘p’ ,否则返回消息0x40F注册失败。

  3. 当满足上面条件后,会第二次进入 sub_1C1CB0 函数,在函数中会判断字符长度是否是7,不满足条件会发送消息0x40E或0x40D导致注册失败,所以 注册码长度是7

  4. 当满足条件后,会进入 sub_1C1A60 ,对注册码进行异或加密,之后会进入 sub_1C1870 函数,在 sub_1C1870 对加密的注册码进行了异或解密,将注册码小写转化成大写之后,进行了字符集检测。并且要求从第三位开始,解密出来的注册码序列是 15PB ,所以注册码的格式是 ??15PB?

  5. 当解密的注册码满足 ??15PB? 格式后进入 sub_1C1740sub_1C1740要求前两位之和是0x63,所以前两位肯定是 ‘1’‘2’,第七位必须是 ‘8’ 。综上,满足条件的注册码有 1215pb8

  6. 分析过程中关键断点:

总结

  • 第一步是过掉反调试,让CM能跑起来。
  • 只有一条道路是通往CM成功的,不断的逆向尝试。