BUUCTF 刮开有奖 1

news2024/11/15 8:00:20

这题使用IDA反汇编的话有windows编程基础会好些,看不懂跟着思路来也行

文章目录

  • 一、基本分析
  • 二、代码分析
    • 第一处判断
      • 疑问
    • 第二个判断
    • 第三处判断
    • 第四处判断
    • 第五处判断
    • 第五处判断
  • 三、flag
  • 四、最后

一、基本分析

在这里插入图片描述
运行后
在这里插入图片描述
然后就什么都没有了

IDA反汇编
在这里插入图片描述
紫色颜色的函数就是windows系统的内置函数,这里是一个对话框函数,主要的就是第四个参数(DialogFunc),这是一个自定义函数,对话框的所有操作都在这里执行了
点进去这个函数

在这里插入图片描述

可以直接跳转到代码分析处
a2是窗口消息,可以看到是自定义函数中传递的,该消息由用户的动作产生,比如鼠标的点击,移动等,对话框的初始化都会产生一个对应的唯一的消息ID,前面消息ID的判断我们就不看了,直接浏览全部代码发现一处弹出框
在这里插入图片描述
这个也是windows的系统函数,用于弹出信息,所以我们猜测,执行到这里,flag就有了(一般出题的套路都是如此好吧,而且就这个if判断的内容最长,也只有你了)
所以我们需要让上一个if判断成立
在这里插入图片描述

所以直接看看如何让判断成立

二、代码分析

第一处判断

String[0] == v7[0] + 34

首先就是String[0]要等于v7[0] + 34, 这里v7我们并不知道,所以向上判断
在这里插入图片描述
你们那里的v7最开始的赋值可能是数字,点击数字然后按r就可以转字符
最开始是Z,后面经过sub_4010F0函数后不知道变成啥了,进去看看
在这里插入图片描述
看着就炸裂有没有,不过这个代码可以直接复制到本地运行一下,将_DWORD换成DWORD就好了,因为DWORD就是4字节大小,也就是32位下指针的大小,也就是c语言中的long类型(也可以换成long类型),DWORD定义在windows.h中,所以我们需要包含下 #include<windows.h>
需要在windows平台下运行

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

int __cdecl sub_4010F0(int a1, int a2, int a3)
{
    int result; // eax
    int i;      // esi
    int v5;     // ecx
    int v6;     // edx

    result = a3;
    for (i = a2; i <= a3; a2 = i)
    {
        v5 = 4 * i;
        v6 = *(DWORD *)(4 * i + a1);
        if (a2 < result && i < result)
        {
            do
            {
                if (v6 > *(DWORD *)(a1 + 4 * result))
                {
                    if (i >= result)
                        break;
                    ++i;
                    *(DWORD *)(v5 + a1) = *(DWORD *)(a1 + 4 * result);
                    if (i >= result)
                        break;
                    while (*(DWORD *)(a1 + 4 * i) <= v6)
                    {
                        if (++i >= result)
                            goto LABEL_13;
                    }
                    if (i >= result)
                        break;
                    v5 = 4 * i;
                    *(DWORD *)(a1 + 4 * result) = *(DWORD *)(4 * i + a1);
                }
                --result;
            } while (i < result);
        }
    LABEL_13:
        *(DWORD *)(a1 + 4 * result) = v6;
        sub_4010F0(a1, a2, i - 1);
        result = a3;
        ++i;
    }
    return result;
}

int main()
{
    int v7[11];
    v7[0] = 'Z';
    v7[1] = 'J';
    v7[2] = 'S';    // v8 = 'S';
    v7[3] = 'E';    // v9 = 'E';
    v7[4] = 'C';    // v10 = 'C';
    v7[5] = 'a';    // v11 = 'a';
    v7[6] = 'N';    // v12 = 'N';
    v7[7] = 'H';    // v13 = 'H';
    v7[8] = '3';    // v14 = '3';
    v7[9] = 'n';    // v15 = 'n';
    v7[10] = 'g';   // v16 = 'g';
    sub_4010F0((int)v7, 0, 10);
    printf("%c", v7[0] + 34);
    return 0;
}

最后输出为 U

疑问

这里看了代码的小伙伴可能会发现我将其他变量的值写在了v7中(这里将其他变量的值转成了字符)
在这里插入图片描述
其实我们在定义变量处就可以发现变量的定义在内存中是连续的,也就是说原本可能是数组,但是IDA识别成了变量,从sub_4010F0函数中也可以发现这一点
在这里插入图片描述
在这里插入图片描述
传递的第一个参数是指针,而第二个参数为0,第三个为10, 这个函数的代码里有一个for循环

