V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
SmaliYu
V2EX  ›  Linux

在 ARM64 的 Linux 内核下,使用比 sp 指针小的内存空间存储变量是否可行

  •  
  •   SmaliYu · 74 天前 · 1434 次点击
    这是一个创建于 74 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在阅读 ptrace 相关代码时,看到为了修改 openat 系统调用的 path 参数,在小于 sp 指针(或者叫高于栈顶位置)保存了新的 path 路径,然后将传递参数的寄存器指向了这个新的 path ,这样做为什么是没有问题的?一般文档上说,sp 指向栈顶,那么如果变量使用了没有被 sp 涵盖的内存空间(字符数组指向了小于 sp 指针的位置),这不会报错吗?

    4 条回复    2024-09-03 00:58:44 +08:00
    moudy
        1
    moudy  
       73 天前
    sp 指向栈顶是个“约定”,你疑惑的出错是 stack overflow 。出这种问题时,是不是按约定使用 sp 已经不重要了
    zizon
        2
    zizon  
       73 天前
    sp 主要是为了支持函数参数调用机制吧,让 cpu call 的时候到了对应 function/routine 能找到 args.
    自己管理或者像 go 之类的有特殊目的的,可以不依赖.

    只要 stack 所在的内存还是可写的在指令级别都是允许的.

    不然也不会有各种 0day 和 address sanitize 的存在.
    s9ar
        3
    s9ar  
       73 天前
    几个例子:
    1. 考虑如下调用链,a() -> b() -> c(),其中 a 函数声明了一个局部变量 aVar ,c 函数即将声明另一个局部变量 cVar 。ARM64 的 ABI 我不是很清楚,不过无论栈往哪个方向增长,在 b 函数中读写 aVar ,以及即将属于 cVar 的地址当然都是允许的,只要语义上没有差错。地址空间中属于栈的那部分是由 OS 事先分配好的,不会另作他用;程序可以自行决定其中内容的含义。当然如果写歪了,把返回地址、canary 或者其他有用结构覆盖了,程序就会产生各种错误。
    2. 如果整个地址空间都属于某个控制流,且读、写、执行权限全部开放,那么想怎样写就怎样写,sp 只是一种随意的标记。(这一般是裸机 / 内核态才有的特权)
    3. 错误地、有意地、被恶意用户夺取控制流等,读写到了不属于自己的内存区域,就可能引起段错误,或引起其他神奇现象。可以了解下 RCE 、ROP 等等有趣的小玩意
    s9ar
        4
    s9ar  
       73 天前
    补充下,我想说明的是:在汇编层面各寄存器、内存地址、内存中的内容只是遵循约定以及汇编语义存在,所以想看清某种读写模式是否正确,需要看的就只是 ABI 、内存段的权限、控制流的语义。有些约定可能会因为编译优化、人为魔改等因素被临时破坏。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1192 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 23:05 · PVG 07:05 · LAX 15:05 · JFK 18:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.