- 使用Exeinfo查看信息,发现是64位的应用,没有加壳

- 使用64位IDA打开,没有main函数
- 使用shift+F12,查看字符串,有三行字符值得关注

- 双击进入后,选中其中一行关键字,鼠标右键选择交叉引用,或者使用快捷键CTRL+X

- 按F5查看编译源码
__int64 sub_140013FC0()
{
int i;
int j;
sub_1400114E2(&unk_14002A0F4);
for ( i = 0; i < 39; ++i )
Str[i] ^= byte_140022000[4 * (i % 6)] + i;
for ( j = 0; j < 39; ++j )
{
if ( Str[j] != dword_140022020[j] )
{
sub_14001123A("Fault! Plz check Your Flag!!");
exit(0);
}
}
return sub_14001123A("Corret! We are the champions!");
}
- 数组byte_140022000[]经过39次异或后得到数组Str[]
- 数组Str[]与数组dword_140022020[]若相等,则会输出"Corret! We are the champions!"
- 分别查看byte_140022000[]和dword_140022020[]的值


- 一个是32位的db,一个是122位的dd,从这句代码
Str[i] ^= byte_140022000[4 * (i % 6)] + i;
来理解,应该是取了前24位进行异或,舍弃了后面填充的0; - 从验证是否是flag的语句也看出,dword_140022020[]也仅比较了有值的前39位,后面填充的0也都忽略了,根据这个逻辑,我们用python编写逆向代码
flag1=[0x20,0x27,0x26,0x25,0x2C,0x2D,0x0F,0x22,0x14,0x1E,
0x21,0x18,0x09,0xDF,0xC8,0x1C,0xE7,0x05,0xE5,0xE2,
0xEE,0x1A,0xE6,0x04,0xD9,0xC9,0xE3,0x0A,0xF5,0xF1,
0xF8,0xF3,0xFA,0xEA,0xFF,0xE7,0xF5,0xB9,0xE4]
key=[0x6E,0,0,0,0x73,0,0,0,0x73,0,0,0,0x63,0,0,0,0x74,0,0,0,0x66,0,0,0]
flag=""
for i in range(len(flag1)):
flag+=chr(flag1[i]^(key[4*(i % 6)]+i))
print(flag)

- 参考文章的解法:https://blog.csdn.net/mata_lee/article/details/143269750
enc = [0x20, 0x27, 0x26, 0x25, 0x2C, 0x2D, 0x0F, 0x22, 0x14, 0x1E, 0x21, 0x18, 0x09, 0xDF, 0xC8, 0x1C, 0xE7, 0x05, 0xE5, 0xE2, 0xEE, 0x1A, 0xE6, 0x04, 0xD9, 0xC9, 0xE3, 0x0A, 0xF5,
0xF1,0xF8, 0xF3, 0xFA, 0xEA, 0xFF, 0xE7, 0xF5, 0xB9, 0xE4]
key = [0x6e,0x73,0x73,0x63,0x74,0x66]
for i in range(len(enc)):
print(chr(enc[i]^key[i%6]+i),end="")