最近几周,媒体对stage怯场非常关注,stage怯场是安卓操作系统的一个基于C的组件,负责播放各种多媒体文件。使用的怯场(在本文中有更详细的讨论)是从根整数缓冲区溢出和下溢的结果。虽然我们之前的文章对此进行了详细的讨论,但它只是在写完这篇文章后才浮出水面,但这个补丁的弱点在于修复了stage怯场。是的,目前发布到该设备的补丁已经在最近几天发布到Nexus设备。所以现在我们需要另一个。
然而,有一个好消息——新补丁只是对源代码的一行更改。您可以看到AOSP gerrit上的实际补丁,它为整数变量添加了另一个边界检查,以防止溢出。
但是“上溢下溢”这个短语不断出现,本文旨在通过一些简单的例子来演示这些例子,让大家了解这些问题的实际含义以及它们在家里是如何工作的。我在Linux上使用GCC C编译器(确切地说是5.2.0版)来进行这个操作。如果你愿意,你可以尝试在家里跟踪,这些结果可以在大多数系统上重现。如果没有,或者您不想启动Linux VM或live CD,请随时阅读它——我将向您展示正在编译的代码以及运行时发生的情况。
如果你对C有一点了解,这将会很有帮助,但这不是必需的——我将解释基础知识。
让我们分配一些内存。
几乎所有用C或C语言编写的软件(就我们这里的目的而言,后者实际上是前者的扩展)都是基于内存分配的。为了储存东西,我们需要记忆。为此,我们声明一个变量。这是为整数(integer)声明变量的示例:
我们在这里告诉编译器,我们将创建一个整数。这显示了我们需要多少内存(也就是说,足够容纳一个标准大小的整数)。我们也把它命名为(a)供以后参考。最后,我们在其中设置一个值(5)——最后一步是可选的。如果我们不这样做,我们将得到一个未初始化的整数。这是一个不可预测的值,因为它恰好是内存中的最后一个值。让我们用一个快速的程序来尝试一下:
在这里,我们将制作几个数组。数组只是一种类型的组的序列。因此,在这种情况下,整数数组只是几个整数的序列,所有整数都排成一行,内存是连续分配的。第一个(称为herpDerp)仅用于占用一些空间,以使结果更容易查看。第二个数组称为myArray,包含10个整数。如果我们想在内存中找到myArray的第一个整数的地址,我们可以一次向前移动一个地址,并检查数组中的下一个值。事实上,这就是以“printf”开头的行的作用——它将变量中的内容打印到屏幕上。这里,我们将数组中每个整数的值打印到屏幕上。