C和C++安全编码(原书第2版)
上QQ阅读APP看书,第一时间看更新

3.3 对象指针

对象指针在C和C++程序中无处不在。Kernighan和Ritchie[Kernighan 1988]对此有如下评论。

指针在C中得以大量使用,部分原因是它们通常能产生更紧凑、更高效的代码,而用其他手段则无法做到这一点。

C和C++中的对象指针用于指向动态分配的结构、函数的引用参数、数组以及其他对象。这些对象指针可能会被攻击者修改,比如当利用一个缓冲区溢出漏洞的时候。如果一个指针接下来被用作一个赋值操作的目的地址,那么攻击者就可以通过控制该地址达到修改其他内存位置内容的目的,这种技术也称为“任意内存写”(arbitrary memory write)。

例3.3包含了一个有漏洞的程序,可以被利用来实现任意内存写。程序第5行包含一个无界内存复制。在溢出缓冲区后,攻击者可以覆写ptr和val。当接下来在第6行中计算*ptr=val时,就会发生任意内存写。另外,某些常见的动态内存管理错误也使攻击者有机会修改对象指针。

例3.3 修改对象指针


1  void foo(void * arg, size_t len) {
2    char buff[100];
3    long val = ...;
4    long *ptr = ...;
5    memcpy(buff, arg, len);
6    *ptr = val;
7    ...
8    return;
9  }

任意内存写在32位的Intel架构(x86-32)上备受关注,因为在这种硬件环境下,sizeof(void*)、sizeof(int)、sizeof(long)都等于4字节。换句话说,在x86-32架构上,有很多机会可以将某4个字节写入另外4个字节,从而覆写任意位置的一个地址。