去OLLVM平坦化([SUCTF2019]hardCPP)
去OLLVM平坦化([SUCTF2019]hardCPP)
用ida打开是这样


十分有十二分的平坦化痕迹,
上次强网杯遇到过,但是因为当时没装好环境,deflat.py跑不出来,遗憾放弃。
这次又碰见不想再回避,打开这个网址把脚本装下来,https://github.com/Pure-T/deflat,看readme,要先装一个angr库(这个库在做VM虚拟机类题,写解析器脚本的时候也会很有用,以后可能再写)
1 | |
下载时间可能会有点长,

官方说的是用8.19.4.5版本,实际较新版本依然可用,
装好后用以下指令去平坦化:
1 | |
然而出错:

回看readme,

下载那个graph.py然后改名为am_graph.py ,将其与deflat.py放在同一目录下,

再次运行相同命令:
1 | |
期间可能会出现大量类似警告:

不要害怕,只要最后是这样就好:

将recovered的文件再放进ida里面看:


成功!
下面就是逆向环节了
也有部分去平坦化操作

首先排除上面这两个循环有用,

看到这一坨函数不要怕,其实就是c++里面的奇奇怪怪的东西(好像叫lambda表达式),来看看他们到底是干嘛的,
在对各函数分析的过程中发现在0x401310、0x4014E0和0x4016C0依然有平坦化,再跑脚本去一下,
1 | |
0x401310:

再跑一遍
1 | |
0x4016C0:

再跑一遍:
1 | |
0x4014E0:

得到hardCPP_recovered_recovered_recovered_recovered 这次再放进ida并改名:
接下来就是搞清func1、func2、func3的功能:
其中两个就是是return第二个数据,另一个是add,
把这几个函数简化成表达式:

是不是已经非常清晰了!
整理一下:
1 | |
从前面看出:v21大概是0 (真的是大概,当时我也不太确定)
然后等式左边的v18就是enc[i]那么这个算法显然可逆:
把函数开头的md5解密一下:


那么flag(input)的第一位是‘#’
好了可以写解密代码了:
1 | |
flag:

flag{mY-CurR1ed_Fns}

