下载题目:下载
下载后发现无壳,64位,拖入IDA。 大致看一下代码,简短感觉很简单,结果还是不会,我是菜鸡... 主要代码为if语句条件判断不为0则输出“TQL!”,就成功。那看一下sub_400917。
发现这是一个数独:每一行每一列不能有相同的数,并且for语句是0到4,所以是5×5数独。要使if条件不等于0,则需要数独成立,即每一行每一列不能有相同的数。
返回到主函数,看sub_4006D6函数。从这里可以知道输入的字符串长度为10,并且输入的必须是字符0-4,否则会goto LABEL_2,就会输出wrong。
返回主函数进入sub_400758()函数。在这里我就懵了,不知道这是什么,经过查阅资料知道这是二叉树知识点,几乎没有接触过...,查阅:[GUET-CTF2019] number_game_firfis的博客-CSDN博客,该函数作用是建一个二叉树,每个节点申请了0x18
位的空间,也就是3
个字节。v6[0]
存储节点的值,v6[1]
存储 左子树的地址,v6[2]
存储 右子树的地址
树的结构与对应的输入值的关系如下图
查阅资料:数据结构之二叉树(C语言附详细代码)_樱桃的崩崩的博客-CSDN博客_二叉树代码,其中前序,中序,后序遍历是蛮重要的应该。
一,二叉树的遍历:
前序遍历:根->左->右;
以上图为例:从根节点开始->输出A,然后找到左子树->输出B,再以B为子根,找到B的左子树->输出D,再以D为子根,找到D的左子树->输出H,然后找到D的右子树->输出I,同样的输出E;
然后到根A的右子树C,同样循环上述操作,右侧输出为CFJG;
总输出顺序为:A-B-D-H-I-E-C-F-J-G;
中序遍历:左->根->右;
通过顺序A->B->D->H,找到最左的H,并输出H,然后返回,输出H的子根D,然后找到D的右子树I并输出,然后继续输出D的子根B,找到B的右子树E并输出,然后找到B的根A并输出;
然后找根A的右子树C,然后通过顺序C->F->J找到J,并对右侧进行相同操作;
最后输出为:H-D-I-B-E-A-J-F-C-G;
通过中序遍历可以清楚的得出结点的左右位置;
后序遍历:左->右->根;
同样的,通过顺序A->B->D->H,找到最左的H,并输出H,然后返回输出H的同层次同根的结点I并输出,最后输出子根D,继续找D的同层次同子根结点E并输出,最后再输出子根B,然后找到与B同层次同根的结点C,然后通过C->F->J的顺序找到J,并重复上述操作;
最后的输出顺序:H-I-D-E-B-J-F-G-C-A;
二,代码① 前序遍历二叉树
首先传入树的首地址,判断是否为空,非空则输出数据,然后循环本函数遍历左子树,根据前序遍历的特点:“根->左->右”,进行遍历输出;
void PreShowBitree(bitree_t *r)
{
if(r == NULL)
{
return;
}
printf("%c",r->data);
PreShowBitree(r->lchild);
PreShowBitree(r->rchild);
}②中序遍历二叉树
首先传入树的首地址,判断是否为空,非空则循环本函数遍历左子树,根据中序遍历的特点:“左->根->右”,进行遍历输出;
void midShowBitree(bitree_t *r)
{
if(r == NULL)
{
return;
}
midShowBitree(r->lchild);
printf("%c",r->data);
midShowBitree(r->rchild);
}③后序遍历二叉树
首先传入树的首地址,判断是否为空,非空则循环本函数遍历左子树,根据后序遍历的特点:“左->右->根”,进行遍历输出;
void PostShowBitree(bitree_t *r)
{
if(r == NULL)
{
return;
}
PostShowBitree(r->lchild);
PostShowBitree(r->rchild);
printf("%c",r->data);
返回主函数,进入sub_400807()函数。发现很像是中序遍历。则有对应关系,摘自[GUET-CTF2019] number_game_firfis的博客-CSDN博客
再进入sub_400881()函数,
发现是把变化后的10个字符分别存入地址中,跟进观察:
变化后的数据是未知数#,根据是5×5数独,可以求出#,为0,4,2,1,4,2,1,4,3,0,即输入的flag变化后的数据。再根据中序变化的加密就可以得出flag。
map = [7, 3, 8, 1, 9, 4, 0, 5, 2, 6] # 对应关系
v7 = [48, 52, 50, 49, 52, 50, 49, 52, 51, 48]
flag=[0]*10
for i in range(10):
flag[map[i]] = chr(v7[i])
flag=''.join(flag)
print('flag{'+flag+'}')
# 1134240024