软件安全原理-复习笔记
本文最后更新于:2026年1月18日 凌晨
刚开学就听说这门课很牢,上了一个学期发现确实如此,希望到了期末能好一点(悲)
开始之前
早在入学之前就听闻过龚老师的大名,开学后也慕名而来报了这门课。这门课几乎上了一整个学期,牢是真的牢,但是确实也学到了不少东西。刚刚去ciscn初赛就看见了一个上课讲过的例子,我认识的一个很强的师傅还说感觉很新奇,这么说来我总算是也能挺直腰杆以一个网安专业正规军学生的身份说一句“我们上课讲过了”这样的话了()
遥想2023年打ccb京津冀高校联赛的时候听后面的柏油✌说赛题知识点在逆向课学过了,真的大为震惊
话说怎么你学过那个时间戳反调试却还是没做出来那道ez_rw(绷不住了我是大废物)
这篇文章主要是对PPT进行一个知识的汇总,这里并不把所有的知识点都端上来,而单纯做一个提纲,对于重要的可能当作大题出现的知识,我会直接复制上来。只看提纲对复习有帮助,但还是建议配合PPT食用。我会把这篇文章分享给同期同学并挂在我的博客上,也欢迎大家传阅,如果你觉得我的内容有问题,欢迎勘误。
有件事情要声明一下,笔者本科是CTF Pwn方向老赛棍(虽说并不强),课堂里有些东西我确实提前就接触过了。我觉得对我是背景知识的一些重要的地方(比如ROP的原理)可能只会一笔带过并标为重点,并不详细展开,但是对一部分没有相关基础的同学来说反而这里会是重难点。由于鼠鼠我现在期末要考四门闭卷,已经要炸掉了,所以很抱歉对这个提纲我仅仅能够回应有足够支撑的质疑,不接受也没有义务对所有同学针对博客本身做答疑。
同时,并不是我写的多的就是重点,写的少的就不是重点。
这篇博客准确来说只是我个人的复习笔记,写于最后一节课之后、期末考试之前这段时间区间内。这篇博客的除了参考了课堂内容以及课程PPT之外,和授课教师、课程助教以及期末考试没有任何直接关联,由于本人能力有限,本人声明这里不能保证这篇博客的知识点以及行文逻辑是完全正确的,也不保证和课堂内容完全无冲突,请大家吸收知识前认真检查,同时本人也不对任何参考了此博客的同学的期末成绩负责。
建议是先扫一轮提纲,然后顺着PPT配合提纲再过一遍。
第一章 软件与网络空间
一般来说第一章会水一点,至少知识点是这样,当然第一节课的课堂汇报也是真的牢。
1.1 重新认识软件
软件的分类(P21),这里给出了按照版权划分、按照基础功能划分两种。
软件的三大特性(P27):复杂性、互联性、可扩展性。
1.2 软件技术发展历程
一些计算机和软件发展的历史。看一看就行。
课堂汇报
软件复杂性,以及其和软件漏洞之间的关系。
(具体细节是什么我也忘了qwq)
第二章 网络安全观
信息安全的三大基本属性:保密性、可用性、完整性。
感觉这一章没啥东西。
课堂练习是写作练习,跟考试没啥关系感觉。
第三章 软件安全
3.1 网络空间安全概述
学科体系划分(网安下面分了六个小学科门类),可以看一看当作枯燥复习的调料
3.2 软件安全
软件安全就是使软件在受到恶意攻击的情形下依然能够继续正确运行的工程化软件思想。
(感觉没啥有体系的考点)
3.3 软件攻防技术的演进
讲了缓冲区溢出等攻防技术的演进,考试大概率不考。
3.4 软件的生成
讲的是编译的过程(大一就学了应该),以及ELF文件的结构以及各个section(PPT 35页):
.bss、.data、.rodata、.text、.debug、.line、.comment、.init、.fini、.plt、.got
Pwn方向的老赛棍应该知道,不熟悉的同学可以看看,建议自己编译一个ELF,看着更直观。
3.5 软件的运行
- x86架构汇编
- 32位操作系统下进程虚拟地址映射
- 大小端序
- 进程内存组织(堆/栈增长方向)以及内存的布局。
- 函数调用栈(调用和返回的时候栈帧的变换过程)
- 32位和64位程序的差异
这一章个人认为非常非常重要,像是函数调用栈我觉得很有可能作为大题的考点。可以说当初笔者学Pwn就是先学的这些东西,老Pwn手对这些知识虽不敢自称烂熟于心,至少也能说是早有耳闻,因此这里我就不再赘述了。没基础的同学一定一定不要因为字少而直接跳过
3.6 课程实践:程序生成与运行实验
主要考验gdb的使用
第四章 软件安全原则
概要(PPT P3)讲了软件安全的目标:“允许对软件进行预期的操作,阻止任何非预期的操作”,以及非预期操作:“有可能因非预期使用计算机资源而带来危害。”
看看图有帮助
4.1 软件与系统安全基本原则
4.1.1 身份认证
身份认证 (Authentication):核实某人是否是其所声称的人的过程。
身份凭证类型分为如下三类:
- 某人知道什么(知识),如PIN
- 某人拥有什么(所有权),如身份证,钥匙
- 某人是什么(特征),如指纹等生物特征
也成为:你所知道的、你所持有的、你的特有属性。
身份认证方式:
- 口令
- 生物特征因子(Biometric)
- 属性(Property)
- 多因子认证
4.1.2 访问权限
访问控制(access control):是一种安全手段,它控制用户和系统如何与其它系统和资源进行通信和交互,从而保护系统和资源免受未授权访问。
访问(access):是在主体和客体之间进行的信息流动,包括读取、增加、删除、修改信息内容及其属性。
4.1.3 安全属性CIA
一个早就烂熟于心的三角形……
4.2 隔离原则
隔离 (Isolation):对系统中两个组件进行相互隔离,并通过将两者之间的交互限制在清晰设定(well-defined)的API之内。
安全监视器(Security Monitor):以比各隔离组件更高权限运行,监视并确保各组件遵循隔离要求。
P22,三个隔离实例:进程隔离、虚拟机与容器、基于软件的故障隔离SFI
4.3 最小权限原则
就一页,直接上图

