[WUSTCTF2020]level4
Start
int __cdecl main(int argc, const char **argv, const char **envp)
{
puts("Practice my Data Structure code.....");
puts("Typing....Struct.....char....*left....*right............emmmmm...OK!");
init("Typing....Struct.....char....*left....*right............emmmmm...OK!", argv);
puts("Traversal!");
printf("Traversal type 1:");
type1((char *)&unk_601290);
printf("\nTraversal type 2:");
type2((char *)&unk_601290);
printf("\nTraversal type 3:");
puts(" //type3(&x[22]); No way!");
puts(&byte_400A37);
return 0;
}
调用了type1、type2、type3对flag进行处理,但是直接看并不能看到对哪些数据进行了处理。
直接运行一下,结果很熟悉:
看到提示:Data Structure
再次查看两个函数:
type1 -> 二叉树中序遍历
__int64 __fastcall type1(char *a1)
{
__int64 result; // rax
if ( a1 )
{
type1(*((_QWORD *)a1 + 1));
putchar(*a1);
result = type1(*((_QWORD *)a1 + 2));
}
return result;
}
type2 -> 二叉树后序遍历
int __fastcall type2(char *a1)
{
int result; // eax
if ( a1 )
{
type2(*((_QWORD *)a1 + 1));
type2(*((_QWORD *)a1 + 2));
result = putchar(*a1);
}
return result;
}
直接用现成的二叉树遍历:已知前序中序输出后序/已知后序中序输出前序,稍微修改一下,就可以拿到flag
exp.cpp:
#include <iostream>
using namespace std;
char post[] = "20f0Th{2tsIS_icArE}e7__w"; // 后序遍历结果
char mid[] = "2f0t02T{hcsiI_SwA__r7Ee}"; // 中序遍历结果
void pre(int root, int start, int end)
{
if (start > end)
return;
int i = start;
while (i < end && mid[i] != post[root]) i++; //定位根在中序的位置
cout << mid[i]; //访问当前处理的树的根
pre(root - 1 - (end - i), start, i - 1); //递归处理左子树
pre(root - 1, i + 1, end); //递归处理右子树
}
int main()
{
pre(24, 0, 24);
return 0;
}
# wctf2020{This_IS_A_7reE}
ps: 审题很重要,最开始并没有想到是考察二叉树的遍历,一股脑的去动态调试,结果分析了半天啥也没有。
最终的二叉树图: