Come utilizzare RIP relativo Indirizzamento in un programma di assembly a 64 bit?
-
15-09-2020 - |
Domanda
Come posso utilizzare Rip relativo indirizzamento in un programma di assembly Linux per l'architettura AMD64? Sto cercando un semplice esempio (un programma Hello World) che utilizza la modalità di indirizzo relativa AMD64 RIP relativa.
Ad esempio, il seguente programma di assembly a 64 bit funzionerà con normale (indirizzamento assoluto):
.text
.global _start
_start:
mov $0xd, %rdx
mov $msg, %rsi
pushq $0x1
pop %rax
mov %rax, %rdi
syscall
xor %rdi, %rdi
pushq $0x3c
pop %rax
syscall
.data
msg:
.ascii "Hello world!\n"
.
Indovina che lo stesso programma usando la rivolta relativa di RIP sarebbe qualcosa come:
.text
.global _start
_start:
mov $0xd, %rdx
mov msg(%rip), %rsi
pushq $0x1
pop %rax
mov %rax, %rdi
syscall
xor %rdi, %rdi
pushq $0x3c
pop %rax
syscall
msg:
.ascii "Hello world!\n"
.
La versione normale funziona bene se compilata con:
as -o hello.o hello.s && ld -s -o hello hello.o && ./hello
.
Ma non riesco a far funzionare la versione RIP.
Qualche idea?
--- Modifica ----
La risposta di Stephen Canon rende il funzionamento della versione RIP.
Ora quando smontare l'eseguibile della versione RIP ottengo:
objdump -d hello
0000000000400078 <.text>:
400078: 48 c7 c2 0d 00 00 00 mov $0xd,%rdx
40007f: 48 8d 35 10 00 00 00 lea 0x10(%rip),%rsi # 0x400096
400086: 6a 01 pushq $0x1
400088: 58 pop %rax
400089: 48 89 c7 mov %rax,%rdi
40008c: 0f 05 syscall
40008e: 48 31 ff xor %rdi,%rdi
400091: 6a 3c pushq $0x3c
400093: 58 pop %rax
400094: 0f 05 syscall
400096: 48 rex.W
400097: 65 gs
400098: 6c insb (%dx),%es:(%rdi)
400099: 6c insb (%dx),%es:(%rdi)
40009a: 6f outsl %ds:(%rsi),(%dx)
40009b: 20 77 6f and %dh,0x6f(%rdi)
40009e: 72 6c jb 0x40010c
4000a0: 64 21 0a and %ecx,%fs:(%rdx)
.
che mostra quello che stavo cercando di realizzare: Lea 0x10 (% RIP),% RSI carica l'indirizzo 17 Byte dopo l'istruzione Lea che è l'indirizzo 0x400096 in cui è possibile trovare la stringa del mondo ciao e quindi con conseguente posizione di posizione.
Soluzione
credo che tu voglia caricare l'indirizzo della stringa in %rsi
;Il tuo codice tenta di caricare un quadword da quell'indirizzo piuttosto che l'indirizzo stesso.Vuoi:
lea msg(%rip), %rsi
.
Se non sono sbagliato.Non ho una scatola Linux da testare, comunque.
Altri suggerimenti
Dal momento che è necessario l'indirizzo di MSG in% RSI, basta sostituire:
mov msg(%rip),%rsi
.
Con:
lea msg(%rip),%rsi
.