蜀道山2024复现笔记

news/2025/3/4 14:41:24/文章来源:https://www.cnblogs.com/Q7h2q9/p/18746847

蜀道山2024复现笔记


Map_maze

PE32文件,ida分析,由题名可知是一道迷宫题

image-20250301173126171

initial函数是地图的初始化,sub_101C40是验证函数

先看验证部分

char __cdecl sub_101C40(_DWORD *a1, _DWORD *a2, int a3)
{char result; // alint i; // [esp+0h] [ebp-8h]for ( i = 0; *(_BYTE *)(i + a3); ++i ){if ( *(_BYTE *)(i + a3) == 'U' && a1[1] && !*(_DWORD *)a1[1] ){a1 = (_DWORD *)a1[1];//上}else if ( *(_BYTE *)(i + a3) == 'D' && a1[2] && !*(_DWORD *)a1[2] ){a1 = (_DWORD *)a1[2];//下}else if ( *(_BYTE *)(i + a3) == 'L' && a1[3] && !*(_DWORD *)a1[3] ){a1 = (_DWORD *)a1[3];//左}else{if ( *(_BYTE *)(i + a3) != 'R' || !a1[4] || *(_DWORD *)a1[4] )return 0;a1 = (_DWORD *)a1[4];//右}}result = (char)a2;if ( a1[2] == a2[2] ){result = (char)a2;if ( a1[1] == a2[1] ){result = (char)a2;if ( a1[3] == a2[3] ){result = (char)a2;if ( a1[4] == a2[4] )return 1;}}}return result;
}

上下左右移动可以猜出来,但是具体的验证逻辑有点看不懂

继续看initial

