x86-64 ELF initial stack layout when calling glibc

2019-08-15 06:16发布

问题:

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>

回答1:

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