Comment utiliser l'adressage relatif RIP dans un programme assembleur 64 bits ?
-
15-09-2020 - |
Question
Comment utiliser l'adressage relatif RIP dans un programme d'assemblage Linux pour l'architecture AMD64 ?Je recherche un exemple simple (un programme Hello world) qui utilise le mode d'adressage relatif AMD64 RIP.
Par exemple, le programme assembleur 64 bits suivant fonctionnerait avec un adressage normal (absolu) :
.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"
Je suppose que le même programme utilisant RIP Relative Addressing ressemblerait à quelque chose comme :
.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 version normale fonctionne correctement lorsqu'elle est compilée avec :
as -o hello.o hello.s && ld -s -o hello hello.o && ./hello
Mais je n'arrive pas à faire fonctionner la version RIP.
Des idées?
--- modifier ----
La réponse de Stephen Canon fait fonctionner la version RIP.
Maintenant, lorsque je démonte l'exécutable de la version RIP, j'obtiens :
objdump -d bonjour
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)
Ce qui montre ce que j'essayais d'accomplir :lea 0x10(%rip),%rsi charge l'adresse 17 octets après l'instruction lea qui est l'adresse 0x400096 où la chaîne Hello world peut être trouvée et aboutissant ainsi à un code indépendant de la position.
La solution
Je crois que vous voulez charger le adresse de votre chaîne dans %rsi
;votre code tente de charger un quadword à partir de cette adresse plutôt que de l'adresse elle-même.Tu veux:
lea msg(%rip), %rsi
si je ne me trompe pas.Cependant, je n'ai pas de machine Linux sur laquelle tester.
Autres conseils
Depuis que vous avez besoin de l'adresse
mov msg(%rip),%rsi
avec:
lea msg(%rip),%rsi