BUUCTF Reverse/[GXYCTF2019]simple CPP

news2024/11/26 8:38:43

BUUCTF Reverse/[GXYCTF2019]simple CPP

在这里插入图片描述

先看文件信息,是个64位的程序,且没有加壳

在这里插入图片描述

IDA64位打开

int __cdecl main(int argc, const char **argv, const char **envp)
{
  bool v3; // si
  __int64 v4; // rax
  __int64 v5; // r8
  __int64 v6; // r8
  unsigned __int8 *v7; // rax
  unsigned __int8 *v8; // rbx
  int v9; // er10
  __int64 v10; // r11
  void **v11; // r9
  void **v12; // r8
  __int64 v13; // rdi
  __int64 v14; // r15
  __int64 v15; // r12
  __int64 v16; // rbp
  int v17; // ecx
  unsigned __int8 *v18; // rdx
  __int64 v19; // rdi
  __int64 *v20; // r14
  __int64 v21; // rbp
  __int64 v22; // r13
  __int64 *v23; // rdi
  __int64 v24; // r8
  __int64 v25; // r12
  __int64 v26; // r15
  __int64 v27; // rbp
  __int64 v28; // rdx
  __int64 v29; // rbp
  __int64 v30; // rbp
  __int64 v31; // r10
  __int64 v32; // rdi
  __int64 v33; // r8
  bool v34; // dl
  __int64 v35; // rax
  void **v36; // rdx
  __int64 v37; // rax
  __int64 v38; // r8
  __int64 v39; // rax
  void *v40; // rcx
  __int64 v42; // [rsp+20h] [rbp-68h]
  void *Block[2]; // [rsp+30h] [rbp-58h] BYREF
  unsigned __int64 v44; // [rsp+40h] [rbp-48h]
  unsigned __int64 v45; // [rsp+48h] [rbp-40h]

  v3 = 0;
  v44 = 0i64;
  v45 = 15i64;
  LOBYTE(Block[0]) = 0;
  v4 = sub_1400019C0(std::cout, "I'm a first timer of Logic algebra , how about you?", envp);
  std::ostream::operator<<(v4, sub_140001B90);
  sub_1400019C0(std::cout, "Let's start our game,Please input your flag:", v5);
  sub_140001DE0(std::cin, Block);               // 输入
  std::ostream::operator<<(std::cout, sub_140001B90);
  if ( v44 - 5 > 0x19 )                         // v44中存储的是输入flag的长度
                                                // 
  {
    v39 = sub_1400019C0(std::cout, "Wrong input ,no GXY{} in input words", v6);
    std::ostream::operator<<(v39, sub_140001B90);
    goto LABEL_43;
  }
  v7 = (unsigned __int8 *)operator new(0x20ui64);
  v8 = v7;
  if ( v7 )
  {
    *(_QWORD *)v7 = 0i64;
    *((_QWORD *)v7 + 1) = 0i64;
    *((_QWORD *)v7 + 2) = 0i64;
    *((_QWORD *)v7 + 3) = 0i64;
  }
  else
  {
    v8 = 0i64;
  }
  v9 = 0;
  if ( v44 )
  {
    v10 = 0i64;
    do
    {
      v11 = Block;
      if ( v45 >= 0x10 )
        v11 = (void **)Block[0];
      v12 = &qword_140006048;
      if ( (unsigned __int64)qword_140006060 >= 0x10 )
        v12 = (void **)qword_140006048;
      v8[v10] = *((_BYTE *)v11 + v10) ^ *((_BYTE *)v12 + v9 % 27);// 对输入的字符串进行异或处理
      ++v9;
      ++v10;
    }
    while ( v9 < v44 );
  }
  v13 = 0i64;
  v14 = 0i64;
  v15 = 0i64;
  v16 = 0i64;
  if ( (int)v44 > 30 )
    goto LABEL_27;
  v17 = 0;
  if ( (int)v44 <= 0 )
    goto LABEL_27;
  v18 = v8;
  do
  {
    v19 = *v18 + v13;
    ++v17;
    ++v18;
    switch ( v17 )                              // flag长度小于32
    {
      case 8:
        v16 = v19;
        goto LABEL_23;
      case 16:
        v15 = v19;
        goto LABEL_23;
      case 24:
        v14 = v19;
LABEL_23:
        v19 = 0i64;
        break;
      case 32:
        sub_1400019C0(std::cout, "ERRO,out of range", (unsigned int)v44);
        exit(1);
    }
    v13 = v19 << 8;
  }
  while ( v17 < (int)v44 );
  if ( v16 )
  {
    v20 = (__int64 *)operator new(0x20ui64);
    *v20 = v16;                                 // 8到15位
    v20[1] = v15;                               // 16到23位
    v20[2] = v14;                               // 24到31位
    v20[3] = v13;                               // 0到7位
    goto LABEL_28;
  }
LABEL_27:
  v20 = 0i64;
LABEL_28:
  v42 = v20[2];
  v21 = v20[1];
  v22 = *v20;
  v23 = (__int64 *)operator new(0x20ui64);
  if ( IsDebuggerPresent() )
  {
    sub_1400019C0(std::cout, "Hi , DO not debug me !", v24);
    Sleep(0x7D0u);
    exit(0);
  }
  v25 = v21 & v22;
  *v23 = v21 & v22;
  v26 = v42 & ~v22;
  v23[1] = v26;
  v27 = ~v21;
  v28 = v42 & v27;
  v23[2] = v42 & v27;
  v29 = v22 & v27;
  v23[3] = v29;
  if ( v26 != 0x11204161012i64 )
  {
    v23[1] = 0i64;
    v26 = 0i64;
  }
  v30 = v26 | v25 | v28 | v29;
  v31 = v20[1];
  v32 = v20[2];
  v33 = v28 & *v20 | v32 & (v25 | v31 & ~*v20 | ~(v31 | *v20));
  v34 = 0;
  if ( v33 == 0x8020717153E3013i64 )
    v34 = v30 == 0x3E3A4717373E7F1Fi64;
  if ( (v30 ^ v20[3]) == 0x3E3A4717050F791Fi64 )
    v3 = v34;
  if ( (v26 | v25 | v31 & v32) == (~*v20 & v32 | 0xC00020130082C0Ci64) && v3 )
  {
    v35 = sub_1400019C0(std::cout, "Congratulations!flag is GXY{", v33);
    v36 = Block;
    if ( v45 >= 0x10 )
      v36 = (void **)Block[0];
    v37 = sub_140001FD0(v35, v36, v44);
    sub_1400019C0(v37, "}", v38);
    j_j_free(v8);
  }
  else
  {
    sub_1400019C0(std::cout, "Wrong answer!try again", v33);
    j_j_free(v8);
  }
LABEL_43:
  if ( v45 >= 0x10 )
  {
    v40 = Block[0];
    if ( v45 + 1 >= 0x1000 )
    {
      v40 = (void *)*((_QWORD *)Block[0] - 1);
      if ( (unsigned __int64)(Block[0] - v40 - 8) > 0x1F )
        invalid_parameter_noinfo_noreturn();
    }
    j_j_free(v40);
  }
  return 0;
}

