[GUET-CTF2019]number_game[数独]

目录

题目

 学到的知识点:


题目

在buu上看到了一道数独题,没见过,记录一下

下载附件,查壳,无壳,在IDA中打开,直接找到主函数

unsigned __int64 __fastcall main(int a1, char **a2, char **a3)
{
  __int64 v4; // [rsp+8h] [rbp-38h]
  __int64 input; // [rsp+10h] [rbp-30h] BYREF
  __int16 v6; // [rsp+18h] [rbp-28h]
  __int64 v7; // [rsp+20h] [rbp-20h] BYREF
  __int16 v8; // [rsp+28h] [rbp-18h]
  char v9; // [rsp+2Ah] [rbp-16h]
  unsigned __int64 v10; // [rsp+38h] [rbp-8h]

  v10 = __readfsqword(0x28u);
  input = 0LL;
  v6 = 0;
  v7 = 0LL;
  v8 = 0;
  v9 = 0;
  scanf("%s", &input);
  if ( function(&input) )                       // 0<v5[i]<=4并且len(v5)==10
  {
    v4 = function_1(&input, 0LL, 10LL);         // 建树
    function_2(v4, &v7);                        // 令v7=input
                                                // 中序遍历  递归
    v9 = 0;
    function_3(&v7);                            // 将中序遍历后的数据存入到一段内存中
    if ( function_4() )                         // 这里进行判断是是将中序遍历转换后的字符串
    {                                           // 实际上就是根据中序遍历求出原本的输入
      puts("TQL!");
      printf("flag{");
      printf("%s", &input);
      puts("}");
    }
    else
    {
      puts("your are cxk!!");
    }
  }
  return __readfsqword(0x28u) ^ v10;
}

 大致理一下思路,可以看到

首先输入一串字符串,在function函数中进行了判断(确保输入的值在字符‘0’~‘4’之间,并且长度要为10)

接着在function_1中进行建树

_QWORD *__fastcall sub_400758(__int64 input, int i, signed int len)
{
  char cnt; // [rsp+1Fh] [rbp-11h]
  _QWORD *v6; // [rsp+28h] [rbp-8h]

  cnt = *(i + input);
  if ( cnt == ' ' || cnt == '\n' || i >= len )  // 判段输入不为空格和换行符
    return 0LL;
  v6 = malloc(0x18uLL);                         // 申请一块内存
  *v6 = cnt;                                    // 存储根结点
  v6[1] = function_1(input, 2 * i + 1, len);    // 递归调用,存储左子树和右子树
  v6[2] = function_1(input, 2 * (i + 1), len);
  return v6;
}

 再在function_2中进行中序遍历的变换

__int64 __fastcall sub_400807(__int64 v4, __int64 v7)
{
  __int64 result; // rax

  result = v4;
  if ( v4 )
  {
    function_2(*(v4 + 8), v7);                  // 左子树
    *(v7 + dword_601080++) = *v4;               // 保存根结点
    return function_2(*(v4 + 16), v7);          // 右子树
  }
  return result;
}

 把经过中序变换的数据在fnction_3里面存储到一段内存中

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

  byte_601062 = *a1;
  byte_601067 = a1[1];
  byte_601069 = a1[2];
  byte_60106B = a1[3];
  byte_60106E = a1[4];
  byte_60106F = a1[5];
  byte_601071 = a1[6];
  byte_601072 = a1[7];
  byte_601076 = a1[8];
  result = a1[9];
  byte_601077 = a1[9];
  return result;
}

 最后进入function_4函数,function_4函数是一个数独游戏函数,代码如下

__int64 sub_400917()
{
  unsigned int v1; // [rsp+0h] [rbp-10h]
  int i; // [rsp+4h] [rbp-Ch]
  int j; // [rsp+8h] [rbp-8h]
  int k; // [rsp+Ch] [rbp-4h]

  v1 = 1;
  for ( i = 0; i <= 4; ++i )                    // 5*5数独游戏
  {
    for ( j = 0; j <= 4; ++j )
    {
      for ( k = j + 1; k <= 4; ++k )
      {
        if ( *(&unk_601060 + 5 * i + j) == *(&unk_601060 + 5 * i + k) )// 每行数无重复元素
          v1 = 0;
        if ( *(&unk_601060 + 5 * j + i) == *(&unk_601060 + 5 * k + i) )// 每列数无重复元素
          v1 = 0;
      }
    }
  }
  return v1;
}

5*5的数独函数,两个if语句判断要求每行元素不重复,每列元素不重复

