程序员的自我修养


=Start=

缘由:

今天刚好看到了一下LD_PRELOAD变量,想起了之前的一个事故,觉得有必要好好补一补系统底层的知识,做演员会有《演员的自我修养》进行指导,做程序员当然也少不了《程序员的自我修养——链接、装载与库》的学习。

正文:

参考解答:

《程序员的自我修养:链接、装载与库》主要介绍系统软件的运行机制和原理,涉及在Windows和Linux两个系统平台上,一个应用程序在编译、链接和运行时刻所发生的各种事项,包括:代码指令是如何保存的,库文件如何与应用程序代码静态链接,应用程序如何被装载到内存中并开始运行,动态链接如何实现,C/C++运行库的工作原理,以及操作系统提供的系统服务是如何被调用的。每个技术专题都配备了大量图、表和代码实例,力求将复杂的机制以简洁的形式表达出来。本书最后还提供了一个小巧且跨平台的C/C++运行库MiniCRT,综合展示了与运行库相关的各种技术。

《程序员的自我修养:链接、装载与库》对装载、链接和库进行了深入浅出的剖析,并且辅以大量的例子和图表,可以作为计算机软件专业和其他相关专业大学本科高年级学生深入学习系统软件的参考书。同时,还可作为各行业从事软件开发的工程师、研究人员以及其他对系统软件实现机制和技术感兴趣者的自学教材。

==

第1部分 简介
第1章 温故而知新
1.1 从 hello world 说起
1.2 万变不离其宗
1.3 站得高,望得远
1.4 操作系统做什么
1.5 内存不够怎么办
1.6 众人拾柴火焰高
1.7 本章小结
第2部分 静态链接
第2章 编译和链接
2.1 被隐藏了的过程
2.2 编译器做了什么
2.3 链接器年龄比编译器长
2.4 模块拼装——静态链接
2.5 本章小结
第3章 目标文件里有什么
3.1 目标文件的格式
3.2 目标文件是什么样的
3.3 挖掘SIMPLESECTION.O
3.4 ELF 文件结构描述
3.5 链接的接口——符号
3.6 调试信息
3.7 本章小结
第4章 静态链接
4.1 空间与地址分配
4.2 符号解析与重定位
4.3 COMMON 块
4.4 C++相关问题
4.5 静态库链接
4.6 链接过程控制
4.7 BFD 库
4.8 本章小结
第5章 WINDOWS PE/COFF
5.1 WINDOWS 的二进制文件格式PE/COFF 134
5.2 PE 的前身——COFF
5.3 链接指示信息
5.4 调试信息
5.5 大家都有符号表
5.6 WINDOWS 下的ELF——PE
5.7 本章小结
第3部分 装载与动态链接
第6章 可执行文件的装载与进程
6.1 进程虚拟地址空间
6.2 装载的方式
6.3 从操作系统角度看可执行文件的装载
6.4 进程虚存空间分布
6.5 LINUX 内核装载ELF 过程简介
6.6 WINDOWS PE 的装载
6.7 本章小结
第7章 动态链接
7.1 为什么要动态链接
7.2 简单的动态链接例子
7.3 地址无关代码
7.4 延迟绑定(PLT)
7.5 动态链接相关结构
7.6 动态链接的步骤和实现
7.7 显式运行时链接
7.8 本章小结
第8章 LINUX 共享库的组织
8.1 共享库版本
8.2 符号版本
8.3 共享库系统路径
8.4 共享库查找过程
8.5 环境变量
8.6 共享库的创建和安装
8.7 本章小结
第9章 WINDOWS 下的动态链接
9.1 DLL 简介
9.2 符号导出导入表
9.3 DLL 优化
9.4 C++与动态链接
9.5 DLL HELL
9.6 本章小结
第4部分 库与运行库
第10章 内存
10.1 程序的内存布局
10.2 栈与调用惯例
10.3 堆与内存管理
10.4 本章小结
第11章 运行库
11.1 入口函数和程序初始化
11.2 C/C++运行库
11.3 运行库与多线程
11.4 C++全局构造与析构
11.5 fread 实现
11.6 本章小结
第12章 系统调用与API
12.1 系统调用介绍
12.2 系统调用原理
12.3 WINDOWS API
12.4 本章小结
第13章 运行库实现
13.1 C 语言运行库
13.2 如何使用Mini CRT
13.3 C++运行库实现
13.4 如何使用Mini CRT++
13.5 本章小结
附录A
A.1 字节序(BYTE ORDER)
A.2 ELF 常见段
A.3 常用开发工具命令行参考
索引

==

参考链接:

=END=

,

