Using RIP Relative Addressing in an OSX x64 Assembly

I tried to make a basic printf example in x86-64 build code for OSX, here is my first version:

 section .data msg db 'hello', 0Ah section .text extern _printf global _main _main: sub rsp, 8 mov rdi, msg mov rax, 0 call _printf add rsp, 8 ret 

So this code moves the absolute msg address to rdi for the first argument _printf , and gcc then complains about the lack of position-independent code. The binary file still works:

 β†’ nasm -f macho64 new.asm && gcc -m64 -o new new.o && ./new ld: warning: PIE disabled. Absolute addressing (perhaps -mdynamic-no-pic) not allowed in code signed PIE, but used in _main from new.o. To fix this warning, don't compile with -mdynamic-no-pic or link with -Wl,-no_pie hello 

Therefore, when I change the code to use RIP-relative addressing using the [rel ...] nasm syntax, the warning disappears, but the executable now performs the following errors:

 section .data msg db 'hello', 0Ah section .text extern _printf global _main _main: sub rsp, 8 mov rdi, [rel msg] mov rax, 0 call _printf add rsp, 8 ret 

And when I compile and run it:

 β†’ nasm -f macho64 new.asm && gcc -m64 -o new new.o && ./new zsh: segmentation fault ./new 

Does anyone know what is going wrong?

+4
source share
1 answer

The problem is that the original mov rdi, msg loaded the msg memory address into rdi during build.

When it was changed to mov rdi, [rel msg] , it created code that used the value in msg as a relative address, as seen in debugging:

 Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_INVALID_ADDRESS at address: 0x00000a6f6c6c6568 

Note that the address contains bytes from msg , 0x00000a<olleh> .

The correct solution is to use the lea command to load the effective RIP relative msg address at runtime, for example:

 lea rdi, [rel msg] 
+5
source

Source: https://habr.com/ru/post/1433231/


All Articles