大致思路就是输入一段字符串,进行给定二叉树的存储,然后再中序遍历存储,最后判断是否满足数独函数,满足则输出正确,反之,错误

二叉树如何存储的呢?树的结构与对应输入树的值存储关系如下

用0~9的数输入来测试输出的顺序。经过变换后的结果是 :7381940526

数独矩阵为

手动解出结果为:0421421430,只要使输入的结果经过变换后满足此顺序即可

借用一下大佬的脚本解密

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

 学到的知识点:

  • 二叉树相关的题目类型
  • 怎么判断代码是数独游戏
  • 额外补充一个在别的题目中遇到的:凯撒加密代码的标志是:

           *v7 = (v5 - 48 + a) % 10 + 48

            *v7=(v5-97+a)%26+97

其中a表示偏移量,但是凯撒加密不会移位数字,但有的题目是凯撒加密的变种,会移位数字

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/25800.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

工程swift与OC混编改造

最近公司项目准备引入swift&#xff0c;由于目前工程已经完成了组件化不再是简单的单仓工程&#xff0c;所以需要进行混编改造。下面记录一下自己对工程进行混编改造的思考以及过程。 混编原理 看了很多文档&#xff0c;比较少有讲混编原理的&#xff0c;这里简单介绍一下语言…

springboot+springsecurity+jwt+elementui图书管理系统

​​图书管理系统​​ 关注公号&#xff1a;java大师&#xff0c;回复“图书”&#xff0c;获取源码 一、springboot后台 1、mybatis-plus整合 1.1添加pom.xml <!--mp逆向工程 --><dependency><groupId>org.projectlombok</groupId><artifactId&…

子串--子字符串 0528

210102 201012 A1A2…An An…A2A1 如何做&#xff0c; 翻转的是21&#xff0c;因为2>1; 翻转的是210&#xff0c;因为2>0; 翻转的是2101&#xff0c;因为2>1&#xff1b; 翻转的是21010&#xff0c;因为2>0&#xff1b; 翻转的是210102&#xff0c;因为22且1&…

2023-05-29 用 fltk gui库编写一个打字练习程序

用 fltk gui库编写一个打字练习程序 前言一、FLTK GUI 库二、使用步骤1.引入库2.使用代码 总结 前言 给孩子练习键盘打字, 发现终端还是欠点意思, 研究了一下gui, 最终用 fltk库弄了一个. 对于没有接触过gui的人, 发现, 编程的逻辑和终端区别很大, 很繁琐, 可能需要适应适应,…

0基础学习VR全景平台篇第32章:场景功能-嵌入视频

大家好&#xff0c;欢迎观看蛙色VR官方系列——后台使用课程&#xff01; 一、本功能将用在哪里&#xff1f; 嵌入功能可对VR全景作品嵌入【图片】【视频】【文字】【标尺】四种不同类型内容&#xff1b; 本次主要带来视频类型的介绍&#xff0c;通过嵌入视频功能&#xff0c;…

Go语言并发

Go语言并发学习目标 出色的并发性是Go语言的特色之一 • 理解并发与并行• 理解进程和线程• 掌握Go语言中的Goroutine和channel• 掌握select分支语句• 掌握sync包的应用 并发与并行 并发与并行的概念这里不再赘述, 可以看看之前java版写的并发实践; 进程和线程 程序、进程…

腾讯云服务器常用端口号大全以及端口开启方法

腾讯云服务器常用端口号如80、21、22、8080等端口&#xff0c;出于安全考虑一些常用端口默认是关闭的&#xff0c;腾讯云服务器端口如何打开呢&#xff1f;云服务器CVM在安全组中开启端口&#xff0c;轻量应用服务器在防火墙中可以打开端口&#xff0c;腾讯云百科来详细说下腾讯…

在云服务器上部署简单的聊天机器人网站(源1.0接口版)

诸神缄默不语-个人CSDN博文目录 又不是不能用.jpg http://47.113.197.198:8000/chat 集成代码可参考&#xff1a;花月与剑/scholar_ease 之所以先用源1.0&#xff0c;一是因为我API都申请了&#xff0c;不用白不用&#xff1b;二是因为源1.0可以直接用国内网络连接&#xf…

Vue登录界面精美模板分享

文章目录 &#x1f412;个人主页&#x1f3c5;Vue项目常用组件模板仓库&#x1f4d6;前言&#xff1a;&#x1f380;源码如下&#xff1a; &#x1f412;个人主页 &#x1f3c5;Vue项目常用组件模板仓库 &#x1f4d6;前言&#xff1a; 本篇博客主要提供vue组件之登陆组件源码…

