调用glibc的时候x86-64的ELF初始堆栈布局 [英] x86-64 ELF initial stack layout when calling glibc
问题描述
基本上,我通过 http://www.nasm.us/links/unix64abi部分阅读一>,并在第29页,它显示了一个C程序的初始进程堆栈。
我的问题是:我试图从X86-64 NASM用glibc接口,并根据上面显示,ARGC应该在RSP什么。所以下面code应打印ARGC:
[段.data]
PrintStr:DB你刚刚踏入%d个参数。,10,0[.bss段][.text段]
EXTERN的printf
全球主要主要:
MOV RAX,0;需要采取的变量没有的功能。 args来
MOV RDI,PrintStr
RSI MOV [RSP]
调用printf
RET
但事实并非如此。有人可以告诉我,如果我在code犯任何错误或告诉我实际的堆栈结构是什么?
谢谢!
更新:我只是随意尝试了一些偏移和改变MOV RSI,[RSP]到MOV RSI,[RSP + 28]的伎俩
但是,这意味着,所示的堆结构体是错误的。有谁知道初始堆栈布局是一个小精灵x86-64的? http://asm.sourceforge.net/articles/startup.html 的等效会是非常好的。
更新2:
我离开了我如何建立这个code。我通过做:
NASM -f ELF64 -g<&名GT;
GCC<&名GT;的.o -o<&OUTPUTFILE GT;
初始堆栈布局包含 ARGC
堆栈指针,随后的阵列 的char * argv的[]
,而不是一个指针,它像主
接收。因此,打电话给主,你需要做的是这样的:
弹出%RDI
MOV%RSP,RSI%
调用主
在现实中通常调用主
,而不是启动code直接这样做。
如果你想简单地打印的argv [0]
,你可以这样做:
弹出%RDI
流行%RDI
电话看跌期权
XOR%EDI,EDI%
JMP出口
Basically, I read through parts of http://www.nasm.us/links/unix64abi and at page 29, it shows the initial process stack of a C program.
My question is: I'm trying to interface with glibc from x86-64 nasm and based on what the above shows, argc should be at rsp. So the following code should print 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
But it doesn't. Can someone enlighten me if I have made any mistakes in my code or tell me what the actual stack structure is?
Thanks!
UPDATE: I just randomly tried some offsets and changing the "mov rsi, [rsp]" to "mov rsi, [rsp+28]" did the trick.
But this means that the stack structure shown is wrong. Does anyone know what the initial stack layout is for an x86-64 elf? An equivalent of http://asm.sourceforge.net/articles/startup.html would be really nice.
UPDATE 2: I left out how I build this code. I do it by:
nasm -f elf64 -g <filename>
gcc <filename>.o -o <outputfile>
The initial stack layout contains argc
at the stack pointer, followed by the array char *argv[]
, not a pointer to it like main
receives. Therefore, to call main, you need to do something like:
pop %rdi
mov %rsp,%rsi
call main
In reality there is usually a wrapper function that calls main
, rather than the startup code doing it directly.
If you want to simply print argv[0]
, you could do something like:
pop %rdi
pop %rdi
call puts
xor %edi,%edi
jmp exit
这篇关于调用glibc的时候x86-64的ELF初始堆栈布局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!