a2=0
a3=10
for(i=0; i <= 10;...)`

这个for循环一共循环11次,而我们将变量加上v7数组后一共11个int大小的单元,也就是说明对其他变量进行了操作,再看这行代码

v6 = *(_DWORD *)(4 * i + a1);

少见这种代码的小伙伴可能会懵逼,这是IDA寻址的一种表示,可以看成

a1[i]

为什么这样看?
首先a1是指针,4就是int类型占用的内存大小,i是数组的下标,里面计算出地址

(4 * i + a1)

然后转成32位下的地址

(_DWORD *)(4 * i + a1)

地址解引用

int* p = (_DWORD *)(4 * i + a1)
*p

此时的*p不就等于 *(_DWORD *)(4 * i + a1)


第二个判断

继续看第二个判断

String[1] == v10

在这里插入图片描述

看起来v10似乎没有变化,但是不要忘了我前面说的,这些变量就是一个int数组,v7被作为指针传递v10在v7的下标也就是4
我们稍微改变我们上一步输出的源代码

在这里插入图片描述

最后输出J


第三处判断

4 * String[2] - 141 == 3 * v8

大概公式推导出

String[2] = (3*v8+141) / 4

直接上代码
在这里插入图片描述

结果 W


第四处判断

String[3] / 4 == 2 * (v13 / 9)

推导

String[3] == 2 * (v13 / 9) * 4

在这里插入图片描述

结果 P


第五处判断

!strcmp(v4, "ak1w")

需要v4ak1w相等
让我们看看v4在何处
在这里插入图片描述
很明显,跟v18扯上了关系
在这里插入图片描述

这里我排个序

v18[0] = String[5];
v18[1] = String[6];
v18[2] = String[7];
v4 = (const char *)sub_401000((int)v18, strlen(v18));

进入函数看看
在这里插入图片描述
这里看到一个比较特殊的变量好吧
点进去看
在这里插入图片描述
一眼盯真,base64编码表
也就是说v4可能是三个字符的编码后的结果
这里对 ak1wbase解码 jMp


第五处判断

!strcmp(v5,"V1Ax"))

这里函数用的都是同一个

在这里插入图片描述

v18[0] = String[2];
v18[1] = String[3];
v18[2] = String[4];

V1Ax解码 WP1

三、flag

至此全部判断都解出来了,可以发现,所有判断都是围绕着String进行的,最后解得的String就是flag

首先是最后两处判断得到的 String[2] - String[7] 等于 WP1jMp
还有第一处得到的 String[0] 等于 U
第二处得到的 String[1] 等于 J

最后得到flag

flag{UJWP1jMp}

在这里插入图片描述

四、最后

我们发现我们解出的其他两处似乎没用上,这个故事告诉我们
捷径总是到成功时才发现,但是一切都不再有回头路。

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

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

相关文章

异常---

目录 认识异常 自定义异常 认识异常 1.异常是什么&#xff1f; 2&#xff0e;异常的代表是谁&#xff1f;分为几类&#xff1f; Error &#xff1a;代表的系统级别错误&#xff08;属于严重问题&#xff09;&#xff0c;也就是说系统一旦出现问题&#xff0c; s u n 公司会把…

RDMA概览

RDMA(Remote Direct Memory Access&#xff0c;远程直接内存访问)&#xff0c;指能够访问(读写)远程机器的内存。有多种支持RDMA的网络协议&#xff0c;包括&#xff1a;Infiniband、RoCE和iWAPP。具体的API定义包含在内核文件linux/include/rdma/ib_verbs.h reference: 【精选…

02【Git分支的使用、Git回退、还原】

上一篇&#xff1a;01【Git的基本命令、底层命令、命令原理】 下一篇&#xff1a;03【Git的协同开发、TortoiseGit、IDEA的操作Git】 文章目录 02【Git分支的使用、Git回退、还原】一、分支1.1 分支概述1.1.1 Git分支简介1.1.2 Git分支原理 1.2 创建分支1.2.1 创建普通分支1.…

如何理解my_map.yaml中origin的含义

当然可以。首先,我们先了解一下2D地图的基本构成。2D地图实际上是一个网格系统,其中每个单元格(或像素)代表现实世界中的一个区域。当我们谈论origin时,我们实际上是在描述这个网格如何在真实的3D空间中放置。 让我们通过一个简单的示意图来解释: 假设上面的矩形表示一个…

分组卷积的思想神了

大家好啊&#xff0c;我是董董灿。 最近&#xff0c;分组卷积帮我解决了一个大忙&#xff0c;事情是这样的。 这几天遇到一个头疼的问题&#xff0c;就是要在某一芯片上完成一个神经网络的适配&#xff0c;这个神经网络中卷积居多&#xff0c;并且有一些卷积的通道数很大&…

Go 命令大全:全面解析与实践

一、Go命令全列表 在这部分&#xff0c;我们将通过一个表格来快速浏览Go语言的所有内建命令及其基本功能。这些命令涵盖了从代码构建、测试&#xff0c;到依赖管理和其他工具等方面。 命令功能描述go build编译Go源文件go run编译并运行Go程序go get下载并安装依赖或项目go m…

AD9371 官方例程HDL详解之JESD204B RX侧时钟生成

AD9371 系列快速入口 AD9371ZCU102 移植到 ZCU106 &#xff1a; AD9371 官方例程构建及单音信号收发 ad9371_tx_jesd -->util_ad9371_xcvr接口映射&#xff1a; AD9371 官方例程之 tx_jesd 与 xcvr接口映射 AD9371 官方例程 时钟间的关系与生成 &#xff1a; AD9371 官方…

是谁在造谣杭州取消直播带货?

我是卢松松&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 这个世道&#xff0c;谣言的传播成本很低&#xff1a;比如“杭州禁止直播带货”这件事。 就在今天若水跟我说&#xff1a;“杭州禁止直播是谣言了&#xff0c;辟谣了”让我也赶紧隐藏或删除内容&…

LVS集群-NAT模式

集群的概念&#xff1a; 集群&#xff1a;nginx四层和七层动静分离 集群标准意义上的概念&#xff1a;为解决特定问题将多个计算机组合起来形成一个单系统 集群的目的就是为了解决系统的性能瓶颈。 垂直扩展&#xff1a;向上扩展&#xff0c;增加单个机器的性能&#xff0c;…

YOLOv7优化:感受野注意力卷积运算(RFAConv),效果秒杀CBAM和CA等 | 即插即用系列

💡💡💡本文改进:感受野注意力卷积运算(RFAConv),解决卷积块注意力模块(CBAM)和协调注意力模块(CA)只关注空间特征,不能完全解决卷积核参数共享的问题 提供多种卷积变体供使用:CBAMConv,CAMConv,CAConv,RFAConv,RFCAConv RFAConv | 亲测在多个数据集能够实现…

时间、空间复杂度的例题详解

文章前言 上篇文章带大家认识了数据结构和算法的含义&#xff0c;以及理解了时间、空间复杂度&#xff0c;那么接下来来深入理解一下时间、空间复杂度。 时间复杂度实例 实例1 // 计算Func2的时间复杂度&#xff1f; void Func2(int N) {int count 0;for (int k 0; k <…

yarn install 这个命令安装如何加速

yarn install 命令用来安装项目依赖&#xff0c;其速度受多种因素影响&#xff0c;如网络速度、npm/yarn包的源服务器、以及本地缓存等。以下是一些可能帮助你加速 yarn install 的方法&#xff1a; 1. 使用国内镜像 如果你在中国&#xff0c;可以使用淘宝的 npm 镜像&#x…

【正点原子STM32连载】 第四十四章 触摸屏实验 摘自【正点原子】APM32F407最小系统板使用指南

1&#xff09;实验平台&#xff1a;正点原子stm32f103战舰开发板V4 2&#xff09;平台购买地址&#xff1a;https://detail.tmall.com/item.htm?id609294757420 3&#xff09;全套实验源码手册视频下载地址&#xff1a; http://www.openedv.com/thread-340252-1-1.html## 第四…

ubuntu 22.04安装百度网盘

百度网盘 客户端下载 (baidu.com) 下载地址 sudo dpkg -i baidunetdisk_4.17.7_amd64.deb

Go RESTful API 接口开发

文章目录 什么是 RESTful APIGo 流行 Web 框架-GinGo HelloWorldGin 路由和控制器Gin 处理请求参数生成 HTTP 请求响应Gin 的学习内容实战用 Gin 框架开发 RESTful APIOAuth 2.0接口了解用 Go 开发 OAuth2.0 接口示例 编程有一个准则——Don‘t Repeat Yourself&#xff08;不要…

强化学习------PPO算法

目录 简介一、PPO原理1、由On-policy 转化为Off-policy2、Importance Sampling&#xff08;重要性采样&#xff09;3、off-policy下的梯度公式推导 二、PPO算法两种形式1、PPO-Penalty2、PPO-Clip 三、PPO算法实战四、参考 简介 PPO 算法之所以被提出&#xff0c;根本原因在于…

简述一下伪共享的概念以及如何避免

缓存行 计算机工程师为了提高 CPU 的利用率&#xff0c;平衡 CPU 和内存之间的速度差异&#xff0c;在CPU 里面设计了三级缓存。 CPU 在向内存发起 IO 操作的时候&#xff0c;一次性会读取 64 个字节的数据作为一个缓存行&#xff0c;缓存到 CPU 的高速缓存里面。 在 Java 中一…

Codeforces Round 905 (Div. 3)ABCDEF

Codeforces Round 905 (Div. 3) 目录 A. Morning题意思路核心代码 B. Chemistry题意思路核心代码 C. Raspberries题意思路核心代码 D. In Love题意思路核心代码 E. Look Back题意思路核心代码 A. Morning 题意 从一开始&#xff0c;每一次操作可以选择当前的数字打印或者是移…

【代码随想录】算法训练计划03

1、203. 移除链表元素 题目&#xff1a; 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 输入&#xff1a;head [1,2,6,3,4,5,6], val 6 输出&#xff1a;[1,2,3,4,5] 思路&#xf…

【Unity实战】手戳一个自定义角色换装系统——2d3d通用

文章目录 每篇一句前言素材开始切换头型添加更改颜色随机控制头型和颜色新增眼睛同样的方法配置人物的其他部位设置相同颜色部位全部部位随机绘制UI并添加点击事件通过代码控制点击事件添加颜色修改的事件其他部位效果UI切换添加随机按钮保存角色变更数据跳转场景显示角色数据 …