IDA打开直接能看到main函数
可以看到,在执行sub_8048838前,调用了前一个函数,对它进行动态patch(直接点进去sub_8048838会发现是无意义代码)
这个动态patch代码的算法有点复杂,直接gdb下断点然后dump memory ./dmp 0x8048838 0x8048de0,然后用WinHex把dump出来的替换掉原本的,IDA重新打开patch后的,就可以了
可以看出来,这是一个虚拟机,main函数里有对其进行初始化的函数
同样在main函数中我们可以找到opcode的位置
用IDAPython导出一下,得到
分析opcode真的难受。。。我简单分析了一下(你看不懂没关系,我自己写的通常只有我看得懂QAQ)
我们可以看到,以opcode-161作为分界线,前面的是对我们一开始输入的%lld进行各种变换和各种比较,不对就退出,对的话,又会对dA0、dA4、dA8、dAC赋值
后面开始,就是逐位对我们输入的flag进行异或,然后和一个数比较,异或的数是前面提到的被赋值的4个地址的数之一
根据flag的格式是GACTF{xxx},而前4次比较直接把4个数都用过一遍了,于是可以直接逆推这4个数,所以opcode-161之前的可以完全不用管了
写个脚本,提取opcode里面的数据,生成了下面的代码
int main()
{
cout << char(11 + 256 ^ 332);
cout << char(122 ^ 59);
cout << char(149