0210、Windows 逆向入门:条件、分支与循环逆向
返回:Windows 逆向入门篇 · Windows 逆向总目录
这一部分把高级语言里的 if、switch、循环还原成汇编中的比较、测试、条件跳转和无条件跳转。控制流能看懂,逆向时就能画出程序逻辑图。
1、内容范围
小节
内容
复盘点
11.2 - 11.9
基础指令补充
ADD/SUB/MUL/DIV/AND/OR/NOT/XOR/CMP
12.0
TEST
位测试和空值判断
12.1
JCC
条件跳转和标志位
12.2 - 12.6
IF/三目/多条件
条件分支结构
12.7 - 13.1
SWITCH
跳转表、中转索引和折半查找
13.2 - 13.3
LOOP/REP
循环计数和重复前缀
13.4 - 13.8
FOR/WHILE/DOWHILE
循环结构、continue/break
13.9
缓冲区溢出案例
只做原理和边界复盘
2、CMP 与 TESTcmp a, b 本质是计算 a - b 并设置标志位,不保存结果。test a, b 本质是按位与并设置标志位,也不保存结果。
指令
常见用途
cmp e ...
0124、安全开发篇(四):类模板与 string
返回:C++ 泛型编程目录 · 安全开发总目录
这一章从类模板进入 STL 和 string。模板解决“同一套类逻辑适配多种类型”,string 则是 C++ 中最常用的字符串工具。安全复盘时,重点看模板实例化、分文件编写、字符串边界、输入读取和编码问题。
2.0 类模板成员函数定义类模板的成员函数通常也要写在头文件里,因为编译器需要看到完整模板定义才能实例化。
123456789template <typename T>class Box {public: explicit Box(T value) : value(value) {} T get() const { return value; }private: T value;};
2.1 类模板继承中的规则类模板可以继承普通类,也可以被普通类或模板类继承。关键是派生类必须知道基类模板参数。
123456789template <typename T>class Base {public: T value; ...
0127、安全开发篇(四):异常处理
返回:C++ 泛型编程目录 · 安全开发总目录
这一章整理异常处理。C 语言通常靠返回值、错误码和宏定位问题;C++ 增加了异常机制,可以把错误沿调用链向上传播。安全开发里异常不是“偷懒不判断错误”,而是要让错误路径可控、资源能释放、日志能复盘。
6.1 C 预定义宏C/C++ 提供一些预定义宏,适合写日志和调试信息。
宏
含义
__FILE__
当前文件名
__LINE__
当前行号
__DATE__
编译日期
__TIME__
编译时间
__FUNCTION__
当前函数名,常见编译器支持
1234#include <iostream>#define LOG(msg) \ std::cout << __FILE__ << ":" << __LINE__ << " " << msg << std::endl
6.3 C 错误规避C 风格错误处理常用返回值。
123456int read_config(const c ...
0125、安全开发篇(四):vector、deque 与 list
返回:C++ 泛型编程目录 · 安全开发总目录
这一章整理三类顺序容器:vector、deque、list。它们接口看起来相似,但内存布局完全不同。安全复盘重点是容量、迭代器失效、边界访问和插入删除成本。
3.4 vector 特性解析vector 是连续动态数组,支持随机访问,尾部追加效率高。
特性
说明
连续内存
适合和 C API、二进制缓冲区交互
动态扩容
容量不够时重新分配
随机访问
v[i] 快
中间插入删除
需要移动元素
3.5 vector 对象初始化123std::vector<int> a;std::vector<int> b(5, 1);std::vector<int> c = {1, 2, 3};
3.6 vector 内存布局vector 通常维护三个关键信息:起始位置、当前结束位置、容量结束位置。扩容后旧指针和迭代器可能全部失效。
3.7 vector 大小函数
函数
作用
size()
当前元素个数
capacity()
当前已分配容量
em ...
0126、安全开发篇(四):set、pair 与 map
返回:C++ 泛型编程目录 · 安全开发总目录
这一章整理关联容器:set、pair、map。它们的核心是“按键组织数据”,适合做去重、索引、配置表、统计表和对象映射。
5.3 set 存储规则set 保存唯一元素,并按比较规则排序。
1std::set<int> ids = {3, 1, 2, 2};
最终只有 1,2,3。
5.4 set 大小替换set 不能像数组一样通过下标修改元素,因为修改可能破坏排序规则。通常要先删除再插入。
12ids.erase(2);ids.insert(20);
5.5 set 重复元素set 会自动去重;如果需要允许重复,用 multiset。
容器
是否允许重复
set
不允许
multiset
允许
5.6 set 查找计数12345if (ids.find(3) != ids.end()) { std::cout << "exists\n";}std::cout << ids.count(3) << ...
0117、安全开发篇(三):引用与内存管理
返回:C++ 面向对象基础目录 · 安全开发总目录
这一章从 C 的指针过渡到 C++ 的引用和资源管理。引用让参数传递更自然,new/delete 让对象生命周期更灵活,智能指针则是后面写安全 C++ 代码时应该优先考虑的工具。
2.0 指针与引用引用可以理解成对象的别名。它不像指针那样保存一个可以随时改的地址,而是初始化后绑定到某个对象。
对比
指针
引用
是否可为空
可以为空
正常引用不应为空
是否可改指向
可以
初始化后不能改绑
使用语法
*p / p->
像普通变量一样
适合场景
可选对象、动态对象、数组遍历
参数传递、别名、返回对象
2.1 引用基本特性引用必须初始化,之后它就是原对象的另一个名字。
12345678910#include <iostream>int main() { int value = 10; int &ref = value; ref = 20; std::cout << value << std::endl; return ...
0121、安全开发篇(三):项目:数据信息管理系统
返回:C++ 面向对象基础目录 · 安全开发总目录
这一部分是 C++ 面向对象基础的项目实践:做一个控制台数据信息管理系统。它的重点不是界面多复杂,而是把类、对象、容器、菜单、输入校验、数据存储和功能分支组织成一个能维护的小项目。
09.6 项目:数据信息管理系统项目可以按三层理解:
层次
内容
数据层
学生、用户、记录等实体对象
管理层
添加、删除、查询、分类、保存
交互层
菜单、输入、提示、错误处理
09.7 - 09.8 菜单设计菜单要清楚、稳定、可重复执行。每个选项对应一个功能,不要把所有逻辑塞进 main。
123456enum class MenuAction { Add = 1, Remove = 2, List = 3, Exit = 0};
复盘重点:输入不是永远合法,菜单必须处理非法选项。
09.9 功能分支流程处理功能分支可以用 switch,也可以用函数表或命令对象。入门阶段先把每个功能拆成函数。
1234void show_menu();void add_record();void ...
0119、安全开发篇(三):构造析构与对象特性
返回:C++ 面向对象基础目录 · 安全开发总目录
构造析构是 C++ 对象生命周期的核心。对象什么时候出生、资源什么时候拿到、什么时候释放、复制时是深拷贝还是浅拷贝,这些都直接影响稳定性和安全性。
4.4 默认构造函数默认构造函数用于创建对象时不传参数。
1234567class Buffer {public: Buffer() : size(0) {}private: int size;};
4.5 带参构造函数带参构造可以在对象创建时建立有效状态。
1234567class User {public: explicit User(int id) : id(id) {}private: int id;};
explicit 可以避免一些隐式转换带来的误用。
4.6 拷贝构造函数拷贝构造在用一个对象初始化另一个对象时触发。如果类里有堆资源,默认浅拷贝可能出问题。
123456789class Person {public: Person(const Person ...
0120、安全开发篇(三):运算符重载、继承与多态
返回:C++ 面向对象基础目录 · 安全开发总目录
这一章是 C++ 面向对象最接近逆向分析的一部分:对象布局、继承层次、虚函数表和动态绑定都会在二进制里留下痕迹。学习时既要能写语法,也要能想象对象在内存中的样子。
6.6 - 7.6 运算符重载运算符重载让自定义类型也能使用 +、==、[]、<< 等语法。它应该让代码更自然,而不是制造难懂的副作用。
1234567891011121314151617181920212223#include <iostream>class Point {public: Point(int x, int y) : x(x), y(y) {} Point operator+(const Point &other) const { return Point(x + other.x, y + other.y); } bool operator==(const Point &other) const { ret ...
0118、安全开发篇(三):函数增强与封装入门
返回:C++ 面向对象基础目录 · 安全开发总目录
这一章一半是函数增强,一半是封装入门。函数增强让 C++ 接口更灵活;封装则把数据和行为放到一起,为后面的对象模型、构造析构和多态打基础。
3.2 默认参数默认参数让调用者可以省略常用值。
12345#include <iostream>void connect(const std::string &host, int port = 80) { std::cout << host << ":" << port << std::endl;}
复盘重点:默认参数通常写在声明处,不要在声明和定义里重复写不同默认值。
3.3 函数重载函数重载允许同名函数根据参数列表区分。
12int add(int a, int b) { return a + b; }double add(double a, double b) { return a + b; }
能否重载
原因
参数个数 ...