4.4 区域化原则
依旧直接上图

4.5 缺陷与漏洞
定义:漏洞是可以导致系统安全策略被违反的缺陷
违反安全策略:漏洞可以使目标系统处于下列危险状态之一
- 允许攻击者以他人身份运行命令
- 允许攻击者违反访问控制策略去访问数据
- 允许攻击者伪装成另一个实体
- 允许攻击者发起拒绝服务攻击
第四章最重要的考点应该就是下面的漏洞分类:
按源代码中缺陷的特征分类:
- 缓冲区溢出
- Use-after-free
- 条件竞争
- 格式化字符串
- 类型混淆
- Missing sanitization
- ……
按缺陷利用的效果分类:
- 权限提升
- 认证绕过
- 代码执行
- 沙盒逃逸
- ……
4.6 威胁模型
可能的考点是STRIDE方法。

第五章 内存与类型安全
五六七八这四章应该是课程的重点,实际上课堂里实践内容最多的就是这四章。这四章也必定承包了所有的代码题(只是推测)。
注意这四章的PPT分类两份,里面有很多代码案例,建议全部认真看一遍。
5.1 基于编程语言的安全问题
操作系统提供了多层次抽象,隐去了大量细节,降低了部件使用的复杂性。操作系统提供了隔离及访问控制机制,为软件运行提供了重要保障。但由于编写软件的各类编程语言自身存在不同缺陷,导致所编写的软件存在各种各样安全问题。
本章以C/C++编程语言为主要考察对象,讨论其缺陷及引发的安全问题。包括:
- 过分依赖开发者的“自觉”
- 将程序控制信息和数据混为一谈
- 将数据和元数据混为一谈
- 不负责内存初始化和清理
这四个案例(P8)建议好好看看。
基于编程语言的安全 (Language-based Security,LS) 是指由编程语言提供的特性或机制,这些特性或机制有助于构建安全的软件。主要包括内存安全 (Memory Safety)和 类型安全 (Type Safety)
5.2 指针的功效
恕我直言如果到现在不知道指针是什么那么真的可以准备好挂科了(x)
指针如何影响内存安全与类型安全?安全的编程语言如何解决指针相关问题?从以下三个方面:指针、有效期、类型(P26 P27)
空指针解引用(漏洞编号CWE-476)成因及后果。(P28)

