0%

深入理解计算机系统第三章 笔记

程序的机器级表示

隐藏的东西 in higher

程序计数器PC,寄存器(整数寄存器,浮点数寄存器,条件码寄存器)。寄存器可以操作不储存不同字节大小的数据。

阅读汇编代码

反汇编得到汇编代码

了解各个指令的具体含义,sub、movb、movzbw、leaq等等。学会阅读不同的操作数格式。

控制语句

根据条件码寄存器跳转到指定位置,以达到循环语句和判断语句的效果。

switch使用跳转表,根据对应值按照跳转表进行跳转,跳转表对应数值较大时可以进行相应加减运算处理。跳转表范围较大且表项比较稀疏的时候,可以构建二叉树 二分查找。

过程

全局变量在data区域,代码在text区域,局部变量在stack区域,new、malloc的变量在heap区域。

Stack

被调用的函数调用结束时,对栈指针进行操作,之后ret弹出返回地址,返回调用函数。

栈帧管理(每一个函数有自己对应的栈帧),函数在stack上的储存空间 成为过程的栈帧(stack fram),栈帧会保留需要保留的寄存器 以便在函数调用结束后恢复寄存器原有的值(有的寄存器由caller保存 有的由callee保存)。

寄存器不足够存放本地数据、对局部变量进行&运算、局部变量为数组或者结构,此时局部变量必须存放在内存中。

Array Union Struct

数组地址顺序排列。结构体地址顺序排列。

Union所占地址空间大小为其中最大的数据所占地址空间,相当于对同一地址空间的不同部分赋予不同的别名,在使用时按照别名进行类型转换。

1
2
3
4
union u{
unsigned i;
float f;
}u0;

则 i 为 f底层float表示方法的 十进制数值。

sizeof(u0)=4
size0f(u0.i)=sizeof(u0.f)=sizeof(u0)=4

数据对齐

任何K字节的基本对象的地址必须是K的倍数

1
2
3
4
5
6
struct test{
int i;
char j;
int k;
}t1;

则 sizeof(t1)=12

i占四字节,j占一字节但是j后面三字节为空以达到数据对齐目的,K占四字节 所以共十二字节。

同一类型对象尽量放在一起,节省空间。

内存越界引用和缓冲区溢出

attack lab就是基于缓冲区溢出后 修改返回地址 达到攻击的效果。

C对于数组引用不进行边界检查,局部变量和状态信息都保存在stack 越界引用数组容易修改状态信息(返回地址等)进行破坏。

gets读函数对读入数据大小不进行检查,数据溢出缓冲区会导致stack中信息被破坏。

防范手段

写更加strong的代码,进行数据大小检查。

对stack进行破坏检测,存储canary(金丝雀)值(通常该值 末尾以 0 结尾,即使字符数组溢出1位也不影响,因为字符以0结尾,不会修改canary数值,贴心)

stack地址随机化

限制可执行代码区域,