软件逆向工程重点知识总结
概述
逆向工程的概念和基本方法
什么是逆向工程?
- 定义1:the progress of understanding a system
- 定义2:从对象中提取知识或设计信息,并重建对象或基于对象信息的任意事务的过程。
什么是软件逆向工程
定义:一种分析目标系统的过程, 其目的是识别出系统的各个组件以及它们之间的关系, 并在较高的抽象层次上以另一形式创建对系统的表示,从而理解目标系统的结构和行为
两阶段过程:- 收集信息: parsers, debuggers, profilers, event recorders
- 抽象信息: 构造可理解的高层次模型(静态或动态)

软件逆向工程的基本方法论
逆向工程的主要活动: 反汇编 + 分析 + 可能的修改(破解)
静态方法 vs.动态方法
- 静态方法
- 分析但不运行代码
- 较动态方法更为安全
- 反汇编器,如IDA Pro,objdump等
- 动态方法
- 检查进程执行过程中寄存器、内存值的实时变化
- 允许操作进程,通常应在虚拟机中运行
- 调试器,如Windows下的WinDBG, Immunity, OllyDBG等,及Linux下的GDB
- 静态方法
逆向工程的应用与合法性(大题)
软件逆向工程的典型应用场景
- 恶意代码分析
- 动态分析:沙箱中执行恶意程序,记录并报告恶意行为
- 静态分析:通过程序代码理解程序行为(Program understanding/comprehension), 自动/人工
- 闭源软件漏洞分析
- 发现和分析漏洞:fuzzing或静态分析,静态分析以反汇编为基础
- 开发破解程序(exploit):结合使用反汇编器和调试器
- 闭源软件互操作性分析
- 只能获得二进制程序而想开发与其互操作的软件
- 依据已有程序,开发适用于其他硬件平台的程序(SW migration),特别适用于支持新硬件的软件驱动程序
- 验证编译器的性能和准确性;调试器中生成汇编代码清单…
- 恶意代码分析
源码级分析 vs 二进制级分析
汇编代码层面的逆向工程结果通常可用于二进制级分析,二进制级分析与源代码级分析的特点不同
典型程序分析通常在源码级(包括各种与源码近似的中间语言代码).
优势:- 源码是结构化的
- 源码有更丰富的信息(如类型等)用于帮助分析
- 在源码级的分析结果对于程序员而言可理解
分析二进制的动机: - 一些情况下, 源码不可用
- 第三方代码/库
- 源码遗失的遗产系统
- 分析二进制意味着不需要信任编译器
- 编译器bug并非不常见
- 即便源代码安全, 编译出的二进制仍可能不安全
- 编译器可能不理解安全需求

