Pregunta

¿Cómo uso el abordaje relativo de RIP en un programa de ensamblaje de Linux para la arquitectura AMD64? Estoy buscando un ejemplo simple (un programa de Hello World) que utiliza el modo de dirección relativa de AMD64 RIP.

Por ejemplo, el siguiente programa de ensamblaje de 64 bits funcionaría con normal (direccionamiento absoluto):

.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"

Estoy adivinando que el mismo programa que usa el direccionamiento relativo de RIP sería algo así como:

.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 versión normal se ejecuta bien cuando se compila con:

as -o hello.o hello.s && ld -s -o hello hello.o && ./hello

Pero no puedo hacer que la versión de RIP funcione.

¿Alguna idea?

--- Editar ----

La respuesta de Stephen Canon hace que la versión de RIP funcione.

Ahora, cuando desmontaré el ejecutable de la versión de RIP, obtengo:

objdump -d hola

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)

que muestra lo que estaba tratando de lograr: LEA 0x10 (% RIP),% RSI carga la dirección 17 Bytes después de la instrucción de LEA que es la dirección 0x400096, donde se puede encontrar la cadena de Hello World y, por lo tanto, lo que resulta en un código independiente de la posición.

¿Fue útil?

Solución

Creo que desea cargar la dirección de su cadena en %rsi;Su código intenta cargar un quadword de esa dirección en lugar de la dirección en sí.Quieres:

lea msg(%rip), %rsi

Si no me equivoco.Sin embargo, no tengo una caja de Linux para probar.

Otros consejos

Dado que necesita la dirección de msg en% rsi, simplemente reemplace:

mov msg(%rip),%rsi

con:

lea msg(%rip),%rsi

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top