NSSCTF [suctf 2019]hardcpp WP 控制流混淆
下载文件,64位主函数非常多循环

去控制流混淆,脚本下载deflat
用法
python 脚本名 文件名 起始地址
例如主函数地址是0x4007E0

python deflat.py hardCpp 0x4007E0
然后就生成了去混淆的文件
主函数非常大,开始分析逻辑
puts("func(?)=\"01abfc750a0c942167651c40d088531d\"?");
输出01abfc750a0c942167651c40d088531d"?
s = getchar();
fgets(v24, 21, stdin);
然后输入字符串,其中第一个值给s,然后再给v24。
if ( y >= 10 && ((((_BYTE)x - 1) * (_BYTE)x) & 1) != 0 )goto LABEL_13;while ( 1 ){v20 = strlen(&s);v34 = v20 != 21;if ( y < 10 || ((((_BYTE)x - 1) * (_BYTE)x) & 1) == 0 )break;
LABEL_13:v20 = strlen(&s);}
这里是个混淆,无论if跳不跳转,v20都等于s长度,注意s前面加了地址符&,
说明是地址,而s和v24的地址是连续的。所以v20本来应该为1,其实为21,不过v20的作用不大。,v34作用不大忽略
while ( 1 ){v19 = 1;if ( y < 10 || ((((_BYTE)x - 1) * (_BYTE)x) & 1) == 0 )break;v19 = 1;}
这里也有混淆,v19就是1
hile ( v19 < 21 ){if ( y >= 10 && ((((_BYTE)x - 1) * (_BYTE)x) & 1) != 0 ){v18 = v21 ^ v24[v19 - 1];v17[0] = main::$_0::operator()(v27, (unsigned int)v18);v16[0] = main::$_1::operator()(v25, (unsigned int)*(&s + v21 + v19 - 1));v8 = main::$_1::operator() const(char)::{lambda(int)#1}::operator()(v16, 7LL);v18 = main::$_0::operator() const(char)::{lambda(char)#1}::operator()(v17, (unsigned int)v8);v15[0] = main::$_2::operator()(v28, (unsigned int)v18);v14[0] = main::$_2::operator()(v28, (unsigned int)*(&s + v21 + v19 - 1));v9 = main::$_2::operator() const(char)::{lambda(char)#1}::operator()(v14, 18LL);v13[0] = main::$_3::operator()(v26, (unsigned int)v9);v10 = main::$_3::operator() const(char)::{lambda(char)#1}::operator()(v13, 3LL);v12[0] = main::$_0::operator()(v27, (unsigned int)v10);v11 = main::$_0::operator() const(char)::{lambda(char)#1}::operator()(v12, 2LL);v18 = main::$_2::operator() const(char)::{lambda(char)#1}::operator()(v15, (unsigned int)v11);}do{v18 = v21 ^ v24[v19 - 1];v17[0] = main::$_0::operator()(v27, (unsigned int)v18);v16[0] = main::$_1::operator()(v25, (unsigned int)*(&s + v21 + v19 - 1));v3 = main::$_1::operator() const(char)::{lambda(int)#1}::operator()(v16, 7LL);v18 = main::$_0::operator() const(char)::{lambda(char)#1}::operator()(v17, (unsigned int)v3);v15[0] = main::$_2::operator()(v28, (unsigned int)v18);v14[0] = main::$_2::operator()(v28, (unsigned int)*(&s + v21 + v19 - 1));v4 = main::$_2::operator() const(char)::{lambda(char)#1}::operator()(v14, 18LL);v13[0] = main::$_3::operator()(v26, (unsigned int)v4);v5 = main::$_3::operator() const(char)::{lambda(char)#1}::operator()(v13, 3LL);v12[0] = main::$_0::operator()(v27, (unsigned int)v5);v6 = main::$_0::operator() const(char)::{lambda(char)#1}::operator()(v12, 2LL);v18 = main::$_2::operator() const(char)::{lambda(char)#1}::operator()(v15, (unsigned int)v6);}while ( enc[v19 - 1] != v18 );while ( y >= 10 && ((((_BYTE)x - 1) * (_BYTE)x) & 1) != 0 );++v19;}
接下来来到了重头戏了,共六个函数一个一个分析
main::$_0::operator()
char __fastcall main::$_0::operator()(__int64 a1, char a2)
{return a2;
}
就是返回a2,我们把函数重命名为return_a2方便后续分析
main::$_1::operator() const(char)::{lambda(int)#1}::operator()
__int64 __fastcall main::$_1::operator() const(char)::{lambda(int)#1}::operator()(char *a1, int a2)
{return (unsigned int)(*a1 % a2);
}
返回a1%a2,这里a2是常数7,命名为return_a1_mod_7
main::$_0::operator() const(char)::{lambda(char)#1}::operator()
__int64 __fastcall main::$_0::operator() const(char)::{lambda(char)#1}::operator()(__int64 a1, char a2)
{int v2; // eaxint v3; // eaxchar *v5; // [rsp+0h] [rbp-40h]int v6; // [rsp+8h] [rbp-38h]int v7; // [rsp+Ch] [rbp-34h]int v8; // [rsp+10h] [rbp-30h]int v9; // [rsp+14h] [rbp-2Ch]char *v10; // [rsp+18h] [rbp-28h]char v11; // [rsp+23h] [rbp-1Dh]int v12; // [rsp+24h] [rbp-1Ch]bool v13; // [rsp+2Ah] [rbp-16h]bool v14; // [rsp+2Bh] [rbp-15h]unsigned int v15; // [rsp+2Ch] [rbp-14h]v13 = ((((_BYTE)x_5 - 1) * (_BYTE)x_5) & 1) == 0;v14 = y_6 < 10;v12 = 1023500310;v11 = a2;v10 = (char *)a1;do{while ( 1 ){while ( 1 ){while ( 1 ){v9 = v12;v8 = v12 + 2037067308;if ( v12 != -2037067308 )break;v5 = v10;*((_BYTE *)&v5 - 16) = v11;v12 = -1418698808;}v7 = v9 + 1418698808;if ( v9 != -1418698808 )break;v3 = -2037067308;v5 = v10;*((_BYTE *)&v5 - 16) = v11;v15 = *((char *)&v5 - 16) + *v5;if ( y_6 < 10 || ((((_BYTE)x_5 - 1) * (_BYTE)x_5) & 1) == 0 )v3 = 1456142001;v12 = v3;}v6 = v9 - 1023500310;if ( v9 != 1023500310 )break;v2 = -2037067308;if ( v14 || v13 )v2 = -1418698808;v12 = v2;}HIDWORD(v5) = v9 - 1456142001;}while ( v9 != 1456142001 );return v15;
核心部分
v11 = a2;v10 = (char *)a1;
v5 = v10;
*((_BYTE *)&v5 - 16) = v11;
v15 = *((char *)&v5 - 16) + *v5;
return v15;
就是返回a1+a2,命名return_a1_add_a2
main::$_2::operator()
核心部分
v12 = a2;
*((_BYTE *)&v5 - 16) = v12;
LOBYTE(v5) = *((_BYTE *)&v5 - 16);
v16 = v5;
return v16;
就是返回v5低位,就是a2re_a22
main::$_2::operator() const(char)::{lambda(char)#1}::operator()
return (unsigned int)(char)(a2 ^ *a1);
命名return_a1_XOR_a2
main::$_3::operator()
v12 = a2;
*((_BYTE *)&v5 - 16) = v12;
LOBYTE(v5) = *((_BYTE *)&v5 - 16);
v16 = v5;
return v16;
命名re_a2222
main::$_3::operator() const(char)::{lambda(char)#1}::operator()
return (unsigned int)(a2 * *a1);
return_a1_x_a2
六个大爹干完了,然后再对逻辑进行分析,就是一直变换,就是解方程
v18=v24[v19-1];v17[0]=v18;//v17[0]=v24[v19-1];v16[0]=s[v19-1];v8=v16%7;//v8=s[v19-1]%7;v18=v17+v8;//v18=v24[v19-1]+s[v19-1]%7;v15[0]=v18;//v15[0]=v24[v19-1]+(s[v19-1]%7);v14[0]=s[v19-1];v9=v14^18;//v9=s[v19-1]^18;v13[0]=v9;//v13[0]=s[v19-1]^18;v10=v13*3;//v10=s[v19-1]^18*3;v12[0]=v10;v11=v12+2;//v11=s[v19-1]^18*3+2;v18=v15^v11;//v18={v24[v19-1]+(s[v19-1]%7)}^{s[v19-1]^18*3+2}
一层一层代入就得到了v18={v24[v19-1]+(s[v19-1]%7)}^{(s[v19-1]^18)*3+2}
然后再与enc[v19 - 1]比较,然后v19加1。继续上述循环。
然后逆过去解方程
v24[v19-1]+(s[v19-1]%7)=v18^(s[v19-1]^18*3+2)
v24[v19-1]=(v18^(s[v19-1]^18*3+2))-(s[v19-1]%7)
这样就能得到每一位了。现在看开头
puts("func(?)=\"01abfc750a0c942167651c40d088531d\"?");
32位,盲猜md5加密,去进行解密,得到符号#,说明第一个字符是#,即知道了s[v19-1],v19=1;.又知道了v18即enc,我们就可以求出第二位,同理得到所有,脚本如下
enc=[0xF3, 0x2E, 0x18, 0x36, 0xE1, 0x4C, 0x22, 0xD1, 0xF9, 0x8C,0x40, 0x76, 0xF4, 0x0E, 0x00, 0x05, 0xA3, 0x90, 0x0E, 0xA5]
lst=[35]
for i in range(len(enc)):lst.append((((enc[i]^((lst[i]^18)*3+2)))-((lst[i]%7)))&0xff)print(lst)
for i in lst:print(chr(i),end='')
这里有个&0xff运算,防止数字溢出
得到flag
#flag{mY-CurR1ed_Fns}
相关文章:
NSSCTF [suctf 2019]hardcpp WP 控制流混淆
下载文件,64位主函数非常多循环 去控制流混淆,脚本下载deflat 用法 python 脚本名 文件名 起始地址例如主函数地址是0x4007E0 python deflat.py hardCpp 0x4007E0然后就生成了去混淆的文件 主函数非常大,开始分析逻辑 puts("func(?…...
计算机毕业论文内容参考|基于神经网络的网络安全态势感知技术研究
文章目录 导文文章重点摘要前言绪论课题背景国内外现状与趋势课题内容相关技术与方法介绍技术分析技术设计技术实现总结与展望导文 基于神经网络的网络安全态势感知技术研究 文章重点 摘要 随着互联网的快速发展,网络攻击的频率和复杂度也在逐年增加。为了更好地保护信息系统…...
Flask框架之Request、Response、Cookies、Session等对象的使用
Request、Response、Cookies、Session等对象的使用 Request对象基本使用参数的获取转换器内置转换器自定义转换器 Response对象基本使用返回模板重定向返回JSON Cookies对象设置cookie获取cookie删除cookie Session会话对象设置SECRET_KEY设置会话获取会话释放会话 Request对象…...
信号与槽机制一
一、信号与槽 1、什么是信号与槽? 信号和槽是用于对象之间的通信,它是Qt的核心机制,在Qt编程中有着广泛的应用。如果想学好Qt,一定要充分掌握信号的槽的概念与使用。 2、信号和槽的代码实例 在Qt中,发送对象、发送的信…...
nodejs 复制文件到指定目录
var fs require(fs), path require(path), exec require(child_process).exec, sourcePath, targetPath; //获取命令行中的路径 process.argv.forEach(function (val, index, array) { if (index 2) { sourcePath val; } if (index 3) { targetPath val; } }); // 定义…...
第八章 使用Apache服务部署静态网站
文章目录 第八章 使用Apache服务部署静态网站一、网站服务程序1、网站服务介绍2、Apache程序介绍 二、配置服务文件参数1、Linux系统中的配置文件2、配置httpd服务程序时最常用的参数以及用途描述 三、SELinux安全子系统1、SELinux介绍2、SELinux服务配置模式3、Semanage命令4、…...
Three——四、几何体、高光网络材质、锯齿模糊以及GUI库的使用
文章: Three——一、初识Three以及基础的前端场景搭建(结尾含源码)Three——二、加强对三维空间的认识Three——三、动画执行、画布大小、渲染帧率和相机适配体验Three——四、几何体、高光网络材质、锯齿模糊以及GUI库的使用Three——五、点线模型对象、三角形概念…...
盲目自学网络安全只会成为脚本小子?
前言:我们来看看怎么学才不会成为脚本小子 目录: 一,怎么入门? 1、Web 安全相关概念(2 周)2、熟悉渗透相关工具(3 周)3、渗透实战操作(5 周)4、关注安全圈动…...
文从字顺|程序员须知,如何编写高质量代码
高质量代码是软件开发中至关重要的一部分。高质量的代码不仅可以提高软件的可维护性和可复用性,还可以增强软件的安全性和稳定性。同时,可以降低软件维护成本,提升开发效率,为用户提供更好的使用体验。 写出高质量代码是每个程序…...
PCIe物理层弹性缓存机制(详细)解析-PCIe专题知识(四)
目录 前言一、简介二、详细解析2.1 实例解析2.2 具体实现过程 三、总结四、其他相关链接1、PCI总线及发展历程总结2、PCIe物理层总结-PCIE专题知识(一)3、PCIe数据链路层图文总结-PCIe专题知识(二)4、PCIe物理层链路训练和初始化总…...
分片上传和断点续传的区别?实现思路是什么?
相同: 分片上传和断点续传都是网络传输中常用的重要技术 不同: 分片上传:将一个大文件切分为多个小文件进行上传。这种方式能够加快上传速度,降低服务器压力,特别适用于大型文件的上传。例如,在云存储系统…...
微前端 qiankun@2.10.5 源码分析(二)
微前端 qiankun2.10.5 源码分析(二) 我们继续上一节的内容。 loadApp 方法 找到 src/loader.ts 文件的第 244 行: export async function loadApp<T extends ObjectType>(app: LoadableApp<T>,configuration: FrameworkConfi…...
08异步请求:何种场景下应该使用异步请求?
异步在计算机科学中早就是一个比较常用的词汇,从操作系统的特性( 并发、共享、虚拟、异步)开始,异步就在处理并发操作中起到很大的作用,不仅如此,在软件层面,异步同样也是解决并发请求的一个关键过程,它可以将瞬时激增的请求进行更加灵活的处理,通过异步请求,客户端可…...
【深度学习 | Transformer】Transformers 教程:pipeline一键预测
文章目录 一、前言二、Computer vision2.1 Image classification2.2 Object detection2.3 Image segmentation2.4 Depth estimation 三、NLP3.1 Text classification3.2 Token classification3.3 Question answering3.4 Summarization3.5 Translation3.6 Language modeling3.6.…...
HTMLCSS
1、HTML 1.1 介绍 HTML 是一门语言,所有的网页都是用HTML 这门语言编写出来的,也就是HTML是用来写网页的,像京东,12306等网站有很多网页。 这些都是网页展示出来的效果。而HTML也有专业的解释 HTML(HyperText Markup Language)…...
【安装Nginx】
Linux上安装Nginx 文章目录 Linux上安装NginxUbuntuCentOS查看已安装的软件 Ubuntu 在 Ubuntu 上安装 Nginx 非常简单。只需按照以下步骤操作: 打开终端,更新软件包索引: sudo apt update安装 Nginx: sudo apt install nginx安…...
VSCode作业1:猜数字游戏和简单计数器(包含完整代码)
目录 猜数字游戏 一、使用‘random’函数获取随机数 二、 分情况讨论输入值大小情况 三、HTML代码 四、CSS样式及运行效果 简单计数器(计时器) 一、使用‘setInterval’函数实现计数效果 二、使用’clearInterval‘函数实现暂停计数和重新计数效果 …...
NANK OE骨传导开放式蓝牙耳机发布,极致体验拉满!
近日,中国专业音频品牌NANK南卡发布了全新一代——骨传导开放式蓝牙耳机NANK OE,耳机采用了传统真无线和骨传导的结合方式,带来更加舒适的佩戴体验和音质升级,同时还支持单双耳自由切换,全新的设计收获了市场的喜爱和认…...
看完这篇文章你就彻底懂啦{保姆级讲解}-----(I.MX6U驱动GPIO中断《包括时钟讲解》) 2023.5.9
目录 前言整体文件结构源码分析(保姆级讲解)中断初始化部分初始化GIC控制器初始化中断向量表设置中断向量表偏移 系统时钟初始化部分使能所有的时钟部分led初始化部分beep初始化部分key初始化部分按键中断初始化部分按键中断服务函数部分 while循环部分 …...
MySql -- 事务
目录 1.概念 2.事务的运用场景 3.事务的四大特点 4.执行事务带来的问题 4.1 脏读 4.2 不可重复度 4.3 幻读 5. MySQL中事务的隔离级别 1.概念 事务就是把若干个独立操作打包成一个整体而诞生的一种功能. 2.事务的运用场景 比如:A——>B 转账500 A的余额-500…...
【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...
EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
