1、原题目
一个out文件 exe文件
题目为drinksome tea,注意这个tea,作为一个提示,该题目全程用tea来作为名称
拿到先查看exe
2、运行与查壳
先查个壳以示尊重。
可以看到,这是一个无壳程序,紧接着就是运行一下,发现,不管tea.png.out不管存在与否都不影响结果,结果都为认为我不爱喝茶
3、逆向反编译程序
通过ida神器可以看到,流程是直接跳转到左边就直接retn,而主要是判断tea.png存在与否,那么接下来就是送它一个tea.png文件,试着直接把tea.png.out的后缀out去掉。
去掉out后,运行程序为直接给我一杯茶,自然不是flag。(想想应该也没那么简单),回到ida中继续查看反编译的代码。
发现程序都执行到正确的方向了,而其中有个字符串提示为flag{fake_flag!}getout! n,下一步先F5看看反编译代码,这里很简单推断不可能是flag{fake_flag!}就是答案。loc_4010A0是执行了某个函数,但是跳转直接没办法进行反编译伪代码
往下走,直接看到0x401116处有个被加密后的函数
完全没办法分析
这时候可以直接用findcrypt分析,直接可以看到是tea加密模式
对tea加密文件没什么概念,因此直接跟着流程走一遍看看处理方案,直接动态调试,断下断点,然后执行。
这里直接弹出失败,就在跳转至401000地址执行后直接返回程序退出了,但是正常运行是不会报这个错误的,这里可以初步判断为检测反调试。考虑到返回值是否影响等问题,直接修改反调试程序流程,不影响返回值,避免后面会有判断或者一些干扰值,就不用进行分析了。
那么静态反编译查看401000处的代码,获取启动信息,分析数据并且比较,这里直接用OD去修改流程跳转,直接把401087代码查看了一遍。
这里的loc_401087代码,直接为输出getout! n后就退出程序,因此,OD直接将jnzshort loc_401087全部给nop然后判断跳转loc_40109B改为jmp跳转(即无条件跳转)。
进入OD,ctrl G根据对应地址进行跳转。
修改后,流程直接变化。这里就不用重新静态了,由于main函数本身没变,只是修改了sub_401000()的函数逻辑。
保存后直接ida动态分析,执行通过后说明反-反调试成功
接下来执行,其实流程并不复杂,但是ida的表达用异或的表达方式,把流程复杂化了,4010A0因为是tea加密,这里直接key为unk_407030=flag{fake_flag!}(因为长度为16),这里为了流程好看,直接用了ghidra_9.1,便知道数据是每俩俩数据传入的,符合tea加密
4、总结
因此,根据参考网络中搜索的tea算法(https://www.cnblogs.com/huhu0013/p/3334890.html),均为两两传入,但是从ghidra可以看出,数据是int* 定义的,因此需要改一下网络上加解密的代码,将long*改为int*,这里是细活。
5、解密的代码
总结信息,写出解密C代码,主函数直接fread文件tea.png.out即可,然后fwrite写出一个tea.png
void decrypt (int* v, int* k) { int y=v[0], z=v[1], sum=0xC6EF3720, i; int delta=0x9e3779b9; int k0=k[0], k1=k[1], k2=k[2], k3=k[3]; for (i=0; i<32; i ) { z -= ((y<<4) k2) ^ (y sum) ^ ((y>>5) k3); y -= ((z<<4) k0) ^ (z sum) ^ ((z>>5) k1); sum -= delta; } v[0]=y; v[1]=z; } |
---|
最后主函数读取解密tea.png.out两两数据解密最后新建文件为tea.png,得到exe文件与tea.png.out文件一块放入同一个目录下,双击exe即解密得到tea.png了
打开png文件,得到flag