0%

BABYRE

本文仅作为技术讨论及分享,严禁用于任何非法用途。

前言

这是一道CTF的逆向题,挺久没做题了,恢复一下记忆。

正文

这题咋一看好像只是个简单异或,实际上是SMC,在运行时动态修改二进制内容重新生成judge函数

如果我们是根据代码简单还原异或原文的话,出来的结果是乱码

参考:XCTF 4th-WHCTF-2017:BABYRE

https://www.shawroot.cc/2262.html

通过动态分析的方法,在调用judge时打上断点

启动debuger,然后输入14位任意字符串

程序在断点暂停,双击进入judge函数

可以对比看到,judge的汇编代码是有被修改的,下图是原二进制文件代码:

这个是运行时代码

所以看网上的wp大多是写Python代码进行patch,对初学者难度比较高。

方法一

我们在动态调试中,在修改后的judge汇编代码段进行F5是无法查看伪代码的,按F7单步,使用F7需先勾选Use source-level debugging

单步进来可以看到judge汇编代码已经修改了,但F5无法反汇编

然后选中600B00-600BB5(judge 的起止位置),重新生成函数

选中按下p键,再F5就可以看到伪代码啦

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
__int64 __fastcall judge(__int64 a1)
{
_BYTE v2[5]; // [rsp+8h] [rbp-20h] BYREF
_BYTE v3[9]; // [rsp+Dh] [rbp-1Bh] BYREF
int i; // [rsp+24h] [rbp-4h]

qmemcpy(v2, "fmcd", 4);
v2[4] = 127;
qmemcpy(v3, "k7d;V`;np", sizeof(v3));
for ( i = 0; i <= 13; ++i )
*(_BYTE *)(i + a1) ^= i;
for ( i = 0; i <= 13; ++i )
{
if ( *(_BYTE *)(i + a1) != v2[i] )
return 0LL;
}
return 1LL;
}

简单异或还原代码即可得到flag

1
2
3
4
5
6
7
8
s1 = 'fmcd'
s2 = 'k7d;V`;np'
s = s1+chr(127)+s2
for i,c in enumerate(s):
print(chr(ord(c)^i), end='')



方法二

根据judge函数的内容,导出汇编代码

1
2
3
4
5
6
7
8
c = [0x59, 0x44, 0x85, 0xE9, 0x44, 0x85, 0x71, 0xD4, 0xCA, 0x49, 0xEC, 0x6A, 0xCA, 0x49, 0xED, 0x61, 0xCA, 0x49, 0xEE, 0x6F, 0xCA, 0x49, 0xEF, 0x68, 0xCA, 0x49, 0xE8, 0x73, 0xCA, 0x49, 0xE9, 0x67, 0xCA, 0x49, 0xEA, 0x3B, 0xCA, 0x49, 0xEB, 0x68, 0xCA, 0x49, 0xE4, 0x37, 0xCA, 0x49, 0xE5, 0x5A, 0xCA, 0x49, 0xE6, 0x6C, 0xCA, 0x49, 0xE7, 0x37, 0xCA, 0x49, 0xE0, 0x62, 0xCA, 0x49, 0xE1, 0x7C, 0xCB, 0x49, 0xF0, 0x0C, 0x0C, 0x0C, 0x0C, 0xE7, 0x24, 0x87, 0x49, 0xF0, 0x44, 0x6F, 0xDC, 0x44, 0x87, 0x49, 0xD4, 0x44, 0x0D, 0xDC, 0x87, 0x59, 0xF0, 0x44, 0x6F, 0xC6, 0x44, 0x87, 0x59, 0xD4, 0x44, 0x0D, 0xC6, 0x03, 0xBA, 0x1E, 0x87, 0x41, 0xF0, 0x3D, 0xC6, 0x84, 0x1C, 0x8F, 0x49, 0xF0, 0x0D, 0x8F, 0x71, 0xF0, 0x01, 0x72, 0xDE, 0xCB, 0x49, 0xF0, 0x0C, 0x0C, 0x0C, 0x0C, 0xE7, 0x25, 0x87, 0x49, 0xF0, 0x44, 0x6F, 0xDC, 0x44, 0x87, 0x49, 0xD4, 0x44, 0x0D, 0xDC, 0x03, 0xBA, 0x1C, 0x87, 0x49, 0xF0, 0x44, 0x94, 0x03, 0xBA, 0x48, 0x09, 0xEC, 0x34, 0xCE, 0x78, 0x0B, 0xB4, 0x0C, 0x0C, 0x0C, 0x0C, 0xE7, 0x03, 0x8F, 0x49, 0xF0, 0x0D, 0x8F, 0x71, 0xF0, 0x01, 0x72, 0xDD, 0xB4, 0x0D, 0x0C, 0x0C, 0x0C, 0x51, 0xCF]


n = [ i^0x0c for i in c]


with open('b.asm', 'wb') as f:
f.write(bytes(n))

直接使用ida打开,同样可以得到伪代码