5.3 内存安全
内存安全 (Memory safety) 确保程序中的指针总是指向有效的内存区域或内存对象,分为空间内存安全和时间内存安全。(PPT 31)
空间内存安全就是不越过边界,时间内存安全就是解引用的时候指针指向的内存仍是有效的对象
一个很重要的C语言指针安全问题案例(PPT 34),这个案例里讲了UAF、double free、内存泄漏三种案例。
5.4 类型安全
(换到新的PPT)
从计算机科学视角,一部分编程语言具备“类型安全”性质。这个术语在不同的研究群体中有不同的定义(在研究计算理论的学者中,类型和类型安全的定义非常复杂)
从安全视角,“类型安全”旨在避免必然的错误形式和不良的程序行为(类型错误)
类型安全是编程语言中的一种概念,它为每个分配的内存对象赋予一个类型,被赋予类型的内存对象只能在期望对应类型的程序点使用。
PPT P5 P6 Trapped error与Untrapped error辨析,以及良好程序在爆error方面的性质。
强类型语言、弱类型语言。
类型转换问题和类型混淆错误 案例PPT P9
第一个案例是由于用了不同类型的指针解析数据而出现问题(如对double用int),第二个案例是一共子类型A用了另一个同层级子类B类型的指针去解析。但是使用指针去调用成员函数的时候,会使用A的虚函数表,导致执行到的函数并不是B类的函数,而是A中相对位置的函数。
5.5 编程语言针对安全问题的演进
这里东西很杂,算是一些较为先进的解决方案像是C++的强化类型检查、智能指针,以及JAVA、Rust这些更安全的语言等等。这里应该不会是考试的重点,看看PPT有点印象就行。
第六章 软件安全攻击手段
6.1 概要
攻击面&攻击向量的概念。
不同攻击技巧对CIA三角(机密性、完整性、可用性)的危害(PPT 第7页)
6.2 拒绝服务攻击
Dos与DDos
两种拒绝服务攻击的方式:面向内存消耗的攻击(关键内存消耗与全局内存消耗)与面向CPU消耗的攻击(进入死循环或者死锁,或是引发超出预期的计算量)。
Dos的效果(进程级Dos,系统级(软件)Dos,硬件级Dos三种级别攻击的效果)
6.3 信息泄露
PPT 27页列举了各种可能被泄露出去的有价值的信息。建议看一看加深理解。

6.4 提权
两类提权攻击:远程代码执行RCE,本地权限提升LPE。
操作系统提权的主要方法:通过系统服务提权,通过内核漏洞提权,通过配置错误提权。
两种提权手段:控制流劫持和命令注入。
写到这里突然感觉列举知识点纯纯就是硬背书,其实打几个题就都理解了()
6.5 混淆代理人(Confused deputy) 问题
PPT里一张图讲的差不多了

在代理人这块还讲了一个D-Bus的课堂讨论案例,这个案例综合性很强,可以回忆一下加深一下理解。
6.6 软件漏洞利用技术
上面几个小节都是一些较为粗略的讲述和事件案例为主。到这里直接换PPT了,而且这一个小节讲了整整一章,可见重头戏来了()
6.6.1 计算机架构与安全
冯·诺依曼架构,哈佛架构的主要区别(是否区分存储指令和数据)
现代计算机结合了以上两种架构的特点,架构也更复杂。但仍然把数据和代码存储在同一块内存地址空间中。
6.6.2 Shellcode
从这里开始一直到第六章结束建议所有的PPT认真去看一边,这边老Pwn手对这些东西都算是熟的不能再熟了,所以我写的笔记大概率对大家来说是有些过于简洁的。老赛棍可以主要看我的提纲补补零碎知识。
什么是shellcode,shellcode与exploit的区别。(shellcode是很直接的能够拿到shell或实现其他效果的二进制代码,而exp是攻击目标软件的一段代码、数据或命令行为序列。exp可能包含了装载shellcode的行为)
shellcode效果过程,慢慢看吧。
shellcode编写挑战,如遇到\x00或者\n的截断等。(即forbidden bytes)
6.6.3 栈溢出漏洞的利用
这位更是重量级
常见的引发缓冲区漏洞的错误:
- 输入缓冲区数据的长度缺少校验
- 整数溢出漏洞导致的缓冲区越界写
- Off-by-One 错误
PPT P25,ret2text和ret2shellcode攻击的原理,以及针对它们的防御手段(ASLR、Canary、DEP),建议仔细看。
6.6.4 ROP
原理这块我真不想写了,老赛棍天天研究花式栈迁移,已经快要吐了()
本质上ROP是一种代码重用的思路,即运用地址确定的gadget来拼装代码片段。至于什么是gadget具体原理这块,我在这里讲也不一定比PPT讲的清楚,看一遍PPT里的案例,自己理一下eip/rip和esp/rsp指针一步一步怎么变化的就都懂了。
对于老赛棍来说更重要的是要记住这个ROP的背景:

