手把手教你用Z3求解器破解GXYCTF2019的CPP逆向题(附完整脚本)

news2026/3/22 3:39:21
用Z3求解器高效破解CTF逆向题的实战指南在CTF竞赛中逆向工程类题目往往需要选手分析二进制程序理解其内部逻辑并提取关键信息。本文将深入探讨如何利用Z3求解器这一强大的数学工具高效解决复杂的逆向题目。我们以GXYCTF2019的一道典型CPP逆向题为例展示从分析到求解的完整流程。1. 逆向工程与Z3求解器基础逆向工程的核心在于理解程序的行为逻辑而Z3求解器则能帮助我们处理复杂的约束条件。Z3是由微软研究院开发的高性能定理证明器特别适合解决包含位运算、算术运算和逻辑关系的约束系统。1.1 Z3求解器的核心优势自动化求解自动寻找满足所有约束条件的变量值支持多种理论包括位向量、整数、实数、数组等高效性能能处理包含数百个变量的复杂系统Python接口易于集成到逆向分析工作流中安装Z3 Python包非常简单pip install z3-solver1.2 CTF逆向题的常见模式大多数CTF逆向题会采用以下一种或多种保护机制输入验证对用户输入进行复杂校验加密变换使用自定义或标准加密算法混淆技术增加反调试和代码混淆数学约束通过数学关系隐藏flag2. 题目分析与约束提取以GXYCTF2019的simple CPP为例我们需要从二进制程序中提取关键约束条件。2.1 初步分析使用IDA Pro分析64位无壳程序定位到主要验证逻辑。关键函数中包含以下重要变量关系v18 [v11, v12, v13, v14] # 存储处理后的输入数据 v22 v18[1] v18[0] v23 v18[2] ~v18[0] v24 ~v18[1] v25 v18[2] v24 v26 v18[0] v242.2 约束条件整理通过逆向分析我们识别出以下核心约束(~x) z 1176889593874((z~x)|(xy)|(z~y)|(x~y))^w 4483974543195470111((z~y)x|z((xy)|y~x|~(y|x))) 577031497978884115((z~x)|(xy)|(z~y)|(x~y)) 44839745440374126393. 构建Z3求解模型将提取的约束转化为Z3可理解的表达式是解题的关键步骤。3.1 变量定义与求解器初始化from z3 import * # 定义64位位向量变量 x, y, z, w BitVecs(x y z w, 64) s Solver()3.2 添加约束条件将逆向得到的约束逐一添加到求解器中s.add((~x) z 1176889593874) s.add(((z ~x) | (x y) | (z ~y) | (x ~y)) ^ w 4483974543195470111) s.add(((z ~y) x | z ((x y) | y ~x | ~(y | x))) 577031497978884115) s.add(((z ~x) | (x y) | (z ~y) | (x ~y)) 4483974544037412639)3.3 求解与结果验证执行求解并检查结果if s.check() sat: m s.model() for var in [x, y, z, w]: print(f{var} {hex(m[var].as_long())}) else: print(无法找到满足条件的解)4. 数据处理与Flag重构获得求解结果后还需要进行适当的数据处理才能得到最终flag。4.1 异或解密处理题目通常会对输入数据进行额外处理如异或操作key i_will_check_is_debug_or_noi_wil encrypted [0x3E,0x3A,0x46,0x05,0x33,0x28,0x6F,0x0D,0x8C,0x00, 0x8A,0x09,0x78,0x49,0x2C,0xAC,0x08,0x02,0x07,0x17, 0x15,0x3E,0x30,0x13,0x32,0x31,0x06] flag .join([chr(ord(key[i]) ^ encrypted[i]) for i in range(len(encrypted))]) print(flag)4.2 多解处理技巧有时Z3会给出多个解需要结合题目上下文判断正确解# 已知部分flag格式 partial_flag e!P0or_a if partial_flag in flag: print(找到有效flag片段)5. 高级技巧与优化策略提升Z3求解效率的几个实用技巧5.1 约束简化在添加约束前尽可能简化表达式# 原始约束 expr (z ~x) | (x y) | (z ~y) | (x ~y) # 可简化为 simplified (x y) | (z ~y) | ((x | z) ~(x y))5.2 求解策略调整Z3支持多种求解策略针对不同问题可优化性能tactic Then(simplify, solve-eqs, bit-blast, sat) s tactic.solver()5.3 并行求解对于大型问题可尝试并行求解from multiprocessing import Pool def solve_with_seed(seed): s Solver() s.add(conditions) s.set(random_seed, seed) return s.check() pool Pool(4) results pool.map(solve_with_seed, range(4))6. 实战案例扩展让我们再看一个典型例子展示Z3在逆向中的灵活应用。6.1 复杂校验函数分析假设遇到如下校验逻辑if ((input[0] * input[1] - input[2]) ^ input[3] 0x1234 (input[4] | input[5]) input[6] 0x56 ~input[7] 0xFF input[8]) { // 验证通过 }6.2 对应的Z3模型in_vars [BitVec(fin_{i}, 8) for i in range(9)] s.add((in_vars[0] * in_vars[1] - in_vars[2]) ^ in_vars[3] 0x1234) s.add((in_vars[4] | in_vars[5]) in_vars[6] 0x56) s.add(~in_vars[7] 0xFF in_vars[8])6.3 结果提取技巧处理多字节结果时的实用方法if s.check() sat: m s.model() solution bytes([m[v].as_long() for v in in_vars]) print(fFound solution: {solution.hex()})7. 常见问题与调试技巧在使用Z3求解逆向问题时可能会遇到各种挑战。7.1 求解时间过长尝试简化约束条件添加已知的变量范围限制分段求解先解部分变量再解剩余部分7.2 结果不符合预期检查约束是否正确转换验证位宽是否设置正确如32位vs64位添加中间变量辅助调试7.3 性能优化示例# 优化前 s.add(x y 100) s.add(x - y 20) # 优化后减少变量数量 s.add(x 60) s.add(y 40)8. 工具链整合建议将Z3集成到逆向工作流中的几种方式8.1 IDA Python脚本直接在IDA中运行Z3求解import idaapi from z3 import * def solve_constraints(): # 从IDA获取约束 constraints get_constraints_from_ida() # 建立Z3模型 s Solver() for cond in constraints: s.add(cond) # 求解并返回结果 if s.check() sat: return s.model()8.2 与angr框架结合import angr from z3 import * proj angr.Project(challenge, auto_load_libsFalse) state proj.factory.entry_state() # 使用angr符号执行获取路径约束 simgr proj.factory.simgr(state) simgr.explore(find0x401234) found simgr.found[0] constraints found.solver.constraints # 转换为Z3表达式 z3_constraints [c.to_z3() for c in constraints]8.3 自动化脚本模板一个通用的Z3求解模板from z3 import * def solve_ctf_challenge(): # 1. 定义变量 vars define_variables() # 2. 初始化求解器 s Solver() # 3. 添加约束 add_constraints(s, vars) # 4. 求解并验证 if s.check() sat: model s.model() return extract_solution(model, vars) else: return None def define_variables(): # 根据题目需求定义变量 pass def add_constraints(solver, vars): # 添加具体约束条件 pass def extract_solution(model, vars): # 从模型中提取并格式化结果 pass9. 数学理论基础深化理解Z3背后的理论能帮助我们更好地应用它。9.1 可满足性模理论(SMT)Z3基于SMT它结合了布尔可满足性(SAT)命题逻辑理论求解器处理特定领域理论如算术、位向量9.2 位向量理论CTF逆向常用的是位向量理论特点包括固定位宽的整数表示支持位级操作AND/OR/XOR等算术运算有明确的溢出语义9.3 量词与存在性虽然CTF逆向中较少使用但Z3支持量词x Int(x) y Int(y) # 对于所有x存在y使得x y s.add(ForAll([x], Exists([y], x y)))10. 扩展应用场景Z3不仅适用于CTF逆向还可用于10.1 软件验证验证程序是否满足特定性质def max(a, b): return If(a b, a, b) a, b Ints(a b) s Solver() s.add(max(a, b) a) assert s.check() unsat # 验证max函数定义正确10.2 符号执行辅助增强符号执行的能力import claripy from z3 import * # 将claripy约束转换为Z3 claripy_constraints get_constraints_from_analysis() z3_constraints [translate_to_z3(c) for c in claripy_constraints] s Solver() s.add(z3_constraints)10.3 算法逆向逆向未知算法的输入输出关系# 假设观察到多组输入输出 inputs [...] outputs [...] # 尝试推断算法逻辑 for i, o in zip(inputs, outputs): s.add(unknown_function(inputs[i]) outputs[i])11. 性能对比与基准测试了解不同求解方法的效率差异11.1 Z3 vs 暴力破解对于8字节以下的输入暴力破解可能更快from itertools import product def brute_force(charset, length): for attempt in product(charset, repeatlength): if check(attempt): return attempt return None11.2 Z3配置调优调整Z3参数提升性能s Solver() s.set(timeout, 60000) # 设置超时(毫秒) s.set(random_seed, 42) # 固定随机种子12. 资源与进阶学习要精通Z3在逆向中的应用推荐以下资源官方文档Z3 GitHub Wiki《Programming Z3》官方指南CTF Writeups学习实战案例SMTLIB标准了解底层理论一个实用的学习方法是分析经典CTF题目的Z3解法# 参考其他选手的解题脚本 def learn_from_others(): # 1. 查找类似题目的writeup # 2. 理解他们的建模方法 # 3. 尝试改进或简化 pass13. 实际案例分析让我们详细分析GXYCTF2019题目的完整解法。13.1 完整解题脚本from z3 import * import struct def solve(): x, y, z, w BitVecs(x y z w, 64) s Solver() # 添加所有约束条件 s.add((~x) z 1176889593874) s.add(((z ~x) | (x y) | (z ~y) | (x ~y)) ^ w 4483974543195470111) s.add(((z ~y) x | z ((x y) | y ~x | ~(y | x))) 577031497978884115) s.add(((z ~x) | (x y) | (z ~y) | (x ~y)) 4483974544037412639) if s.check() sat: m s.model() x_val m[x].as_long() y_val m[y].as_long() z_val m[z].as_long() w_val m[w].as_long() # 转换为字节序列 x_bytes struct.pack(Q, x_val) y_bytes struct.pack(Q, y_val) z_bytes struct.pack(Q, z_val) w_bytes struct.pack(Q, w_val) # 异或处理 key bi_will_check_is_debug_or_noi_wil encrypted bytes([ 0x3E,0x3A,0x46,0x05,0x33,0x28,0x6F,0x0D,0x8C,0x00, 0x8A,0x09,0x78,0x49,0x2C,0xAC,0x08,0x02,0x07,0x17, 0x15,0x3E,0x30,0x13,0x32,0x31,0x06 ]) flag bytes([key[i] ^ encrypted[i] for i in range(len(encrypted))]) return flag.decode(latin1) else: return No solution found if __name__ __main__: print(Flag:, solve())13.2 关键步骤解析变量定义使用64位位向量表示程序中的关键变量约束转换将逆向得到的复杂位运算关系准确转换为Z3表达式结果处理将求解得到的数值转换为字节序列解密处理通过异或操作还原原始flag13.3 经验总结约束准确性确保Z3约束完全对应程序逻辑字节序处理注意平台字节序小端/大端编码问题处理非ASCII字符时注意编码转换14. 创新解法探讨除了标准解法外还可以尝试以下创新方法14.1 分段求解策略将大问题分解为小问题逐步求解def staged_solving(): # 第一阶段先解x和z s1 Solver() s1.add((~x) z 1176889593874) # ...其他仅涉及x,z的约束 if s1.check() sat: m1 s1.model() # 固定x,z的值解y,w s2 Solver() s2.add(y m1[y]) # ...添加剩余约束14.2 机器学习辅助使用机器学习预测变量关系from sklearn.ensemble import RandomForestRegressor # 基于已有解训练模型 model RandomForestRegressor() model.fit(features, targets) # 预测可能的变量值作为Z3初始值 initial_guess model.predict(new_features)14.3 并行多解搜索from concurrent.futures import ThreadPoolExecutor def solve_with_assumption(assumption): s Solver() s.add(assumption) # ...添加其他约束 return s.check() with ThreadPoolExecutor() as executor: results list(executor.map(solve_with_assumption, assumptions))15. 安全编程实践在编写Z3解题脚本时也要注意代码安全15.1 输入验证def safe_eval(expr, env): allowed_vars {x, y, z, w} if not set(expr.get_vars()).issubset(allowed_vars): raise ValueError(禁止使用未授权变量) # ...安全评估表达式15.2 资源限制import resource def set_memory_limit(): # 限制内存使用(MB) resource.setrlimit(resource.RLIMIT_AS, (512*1024*1024, 512*1024*1024))15.3 沙箱执行import tempfile import os def run_in_sandbox(): with tempfile.TemporaryDirectory() as tmpdir: os.chdir(tmpdir) # 在沙箱中执行求解 result solve_challenge() return result16. 调试与验证技巧确保Z3模型正确性的方法16.1 单元测试为约束条件编写测试用例def test_constraints(): x, y BitVecs(x y, 32) s Solver() s.add(x y 10, x - y 2) assert s.check() sat assert s.model()[x].as_long() 6 assert s.model()[y].as_long() 416.2 可视化调试绘制约束关系图辅助理解import networkx as nx import matplotlib.pyplot as plt def visualize_constraints(expr): G nx.DiGraph() # 构建表达式树 # ...添加节点和边 nx.draw(G, with_labelsTrue) plt.show()16.3 交叉验证使用不同方法验证结果正确性def cross_validate(): z3_result solve_with_z3() brute_result brute_force_solution() assert z3_result brute_result17. 教育意义与学习路径掌握Z3求解器对逆向工程师的长期价值思维训练培养抽象和建模能力效率提升自动化解决复杂数学问题技术拓展为学习形式化方法打下基础建议的学习路径基础布尔代数、位运算中级SMT理论、Z3 Python API高级符号执行、程序验证18. 社区与资源活跃的Z3和CTF社区Z3 GitHub问题讨论和最新进展CTFtime比赛平台和writeup收集Reddit逆向工程版块经验分享专业博客如符号执行实战系列19. 未来趋势Z3在安全领域的应用前景自动化漏洞发现结合符号执行智能模糊测试指导测试用例生成协议逆向分析网络协议格式反混淆研究对抗代码混淆技术20. 持续实践建议保持技能的几种方式定期参加CTF比赛实战是最好的学习复现经典题目深入理解各种技巧开源项目贡献如Z3或相关工具技术分享写作巩固自身知识在实际使用Z3求解器解决CTF逆向题时我发现最有效的策略是先静态分析理清程序逻辑然后逐步构建约束系统。对于复杂的位运算关系画出真值表往往能帮助理解。当遇到多解情况时结合动态调试或题目给出的部分提示可以有效缩小解空间范围。

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

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

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…