1.知识总结(主要对新知识)
(1)计算机提供不同层次的抽象表示,来隐藏实际实现的复杂性
- 文件是对I/O设备的抽象表示
- 虚拟存储器是对主存和磁盘I/O设备的抽象表示
- 进程是对处理器、主存和I/O设备的抽象表示
(2)程序员必须知道编译系统是如何工作的原因:
- 优化程序性能:知其原理,才可优化。
- 理解连接时出现的错误
- 避免安全漏洞:缓冲区溢出错误。
(3)运行hello程序
- shell 上输入”./hello”后,回车,shell逐一读入字符串到寄存器,之后把字符串存入内存中
- shell 加载hello程序从磁盘到内存(最开始hello是放在磁盘上的)
- hello加载完毕后,CPU执行hello程序的main程序的机器指令。将主存中要打印的”hello, world\\n”,从内存加载到寄存器,再从寄存器复制到显示设备,最终显示在屏幕上
(4)并发是一个通用的概念,指一个同时具有多个活动的系统;并行指的是用并发使一个系统运行的更快
(5)意识到高速缓存的存在,可以利用高速缓存将程序的性能提高一个数量级。
(6)虚拟内存为每个进程提供一个假象,即每个进程都在独占的使用主存。每个进程看到的是一致的存储器,称为虚拟地址空间。进程的虚拟地址空间从下往上(从小到大)依次放的是:
- 程序代码和数据:对于所有的进程来说,代码是从同一固定地址开始,紧接着是C全局变量相对应的数据位置。
- 运行时堆:代码和数据区是在进程一开始运行时就被规定了大小,而当调用如malloc和free这样的标准库函数时,堆可以在程序运行时动态的扩展和收缩。
- 共享库:存储C标准库和数学库等的代码和数据。
- 用户栈:实现函数调用。
- 内核虚拟内存:不允许应用程序读写,或者直接调用内核代码定义的函数。
2.问题思考解决
缓冲区溢出错误如何造成免安全漏洞?
参考缓冲区溢出攻击原理分析,结合学习过的栈帧变化,知道了缓冲区溢出攻击会通过某种方式修改eip的值,让其指向恶意代码。当buf变量发生溢出时会往高地址空间覆盖,先是覆盖本函数的其它局部变量,然后是调用函数的ebp,再次是eip,最后是调用函数的栈空间。如果读取的文件内容覆盖掉eip,就可以修改程序的执行路径(传入一个超长的带有shellcode的字符缓冲,覆盖栈中的EIP值,这样当函数执行完成返回后就会返回到有shellcode的地方,执行恶意代码)。