PPT 49页还有一个常见ROPgadget,可以看看(刚刚瞥了一眼居然真有栈迁移gadget……)
6.6.5 竞争条件
完啦鼠鼠当年操作系统考试是一天一夜速通的qwq
当一个程序的两个并发线程同时访问共享资源时,如果执行时间和顺序不同,会对结果产生影响,这时就称作发生了竞争条件。
这里分为两种
- 竞争条件漏洞(Race Condition Vulnerability)
- TOCTOU漏洞(Time of Check / Time of Use)
说到这里,之前埋洞的大作业里有个CWE-366 Race Condition within a Thread这里贴一个链接:https://bbs.kanxue.com/thread-289309.htm这里有详细的各种CWE的代码模式的举例,也包括上面这两个CWE的区分。
这个帖主的ID我很眼熟,加上时间和课件发布时间很能对的上,我这边严重怀疑是班里的同学()


建议好好看,条件竞争是很隐蔽的一个漏洞点,看起来感觉晕晕乎乎的,不像上面的漏洞和攻击这么直观。这里有一个概念辨析:可重入函数/不可重入函数。在PPT第59页,记得看一下。
第七章 软件安全防御策略
7.1 概述
主要讲了软件验证这个概念,看看得了
7.2 软件漏洞缓解措施
分了好多点,一看就是重点()
7.2.1 漏洞缓解机制简介
对于一个存在漏洞的软件,漏洞缓解(Mitigation)措施可以使其漏洞利用变得更难,但不会修复漏洞,因此漏洞依然存在于软件中。
7.2.2 数据执行保护
DEP目的是不让用户注入恶意代码,但是冯·诺依曼架构不区分数据和代码。解决方案是给内存页面添加权限标记。(用户能写如的数据的只要RW权限,没有X权限)
目前主流DEP都是基于NX实现的。
PPT第22页,有关于操作系统页面管理的知识回顾,操作系统基础较差的同学(比如我)可以看看。
DEP仍存在两个可能的攻击点已实现代码注入:
- de-protecting memory,即使用mprotect这类能够修改页面权限的系统调用修改某个页面位可执行页。(执行mprotect修改页面需要ROP)
- JIT (Just in Time Compilation),对于有即时编译功能的软件,其功能上就有运行时动态生成可执行代码并执行的行为,这就有了注入恶意代码的机会。
7.2.3 地址空间随机化
地址空间随机化 (Address Space Randomization, ASR)对进程内存地址空间进行随机化,使攻击者难以确定程序控制流劫持的目标或内存中某些关键数据所在位置等攻击者期望的内存地址。
挑战:应该随机化哪些对象?需要权衡性能开销、复杂度与安全性,
ASLR和PIE防护(都能防护到哪种程度,ASLR有0,1,2三个等级)
7.2.4 栈完整性保护
攻击向量:栈溢出覆盖返回地址。
缓解措施:函数起始时,在栈缓冲区和程序控制信息之间插入一个被称为 canary 的随机数。函数返回前,检查 canary 是否发生变化。如果发生栈溢出,那么在返回地址被覆盖之前,canary 会被首先覆盖,如果函数结束时检查到 canary 的值被修改,程序则会终止执行。
这一章也是看一遍案例就差不多了()
7.2.5 Fortify Source
(换了PPT继续看)
缓解措施:编译器有一个名为 FORTIFY_SOURCE 的编译选项,它可以将危险函数替换为可自动检查缓冲区边界的对应函数,以防止简单的缓冲区溢出和格式化字符串漏洞
(如strcpy 凼数被替换为 __strcpy_chk 凼数)
7.2.6 控制流完整性保护
缓解措施:控制流完整性 (CFI) 是一种软件漏洞缓解机制,用于保护程序免受控制流劫持攻击,成功的 CFI 确保程序的控制流永远不会离开其预定义的有效控制流,这意味着攻击者将无法重定向控制流至意位置。
控制流分类:前向控制流(call,jmp),后向控制流(ret)
后向控制流的完整性保护策略是影子栈,利用影子栈记录返回地址,在函数返回时进行比对。影子栈只保存返回地址。
前向控制流完整性 —— 基于静态分析的控制流图检查:
- 采用针对源代码或二进制程序的静态分析方法构建程序函数调用关系表。
- 将表存储在 ELF 的只读区域内,防止被修改。
- 利用编译器插桩,在函数调用时检查跳转目标是否在表内。
- 由于静态分析算法通常不精确,表内目标范围仍然过大。
Indirect Branch Tracking,在函数起点加入了endbr64指令,这个指令效果类似nop,但是如果call和jmp间接跳转指令的目标不是endbr,就会触发异常。
Windows CFG实现(PPT 12页)
7.2.7 代码指针完整性保护
敏感指针
感觉不是重点,有空就慢慢看得了
7.2.8 沙箱与基于软件的错误隔离
沙箱(Sandbox)是一种安全机制,为执行中的程序提供隔离环境。
感觉不是重点。
7.3 基于编程语言的安全
Rust!!!!!!!
所有权机制,借用机制。
这个是最先提到的一个点,不知道考不考,有空最好看一下,可能是一个小考点。
第八章 软件安全分析基础
软件安全分析:针对目标软件(分析对象)通过(组合)运用逆向工程、抽象与运、定制特殊输入数据与受控运行等操作,了解目标软件架构、理解其运行机理,发现并确证其脆弱点(漏洞),为进一步利用或缓解其漏洞提供支持
8.1 逆向分析
逆向工程 (reverse engineering):通过观察系统及其行为,建立其结构蓝图(blueprint),以弄清其运行规律的过程。
下面目录应该是8.1.X,PPT上面是8.2.x,我这里改了一下
8.1.1 基本原理
莱斯定理
给定一个程序性质 P,如果:
- P 是非平凡的(即存在程序满足P,也存在程序不满足P)
- P 是语义性质(只依赖于程序的输入-输出行为,不依赖于具体实现)
那么不存在一个通用算法,能够对任意程序判断它是否具有性质 P。
莱斯定理是计算理论中的一个重要定理,它揭示了关于程序行为的深刻限制:对于任何有意义的程序行为特性,都不可能编写出全准确的通用分析工具。
(P22详细解释)
两组衡量性能的指标
误报率与漏报率,召回率与准确率。