int __cdecl initial(_DWORD *a1, _DWORD *a2)
{_DWORD *v2; // eax_DWORD *v3; // eaxint result; // eax_DWORD v5[105]; // [esp+0h] [ebp-424h] BYREF_DWORD v6[119]; // [esp+1A4h] [ebp-280h]//事实上,v5和v6都是地图的一部分,查看内存可知它们是连在一起的,105+119+[0]=225也可以验证这一点_DWORD *v7; // [esp+380h] [ebp-A4h]int i28; // [esp+384h] [ebp-A0h]int i27; // [esp+388h] [ebp-9Ch]int i26; // [esp+38Ch] [ebp-98h]int i25; // [esp+390h] [ebp-94h]int i24; // [esp+394h] [ebp-90h]int i23; // [esp+398h] [ebp-8Ch]int i22; // [esp+39Ch] [ebp-88h]int i21; // [esp+3A0h] [ebp-84h]int i20; // [esp+3A4h] [ebp-80h]int i19; // [esp+3A8h] [ebp-7Ch]int i18; // [esp+3ACh] [ebp-78h]int i17; // [esp+3B0h] [ebp-74h]int i16; // [esp+3B4h] [ebp-70h]int i15; // [esp+3B8h] [ebp-6Ch]int i14; // [esp+3BCh] [ebp-68h]int i13; // [esp+3C0h] [ebp-64h]int i12; // [esp+3C4h] [ebp-60h]int i11; // [esp+3C8h] [ebp-5Ch]int i10; // [esp+3CCh] [ebp-58h]int i9; // [esp+3D0h] [ebp-54h]int i8; // [esp+3D4h] [ebp-50h]int i7; // [esp+3D8h] [ebp-4Ch]int i6; // [esp+3DCh] [ebp-48h]int i5; // [esp+3E0h] [ebp-44h]int i4; // [esp+3E4h] [ebp-40h]int i3; // [esp+3E8h] [ebp-3Ch]int i2; // [esp+3ECh] [ebp-38h]int i1; // [esp+3F0h] [ebp-34h]int nn; // [esp+3F4h] [ebp-30h]int mm; // [esp+3F8h] [ebp-2Ch]int kk; // [esp+3FCh] [ebp-28h]int jj; // [esp+400h] [ebp-24h]int ii; // [esp+404h] [ebp-20h]int n; // [esp+408h] [ebp-1Ch]int m; // [esp+40Ch] [ebp-18h]int k; // [esp+410h] [ebp-14h]int j; // [esp+414h] [ebp-10h]int i; // [esp+418h] [ebp-Ch]int i30; // [esp+41Ch] [ebp-8h]int i29; // [esp+420h] [ebp-4h]for ( i = 0; i < 15; ++i ){for ( j = 0; j < 15; ++j )v5[15 * i + j] = sub_101080(0);//初始化为0(墙),15x15的map}for ( k = 1; k < 15; ++k )*(_DWORD *)v5[k] = 1;for ( m = 9; m < 15; ++m )*(_DWORD *)v5[m + 15] = 1;for ( n = 0; n < 2; ++n )*(_DWORD *)v5[n + 30] = 1;for ( ii = 3; ii < 8; ++ii )*(_DWORD *)v5[ii + 30] = 1;for ( jj = 9; jj < 15; ++jj )*(_DWORD *)v5[jj + 30] = 1;for ( kk = 0; kk < 2; ++kk )*(_DWORD *)v5[kk + 45] = 1;for ( mm = 3; mm < 8; ++mm )*(_DWORD *)v5[mm + 45] = 1;for ( nn = 12; nn < 15; ++nn )*(_DWORD *)v5[nn + 45] = 1;for ( i1 = 0; i1 < 2; ++i1 )*(_DWORD *)v5[i1 + 60] = 1;for ( i2 = 7; i2 < 10; ++i2 )*(_DWORD *)v5[i2 + 60] = 0;*(_DWORD *)v5[67] = 1;for ( i3 = 11; i3 < 15; ++i3 )*(_DWORD *)v5[i3 + 60] = 1;for ( i4 = 0; i4 < 2; ++i4 )*(_DWORD *)v5[i4 + 75] = 1;for ( i5 = 3; i5 < 6; ++i5 )*(_DWORD *)v5[i5 + 75] = 1;for ( i6 = 11; i6 < 15; ++i6 )*(_DWORD *)v5[i6 + 75] = 1;for ( i7 = 0; i7 < 2; ++i7 )*(_DWORD *)v5[i7 + 90] = 1;*(_DWORD *)v5[92] = 0;for ( i8 = 3; i8 < 6; ++i8 )*(_DWORD *)v5[i8 + 90] = 1;for ( i9 = 7; i9 < 10; ++i9 )*(_DWORD *)v5[i9 + 90] = 1;for ( i10 = 11; i10 < 15; ++i10 )*(_DWORD *)v5[i10 + 90] = 1;*(_DWORD *)v6[0] = 1;*(_DWORD *)v6[1] = 0;*(_DWORD *)v6[2] = 0;*(_DWORD *)v6[3] = 1;for ( i11 = 4; i11 < 6; ++i11 )*(_DWORD *)v6[i11] = 1;for ( i12 = 7; i12 < 10; ++i12 )*(_DWORD *)v6[i12] = 1;for ( i13 = 11; i13 < 15; ++i13 )*(_DWORD *)v6[i13] = 1;for ( i14 = 0; i14 < 2; ++i14 )*(_DWORD *)v6[i14 + 15] = 1;for ( i15 = 7; i15 < 10; ++i15 )*(_DWORD *)v6[i15 + 15] = 1;for ( i16 = 11; i16 < 15; ++i16 )*(_DWORD *)v6[i16 + 15] = 1;for ( i17 = 0; i17 < 6; ++i17 )*(_DWORD *)v6[i17 + 30] = 1;for ( i18 = 7; i18 < 10; ++i18 )*(_DWORD *)v6[i18 + 30] = 1;for ( i19 = 11; i19 < 15; ++i19 )*(_DWORD *)v6[i19 + 30] = 1;for ( i20 = 0; i20 < 6; ++i20 )*(_DWORD *)v6[i20 + 45] = 1;for ( i21 = 11; i21 < 15; ++i21 )*(_DWORD *)v6[i21 + 45] = 1;for ( i22 = 0; i22 < 9; ++i22 )*(_DWORD *)v6[i22 + 60] = 1;for ( i23 = 13; i23 < 15; ++i23 )*(_DWORD *)v6[i23 + 60] = 1;for ( i24 = 0; i24 < 9; ++i24 )*(_DWORD *)v6[i24 + 75] = 1;*(_DWORD *)v6[84] = 0;*(_DWORD *)v6[85] = 1;*(_DWORD *)v6[86] = 1;*(_DWORD *)v6[87] = 0;for ( i25 = 13; i25 < 15; ++i25 )*(_DWORD *)v6[i25 + 75] = 1;for ( i26 = 0; i26 < 9; ++i26 )*(_DWORD *)v6[i26 + 90] = 1;*(_DWORD *)v6[99] = 0;*(_DWORD *)v6[100] = 1;*(_DWORD *)v6[101] = 1;*(_DWORD *)v6[102] = 0;for ( i27 = 13; i27 < 15; ++i27 )*(_DWORD *)v6[i27 + 90] = 1;for ( i28 = 0; i28 < 12; ++i28 )*(_DWORD *)v6[i28 + 105] = 1;for ( i29 = 0; i29 < 15; ++i29 ){for ( i30 = 0; i30 < 15; ++i30 ){if ( i29 > 0 )*(_DWORD *)(v5[15 * i29 + i30] + 4) = v5[15 * i29 - 15 + i30];if ( i29 < 14 )*(_DWORD *)(v5[15 * i29 + i30] + 8) = v5[15 * i29 + 15 + i30];if ( i30 > 0 )*(_DWORD *)(v5[15 * i29 + i30] + 12) = v5[15 * i29 - 1 + i30];if ( i30 < 14 )*(_DWORD *)(v5[15 * i29 + i30] + 16) = v5[15 * i29 + 1 + i30];}}//确定上下左右的指针逻辑,这段代码的主要目的是构建一个包含方向信息的15x15网格结构,使得每个格子都知道它在四个基本方向上的邻居是谁。v2 = (_DWORD *)v5[0];*a1 = *(_DWORD *)v5[0];a1[1] = v2[1];a1[2] = v2[2];a1[3] = v2[3];a1[4] = v2[4];v3 = v7;*a2 = *v7;a2[1] = v3[1];a2[2] = v3[2];a2[3] = v3[3];result = v3[4];a2[4] = result;return result;
}

