文件无壳 拖入ida
shift+F12查找可疑字符串 发现一串很像base64编码表的字符串
双击进去 F5查看伪c代码
跟进RxEncode函数
void *__fastcall RxEncode(const char *a1, int a2)
{
int v3; // [rsp+18h] [rbp-38h]
int v4; // [rsp+1Ch] [rbp-34h]
int v5; // [rsp+20h] [rbp-30h]
int v6; // [rsp+24h] [rbp-2Ch]
int v7; // [rsp+28h] [rbp-28h]
int v8; // [rsp+28h] [rbp-28h]
int i; // [rsp+2Ch] [rbp-24h]
_BYTE *v10; // [rsp+30h] [rbp-20h]
void *s; // [rsp+38h] [rbp-18h]
v3 = 3 * (a2 / 4);
v5 = 0;
v4 = a1[a2 - 1] == 61;
if ( a1[a2 - 2] == 61 )
++v4;
if ( a1[a2 - 3] == 61 )
++v4;
if ( v4 == 3 )
{
v3 += 2;
}
else if ( v4 <= 3 )
{
if ( v4 == 2 )
{
v3 += 3;
}
else if ( v4 )
{
if ( v4 == 1 )
v3 += 4;
}
else
{
v3 += 4;
}
}
s = malloc(v3);
if ( s )
{
memset(s, 0, v3);
v10 = s;
while ( v5 < a2 - v4 )
{
v6 = 0;
v7 = 0;
while ( v6 <= 3 && v5 < a2 - v4 )
{
v7 = (v7 << 6) | (char)find_pos(a1[v5]);
++v6;
++v5;
}
v8 = v7 << (6 * (4 - v6));
for ( i = 0; i <= 2 && i != v6; ++i )
*v10++ = v8 >> (8 * (2 - i));
}
*v10 = 0;
return s;
}
else
{
puts("No enough memory.");
return 0LL;
}
}
编码过程
- 使用一个循环遍历输入字符串的前
a2 - v4
个字符(其中v4
是末尾等号的数量),这些字符将被编码。 - 对于每组4个输入字符(或更少,如果接近字符串末尾),使用
find_pos
函数(该函数未在代码中定义,但可能是一个查找字符在Base64编码表中的位置的函数)将每个字符转换为一个6位的二进制数,并将这些数拼接成一个较大的二进制数。 - 如果一组字符少于4个,则在拼接的二进制数左侧进行零填充,以模拟完整的4字节输入。
- 然后,将这个大二进制数拆分成3字节的块(每个块对应于Base64编码中的4个字符),并将这些块转换为相应的Base64字符。
- 将编码后的字符存储在之前分配的内存中。
输入数据后直接base64解码然后比较,只是把base64的56改为{}
上脚本 这里借鉴这位师傅的代码http://t.csdnimg.cn/yo118
s2 = b'\x0F\xD3p\xFE\xB5\x9C\x9B\x9E'[::-1]+ b'\xDE\xAB\x7F\x02\x9CO\xD1\xB2'[::-1] + b'\xFA\xCD\x9D@\xE7ceY'[::-1]
#仅56换为{} 的base64
from base64 import b64encode
print(b64encode(s2))
得到flag
flag{w0w+y0U+cAn+r3lllY+dAnc3}