逆向工程实战

逆向工程实战

逆向的本质只有一件事:把编译器做的事逆回去。编译器把人的逻辑变成机器指令,逆向就是从机器指令还原人的逻辑。本文不讲工具操作手册,只讲逆向的思维方法和比赛中的实战套路。


一、逆向的本质

为什么能逆向

源代码 → 编译器 → 机器码

编译是确定性的映射:同一段源码,同一编译器,同一优化级别,产出相同的机器码。
逆向利用的就是这个确定性——机器码中保留了源码的逻辑结构,只是表达形式变了。

逆向做不到完美还原源码(变量名、注释丢失),但能还原程序的行为逻辑——这对CTF足够了。

逆向的核心循环

观察现象 → 定位关键代码 → 理解逻辑 → 构造输入

1. 观察现象:程序做了什么?输入什么?输出什么?
2. 定位关键代码:找到判断flag的逻辑在哪
3. 理解逻辑:这个判断条件是什么?算法是什么?
4. 构造输入:根据逻辑算出正确的输入(flag)

二、前置知识

2.1 汇编——逆向的"英语"

不需要会写汇编,但必须能读。逆向中99%的时间在读汇编,只有1%在写。

x86-64 核心指令(掌握这些就能读大部分代码):

类别 指令 含义
数据移动 mov dst, src dst = src
算术运算 add/sub/imul/idiv 加/减/乘/除
逻辑运算 and/or/xor/not/shl/shr 与/或/异或/非/左移/右移
比较 cmp a, b 计算a-b设置标志位
测试 test a, b 计算a&b设置标志位
跳转 je/jne/jg/jl/jge/jle 等于/不等于/大于/小于/大于等于/小于等于时跳转
函数调用 call/ret 调用函数/返回
栈操作 push/pop 入栈/出栈

关键寄存器:

通用寄存器(x86-64):
  rax — 函数返回值
  rdi, rsi, rdx, rcx, r8, r9 — 函数参数(按顺序)
  rbx, r12-r15 — 被调用者保存(函数内用前必须保存)
  rsp — 栈顶指针
  rbp — 栈底指针(帧指针)

标志寄存器关键位:
  ZF — 零标志(结果为0时置1)
  SF — 符号标志(结果为负时置1)
  CF — 进位标志
  OF — 溢出标志

2.2 调用约定

Linux (System V AMD64 ABI):
  参数传递:rdi → rsi → rdx → rcx → r8 → r9 → 栈
  返回值:rax
  栈对齐:call前RSP必须是16的倍数

Windows (x64):
  参数传递:rcx → rdx → r8 → r9 → 栈
  返回值:rax
  影子空间:调用者预留32字节

识别调用约定的作用:
  看到mov rdi, xxx → call → Linux约定
  看到mov rcx, xxx → call → Windows约定
  由此判断参数个数和类型

2.3 可执行文件格式

ELF (Linux):
  ELF Header → 文件类型、入口点、架构
  Program Headers → 内存段布局(加载器用)
  Section Headers → 代码段(.text)、数据段(.data/.bss)、符号表(.symtab)

PE (Windows):
  DOS Header → PE签名
  Optional Header → 入口点、镜像基址
  Section Table → .text/.data/.rdata/.rsrc

逆向关注点:
  入口点(Entry Point)→ 程序从哪开始执行
  .text段大小 → 代码量,判断是否有壳
  .symtab是否存在 → 有符号表则函数名可读,逆向难度骤降

三、静态分析

3.1 思路

静态分析的核心是不运行程序,通过阅读反编译代码理解逻辑

IDA Pro / Ghidra 工作流:

1. 找入口点 → F5反编译main
2. 识别关键函数 → 看字符串引用(Shift+F12)→ 交叉引用(X键)定位
3. 读伪代码 → 理解算法逻辑
4. 标注 → 重命名变量/函数,加注释,让逻辑越来越清晰

3.2 定位关键代码

最快的方法:字符串引用。

程序总要输出"correct"/"wrong"/"flag{"之类的字符串
  → IDA中 Shift+F12 打开字符串窗口
  → 找到关键字符串
  → 双击 → 交叉引用(X) → 直接跳到判断逻辑

