题目:[RoarCTF2019]polyre
去除控制流平坦化

一眼看出是控制流平坦化后的程序,可以使用deflat.py去除常规的混淆。
在配置了angr的环境运行
1
| python deflat.py attachment
|
可以得到attachment_recovered文件。
去除虚假控制流
这是去除平坦化之后的程序

看流程图更明显一些
可以确定这是进行了虚假控制流的混淆,因为它的调转逻辑不受输入的影响,是既定的跳转,所以我们可以将那些根本没执行过的指令nop掉。借助ida trace可以清晰明了的知道哪些执行过,哪些是假的。
执行过的代码块都进行了高亮处理,只需将为执行的部分nop掉然后重新解析即可。
反编译后逻辑很简单
验证输入,首先判断大于零还是小于零,也就是检测最高位是否为1,如果小于零,也就是最高位为1,那么乘2也就是左移一位,再异或上一个数。如果最高位为0,那么仅左移一位。
逆向过程就是判断最低位,直接左移的最低位为0。由于异或的数据最低位为1,所以经异或处理,最低位为1。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| #include<stdio.h> int main() { unsigned long long int cpdata[7] = {0xBC8FF26D43536296, 0x520100780530EE16, 0x4DC0B5EA935F08EC, 0x342B90AFD853F450, 0x8B250EBCAA2C3681, 0x55759F81A2C68AE4, 0xB0004B7679FA26B3}; for(int i=0;i<7;i++) { unsigned long long int tmp=cpdata[i]; for(int j=0;j<64;j++) { if(tmp&0x1==1) { tmp=((tmp^0xB0004B7679FA26B3)>>1)|0x8000000000000000; } else { tmp=tmp>>1; } } cpdata[i]=tmp; } for(int i=0;i<7;i++) { printf("0x%llx,",cpdata[i]); } }
|
最后大小端反转一下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #include <stdio.h> #include <stdint.h>
int main() { unsigned long long int v[7] = {0x6666367b67616c66,0x63362d3039333932,0x2d363563342d3032,0x3539612d30376162,0x6631643365383537,0x7d38,0x1};
for (int i = 0; i < 7; i++) { printf("0x"); for (int j = 0; j < sizeof(unsigned long long); j++) { printf("%x", (v[i] >> (j * 8)) & 0xFF); } printf(","); } printf("\n");
return 0; }
|