• 逆向project实战--Acid burn


    0x00 序言

    这是第二次破解 crackme 小程序,感觉明显比第一次熟练。破解过程非常顺利,差点儿是分分钟就能够找到正确的 serial,可是我们的目标是破解计算过程。以下将具体介绍。

    0x01 初次执行

    刚開始拿到 crackme 先执行程序。看看有哪些明显的特征。或者有哪些任务须要完毕:
    这里写图片描写叙述
    双击程序后弹框,显然第一个任务就是把这个框框弄掉,我们继续执行:
    这里写图片描写叙述

    这个小程序比上次的要复杂,有两个 serial ,我们先看看左边的:

    这里写图片描写叙述
    不出意外。猜错了,有明显的弹框和失败字符串作为特征。我们接着看右边的:
    这里写图片描写叙述

    不出意外,再次失败,依旧是弹框。

    0x02 開始调试

    1、明白目标
    通过上面的执行分析,我们须要干掉第一个弹框,以及兴许的两个 serial 。同一时候我们发现三者的共同特征为弹框。所以首先拦截弹框函数:
    右键代码区选择 “serach for” => “All intermodules calls”:
    这里写图片描写叙述

    在新窗体中输入 messageboxa,右键。选择”Set breakpoint on every call to MessageBoxA”:
    这里写图片描写叙述

    这样我们就给全部调用弹框函数的地方下了断点,接着回到代码区执行程序。

    2、调用者
    按 F9 执行到弹框函数处,我们发现此时的栈顶就是第一次弹框时的字符串的地址,于是我们须要找到那个调用弹框函数的函数。叫做调用者。

    这里我们往上看,找到当前这个函数的入口并下断点:
    这里写图片描写叙述

    然后我们 Ctrl + F2 又一次加载程序。F9 执行到刚才下断点的入口:
    这里写图片描写叙述
    此时栈顶就是调用者执行call指令时保存的返回点。我们在代码区中查找这个地址(42F79C),注意单击代码区,按 Ctrl + G 进行查找:
    这里写图片描写叙述

    看见了吗,就是这个函数,仅仅有几句代码。以下我们就来消灭它。

    3、去掉弹框
    调用了函数才会弹框,我们的想法就是让它不调用函数,那么直接让函数返回是最简单的方式。于是我们把函数入口处的第一条指令改成RETN 就可以:
    单击指令,按一下空格键能够改动:
    这里写图片描写叙述

    此时我们能够把改动保存到文件里:
    右键指令,选择 “Copy to executable” => “selection”:

    这里写图片描写叙述

    在新窗体中右键选择 “Save file”:
    这里写图片描写叙述

    然后保存:
    这里写图片描写叙述

    执行新的程序发现第一次的弹框成功消失。

    4、破解右側serial
    接下来我们转到右边的 serial,输入随意字符串。然后点击button:
    我们发现程序停在了弹框函数的入口:
    这里写图片描写叙述

    此时栈顶的值就应该是上级函数的返回地址:
    这里写图片描写叙述

    我们继续在代码区搜索此地址(42F509):
    这里写图片描写叙述

    发现了吗,有推断条件。能够看出是字符串比較函数,我们设置断点。F9 执行究竟后又一次点击button:
    这里写图片描写叙述

    程序停在了断点处。看看栈区。发现给函数的參数中的字符串:
    这里写图片描写叙述

    破解起来确实非常轻松,字符串是固定的:Hello Dude!
    这里写图片描写叙述

    5、破解左側 serial
    我们继续执行,转到左側。输入随意字符串后点击button:
    依据刚才的方式找到调用者返回地址:42FB37
    这里写图片描写叙述

    查找代码区:
    这里写图片描写叙述

    发现字符串比較函数并下断点。此时查看栈区:
    这里写图片描写叙述

    再往上看代码区:
    这里写图片描写叙述

    我们能够猜測出 serial 是 “CW-” + 某个数 + “CRACKED”,中间的数是我们须要找的目标。

    6、真实的目标
    我们给 serial 生成函数的入口下一个断点,然后又一次点击button执行到断点处 F8 单步走:
    这里写图片描写叙述

    中间发现两段代码:

    EAX = name[0] * 7 + name[1] * 0x10;
    EAX = name[3] * 0xB + name[2] * 0xE

    继续向下执行,发现另外一段代码:
    这里写图片描写叙述
    函数入口的以下有一句不起眼的代码:
    这里写图片描写叙述

    两个结合起来就是:

    EAX = name[0] * 0x29 * 2;

    后面我们发现调用字符串输出函数之前 EAX 的值被置为那个内存单元的值:
    这里写图片描写叙述

    继续往下调试结果就非常明显了,第三段代码才是我们要的。

    0x03 双重检測

    1、简单粗暴的 C语言
    代码例如以下:

    #include <stdio.h>
    
    int main()
    {
        char name[1024];
    
        printf("Input your name: ");
        scanf("%s", name);
        printf("Serial: CW-%d-CRACKED
    ", name[0] * 0x29 * 2);
        return 0;
    }

    执行结果:
    这里写图片描写叙述

    2、原程序检验
    这里写图片描写叙述

    0x04 总结

    这个小程序左边的 serial 和 name 的第一个字符有关,而且字符串长度不能小于4.

  • 相关阅读:
    vue-面试
    使用webpack4搭建一个基于Vue的组件库
    vue 仿今日头条
    如何正确的在项目中接入微信JS-SDK
    vuejs实现折叠面板展开收缩动画
    Vue的watch和computed属性
    Android Studio(十):添加assets目录
    Android Studio(九):引用jar及so文件
    Android Studio(八):Android Studio设置教程
    Android Studio(七):项目从Eclipse到Android Studio迁移
  • 原文地址:https://www.cnblogs.com/yangykaifa/p/7396298.html
Copyright © 2020-2023  润新知