没有明显字符串?
  → 看输入函数:scanf/gets/read/fgets → 交叉引用找调用点
  → 看比较函数:strcmp/memcmp/strncmp → 交叉引用找比较逻辑
  → 看加密函数:AES/DES/RC4/TEA/XTEA 的特征常量

3.3 识别常见算法

加密算法的特征常量——逆向中的"指纹":

算法 特征常量/特征操作
AES S盒 0x63,0x7c,0x77,0x7b...,轮常量 0x01,0x02,0x04...
DES 初始置换表,S盒,P盒
RC4 初始化循环 for(i=0;i<256;i++) S[i]=i,swap操作
TEA/XTEA 魔数 0x9E3779B9(delta),循环32次,+=/^=交替
MD5 初始值 0x67452301,0xEFCDAB89...,64轮循环
SHA1 初始值 0x67452301,0xEFCDAB89,0x98BADCFE...,80轮
SHA256 初始值 0x6a09e667...,64轮,K常量表
Base64 字符表 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/

看到0x9E3779B9就是TEA/XTEA,看到0x67452301就是MD5/SHA——这是逆向的速判技巧。

3.4 读反编译代码的方法

核心原则:不要逐行读,先抓结构再填细节

1. 识别控制流
   if-else → 看cmp/test后的分支
   循环 → 看跳回指令,判断是for/while
   switch → 跳表结构

2. 识别数据流
   输入在哪?→ 追踪输入变量的使用
   比较在哪?→ 找到flag判断点
   中间做了什么?→ 加密/编码/变换

3. 识别函数功能
   看参数和返回值 → 推断函数用途
   看内部操作 → 确认推断
   重命名函数 → 让代码可读

四、动态调试

4.1 什么时候需要动态调试

静态分析够用时不需要动态调试。以下情况必须动态:

1. 反编译代码看不懂 → 运行时观察变量值
2. 有反调试 → 需要绕过
3. 有自解密/加壳 → 需要脱壳后dump
4. 算法复杂 → 需要单步跟踪确认理解
5. 需要修改跳转 → 直接patch掉判断

4.2 GDB(Linux)

# 启动
gdb ./program
gdb -q ./program  # 安静模式

# 断点
b main              # 在main下断
b *0x401234         # 在地址下断
b func_name         # 在函数下断
b file.c:42         # 在源码行下断
delete              # 删所有断点

# 执行
r                   # 运行
r arg1 arg2         # 带参数运行
c                   # 继续执行
si                  # 单步进入(进函数)
ni                  # 单步越过(不进函数)
finish              # 执行到当前函数返回

# 观察
info registers      # 查看所有寄存器
p $rax              # 打印寄存器
p/x $rax            # 十六进制打印
p/s (char*)$rdi    
内容概要:本文围绕可变桨叶四旋翼无人机的规范控制与点对点运动模拟展开,重点研究优化推力分配策略在翻转动作中的应用与性能比较。通过Matlab代码实现,构建了四旋翼动力学模型,并设计了多种控制算法以实现精确的姿态调整与轨迹跟踪。研究对比了不同推力分配方案在执行高机动性翻转动作时的稳定性、能耗效率与响应速度,旨在提升无人机在复杂飞行任务中的动态性能与控制精度。该仿真研究为无人机飞控系统的设计与优化提供了理论依据和技术支持。; 适合人群:具备一定自动控制理论基础和Matlab编程能力,从事无人机控制、飞行器动力学或机器人系统研究的科研人员及研究生。; 使用场景及目标:① 实现四旋翼无人机在三维空间中的精确点对点运动控制;② 对比分析不同推力分配策略在执行翻转等高难度动作时的控制效果与能耗表现,优化飞行性能;③ 为无人机自主飞行、特技飞行及复杂环境下的机动控制提供算法验证平台。; 阅读建议:此资源以Matlab仿真为核心,建议读者结合相关控制理论知识,深入理解代码实现细节,重点关注动力学建模、控制律设计与推力分配模块。在学习过程中,应动手调试参数,复现文中翻转动作的仿真结果,并尝试拓展至其他复杂飞行任务,以加深对无人机控制机理的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿阿三

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值