文章总结: 本文系统总结了程序从源码到运行的全流程,深入解析编译、静态链接、ELF目标文件格式、装载、动态链接及运行库等底层机制。文档详细阐述了符号解析、重定位、虚拟内存管理等关键技术点,并对比了Linux与Windows平台的实现差异,适合程序员深入理解系统原理与二进制安全基础。 综合评分: 85 文章分类: 二进制安全,逆向分析,安全开发
链接、装载与库
原创
guowei guowei
网络安全直通车
2026年3月17日 13:24 北京
程序从源代码到运行的全流程展开,系统讲解编译、静态链接、目标文件 (ELF/PE)、装载、动态链接、运行库与系统调用,以x86/Linux/Windows为平台,用HelloWorld贯穿案例,拆解目标文件分段、符号解析、重定位、虚拟内存、线程安全等底层机制,还给出MiniCRT实现,帮程序员理解程序背后的系统原理。
3. 详细总结
一、全书定位与核心脉络
- 定位:系统底层经典书,聚焦链接、装载、库三大核心
- 平台:32 位 x86、Windows、Linux
- 主线:源代码 → 编译 → 链接 → 装载 → 运行 → 系统调用
二、计算机底层基础
- 硬件核心
- 关键部件:CPU、内存、北桥 (高速)、南桥 (低速)
- 发展:单核→SMP 多核,频率停滞→多核并发
- 操作系统核心
- 任务:资源管理、抽象接口、抢占式多任务
- 内存:虚拟内存 + 分页 (4KB),MMU 完成地址转换
- 隔离:进程独立虚拟空间,防止相互干扰
- 线程基础
- 组成:PC、寄存器、栈,共享进程地址空间
- 状态:运行→就绪→等待
- 安全:原子操作、锁、信号量、读写锁、volatile
- 模型:一对一 / 多对一 / 多对多
三、编译全过程(4 步)
表格
| 步骤 | 工具 | 输入 | 输出 | 核心动作 | | — | — | — | — | — | | 预处理 | cpp | .c | .i | 展开头文件 / 宏 / 删注释 | | 编译 | cc1 | .i | .s | 词法 / 语法 / 语义分析→汇编 | | 汇编 | as | .s | .o | 转机器码,生成目标文件 | | 链接 | ld | .o/.a | 可执行文件 | 重定位、符号解析、合并段 |
- 关键:链接是多模块合并的核心,解决地址引用问题
四、目标文件格式(ELF 重点)
- ELF 文件类型
-
REL 可重定位
:.o 文件,待链接
-
EXEC 可执行
:直接运行
-
DYN 共享库
:.so 文件
- 核心段(Section)
-
.text
:代码段,只读可执行
-
.data
:已初始化全局 / 静态变量
-
.bss
:未初始化变量,不占文件空间
-
.rodata
:只读数据 / 字符串常量
- 关键表
-
文件头
:魔数 0x7F454C46、类型、入口、段表位置
-
段表
:描述所有段的位置 / 大小 / 权限
-
符号表
:函数 / 变量名对应地址
-
重定位表
:标记需要修正的地址引用
五、静态链接核心机制
-
两步链接
-
空间与地址分配:相似段合并,计算虚拟地址
-
符号解析 + 重定位:修正外部符号地址
-
重定位公式
- 绝对寻址:S + A
- 相对寻址:S + A – P
- 符号规则
-
强符号
:函数、已初始化全局变量
-
弱符号
:未初始化全局变量
-
规则:强符号优先,弱符号取最大空间
-
COMMON 块
:未初始化全局变量延迟分配,链接时确定大小
六、可执行文件装载
- 核心:从文件变成进程
- 机制:分页映射到虚拟地址空间,不一次性全载入
- 页错误:缺页时从磁盘加载,提高效率与隔离性
七、动态链接
-
优势
:共享内存、升级不重编译、解决 DLL Hell
-
Linux
:.so 共享库,GOT/PLT 延迟绑定
-
Windows
:DLL,导出表 / 导入表
-
对比静态库
:静态链接打包进程序,动态链接运行时绑定
八、运行库与系统调用
-
运行库
:程序入口初始化、全局构造、标准函数
-
系统调用
:应用→内核的唯一入口
- Linux:0x80 中断
- Windows:0x2E 中断
-
MiniCRT
:极简跨平台 C 运行库实现
九、C++ 特殊机制
-
符号修饰
:解决重载 / 命名空间 / 类成员冲突
-
全局构造析构
:.init/.fini 段在 main 前后执行
-
ABI 问题
:不同编译器二进制不兼容,影响跨模块链接
4. 关键问题与答案
问题 1:目标文件中的 .bss 段为什么不占用磁盘空间?
答案:.bss 段存放未初始化的全局变量和静态变量,这类变量默认值为 0,无需在文件中存储大量 0 数据;链接器只需记录总长度,程序装载时由系统直接分配清零内存,因此不占用文件空间,只占运行时内存。
问题 2:静态链接中 “重定位” 到底做了什么?为什么必须重定位?
答案:重定位是修正代码中外部符号的地址。编译单个目标文件时,编译器不知道函数 / 变量的最终虚拟地址,会先用占位符代替;链接时合并所有模块、确定最终地址后,把占位符替换成真实地址,保证调用与访问正确。
问题 3:强符号与弱符号的链接规则是什么?有什么实际作用?
答案:
- 规则 1:多个强符号同名,直接报重复定义
- 规则 2:强符号 + 弱符号,选用强符号
- 规则 3:全弱符号,选用占用空间最大的
- 作用:支持库函数覆盖、模块扩展,未初始化全局变量按弱符号处理,避免多模块冲突。
请在微信客户端打开
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:网络安全直通车 guowei guowei《链接、装载与库》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论