栈保护者Canary的实现细节

1.示例copy函数 在这里插入图片描述
汇编代码:
在这里插入图片描述
失去栈保护的汇编代码:
在这里插入图片描述
比对发现,在有栈保护的汇编代码中增加了一些指令,其中:

mov %gs:0x14,%eax
mov %eax,-0xc(ebp)

两句指令,是向栈中插入一个canary值。使用栈保护的copy函数栈是这样的:

canary的值是随机生成的,在内存中保存有两份:
①一个是保存在特殊的段内,这个段被标示为只读,不可修改。
②另一个在栈内,可修改。
③如果缓冲区溢出,canary在栈中的值被修改,系统比对两处的值发现不一样,就会调用一个错误处理例程。

另外,发现形式参数s在被调用者栈内多了一份拷贝
博主zq301在文章GCC编译器局部变量地址分配为什么总是从低地址向高地址增加?中提到:
SSP有意将局部变量中的数组放在函数栈的高地址,而将其他变量放在低地址。这样就使得通过溢出一个数组来修改其他变量(比如一个函数指针)变得更为困难。

在这里插入图片描述
2.canary实现
①gcc编译时选择canary的插入位置,生成含有canary的汇编代码。
②glibc产生实际的canary值,以及提供错误捕捉函数和报错函数。
因此canary是运行时动态产生的,不能通过查看静态的bianry得到。

也就是说gcc只是声明和使用了_ stack chk guard/_ stack_ chk_ fail,并没有定义定义是在glibc里.
stack_ chk_ guard_ stack_ chk_fail 的插入是在gcc将GIMPLE转换为RTL的pass里分别通过函数default__stack_ protect_guard()ix86_ stack_ protect _fail() 构建手动的tree,然后调用 expand_ normal() 自动转换为RTL再插入待分析的用户代码来进行的.

canary的值的流向
①kernel初始化了跟TLS相关的寄存器gs,并且提供了canary这个随机值。
②glibc写入%gs:0x14这个保存随机值的位置并且提供变定义和打印函数定义。
③gcc插入对canary的值的引用和出错函数到用户代码里。
详细细节见参考文章:最初九月雪《canary分析》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hnu哈哈

请接受直女的么么哒????

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值