- 以上例子在密码不再被需要时, 从内存中擦除密码,其目的是规避某些攻击
- 编译器可能将语句“memset(password, 0, length)”视作“死代码”, 通过死代码消除机制将其删除, 原因是变量password在process()调用以后没有再被使用, 早期微软VC++.NET编译器就是这么做的
二进制级分析的更大挑战
- 二进制代码无结构(大量使用“goto”)
- 二进制代码可能不包含元信息
- 可能没有符号、类型信息等
- 程序分析需要使用一些算法来恢复(部分)元信息
- 在二进制代码上的分析结果不容易被理解
- 二进制代码是体系结构相关的: 同样的源代码可以被编译为x86,ARM, SPARC, MIPS等不同体系结构下的二进制, 二进制之间差异大
- 指令集的复杂度
- 二进制代码存在混淆、加密、压缩和打包, 恶意软件通过混淆、加密等机制隐藏自己
- Self-modifying code: 代码可以在运行时生成、在运行后销毁
软件逆向工程的合法性
通常允许:- 以互操作为目的的逆向工程
- 当软件版权所有者无法进行软件错误修正时,通过逆向工程对软件错误进行修正和破解
- 在不违反专利权或商业秘密保护的前提下,通过逆向工程确定软件中不受版权保护的部分(如一些算法)
针对软件逆向工程的法规通常声明如下合法性限制: - 逆向工程人员为合法用户
- 需获取的“必要信息”不能从其他途径取得
- 逆向工程以互操作为目的,仅对实现互操作程序所必要的那部分程序进行逆向工程, 通过逆向工程获得的信息不能用于实现互操作程序以外的目的
- 通过逆向工程获得的信息不能扩散给不必要的第三人
- 不能用于开发形式类似或有其他著作权侵权因素的程序
- 不得不合理地损害权利人的正当利益或妨碍计算机程序的正常使用
X86与x64体系结构(选择题)
x86与x64的基本概念
基本概念
- x86: 基于Intel 8086/8088处理器的一系列向后兼容的指令集体 系结构(ISA)的总称
- IA-32: 32位版本的x86指令集体系结构
- 具有三种主要操作模式
- 实模式(Real Mode): 只支持16位指令集和寄存器,MS-DOS 的运行环境
- 保护模式(Protected Mode): 支持虚拟内存、分页等 (Windows,Linux, …)
- 系统管理模式(System Management Mode): 用于执行嵌入 在固件中的特殊代码
- 是一种CISC(Complex Instruction Set Computer)体系结构
- x64: 又称x86-64, 是x86体系结构的扩展, 是与x86(IA-32)兼容 的64位CPU体系结构
- x86: 基于Intel 8086/8088处理器的一系列向后兼容的指令集体 系结构(ISA)的总称
字节序
字节序:多字节数据在内存中存储或在网络上传输时各字节的存储/传输顺序- 小端序(little endian):低位字节存储在内存中低位地址,效率较高(Intel CPU使用)
- 大端序(big endian):低位字节存储在内存中高位地址,符合思维逻辑。RISC架构处理器(如MIPS, PowerPC)采用
IA-32内存模型与内存管理
IA-32内存模型
- 平面内存模型
代码、数据和栈在线性地址空间中,线性地址$0 ∼ 2^{31} − 1$连续 - 分段内存模型
- 程序内存由一系列独立的地址空间(称为“段”)组成。代码、数据和栈在不同的段中
- 逻辑地址=段选择器+偏移量
- 平面内存模型
不同操作模式下的内存管理
对于分段内存模型, 不同操作模式(实模式/保护模式)下, 内存管理
方式和寻址模式存在差异- 实模式下的内存管理
- Intel 8086 CPU使用,是特殊的分段内存模型
- 线性地址空间由一系列64KB大的段组成
- 线性地址范围$0 ∼ 2^{20} − 1$
- 保护模式下的内存管理
- 分段(必须)+ 分页(可选)
- 物理地址是CPU访问的实际内存位置
- CPU的内存管理单元(MMU)透明地将虚拟地址(线性地址)转换为物理地址
- 实模式下的内存管理
IA-32寄存器
寄存器分类
- 通用寄存器
- 程序状态与控制寄存器
- 指令指针寄存器
- 段寄存器
- 控制寄存器(CR0-CR4)
- 调试寄存器(DR0-DR7)
- 系统表指针寄存器(GDTR, LDTR, IDTR, task register)
- MMX(MM0-MM7, XMM0-XMM7)
- FPU(ST0-ST7, …)
通用寄存器(GPR)
8个32位通用寄存器: EAX, EBX, ECX, EDX, EDI, ESI, EBP, ESP
其中一些GPR可进一步切分为16位或8位寄存器GPR的具体功能
正常编译器的编译结果中- EAX:(操作数和结果数据的)累加器
- EBX:(在DS段中数据的指针)基址寄存器
- ECX:(字符串和循环操作的)计数器
- EDX:(I/O指针)数据寄存器
- EDI: 变址寄存器, 字符串/内存操作的目的地址
- ESI: 变址寄存器, 字符串/内存操作的源地址
- EBP:(SS段中的)栈内数据指针, 栈帧的基地址,用于为函数调用创建栈帧
- ESP:(SS段中的)栈指针, 栈区域的栈顶地址
程序状态与控制寄存器(EFLAGS)
- 32位,存储算数操作符状态或其他执行状态
- 含一组状态标识(S)、一个控制标识(C)、一组系统标识(X)
- EFLAGS中的标识主要用于实现条件分支, 程序调试与控制

- 关键标识位
- ZF: 零标识(S):: 若运算结果为0, 则ZF值为1, 否则ZF值为0
- OF: 溢出标识(S): 有符号整数溢出时, OF置为1;最高有效位(MSB)改变时, OF置为1
- CF: 进位标识(S): 无符号整数溢出时, CF置为1
- SF: 符号标识(S):: 等于运算结果的最高位(即有符号整数的符号位);0表示正数, 1表示负数
- DF: 方向标识(C):控制串处理指令处理信息的方向
- 当DF=1时, 每次串操作后, 变址寄存器ESI和EDI减小(即串处理沿“高地址→低地址”处理)
- 当DF=0时, 处理方向相反
- 由STD指令置位, 由CLD指令清除
- TF: 陷阱标识(X): 若置1, 则CPU执行每条指令后产生单步中断,该特性用于调试器单步执行程序; 还可用于检测调试器是否运行
- IF: 中断允许标识(X): 若置1, 则CPU在收到中断请求后,应该对中断请求进行响应处理
指令指针寄存器(EIP)
- 32位, 存放指令指针, 即当前代码段中将被执行的下一条指令的线性地址偏移
- 程序运行时, CPU根据CS段寄存器和EIP寄存器中的地址偏移读取下一条指令, 将指令传送到指令缓冲区, 并将EIP寄存器值自增, 增大的大小即被读取指令的字节数
- 不能直接修改EIP, 修改途径:
- 指令JMP, Jcc, CALL, RET
- 中断或异常
段寄存器
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 just.ok的个人博客!






