008、安全开发篇(一):函数调用过程
返回:安全开发篇(一)目录 · 上一篇:007、程序入口点 · 下一篇:009、控制台指令
对应视频:1.7 基础-函数调用过程.mp4
1、学习目标
这一节理解函数是如何被调用的。后续学习函数栈、调用约定、返回地址、栈溢出和逆向分析时,函数调用过程是绕不开的基础。
需要掌握:
- 函数声明;
- 函数定义;
- 函数调用;
- 参数和返回值;
- 调用完成后回到原位置继续执行。
2、函数基本写法
1 |
|
3、调用流程
上面的程序可以按这个顺序理解:
| 步骤 | 说明 |
|---|---|
| 1 | 程序从 main 开始 |
| 2 | 执行到 print_banner();,跳到 print_banner 函数 |
| 3 | print_banner 执行完,返回 main |
| 4 | 执行到 add(3, 5),把参数传给 add |
| 5 | add 返回计算结果 |
| 6 | main 输出结果并结束 |
函数调用的关键直觉是:执行流会临时跳到另一个函数,执行完后再回到调用位置。
4、声明、定义和调用
1 |
|
| 概念 | 含义 |
|---|---|
| 声明 | 告诉编译器有这个函数,参数和返回值长什么样 |
| 定义 | 函数真正的实现代码 |
| 调用 | 在某个位置使用这个函数 |
5、参数和返回值
参数是调用者传给函数的数据,返回值是函数处理后交回调用者的数据。
1 | int max_value(int left, int right) |
调用:
1 | int result = max_value(10, 20); |
函数设计时要先说清楚:
- 需要哪些输入;
- 返回什么结果;
- 出错时怎么表示;
- 参数是否允许为空;
- 缓冲区长度是否需要一起传入。
6、安全开发观察
函数调用和安全的关系很深:
| 函数概念 | 安全连接 |
|---|---|
| 参数传递 | 输入是否可信、长度是否检查 |
| 返回值 | 是否判断错误状态 |
| 局部变量 | 栈空间、生命周期和越界风险 |
| 调用栈 | 逆向追踪和崩溃定位 |
| 返回地址 | 栈溢出分析基础 |
后续看到漏洞时,要经常问:
- 外部输入从哪个函数进入?
- 传参时有没有长度?
- 返回值有没有检查?
- 函数内部有没有数组或指针操作?
- 出错后执行流会不会继续往下走?
7、代码实验
1 |
|
这段代码提前引入一个安全习惯:函数通过返回值表示成功失败,指针参数使用前先判断是否为空。
8、复盘题
8.1 函数声明和函数定义有什么区别?
声明只告诉编译器函数的名字、参数和返回值;定义包含函数真正执行的代码。
8.2 函数调用结束后会发生什么?
函数执行完成后,程序会回到调用它的位置继续执行。如果函数有返回值,返回值会交给调用者使用。
8.3 为什么安全开发里要检查函数返回值?
因为很多函数会通过返回值表示成功或失败。如果不检查错误状态,程序可能在失败条件下继续执行,导致越界、空指针、权限绕过或数据错误。
这一节的核心:函数不是孤立代码块,而是执行流、参数、返回值和调用栈共同构成的行为单元。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Ruiqy~!


