参考文章:re学习笔记(22)爱春秋CTF答题夺旗赛(第四季)-re-basebasebase_ctfbase~base_Forgo7ten的博客-CSDN博
总结:1.flag——→base64加密(自定义)——→与3异或——→加密后数据(对比,相等成功)
2.关键代码?构造函数(P键)?
3.为什么要进行栈指针的调整?那个快捷键进行栈指针调整?如何打开栈指针?
Alt+K键(调整栈指针)
4.base64解密
自定义base64编码表
转义字符串
加密解密字符串的长度关系
题解:
构造函数后发现的函数:
int __usercall sub_40103B@<eax>(int a1@<ebp>)
{
*(_DWORD *)(a1 - 132) = 0;
*(_BYTE *)(a1 - 40) = 89;
*(_BYTE *)(a1 - 39) = 110;
*(_BYTE *)(a1 - 38) = 123;
*(_BYTE *)(a1 - 37) = 107;
*(_BYTE *)(a1 - 36) = 89;
*(_BYTE *)(a1 - 35) = 32;
*(_BYTE *)(a1 - 34) = 119;
*(_BYTE *)(a1 - 33) = 106;
*(_BYTE *)(a1 - 32) = 90;
*(_BYTE *)(a1 - 31) = 91;
*(_BYTE *)(a1 - 30) = 77;
*(_BYTE *)(a1 - 29) = 111;
*(_BYTE *)(a1 - 28) = 91;
*(_BYTE *)(a1 - 27) = 67;
*(_BYTE *)(a1 - 26) = 90;
*(_BYTE *)(a1 - 25) = 42;
*(_BYTE *)(a1 - 24) = 90;
*(_BYTE *)(a1 - 23) = 67;
*(_BYTE *)(a1 - 22) = 119;
*(_BYTE *)(a1 - 21) = 101;
*(_BYTE *)(a1 - 20) = 86;
*(_BYTE *)(a1 - 19) = 110;
*(_BYTE *)(a1 - 18) = 85;
*(_BYTE *)(a1 - 17) = 67;
*(_BYTE *)(a1 - 16) = 89;
*(_BYTE *)(a1 - 15) = 91;
*(_BYTE *)(a1 - 14) = 73;
*(_BYTE *)(a1 - 13) = 121;
*(_BYTE *)(a1 - 12) = 89;
*(_BYTE *)(a1 - 11) = 91;
*(_BYTE *)(a1 - 10) = 42;
*(_BYTE *)(a1 - 9) = 41;
*(_BYTE *)(a1 - 8) = 3;
printf("Give Me Flag:");
*(_BYTE *)(a1 - 76) = 0;
*(_DWORD *)(a1 - 75) = 0;
*(_DWORD *)(a1 - 71) = 0;
*(_DWORD *)(a1 - 67) = 0;
*(_DWORD *)(a1 - 63) = 0;
*(_DWORD *)(a1 - 59) = 0;
*(_DWORD *)(a1 - 55) = 0;
*(_DWORD *)(a1 - 51) = 0;
*(_DWORD *)(a1 - 47) = 0;
scanf("%s", a1 - 76); // a1-76为用户的输入
*(_DWORD *)(a1 - 128) = a1 - 76; // a1-128 是一个指针,指向用户输入
*(_DWORD *)(a1 - 144) = *(_DWORD *)(a1 - 128) + 1;// a1-144存储用户输入第二个字符
do
*(_BYTE *)(a1 - 113) = *(_BYTE *)(*(_DWORD *)(a1 - 128))++;
while ( *(_BYTE *)(a1 - 113) );
*(_DWORD *)(a1 - 140) = *(_DWORD *)(a1 - 128) - *(_DWORD *)(a1 - 144);
*(_DWORD *)(a1 - 148) = base64((char *)(a1 - 76), *(_DWORD *)(a1 - 140), (int *)(a1 - 136));// a1-140 为编码之前的长度
// a1-136 为base64编码后的长度
for ( *(_DWORD *)(a1 - 124) = 0; *(int *)(a1 - 124) < 33; ++*(_DWORD *)(a1 - 124) )// a1-124 为计数器 <33 33位
*(_BYTE *)(a1 + *(_DWORD *)(a1 - 124) - 112) = *(_BYTE *)(*(_DWORD *)(a1 - 124) + *(_DWORD *)(a1 - 148)) ^ 3;// base64编码后与3异或
// 赋给a1-112
for ( *(_DWORD *)(a1 - 120) = 0; *(_DWORD *)(a1 - 120) < *(_DWORD *)(a1 - 136); ++*(_DWORD *)(a1 - 120) )
{ // a1-120为计数器,循环次数为base64编码后的长度
if ( *(char *)(a1 + *(_DWORD *)(a1 - 120) - 112) != *(char *)(a1 + *(_DWORD *)(a1 - 120) - 40) )// a1-40上面有数据
{ // base64编码后,再与3异或,然后与a1-40比较
printf(&byte_40302C);
exit(0);
}
++*(_DWORD *)(a1 - 132); // 如果不相等,a1-132就不加,不加的话,下面判断就会失败
}
if ( *(_DWORD *)(a1 - 132) == *(_DWORD *)(a1 - 136) )
printf("Successful!\n");
return 0;
}
全程指针操作
上解密脚本:
import base64
text = [89,110,123,107,89,32,119,106,90,91,77,111,91,67,90,42,90,67,119,101,86,110,85,67,89,91,73,121,89,91,42,41,3]
for i in range(len(text)):
text[i] ^= 3
text[i] = chr(text[i])
text = ''.join(text)
text += "==="
print(base64.b64decode(text.translate(str.maketrans("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz)!@#$%^&*(+/","ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")).encode('utf-8')))
#b'flag{base_f4ck_Reverse}<' 在Python中,前缀"b"表示一个字节字符串(bytes)
#当您使用base64.b64decode()函数解码Base64编码的数据时,返回的结果是字节字符串。
# 字节字符串是由原始字节组成的,每个字节对应一个ASCII字符或二进制数据。
总结:IDA无法识别函数(F5大法失效原因)
1.堆栈指针问题
2.花指令问题