输入的flag存储在block中

在这里插入图片描述

一段段分析代码

这里将输入的字符串与 ==“i_will_check_is_debug_or_not”==进行异或

在这里插入图片描述

这一段将输入字符串八个字符转成16进制后拼到一起,

  do
  {
    v19 = *v18 + v13;
    ++v17;
    ++v18;
    switch ( v17 )
    {
      case 8:
        v16 = v19;
        goto LABEL_23;
      case 16:
        v15 = v19;
        goto LABEL_23;
      case 24:
        v14 = v19;
LABEL_23:
        v19 = 0i64;
        break;
      case 32:                                  // 长度要小于32
        sub_7FF616CB19C0(std::cout, "ERRO,out of range", (unsigned int)v44);
        exit(1);
    }
    v13 = v19 << 8;                             // 16进制左移两位,就是将8个16进制数拼到一起
  }

后面的比较条件,然后像v26、v25这些都可以用v20来表示

在这里插入图片描述

比如:
v26 = v42 & ~v22 = v20[2] & ~v20[0] = 0x11204161012

都这样表示后,可以转换成z3方程求解

from z3 import *
s = Solver()
v20_0,v20_1,v20_2,v20_3 = BitVecs('v20_0 v20_1 v20_2 v20_3',64)


s.add(v20_2 & ~v20_0  == 0x11204161012)

s.add( ((v20_2 & ~v20_0) | (v20_1 & v20_0) | (v20_2 & ~v20_1) | (v20_0 & ~v20_1)) == 0x3E3A4717373E7F1F)

s.add(( (v20_2 & ~v20_0)| (v20_1 & v20_0) | v20_1 & v20_2 ) == ((~v20_0 & v20_2) | 0xC00020130082C0C) )

s.add((v20_2 & ~v20_1) & v20_0 | v20_2 & ((v20_1 & v20_0) | v20_1 & ~v20_0 | ~(v20_1 | v20_0)) == 0x8020717153E3013)

s.add(v20_3 == 0x3E3A4717050F791F ^ 0x3E3A4717373E7F1F)

check = s.check()

print(check)

model = s.model()

print(model)