Must分析和May分析
面对不可判定性时,在可靠性和完全性之间取舍。
Must,只输出“是”或者“不知道”,保证可靠,会引入漏报
May,只输出“否”或者“不知道” ,保证完全,会引入误报
soundness(健壮性) 和 completeness(完整性)
8.1.2 控制流分析
鼠鼠编译原理学的特别烂(其实是没学过)所以多写了一些。
程序的生产有两个产物,抽象语法树AST,中间表示IR。
控制流图 (Control Flow Graph, CFG):以图 (Graph) 的形式来表示程序的控制流,通过遍历 CFG 可以获得程序所有可能的执行路径。
CFG 的节点可以是一条语句(源代码)、一条指令(二进制程序)、一条三地址码(IR)或一个基本块
基本块(Basic Block):是连续的语句/指令/三地址码的最大序列,具有以下特点:
- 只能从基本块的第一条指令处进入该基本
- 只能从基本块的最后一条指令处离开该基本块
- 要点:基本块内不发生控制流跳转
8.1.3 数据流分析基础
数据流分析(Data Flow Analysis, DFA)是指分析“数据在程序的控制流图上是怎样流动的”。具体来讲,数据流分析的对象是基于抽象的应用特定数据、分析的基础是程序控制流图(CFG),分析的行为是数据沿着 CFG 的节点和边的“流动”。大多数据流分析算法的理论基础是抽象解释。
设计数据流分析算法分为4个步骤:
- 设计“抽象域”,对应的𝛼、𝛾函数和初始值
- 设计转移函数
- 处理控制流路径分叉与合并
- 设计算法使数据流抵达“不动点”(例如 WorkList 算法)
8.1.4 抽象解释
P47慢慢看吧,我已经脑袋要爆炸了。
8.1.5 数据流分析应用
静态污点分析,这一章偏向于介绍,感觉不会考。
8.1.6 CodeQL
大作业,考试应该不考了吧……
8.2 人工分析
黑盒、白盒、灰盒分析
IDA、Ghidra、gdb、x64dbg、windbg等工具介绍(侧重实战)
反调试技术
反调试技术的类型:
静态反调试技术:目标程序作为被调试进程开始运行时,采用一些方法来侦测自身是否处于被调试状态,若是则执行非常规代码(主要是终止代码)来阻止调试。
动态反调试技术:目标程序在被调试过程中,采用一些方法来扰乱跟踪功能,导致调试无法正常进行
基于时间,0xcc,SHE的反调试等…..
逆向分析方法:软件版本差异分析、代码审计。
这一节侧重于实践
8.3 模糊测试
篇幅较少,重点应该是下面的概念。