事实上,这里的v5v6map[]是结构体类型的数据,具体定义如下

typedef enum{NotWall,IsWall
} WallState;
struct Cell{WallState isWall;//是否为墙的枚举值struct Cell* U;//指向上方的指针struct Cell* D;//指向下方的指针struct Cell* L;//指向左方的指针struct Cell* R;//指向右方的指针
}

因此,对于一个Cell类型的数据a1,从内存上,

a1[0]=a1.isWall;
a1[1]=a1.U;
a1[2]=a1.D;
a1[3]=a1.L;
a1[4]=a1.R;

逻辑很清晰了,接下来就是拿到map

'''
011111111111111
000000000111111
110111110111111
110111110000111
110000010001111
110111000001111
110111011101111
100111011101111
110000011101111
111111011101111
111111000001111
111111111000011
111111111011011
111111111011011
111111111111000
'''

地图有多解,flag只有唯一解,多尝试几次,正确答案是

#DRRDDDDDDDRRRRDDRRRDRRRDDDRR

Potato Toolkit

运行程序,发现要输入http指令和参数

image-20250301181457890

ida分析,查找关键字符串Complie Error

定位到关键逻辑代码

image-20250301181604739

往上看,找到两个字符串1wesa234,qwe123998244353,输进去执行发现直接闪退

image-20250301181621038

找到exit(0),下断点动调,这里应该是数据操作部分

image-20250301181915052

重点看加密部分

v10 = v20;
do
{v12 = QString::length((QString *)v17);//获取字符串长度v13 = (QChar *)QString::operator[](v17, v2 % v12);//根据索引v2%length访问v17中的特定字符给v13v14 = QChar::unicode(v13);//获取v13(char型)的unicode值v15 = QChar::QChar((QChar *)&v16, *(_BYTE *)v10 ^ *(_BYTE *)v14);//对v10指向的数据和v14处的字符的字节表示进行按字节的异或,结果存在v15(QChar对象)QString::operator+=(v18, *(unsigned __int16 *)v15);//将新生成的字符存在v18所指向的QString对象中
//更新循环变量++v2;v10 = (__int128 *)((char *)v10 + 4);--v11;
}
while ( v11 );

逻辑很清晰,就是循环异或,这里已经动调到exit(0)处,直接进v18,注意,这里的v18是一个指针,其指向的内容才是flag

image-20250301182528990

0x8处按d,得到指向的flag

HelloHarmony

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了

大家好!今天给大家带来一个好消息,Dapr(Distributed Application Runtime)1.15版本正式发布啦!对于不熟悉Dapr的朋友来说,Dapr是一个开源的、跨平台的运行时,它简化了微服务架构中的许多复杂问题,比如服务发现、配置管理、状态管理等。那么,Dapr 1.15版本都带来了哪些…