idea连接Linux服务器

一、 介绍 配置idea的ssh会话和sftp可以实现对linux远程服务器的访问和文件上传下载&#xff0c;是替代Xshell的理想方式。这样我们就能在idea里面编写文件并轻松的将文件上传到linux服务器中。而且还能远程编辑linux服务器上的文件。掌握并熟练使用&#xff0c;能够大大提高我…

操作系统复习2.4.0-死锁详解

什么是死锁 各进程互相竞争对手里的资源&#xff0c;导致各进程都阻塞&#xff0c;都无法向前推进 死锁、饥饿、死循环的区别 死锁&#xff1a;各进程互相持有对方想要的资源且不释放&#xff0c;导致各进程阻塞&#xff0c;无法向前推进 饥饿&#xff1a;由于长期得不到想要…

四站精彩回顾 | Fortinet Accelerate 2023·中国区巡展火热进行中

Fortinet Accelerate 2023中国区巡展 上周&#xff0c;Fortinet Accelerate 2023中国区巡展分别走过青岛、南京、长沙、合肥四站&#xff0c;Fortinet携手太平洋电信、亚马逊云科技、中企通信等云、网、安合作伙伴&#xff0c;与各行业典型代表客户&#xff0c;就网安融合、网…

电动葫芦无法运转怎么办?

有关电动葫芦无法起动与运转故障&#xff0c;电动葫芦无法起动怎么办&#xff0c;有没有好的解决办法&#xff0c;检查电源熔丝是否烧断&#xff0c;定子绕组相间短路、接地或断路&#xff0c;以及是否负载过大或传动机械故障等。 电动葫芦无法运转故障怎么办 1、首先&#xf…

C语言基础习题讲解

C语言基础习题讲解 运算符判断简单循环 运算符 1. 设计一个程序, 输入三位数a, 分别输出个,十,百位. (0<a<1000) 样例输入: 251 样例输出: 2 5 1 #include <stdio.h> int main() {int input 0;int x 0;int y 0;int z 0;scanf("%d", &input);x …

7 种常见的路由协议

网络路由是网络通信的重要组成部分&#xff0c;通过互联网将信息从源地址移动到目的地的过程。路由发生在 OSI 模型的第 3 层&#xff08;网络层&#xff09;。实际网络中通常会将静态和动态路由结合使用。静态路由适用于小型网络&#xff0c;而动态路由适用于大型网络。 什么…

界面控件DevExpress ASP.NET新主题——Office 365暗黑主题的应用

DevExpress ASP.NET Web Forms Controls拥有针对Web表单&#xff08;包括报表&#xff09;的110种UI控件&#xff0c;DevExpress ASP.NET MVC Extensions是服务器端MVC扩展或客户端控件&#xff0c;由轻量级JavaScript小部件提供支持的70个高性能DevExpress ASP.NET Core Contr…

华为路由器 IPSec VPN 配置

需求&#xff1a; 通过 IPSecVPN 实现上海与成都内网互通 拓扑图如下&#xff1a; 一、首先完成网络配置 1、R1 路由器设置 <Huawei>sys [Huawei]sys R1 [R1]un in en# 开启DHCP [R1]dhcp enable# 设置内网接口 [R1]int g0/0/0 [R1-GigabitEthernet0/0/0]ip addr 10.…

Git日常使用技巧 - 笔记

Git日常使用技巧 - 笔记 Git是目前世界上最先进的分布式版本控制系统 学习资料 廖雪峰 学习视频 https://www.bilibili.com/video/BV1pX4y1S7Dq/?spm_id_from333.337.search-card.all.click&vd_source2ac127043ccd79c92d5b966fd4a54cd7 Git 命令在线练习工具 https://l…

国内可用 ChatGPT 网页版

前言 ChatGPT持续火热&#xff0c;然鹅国内很多人还是不会使用。 2023年6月1日消息&#xff0c;ChatGPT 聊天机器人可以根据用户的输入生成各种各样的文本&#xff0c;包括代码。但是&#xff0c;加拿大魁北克大学的四位研究人员发现&#xff0c;ChatGPT 生成的代码往往存在严…

项目开发-依赖倒置、里式替换、接口隔离的应用深入理解

文章目录 前言依赖倒置定义不符合依赖倒置原则是什么样子&#x1f604;完善 里式替换定义具体应用 接口隔离定义具体应用 前言 最近在做.net项目和学习这个设计模式中的依赖倒置和工厂方法&#xff0c;这个过程当中发现在开发这个.net项目中有很多不合理的地方&#xff0c;就是…