二进制安全之——栈相关漏洞

本文详细探讨了栈的运作机制,包括栈的简介、函数调用和参数传递,重点分析了栈溢出的概念和影响,如数据不可执行(NX/DEP)、栈保护哨(Canary)以及控制流劫持。此外,还介绍了栈的特殊利用技巧,如通过libc信息泄露、多级指针和环境变量修改等。
摘要由CSDN通过智能技术生成

目录

一、栈

1.栈的简介

2.函数栈的调用机制

3.函数参数传递

(1)调用协议的常用场合

(2)函数参数的入栈方式

(3)栈平衡修复方式

(4)对于x86程序

普通函数传参

syscall传参

(5)对于x64程序

普通函数传参

syscall传参

(6)对于ARM程序

二、栈溢出

1.介绍

(1)局部变量

(2)bp

(3)ip

2.覆盖栈缓冲区的具体作用

(1)数据不可执行(NX/DEP)

(2)栈保护哨(canary)

(3)劫持控制流

(3)覆盖栈中的临时变量

(4)覆盖栈底寄存器bp

(5)敏感函数

、栈的特殊利用

1.libc信息泄露

2.多级指针:path指针

3.环境变量修改

4.通过libc泄露栈地址

5.栈上写rop的技巧


一、栈

1.栈的简介

栈主要是用于存储程序运行过程中的局部信息,大小不一,动态增长。栈的内存一般根据函数栈来进行划分(不用函数的程序很少见),不同的函数栈之间是互相隔离的,从而能实现函数的有效切换。函数栈上存储的信息一般包括:临时变量(包括栈保护哨carry)、函数栈的返回栈基址(bp)、函数的返回地址(ip)。

程序栈

2.函数栈的调用机制

程序运行时,为了实现函数之间的互相隔离,需要在进入新函数之前保存当前函数的状态,而这些状态信息全在栈上,为了实现状态的隔离,由此引出函数栈的概念,当前函数栈的边界就是栈顶指针(sp)和栈底指针(bp)所知的区域所指的区域。sp主要指的是esp(x86)和rsp(x64),bp主要指ebp(x86)和rbp(x64)

在函数调用(即进入子函数时)时,首先将参数入栈,然后压入返回地址和栈底指针寄存器bp(也有不压bp的情况),其中压入返回地址是通过call实现的。

在函数结束时,将sp重新指向bp的位置,并弹出bp(与前面是否压入bp保持一致)和返回地址ip,通常,弹出bp是通过leave或者pop bp(pop rbp或者pop ebp)来实现。

 x86程序参数传递实例

x64程序参数传递实例

修改bp寄存器,然后执行ret,函数状态将恢复成进入子函数时的状态,实现了函数栈的切换。

在函数栈中,bp中存储上个函数栈的基址,而ip存储的是调用处的下一条指令位置,返回当前函数,会从栈上弹出这两个值,从而恢复上一个函数的信息。

3.函数参数传递

由于函数的传参规则受函数调用协议的影响,首先介绍函数调用的协议,_stdcall、_cdecl、_fastcall是三种函数调用,函数调用协议会影响函数参数的入栈方式、栈平衡的修复方式、编译器函数名的修饰规则。

(1)调用协议的常用场合

_stcall:windows API默认的函数调用协议

_cdecl:C/C++默认的函数调用协议

_fastcall:适用于对性能要求较高的场景

(2)函数参数的入栈方式

_stcall:函数参数从左向右入栈

_cdecl:函数参数从右向左入栈

_fastcall:从左开始将小于4字节的参数放入CPU的ecx和edx寄存器,其余参数从右往左入栈

(3)栈平衡修复方式

_stcall:函数调用结束后由被调用函数来平衡栈

_cdecl:函数调用结束后函数调用者来平衡栈

_fastcall:函数调用结束后由被调用函数来平衡栈

对于linux来说,通常采用_cdecl的调用方式

(4)对于x86程序

普通函数传参

参数基本压在栈上(有寄存器传参的情况)

syscall传参

eax对应系统调用号,ebx,ecx,edx,esi,edi,ebp分别对应前6个参数。多余的参数压在栈上。

(5)对于x64程序

普通函数传参

先使用rdi,rsi,rdx,rex,r8,r9寄存器作为函数参数的前六个参数,多余的参数会依次压在站上。

syscall传参

rax对应系统调用号,传参规则与普通函数传参一致。

(6)对于ARM程序

R0,R1,R2,R3,依次对应前四个参数,多余的参数会依次压在栈上。

普通函数传参如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

「已注销」

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值