关闭自检硬盘

关闭自检硬盘 来源 https://zhuanlan.zhihu.com/p/491844439 第一个办法: 1.新建TXT文档 2.复制以下代码 @echo off chkntfs /x C: chkntfs /x D: chkntfs /x E: chkntfs /x F: chkntfs /x G: chkntfs /x H: chkntfs /x I: chkntfs /x J: pause 3.保存文档并更改后缀为.bat 4…

解析若依框架的logback.xml文件

1.确定输出方式,输出到控制台还是文件2.用于限制某一 appender 接收哪些日志级别的日志3.不同包确定不同的消息级别4.为所有未单独配置的日志记录器提供默认的日志级别和输出设置(不同的appender),5.配置logger通过这个方法,给sys-user Logger logger = LoggerFactory.get…

程序员日志管理的两种方式

1.linux命令来查看日志信息 若依框架日志文件目前有三类文件,分别是sys-error.log、sys-info.log、sys-user.log文件 文件中不带日期记录的当天的日志 sys-info.log记录的是系统日志,包含了运行日志和错误日志(较全) sys-error.log记录的是错误日志,排查错误一般看这个文件…

GormTabsBar 待完成

前言 RAD Studio Athens 12.0 添加了一个新的 FormTabsBar 控件,作为通用且即用型的解决方案,用于在现代选项卡状用户界面中托管多个子表单,是在 VCL 中创建全新应用程序的一种方式。 这句话是官方的介绍,您应该知道,随着程序的功能日渐增多,传统的界面无论怎么设计都已经…

.Net 异步与同步

namespace demoSp;class Program {static void Main(string[] args){threadpl();}public static void threadpl(){Console.WriteLine("Async Test job:");Console.WriteLine("main start..");AsyncMethod(); Console.WriteLine("MyMethod()异步方法同…

Hackthebox Season 赛季靶场TitanicWP随笔

一个比较简单的赛季靶场,就是服务器十分不稳定,打起来经常抽风,curl和ping都不通,有点磨人心态 一、信息收集 先nmap扫描一下ip吧,输入nmap -sV -sC 10.10.11.55 -Pn 可以看到需要自行前往hosts中添加10.10.11.55 titanic.htb后才能访问网页,添加后使用whatweb跑一下,看看…

Qt图形连线功能升级:支持多拐点和颜色区分

本文在Qt图形框架中扩展了连线功能,实现了给连线添加多个拐点并使用不同颜色绘制的效果。该实现优化了连线的可视化效果,提升了代码可扩展性,为复杂图形编辑工具的开发提供了参考。摘要:本文在Qt图形框架中扩展了连线功能,实现了给连线添加多个拐点并使用不同颜色绘制的效…

《历史代码分析》1、接口安全校验-拦截器的使用

1、接口安全校验-拦截器的使用 ​​ 本系列《历史代码分析》为工作中遇到具有代表性的代码,已做脱敏处理。今天我们讲一下接口安全检验,使用到Spring中的拦截器。 请先看下面代码: package tech.xueyao.filter.interceptor;import tech.xueyao.contant.properties.SystemPro…

Anaconda安装指南(conda 不是内部或外部命令,也不是可运行的程序 或批处理文件)

原文链接:https://zhuanlan.zhihu.com/p/101434455 第一步:附上软件下载链接,自行下载 以下是Anaconda的下载链接及相关信息: 官方下载链接Anaconda官网下载地址:https://www.anaconda.com/products/distribution。Anaconda中文官网下载地址:https://www.anacondacn.com/…

docker-compose本地部署前后端分离的项目

本文使用docker-compose进行容器化部署前后端分离的项目(前端vue、后端springboot),部署的虚拟机是centOS系统1.准备打包项目 使用maven打包springboot项目为.jar文件得到springboot-0.0.1-SNAPSHOT.jar打包vue项目 npm install -g @vue/cli安装Vue CLI 在项目根目录下,运行…

使用云效实现流水线部署前后端分离的项目

使用云效实现流水线部署前后端分离的项目1.流水线远程自动化部署 1.1核心代码准备 使用git add .,git commit,git push将本地部署项目中的文档上传到远端仓库(新建的docker12)代码已上传成功修改Dockerfile有关镜像部分,使用阿里云容器镜像服务制品中心的base镜像。 jdk镜…