我只是编译了一些使用gets读入输入的C代码,然后反汇编了这些代码。该平台是Ubuntu 32位。

这三行代码检查canary值是否已被篡改。

0x08048459上设置一个断点,并看到gs寄存器的值为0x33。 ? 0x33是某物的索引吗?
是否有任何x86指令将gs的值移动到任何其他寄存器?还是将其推入堆栈?


#1 楼

检查linux内核源代码中的堆栈保护。内核将gs寄存器初始化为percpu结构,该结构包含旨在用作堆栈金丝雀的随机值。对于32位程序,此堆栈金丝雀的偏移量为20(0x14)。对于每个进程,它都是随机的,以避免恶意软件能够始终依赖它的相同值。

0x33实际上是您无法访问的内核中表的索引,因此,对于用户而言,这毫无意义。通过gs和gs映射到的内核表索引,构成percpu结构的虚拟内存被映射到物理内存“某处”,但是该物理内存没有映射到您可以“正常”寻址的任何地址,即通过“正常的” cs / ds / ss段。结果为实地址”,但这仅适用于实模式。 Linux一直使用保护模式。您可以在此处找到有关实模式和保护模式下段的更多详细信息。

要读取该值,可以使用push gs指令。还有一个pop gs。但是如前所述,知道该值将无济于事,将值设置为任何值很可能会导致分段错误。