首页 > 其他 > 详细

buuctf-level4

时间:2020-09-24 16:19:06      阅读:38      评论:0      收藏:0      [点我收藏+]

下载附件打开后,发现是linux下的可执行文件,使用IDA(64)打开,发现与二叉树的遍历顺序有关,如图:

技术分享图片

 

 

 可以发现type1和type2函数即为关键的函数,进去查看发现:

__int64 __fastcall type1(char *a1)
{
  __int64 result; // rax

  if ( a1 )
  {
    type1(*((_QWORD *)a1 + 1));
    putchar(*a1);
    result = type1(*((_QWORD *)a1 + 2));
  }
  return result;
}
int __fastcall type2(char *a1)
{
  int result; // eax

  if ( a1 )
  {
    type2(*((_QWORD *)a1 + 1));
    type2(*((_QWORD *)a1 + 2));
    result = putchar(*a1);
  }
  return result;
}

结合主函数我们可以知道,程序会打印出中序遍历和后序遍历的结果,已知一个二叉树的中序和后序,那么我们就可以画出这个二叉树,而flag应该就是二叉树先序遍历的结果。先把程序放到linux下运行,看看结果:

技术分享图片

 

中序:"2f0t02T{hcsiI_SwA__r7Ee}"
后序:"20f0Th{2tsIS_icArE}e7__w"
于是我们可以根据中序遍历与后序遍历的顺序特征来画出二叉树
先序遍历:先根,后左,再右
中序遍历:先左,后根,再右
后序遍历:先左,后右,再根
解决思路如下:
技术分享图片

 

①根据后序(左,右,根),可以知道‘w‘为整个二叉树的根节点,再根据中序遍历,可以知道数的左边为‘2f0t02T{hcsiI_S’,右边集合为‘A__r7Ee}‘

②再根据后序遍历的结果,可以知道对应左边和右边的最后一位定是根节点,也就是‘w‘根节点的左右孩子,即左孩子‘c‘,右孩子‘_‘

③先分别左边,对于中序遍历结果‘2f0t02T{hcsiI_S’而言,现在‘c‘为根节点,故节点左边集合为‘2f0t02T{h’,右边为‘siI_S‘,此时再根据对应的后序,可以知道,对于左边,‘t‘为根,对于右边‘i‘为根,以此类推,最终可以画出这样一个二叉树,如图:

技术分享图片

 写出次二叉树的先序遍历结果:wctf2020{This_IS_A_7reE},得到flag!

buuctf-level4

原文:https://www.cnblogs.com/jane315/p/13724084.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!