【问题标题】:x86-64 ELF initial stack layout when calling glibc调用 glibc 时的 x86-64 ELF 初始堆栈布局
【发布时间】:2011-08-16 01:36:53
【问题描述】:

基本上,我通读了http://www.nasm.us/links/unix64abi 的部分内容,在第 29 页,它显示了 C 程序的初始进程堆栈。

我的问题是:我正在尝试从 x86-64 nasm 与 glibc 交互,根据上面显示的内容,argc 应该位于 rsp。所以下面的代码应该打印 argc:

[SECTION .data]
PrintStr: db "You just entered %d arguments.", 10, 0

[SECTION .bss]

[SECTION .text]
extern printf
global main

main:
     mov rax, 0        ; Required for functions taking in variable no. of args
     mov rdi, PrintStr
     mov rsi, [rsp]
     call printf
     ret

但事实并非如此。如果我在代码中犯了任何错误或告诉我实际的堆栈结构是什么,有人可以启发我吗?

谢谢!

更新:我只是随机尝试了一些偏移量并将“mov rsi, [rsp]”更改为“mov rsi, [rsp+28]”就可以了。

但这意味着显示的堆栈结构是错误的。有谁知道 x86-64 精灵的初始堆栈布局是什么?相当于http://asm.sourceforge.net/articles/startup.html 会非常好。

更新 2: 我省略了如何构建此代码。我这样做:

nasm -f elf64 -g <filename>
gcc <filename>.o -o <outputfile>

【问题讨论】:

    标签: c assembly x86-64 nasm glibc


    【解决方案1】:

    初始堆栈布局在堆栈指针处包含argc,然后是数组 char *argv[],而不是像main 接收的指向它的指针。因此,要调用 main,您需要执行以下操作:

    pop %rdi
    mov %rsp,%rsi
    call main
    

    实际上通常有一个包装函数调用main,而不是启动代码直接调用。

    如果您只想打印argv[0],您可以执行以下操作:

    pop %rdi
    pop %rdi
    call puts
    xor %edi,%edi
    jmp exit
    

    【讨论】:

    • 您好,感谢您的回复。澄清一下,我不是用主函数调用 C 程序,而只是使用 C 库函数。我更新了问题中代码的构建方式。我尝试让另一个全局标签调用主标签,但在链接阶段失败了(gcc 用于链接代码)。在这种情况下,显然 main 必须是一个全局标签。
    • 如果你打算使用 libc 函数,你应该知道绕过 libc 启动代码可能会导致它们崩溃。例如,glibc 可能想要初始化 %gs 线程本地存储选择器,即使没有使用线程,使用它进行 sysenter-type 系统调用并在那里存储其他随机垃圾。您应该在 asm 中创建一个全局 main 并让 libc 启动代码调用它,或者完全省略 libc 并在 asm 中执行所有系统调用。
    • 嗨,我是在绕过 libc 启动代码吗?我正在关注 Jeff Duntemann 的“Assembly Language Step by Step”如何从 nasm 调用 C 代码。如果我这样做,您能否为我提供如何不绕过 libc 启动代码的示例?谢谢!
    • 哦,我是个傻瓜。不知何故,我以为你写了一个_start 入口点,因为这是大多数人执行纯 asm 程序的方式。如果您使用了main,那么堆栈将不包含任何有意义的内容,并且参数将是rdi 中的argcrsi 中的argvchar ** 类型)。
    • 另请注意,_startmain 在 i386 上也完全不同。 _start 得到argc 后跟堆栈上字符串指针的array,而main 得到argc 后跟argv(指向字符串指针数组的指针),也后跟一个(通常未使用且非标准的)指向环境变量字符串指针数组的指针。
    猜你喜欢
    • 2017-09-24
    • 1970-01-01
    • 2018-09-07
    • 1970-01-01
    • 2022-01-27
    • 2021-12-05
    • 2015-02-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多