8.4 符号执行
全是图片和少量配文,我也不懂qwq。估计不是重点吧
第九章 移动App的安全
我个人认为后面内容不是考试的重点,当然像安卓这种我觉得挺有学习价值的()
9.1 Android平台App安全
9.1.1 Android平台介绍
Android系统架构(P7):
- 应用程序层(JAVA)
- 应用程序框架层
- 系统运行层—系统库
- Linux内核层
9.1.2 Android平台App的生成和逆向
典型的Android应用模块的构建流程通常依循下列步骤:
- 编译器将源代码转换成DEX文件(其中包括运行在Android设备上的字节码),将所有其他内容转换成已编译资源。
- APK打包器将DEX文件和已编译资源合并成单个APK。不过必须先进行签名,才能将应用安装并部署到Android设备上。
- APK打包器使用调试或发布密钥库签署APK。
- 在生成最终APK之前,打包器会使用zipalign工具对应用进行优化,减少其在设备运行时的内存占用。
APK打包过程是一个编译、加密和打包的过程,因此逆向就是解压、解密和反编译的过程。如需解密资源文件,需要用到apktool工具。
9.1.3 Android平台App典型安全威胁与攻击面
Activity劫持(P30),即APP正常的Activity界面被恶意攻击者替换上仿冒的恶意Activity界面进行攻击和非法用途。
Database配置模式,开发者在创建数据库(Database)时没有正确的选取合适的创建模式进行权限控制,从而导致数据库(Database)内容被恶意读写,造成账户密码、身份信息、以及其他
敏感信息的泄露,甚至攻击者进一步实施恶意攻击。
9.1.4 Android平台App安全问题产生的原因
- 开发门槛低导致的安全问题
- 第三方库导致的安全问题
- 应用重打包导致的安全问题
- 第三方市场监管不力导致的安全问题
9.2 iOS平台App安全
iOS系统分为可分为四级结构,由上至下分别为:
- 可触摸层(Cocoa Touch Layer)
- 媒体层(Media Layer)
- 核心服务层(Core Services Layer)
- 核心系统层(Core OS Layer)
我觉得IOS不太可能考,感觉写的很泛。我个人是懒得复习了,有兴趣可以看看。
第十章 智能软件系统脆弱性 & 第十一章 智能软件系统后门
这两张是AI相关的,我个人对这一块是一窍不通。两章加起来也只讲了一节课,我认为不是这门课的重点。
如果这两章的知识点加起来考了超过一个选择题的分值,我就把我本科室友CZZ的袜子用开水煮了吃下去。
第十二章 软件开发与安全 & 第十三章 软件安全开发方法
这种一节课讲两章的感觉都不会是考试的重点()
第十二章,P24的内构安全,P29的三大软件支柱。
第十三章,看看SDL是啥应该就差不多了,其余的当背景故事看看得了。
第十四章 软件供应链安全
PPT P18,上游组件的识别,传统方法和机器学习方法。
其他的感觉不大可能考了。