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
。但是如前所述,知道该值将无济于事,将值设置为任何值很可能会导致分段错误。