文章总结: 本文系统介绍CTF逆向分析技术,涵盖汇编跳转指令解析、GDB/x64dbg调试工具实战应用(含断点设置、内存查看、反汇编技巧)、反编译与伪代码重构方法,并提供从工具配置到代码还原的完整操作流程。 综合评分: 85 文章分类: CTF,逆向分析,二进制安全,安全工具,实战经验
CTF之逆向分析——没有源代码一样能干
原创
书中自有代码来 书中自有代码来
书中自有代码来
2026年5月2日 20:44 四川
在小说阅读器读本章
去阅读
一、什么是逆向分析
在常见的系统环境中,开发者或开发组织通常向用户提供的是编译好的程序,而非原始的代码文件,这种形式便于机器执行而并不便于人类阅读,为了分析这些程序的运行逻辑,达到去除恶意代码以及为老旧程序提供支持,部分开发者开始尝试逆向这些文件,以获取厂商所提供的软件的代码逻辑,为自己所用,部分安全厂商也在逆向恶意的木马、病毒等,以协助用户清理病毒的感染痕迹。
二、汇编基础
参考之前的文章,以及下面的内容:汇编指令 · 语雀
在常见的逆向中,跳转指令是程序逻辑的关键所在,汇编中的跳转指令往往对应着C语言中的if判断语句、while循环语句、for循环语句、switch判断语句等,跳转指令通过各种判断来实现高级语言的各种结构,下面是一些汇编的跳转指令:
| 指令 | 描述 | 备注 | | — | — | — | | JMP | 无条件跳转 | – | | JCXZ / JECXZ | CX / ECX 寄存器为 0 则跳转 | 计数器专用 | | JE / JZ | 等于 / 为零则跳转 | 标志位 ZF=1 | | JNE / JNZ | 不等于 / 不为零则跳转 | 标志位 ZF=0 | | JA / JNBE | 无符号大于 / 不小于等于 | Above | | JAE / JNB / JNC | 无符号大于等于 / 不低于 / 无进位 | Above or Equal | | JB / JNAE / JC | 无符号小于 / 不大于等于 / 进位 | Below | | JBE / JNA | 无符号小于等于 / 不大于 | Below or Equal | | JG / JNLE | 有符号大于 / 不小于等于 | Greater | | JGE / JNL | 有符号大于等于 / 不小于 | Greater or Equal | | JL / JNGE | 有符号小于 / 不大于等于 | Less | | JLE / JNG | 有符号小于等于 / 不大于 | Less or Equal | | JS / JNS | 结果为负 / 不为负 | 符号标志 SF | | JO / JNO | 溢出 / 不溢出 | 溢出标志 OF | | JP / JPE | 奇偶位为偶 | 奇偶标志 PF | | JNP / JPO | 奇偶位为奇 | 奇偶标志 PF |
三、调试基础
(一)gdb调试
协助工具安装
- pwndbg
打开Releases · pwndbg/pwndbg · GitHub,选择对应架构的portable版本下载,下载后解压到你想要放置的目录下面,进入解压目录的bin文件夹,右键打开终端,输入下面的命令即可,无需另外安装gdb:
./pwndbg 目标调试文件
- gef
打开 hugsy/gef,使用下面命令克隆到本地:
git clone https://github.com/hugsy/gef.git
然后进入scripts目录,运行gef.sh安装即可,也可以将项目目录下的gef.py拷贝出来,在~/.gdbinit文件中添加下面的一行即可:
source ~/目标路径/gef.py
运行gdb,提示符已经变成gef>,说明安装成功。
调试指令
内存操作
用于查看和修改程序运行时的内存数据。
| 命令格式 | 说明 | 参数详解 | | — | — | — | | x/nfu addr | 查看内存通用命令 | n:个数(如20);f:格式(x/d/u/c/s…);u:单位(b/h/w/g) | | x/s addr | 查看字符串 | 以字符串格式显示内存内容 |
| 显示格式(f) | 含义 | 单位大小(u) | | — | — | — | | x | 十六进制 | b(1字节) | | d | 十进制有符号 | h(2字节) | | u | 十进制无符号 | w(4字节) | | c | 字符 | g(8字节) | | t | 二进制 | – | | s | 字符串 | – |
断点管理
控制程序在特定位置暂停执行。
| 命令 | 说明 | | — | — | | b function / b filename:line | 在函数入口或指定文件行号下断点 | | b *0xaddr | 在内存地址处下断点 | | b func if var>10 | 设置条件断点(满足条件才暂停) | | info b | 查看所有断点信息 | | delete [n] | 删除指定编号断点(不填编号则删除所有) | | disable [n] / enable [n] | 暂停/开启指定断点 | | c / continue | 继续运行,直到下一个断点 |
执行控制
控制程序的运行流程(单步、步入、步过等)。
| 命令 | 说明 | | — | — | | r / run | 开始运行程序 | | s / step | 步入:单步执行,遇到函数会进入函数内部 | | n / next | 步过:单步执行,遇到函数不进入,直接跳过 | | si / ni | 指令级的步入/步过(针对汇编指令) | | finish | 运行至当前函数结束并返回 | | u / until | 运行直到退出循环,或运行至指定行号 | | call func | 调用指定的函数(如call my_func()) | | q / quit | 退出GDB |
变量与表达式
查看和监视变量、表达式的值。
| 命令 | 说明 | | — | — | | p / print expr | 打印表达式的值(如p a, p func(1)) | | display expr | 每次单步调试暂停时自动打印该表达式 | | watch expr | 设置监视点,当表达式值改变时自动暂停程序 | | whatis var | 查询变量或函数的数据类型 | | set args arg1 | 设置程序运行时的命令行参数 | | show args | 显示当前设置的运行参数 |
寄存器与汇编
查看底层状态和汇编代码。
| 命令 | 说明 | | — | — | | info r / info registers | 打印所有寄存器的值 | | i r rax | 打印特定寄存器(如rax)的值 | | p/x $rax | 以十六进制格式打印rax寄存器的值 | | disas func / disas addr | 反汇编指定函数或地址的代码 | | disas /r / disas /sr | 显示汇编代码及对应的机器码(硬编码)/ 显示汇编、机器码及源码(混合模式) | | display /i $pc | 每次单步调试时自动显示当前汇编指令 | | set disassembly-flavor intel / att | 切换汇编显示格式为Intel风格/AT&T风格 |
栈与源码
查看调用堆栈和源代码。
| 命令 | 说明 | | — | — | | bt / where | 查看当前函数调用堆栈(Backtrace) | | up / down | 在堆栈帧之间向上/向下切换 | | l / list | 列出源代码(默认显示当前行附近10行) | | l line / l func | 显示指定行号或函数的源码 | | info locals | 显示当前栈帧内的所有局部变量 | | info program | 查看程序运行状态(是否运行、进程号、暂停原因) |
(二)xdbg调试
x64dbg是一款专为Windows平台设计的开源动态调试器,支持对x86和x64架构的应用程序进行实时调试与分析。它通过直观的图形界面,让使用者能够深入观察程序的执行流程,包括反汇编代码、寄存器状态、内存数据和调用堆栈等关键信息。调试过程中,可以通过设置软件断点、硬件断点或内存断点来精确控制程序在特定位置暂停,从而逐条指令地跟踪程序行为。其内置的汇编器和脚本系统,支持在运行时修改指令或自动化调试任务,极大地提升了逆向分析的效率,是分析程序逻辑、定位漏洞或破解软件保护的常用工具。
四、逆向分析
(一)反汇编
反汇编是将计算机程序的可执行机器码转换回人类可读的汇编语言的过程,它是逆向工程中最基础也是最核心的环节。由于大多数商业软件不提供源代码,安全研究人员和逆向工程师必须依赖反汇编技术来理解程序的底层运作机制。这一过程利用如Zydis等反汇编引擎,将二进制指令流解析为助记符,从而还原出程序的控制流图、函数调用关系以及数据处理逻辑。通过反汇编,分析者可以绕过高级语言的抽象层,直接审视代码如何与操作系统API交互、如何管理内存以及如何处理加密算法,为后续的漏洞挖掘或逻辑还原奠定坚实基础。
(二)反编译
反编译是在反汇编的基础上,进一步尝试将底层的汇编代码或中间代码还原为高级编程语言(如C、C++或伪代码)的技术过程。与反汇编关注指令细节不同,反编译旨在恢复程序的宏观结构和语义,通过复杂的算法识别变量类型、控制结构(如循环、条件判断)以及函数原型。工具如Snowman或IDA Pro的F5插件,能够将晦涩难懂的跳转指令重组为结构清晰的伪代码,极大地降低了理解复杂程序逻辑的认知负担。尽管反编译生成的代码往往缺乏原始变量名和注释,且难以做到与源码完全一致,但它能快速揭示算法的核心逻辑,是进行恶意代码分析和软件功能复现的高效手段。
(三)工具的使用
- 反编译程序,搜索相关字符串,便于进一步分析。
- 将关键变量改名,从一些无语义的变量名改为有语义的变量名,将数据类型进行初步修复,结构体的定义,数组的结构,布尔类型的修改(一般识别为unsigned char),字符指针的修复((long) 即char *)根据函数调用图分析函数关键调用代码 ,对代码预处理。
- 导出关键代码便于后续处理。
- 将数据类型规范化,整理代码,简化过于复杂的逻辑,例如把while改为for语句,编写伪代码。
- 根据伪代码编写破解程序,并编译调试,获取结果。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:书中自有代码来 书中自有代码来 书中自有代码来《CTF之逆向分析——没有源代码一样能干》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。











评论