《“程序员的自我修养”》 有 8 条评论

  1. Go 程序是怎样跑起来的
    https://mp.weixin.qq.com/s/Rewl0DKnq6CY53m5D3G2qw
    `
    源码编辑
    编译链接概述
      编译过程
        词法分析
        语法分析
        语义分析
        中间代码生成
        目标代码生成与优化
      链接过程
    Go 程序启动
    GoRoot 和 GoPath
    Go 命令详解
      go build
      go install
      go run
    总结
    参考资料
    `

  2. 程序的一生:从源程序到进程的辛苦历程
    https://segmentfault.com/a/1190000022040651
    `
    摘要:一个程序的一生,从源程序到进程的辛苦历程!本文不深入研究编译原理、操作系统原理,主要聚焦于程序的加载和链接。

    一、前言
    二、概述
    三、基础
    3.1 硬件基础
    3.2 汇编基础
    3.3 一些工具和玩法
    3.4 其他
    四、编译
    4.1 词法分析
    4.2 语法分析
    4.3 语义分析
    4.4. 中间语言生成
    4.5 目标代码生成
    五、链接
    5.1 目标文件
    5.2 目标文件的结构
    六、静态链接
    6.1 目标ELF文件和可执行ELF文件
    6.2 合体的ELF可执行文件
    6.3 符号重定位
    6.4 重定位表
    6.5 指令修改
    6.6 静态链接库
    七、装载
    7.1 虚拟地址空间
    7.2 如何载入内存
    7.3 进程视角
    7.4 段(Segment)地址对齐
    7.5 堆和栈
    八、动态链接
    8.1 一个栗子
    8.2 GOT和PLT
    8.3参考
    8.4 Linux的共享库组织
    8.5 系统的共享库路径
    九、后记
    参考
    `

  3. 软件源码安全攻防之道(上)
    https://mp.weixin.qq.com/s/jb3VQyK3U6BQS0-0ad0K_w
    `
    一提到软件安全,大家自然会想到“漏洞”这个关键词。一般来说,一款软件如果出了安全问题,那大概率是因为出了安全漏洞导致的。

    对于开发人员来说,觉得这有些小题大做,认为漏洞无非就是一个缺陷或一个bug,改掉就行,没有什么特别的。

    对于安全人员来说,一个漏洞的利用其实是一门艺术,如果从源码层面来深究,会发现更多的奥妙。

    本篇先介绍漏洞与缺陷的区别,阐述实施安全编码的必要性,并以内存的源码攻防之争来说明安全攻防中常见的几种思路和方式。

    # “漏洞”与“缺陷”

    CVE(Common Vulnerabilities and Exposures)实例可以形成攻击,而CWE(Common Weakness Enumeration)实例可能导致问题。通过此类比,我们可以初步来区分“漏洞”和“缺陷”。

    漏洞:往往由一个或多个缺陷导致,容易被攻击者利用而形成攻击。
    缺陷:从质量视角来看,导致软件存在安全脆弱性,不过未必能直接形成攻击。

    必然和或然,反映到业务团队,往往会给出两种截然不同的处置态度。

    面对漏洞,业务团队往往会积极配合并火速整改,甚至“刮骨疗毒”也在所不惜。
    面对缺陷,业务团队往往“讳疾忌医”,抱着侥幸心理,视而不见。

    这两种态度都存在一定问题,难以长久处之。

    案例1:冲击波蠕虫
    案例2:openssl心脏滴血
    通过以上2个案例,我们可以看到,要想软件安全性高,实施安全的编码是一个很好的实践,减少了缺陷的出现,自然也就能减少潜在漏洞的发生。

    # 源码漏洞类型和常见攻击手段

    最开始的漏洞利用,战场实际上就是内存,攻防双方在这个战场上展开“内存之争”。

    Round 1 – 通过各种手段控制程序指令指针,一字曰“夺”

    Round 2 – 如何绕过一些防护与限制,一字曰“绕”
    既然防御者设置了“陷阱”,那就绕过这个保护。当然这个“绕”,是建立在你有足够知识了解的前提下,才能进行(“屯田日久,当见其功!”)

    Round 3 – 如何巧妙执行shellcode,一字曰“借”
    前面主要讲“夺”和“绕”,那么拿到CPU执行权,要怎么利用呢,这就涉及到shellcode的执行。所谓shellcode,就是一串具有一定代码意义的字节序列,能够直接或间接执行达到攻击者不可告人目的的代码逻辑。

    Round 4 – 随机与预测,一字曰“猜”
    面对攻击者这种在内存中“蹦蹦跳跳”的行为,防御者提出了ASLR(Address Space Layout Randomization,地址空间布局随机化),让你找不到地方去跳。
    整个系统没有代码片段是事先知道的,没有了第一环,所以整个ROP链条就无法顺利构建。
    面对这种防御,攻击者采用了“普遍撒网”的策略,把大量构建好的shellcode指令进行复制,在内存中批量覆盖,就像拿着喷射枪四处乱喷,也叫做堆喷射攻击(Heap Spray)。

    “内存之争”的介绍就到此为止,相信攻防博弈也并未因此停止,各种先进的技术也不断演进出现。关于软件源码安全攻防系列的文章……未完待续。

    通过以上介绍,我们可以看到,正是这些攻防相抗,强化了我们软件的安全性,安全防御也从点防提升到面防,安全设计思想也随后被提出并被各大软件厂商广泛采纳。
    `

回复 a-z 取消回复

您的电子邮箱地址不会被公开。 必填项已用*标注