跳到主要内容

指针与缓冲区溢出

指针的本质是什么?​

  • 类型: 指针有明确的类型, 类型信息由编译器维护;
  • 值: 指针的值就是该类型对象所在的内存地址;
  • 机器级: 在汇编中指针只是一个 64 位的整数地址;

内存越界引用和缓冲区溢出是怎样发生的?​

  • 内存越界引用: 访问了不属于该对象的内存地址, 常见于数组越界;
  • 缓冲区溢出: 栈按声明的类型大小分配空间, 实际写入超过该空间, 常见于字符串拷贝;
  • 后果: 覆盖相邻的栈数据, 包括返回地址, 从而改变控制流;

有哪些对抗缓冲区溢出攻击的手段?​

手段机制
栈随机化栈地址在每次运行时都变化, 攻击者无法定位注入代码的位置
栈破坏检测缓冲区与栈状态之间放入随机金丝雀值, 返回前校验其是否改变
限制可执行区域虚拟内存按页划分, 限制程序可以执行的页

变长栈帧怎样寻址?​

  • 问题: 栈帧大小在运行时才确定时, 无法用编译期常量偏移访问局部数据;
  • 方案: 用一个寄存器保存帧指针, 以帧指针为基准访问栈帧内的数据;