v20 = [4483973367147818765,937912183768591500,577031497978884115,842073600]
flag = [0] * 32
k = 0
for i in range(4):
    s = str(hex(v20[i])).replace('0x','')
    if i == 1 or i == 2:
        s = '0' + s
    print(s)
    for j in range(0,len(s),2):
       #print(chr(int(s[j:j+2],16)),end='')
       flag[k] = (int(s[j:j+2],16))
       k+=1

t = [ord(i) for i in "i_will_check_is_debug_or_not"]
print(t)
for i in range(len(t)):
    flag[i] ^= t[i % 27]
    #print(chr(flag[i])," ",flag[i] ,end='\n')
    print(chr(flag[i]) ,end='')

输出

sat
[v20_2 = 577031497978884115, 
 v20_0 = 4483973367147818765,
 v20_1 = 936750926617127948,
 v20_3 = 842073600]
3e3a460533286f0d
0d0422297009ac8c
08020717153e3013
32310600
[105, 95, 119, 105, 108, 108, 95, 99, 104, 101, 99, 107, 95, 105, 115, 95, 100, 101, 98, 117, 103, 95, 111, 114, 95, 110, 111, 116]
We1l_D0neaAB/`ßÓlgebra_am_ii

得到 We1l_D0neaAB/`ßÓlgebra_am_ii ,但这玩意中间是乱码,我还以为方程抄错了,检查了好几遍,搜了下别的大佬博客才发现,这题有问题,找到原因是方程不止一个解,而比赛的时候给出了第二部分的结果e!P0or_a

得到最终flag: flag{We1l_D0ne!P0or_algebra_am_i}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【ESP32_8266_MQTT篇】

文章目录MQTT介绍1 MQTT历史2 MQTT版本MQTT介绍 MQTT是一个客户端服务端架构的发布/订阅模式的消息传输协议。它的设计思想是轻巧、开放、简单、规范&#xff0c;易于实现。这些特点使得它对很多场景来说都是很好的选择&#xff0c;特别是对于受限的环境如机器与机器的通信&…

Java面向对象的特点之:继承

对于继承&#xff0c;当大家看到这个词语的时候&#xff0c;在现实生活中&#xff0c;想必也会自然而然的想到了&#xff1a;继承家产&#xff1f;&#xff1f;那么&#xff0c;在Java的面向对象的时候&#xff0c;也存在这样的思想&#xff01;&#xff01; 下面笔者来带领大…

【ASM】字节码操作 工具类与常用类 LocalVariablesSorter 源码介绍以及原理介绍

文章目录 1.概述2. LocalVariablesSorter#2.1 class info2.2 fields2.3 constructors2.4 methods2.4.1 newLocal method2.4.2 local variables method3.工作原理3.1 添加新変量3.2处理旧变量4.总结1.概述 在上一节文章中:【ASM】字节码操作 工具类与常用类 LocalVar

深度学习入门——基于TensorFlow的鸢尾花分类实现(TensorFlow_GPU版本安装、实现)

基于TensorFlow的鸢尾花分类实现0 引言1 基本介绍和环境搭建1.1关于TensorFlow-GPU环境搭建第一步:安装Anaconda&#xff1a;第二步&#xff1a;安装GPU版本需要&#xff0c;明确显卡型号第三步&#xff1a;打开conda终端建立Tensorflow环境第四步&#xff1a;激活虚拟环境&…

最简单例子解释python的transpose函数

二维数组的transpose就是矩阵的转置&#xff0c;这里直接略过。直接讨论三维情况。 首先&#xff0c;我们要弄清楚transpose的轴是什么意思&#xff1f; 0是代表了第一个轴&#xff0c;1是代表了第二个轴&#xff0c;2是代表了第三个轴&#xff0c;这里我们用x&#xff0c;y&…

基于PHP+MySQL米步童鞋商城网站的设计与实现

随时时代的发展,更多的宝妈们希望给宝宝买鞋子的时候能够通过更加简单方便的方式来进行,因为宝妈每天都要面对很多的时候,不能够经常到商场闲逛,所以她们急需一种通过互联网的方式来购买童鞋,所以我们通过PHP语言和MySQL数据开发了米步童鞋商城网站 米步童鞋商城网站的主要功能…

认识JUC

JUC 一、Java JUC 简介 在 Java 5.0 提供了 java.util.concurrent &#xff08;简称 JUC &#xff09;包&#xff0c;在此包中增加了在并发编程中很常用 的实用工具类&#xff0c;用于定义类似于线程的自定义子 系统&#xff0c;包括线程池、异步 IO 和轻量级任务框架。 提供…

基于阈值预分割的区域生长分割法研究-含Matlab代码

⭕⭕ 目 录 ⭕⭕✳️ 一、引言✳️ 二、区域生长原理✳️ 三、基于阈值预分割的区域生长算法✳️ 四、确定生长准则✳️ 五、实验结果✳️ 六、参考文献✳️ 七、Matlab代码获取✳️ 一、引言 在区域分割处理技术之中&#xff0c;又包含有区域生长分割技术以及区域分裂合并分割…

