top - ver procesos corriendo en linux
LĂnea de comando de proceso en Linux 64 bit (2)
Esta pregunta ya tiene una respuesta aquí:
Tengo problemas para acceder a la línea de comandos del proceso desde el programa de ensamblaje Linux de 64 bits. Para reproducir esto con un código mínimo, hice este programa de 32 bits que imprime los primeros 5 caracteres del nombre del programa:
.section .text .globl _start _start: movl %esp, %ebp movl $4, %eax # write movl $1, %ebx # stdout movl 4(%ebp), %ecx # program name address (argv[0]) movl $5, %edx # hard-coded length int $0x80 movl $1, %eax movl $0, %ebx int $0x80
Este programa está funcionando. Cuando lo traduzco a 64 bits y lo ejecuto en Linux 64, no imprime nada:
.section .text .globl _start _start: movq %rsp, %rbp movq $4, %rax movq $1, %rbx movq 8(%rbp), %rcx # program name address ? movq $5, %rdx int $0x80 movq $1, %rax movq $0, %rbx int $0x80
¿Dónde está mi error?
Como se indica en X86_64 ABI : Use la instrucción syscall
lugar de int $0x80
. El Kernel usa diferentes registros en 64 Bit como argumentos de syscall, y el número asignado para una función syscall también varía entre i386 y x86_64.
Un ejemplo - en alemán, lo siento - se puede encontrar aquí:
http://zygentoma.de/codez/linux_assembler.php
Está cargando la dirección correcta en %rcx
.
int 0x80
luego invoca la interfaz syscall de 32 bits. Eso trunca la dirección a 32 bits, lo que la hace incorrecta. (Si usa un depurador y establece un punto de interrupción justo después de la primera int 0x80
, verá que regresa con -14 en %eax
, que es -EFAULT
).
El segundo syscall, exit
, funciona bien porque el truncamiento a 32 bits no hace ningún daño en ese caso.
Si desea pasar una dirección de 64 bits a una llamada al sistema, deberá usar la interfaz syscall de 64 bits:
- use
syscall
, noint 0x80
; - se usan diferentes registros: ver aquí ;
- los números de llamada del sistema también son diferentes: mira aquí .
Aquí hay una versión de trabajo de su código:
.section .text
.globl _start
_start:
movq %rsp, %rbp
movq $1, %rax
movq $1, %rdi
movq 8(%rbp), %rsi # program name address ?
movq $5, %rdx
syscall
movq $60, %rax
movq $0, %rdi
syscall