linux_x86进程是干嘛的,为什么x86上的Linux对用户进程和内核使用不同的段?

在X86中 - linux段寄存器用于缓冲区溢出检查[参见下面的代码片段,它已在堆栈中定义了一些char数组]:

static void

printint(int xx, int base, int sgn)

{

char digits[] = "0123456789ABCDEF";

char buf[16];

int i, neg;

uint x;

neg = 0;

if(sgn && xx < 0){

neg = 1;

x = -xx;

} else {

x = xx;

}

i = 0;

do{

buf[i++] = digits[x % base];

}while((x /= base) != 0);

if(neg)

buf[i++] = '-';

while(--i >= 0)

my_putc(buf[i]);

}

现在,如果我们看到代码gcc生成代码的解组。

函数printint的汇编代码转储:

0x00000000004005a6 : push %rbp

0x00000000004005a7 : mov %rsp,%rbp

0x00000000004005aa : sub $0x50,%rsp

0x00000000004005ae : mov %edi,-0x44(%rbp)

0x00000000004005b1 : mov %esi,-0x48(%rbp)

0x00000000004005b4 : mov %edx,-0x4c(%rbp)

0x00000000004005b7 : mov %fs:0x28,%rax ------> obtaining an 8 byte guard from based on a fixed offset from fs segment register [from the descriptor base in the corresponding gdt entry]

0x00000000004005c0 : mov %rax,-0x8(%rbp) -----> pushing it as the first local variable on to stack

0x00000000004005c4 : xor %eax,%eax

0x00000000004005c6 : movl $0x33323130,-0x20(%rbp)

0x00000000004005cd : movl $0x37363534,-0x1c(%rbp)

0x00000000004005d4 : movl $0x42413938,-0x18(%rbp)

0x00000000004005db : movl $0x46454443,-0x14(%rbp)

...

...

// function end

0x0000000000400686 : jns 0x40066a

0x0000000000400688 : mov -0x8(%rbp),%rax -------> verifying if the stack was smashed

0x000000000040068c : xor %fs:0x28,%rax --> checking the value on stack is matching the original one based on fs

0x0000000000400695 : je 0x40069c

0x0000000000400697 : callq 0x400460 <__stack_chk_fail>

0x000000000040069c : leaveq

0x000000000040069d : retq

现在,如果我们从此函数中删除基于堆栈的char数组,gcc将不会生成此警卫检查。

我已经看到了gcc甚至为内核模块生成的内容。基本上我在看到一些内核代码崩溃时发生了崩溃,并且虚拟地址为0x28。后来我认为我已经正确初始化了堆栈指针并正确加载了程序,我没有在gdt中使用正确的条目,这会将基于fs的偏移转换为有效的虚拟地址。

但是在内核代码的情况下,它只是忽略了错误而不是像__stack_chk_fail @ plt>那样跳转。

在gcc中添加此保护的相关编译器选项是-fstack-protector。我认为这是默认启用的,它编译用户应用程序。

对于内核,我们可以通过config CC_STACKPROTECTOR选项启用此gcc标志。

配置CC_STACKPROTECTOR

699 bool“启用-fstack-protector buffer overflow detection(EXPERIMENTAL)”

700取决于SUPERH32

701帮助

702此选项打开-fstack-protector GCC功能。这个

703功能在函数的开头放置一个金丝雀值

704返回地址之前的堆栈,并验证

705实际返回前的值。基于堆栈的缓冲区

706现在也溢出(需要覆盖此返回地址)

707覆盖了金丝雀,后者被检测到,然后是攻击

708通过内核恐慌中和。

709

710此功能需要gcc 4.2或更高版本。

相关的内核文件,其中gs / fs是linux / arch / x86 / include / asm / stackprotector.h

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值