车辆工程的入门学习

知乎 汽车控制需要了解的 汽车的行驶阻力与驱动力 做好汽车控制需要学什么 车辆控制工程 off-road vehicle 越野车 各智能系统介绍 制动防抱死系统&#xff08;anti-lock brake system, ABS&#xff09; 电子稳定性控制&#xff08;electronic stability control&#xff0c;…

SAP ADM100-1.1之SAP系统架构

一、SAP系统组成结构 SAP系统包括一个逻辑数据库、一个或多个实例。实例(也称为Central Instance中央实例)与数据库一起形成功能性的SAP系统。在每个SAP系统中都应该配置一个Central Instance中央实例。如果系统中仅有一个单实例那就存在“中央系统”,并且与它的数据库运行在…

上海亚商投顾:沪指冲高回落 中字头板块爆发领涨

上海亚商投顾前言&#xff1a;无惧大盘大跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 市场情绪沪指今日冲高回落&#xff0c;3100点得而复失&#xff0c;黄白二线分化严重&#xff0c;权重走强题材弱势&#xff…

[附源码]java毕业设计校园跑腿系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

深度学习入门(四十六)计算机视觉——区域卷积神经网络(R-CNN)系列

深度学习入门&#xff08;四十六&#xff09;计算机视觉——区域卷积神经网络&#xff08;R-CNN&#xff09;系列前言计算机视觉——区域卷积神经网络&#xff08;R-CNN&#xff09;系列课件R-CNN兴趣区域(RoI)池化层Faster R-CNNFaster R-CNNMask R-CNN精度和速度比较总结教材…

Maven基础学习——tomcat插件配置(含web工程配置)

tomcat插件配置一、前言二、步骤1.登录网站后搜索TomcatMaven2.找到插件坐标3.选择插件版本4.将插件配置到web工程中5.测试插件三、Web工程配置1.在webapp下新建文件2.删除web.xml中多余代码3.pom.xml文件一、前言 在学习Maven时&#xff0c;肯定会遇到tomcat插件&#xff0c;…

ESP8266--Arduino开发(驱动OLED显示文字和图片)

文章目录一、0.96 IIC OLED介绍二、安装库文件2.1、库屏幕控制相关API2.2、库绘制相关API2.3、文本相关API2.4、图像相关API三、显示字母四、显示汉字五、显示图片一、0.96 IIC OLED介绍 OLED是一种利用多层有机薄膜结构产生电致发光的器件&#xff0c;它很容易制作&#xff0…

SPARKSQL3.0-Catalog源码剖析

SPARKSQL3.0-Catalog源码剖析 一、前言 阅读本节需要先掌握Analyzer阶段的相关知识 在Spark SQL 系统中&#xff0c;Catalog 主要用于各种函数资源信息和元数据信息 &#xff08;数据库、数据表数据视图、数据分区等&#xff09;的统一管理。 初次看这种解释还是比较模糊&a…

5周年,时过境迁,千变万化

2022年11月22日 小雪 长沙 阴小雨 下午 吃饭 遇雨 跑 不知不觉开始博客5年啦&#xff0c;注册账号有6年了。 ~~~那就浅写一首不像诗的诗聊表纪念吧~~~ 其实偶尔还是会迷茫&#xff0c; 但不必过分紧张&#xff0c; 每个时代都有每个时代化的特色的机遇与挑战&#xff0c; …

服务案例|AI算法在Oracle指标异常检查、故障预测之牛刀小试

LinkSLA与南京大学合作&#xff0c;将AI算法引入运维平台&#xff0c;将趋势性、周期性强的指标数据通过机器学习&#xff0c;实现异常检测、故障预测等功能。 下面分享一个通过AI算法&#xff0c;对Oracle数据库故障预测的案例。 在3月16日&#xff0c;MOC工程师接到某公司的…

中学数学教学参考杂志社中学数学教学参考编辑部2022年第27期目录

谈学论教 “平行四边形”章首课的教学思考 李斌; 1-3 高中数学课程中的函数教学 孔鑫辉; 3-4《中学数学教学参考》投稿&#xff1a;cn7kantougao163.com 对方程起始课教学的探究 梅琴; 5-7 注重师生互动,激活数学课堂 董启福; 8-9 例析高中数学体验教学法的…

RPC框架(一)——简易RPC

RPC介绍 RPC&#xff0c;Remote Procedure Call 即远程过程调用&#xff0c;远程过程调用其实对标的是本地过程调用 一个RPC框架要进行使用应该要具有如下的组件&#xff08;功能&#xff09; 从整体层次来看&#xff0c;一个RPC协议的框架应该具有三个层面&#xff1a; 服…