0111、安全开发篇(二):入口函数与参数传递
返回:安全开发篇(二)汇总 · Ferry 学院安全开发总目录 · 网络安全学习主页
这一部分从入口函数和函数参数开始。
第一篇已经会写 main、普通函数和指针了;第二篇要往下追一层:程序真正从哪里进来,main 的参数是谁传的,函数调用时栈里发生了什么,为什么在 IDA 和调试器里能回溯到入口和调用链。
1.0 汇编眼中的入口函数参数平时写 C 程序,常把 main 当成程序入口。
1234int main(void){ return 0;}
但从操作系统和运行库角度看,程序并不是一上来就直接执行这几行源码。通常会先经过运行库启动代码,完成一些初始化,然后再调用用户写的 main。
入口层次
层次
说明
系统入口
操作系统加载程序后进入的启动位置
运行库入口
完成 C/C++ 运行环境初始化
用户入口
调用用户写的 main 或 WinMain
函数返回
main 返回值最终会被传给运行库和系统
从汇编角度看,函数参数不是凭空出现的,它们会按照调用约定,通过寄存器或栈传给被调用函数。
现在先建立直觉:源码里的 main( ...
0110、安全开发篇(二):C/C++ 进阶提升
返回:Ferry 学院安全开发总目录 · 网络安全学习主页
这一篇开始进入 C/C++ 进阶提升。相比第一篇的语法入门,这一篇更靠近安全开发真正需要反复复盘的部分:入口函数、调用堆栈、调用约定、指针高级用法、堆内存、文件读写和项目组织。
1、学习定位第一篇解决的是“能写出 C 语言基础代码”,第二篇要解决的是“能理解程序怎么运行”。
这里的重点不是把语法再背一遍,而是把源码、汇编、栈、堆、指针、文件和项目流程串起来。后面做逆向、调试、内存分析和安全工具开发时,这一篇会经常回看。
2、章节目录
编号
章节
主要内容
笔记
0111
01 入口函数与参数传递
main 参数、调用堆栈、IDA/DBG 回溯、函数声明、分文件、值传递、地址传递、寄存器与线程栈
0111
0112
02 调用栈与函数高级
汇编指令、函数调用堆栈、调用约定、堆栈平衡、宏函数、数组/结构体参数、可变参数、printf 原理、变量内存布局
0112
0113
03 内存管理与指针限定
内存属性探测、void 指针、堆区管理、内存回收、设置内存、const 指针组合、数组寻址、指针运算、多级指针 ...
0122、安全开发篇(四):C++ 泛型编程详解
返回:Ferry 学院安全开发总目录 · 网络安全学习主页
这一篇进入 C++ 泛型编程和 STL。
前面的面向对象解决“如何把数据和行为组织成对象”,泛型编程则解决“如何把一套逻辑适配多种类型”。模板、容器、迭代器和异常处理在 C++ 项目里非常常见;对安全开发来说,重点不是只会调用接口,而是理解模板展开、容器内存布局、迭代器失效、边界检查和异常传播。
1、学习定位泛型编程复盘时要同时看三层:
层次
重点
语法层
函数模板、类模板、模板特化、默认模板参数、STL 容器接口
编译层
模板实例化、类型推导、重载匹配、分文件编写问题
内存层
string/vector/deque/list/set/map 的存储方式、迭代器和对象生命周期
后面看 C++ 程序、逆向 STL 容器、定位越界或迭代器失效问题时,这一篇会很值得回看。
2、章节目录
编号
章节
主要内容
笔记
0123
01 模板基础
泛型编程概念、函数模板、模板底层原理、函数模板特化、默认模板参数、多个模板参数、模板调用规则、类模板定义与实例化
0123
0124
02 类模 ...
0115、安全开发篇(三):C++ 面向对象基础
返回:Ferry 学院安全开发总目录 · 网络安全学习主页
这一篇进入 C++ 面向对象基础。和前两篇相比,这里不只是“语法更多”,而是开始接触 C++ 程序真正容易在逆向里出现的东西:对象布局、构造析构、访问权限、重载、继承、多态、虚表和项目中的对象关系。
1、学习定位C++ 面向对象这部分,复盘时要同时看三层:
层次
重点
语法层
namespace、引用、类、对象、构造析构、重载、继承、多态
内存层
对象占用空间、成员偏移、静态成员、虚函数表、构造析构顺序
工程层
如何用类组织项目,如何拆分对象关系、数据存储和菜单流程
后续分析 C++ 程序时,很多“看起来像语法”的东西都会变成内存和调用关系问题。
2、章节目录
编号
章节
主要内容
笔记
0116
01 C++ 入门与命名空间
C++ 特性、控制台框架、iostream、namespace、using、嵌套/匿名/别名/合并命名空间、auto 类型推断
0116
0117
02 引用与内存管理
指针与引用、引用参数/返回值、常量引用、数组引用、内存分区、new/delete、 ...
0109、安全开发篇(一):指针与函数入门
返回:安全开发篇(一)汇总 · 上一节:数组、字符串与结构体 · 安全开发总目录
这一篇开始进入 C 语言里最容易卡住、但也最值得啃下来的部分:指针。
指针不是一个单独的语法点,它连接了变量、地址、数组、字符串、函数调用和内存布局。后面做安全开发、逆向调试、漏洞分析时,很多问题最终都会落到一句话上:这块内存在哪里,指针指向哪里,按什么类型解释,能不能读写。
8.0 内存存储单元程序运行时,变量会被放进内存。内存可以先粗略理解成一排连续编号的存储单元,每个单元都有自己的地址。
1234567891011121314#include <stdio.h>int main(void){ int age = 20; double score = 95.5; char level = 'A'; printf("age = %d, address = %p\n", age, (void *)&age); printf("score = %.1f, address = %p\n" ...
0108、安全开发篇(一):数组、字符串与结构体
返回:安全开发篇(一)汇总 · 上一节:循环跳转与数组基础 · 安全开发总目录
这一篇是安全开发篇(一)的收尾:数组继续往多维展开,字符串开始接入输入输出和缓冲区边界,结构体则用于组织更复杂的数据。
对 C 语言来说,这几块内容非常重要。数组和字符串贴着内存走,结构体决定数据如何排列。后面学指针、文件格式、网络协议、PE 结构、逆向和漏洞分析时,都会反复回到这些基础问题:地址怎么算,长度是多少,是否越界,结构体成员在内存里怎么排。
7.0 多维数组特性解析二维数组已经可以看成“行和列”,多维数组则是在这个基础上继续增加维度。
1234567891011121314#include <stdio.h>int main(void){ int cube[2][3][4] = {0}; cube[0][0][0] = 10; cube[1][2][3] = 99; printf("cube[0][0][0] = %d\n", cube[0][0][0]); printf("cube[1][2 ...
0107、安全开发篇(一):循环跳转与数组基础
返回:安全开发篇(一)汇总 · 上一节:选择与循环 · 安全开发总目录
这一篇从循环控制过渡到数组。
循环解决“重复做一件事”,数组解决“批量组织一组同类型数据”。两者放在一起看很自然:大多数数组操作都离不开循环,很多越界、死循环、下标错误和内存覆盖问题,也正是从这里开始出现的。
6.0 嵌套循环嵌套循环就是循环里面再写循环。最常见的场景是处理二维数据,比如表格、矩阵、地图、棋盘、二维数组。
12345678910111213141516#include <stdio.h>int main(void){ for (int row = 0; row < 3; row++) { for (int col = 0; col < 4; col++) { printf("(%d,%d) ", row, col); } printf("\n"); } return 0;}
...
0106、安全开发篇(一):选择与循环
返回:安全开发篇(一)汇总 · 上一节:类型转换与运算符 · 安全开发总目录
这一篇开始整理程序的执行路径。
前面几章更多是在学习“数据怎么表示、表达式怎么算”,这一章要解决的是“程序应该走哪条路、什么时候重复执行、什么时候退出”。后面做输入校验、菜单程序、文件解析、网络数据处理和安全实验时,条件判断和循环边界会反复出现。
5.0 多行 IF 语句多行 if 用来表达“满足条件时执行一段代码”。
1234567891011121314#include <stdio.h>int main(void){ int score = 75; if (score >= 60) { printf("pass\n"); printf("score = %d\n", score); } return 0;}
推荐始终写花括号即使 if 里只有一行,也建议保留 {}。
1234if (score >= 60){ ...
0105、安全开发篇(一):类型转换与运算符
返回:安全开发篇(一)汇总 · 上一节:数据与运算 · 安全开发总目录
这一篇接着数据类型往下走,重点是“数据如何参与表达式计算”。
C 语言里的运算符看起来简单,但很多安全问题都藏在这些小地方:类型被自动转换、整数被截断、条件判断写错、&& 和 || 的短路顺序被误用、= 和 == 混淆、优先级靠猜。复盘这一章时,不需要追求花哨写法,先把表达式写清楚、算明白、调试看得到。
4.0 数据类型转换类型转换可以分成两类:隐式转换和显式转换。
类型
示例
说明
隐式转换
double x = 10;
编译器自动把 int 转成 double
显式转换
(double)a / b
程序员明确要求转换
赋值转换
char c = 300;
赋值时目标类型可能装不下
表达式转换
1 + 2.5
运算前操作数会被转换到合适类型
整数和浮点数转换123456789101112#include <stdio.h>int main(void){ int a = 5; int b = 2; printf(" ...
0203、Windows 零基础逆向教程(三):攻防篇
返回:Windows 逆向总目录 · 网络安全学习主页
攻防篇是 Windows 逆向里最容易“看起来很酷、实际很危险”的一部分。这里的整理原则很明确:只做合法授权环境下的原理学习、行为识别、调试复盘和防护理解,不把笔记写成未授权利用流程。
这部分内容可以当成“理解攻击技术如何留下痕迹”的路线。知道它们大致怎么发生,才能知道日志、内存、模块、线程、句柄、异常、Hook 和反调试检测应该看哪里。
1、学习定位
线索
目标
注入与加载
理解跨进程代码执行、模块加载和 PE 修复相关概念
ShellCode
理解位置无关代码、API 解析、字符串处理和二进制提取的风险点
进程伪装
理解进程映像、节对象、PEB、文件对象和检测视角
Hook
理解 IAT、Inline、VTable、VEH、硬件断点等 Hook 的原理和检测点
监控与检测
通过 ETW、WMI、调试事件和进程/线程信息观察行为
反调试
理解调试标志、断点、异常、对象查询等检测方向
本篇不记录可直接用于未授权入侵、持久化、绕过检测或隐蔽执行的操作步骤。后续所有小结都以授权实验、检测分析 ...
