2012-06-19 16 views
5

yo estaba pasando por un artículo here y estaba tratando a cabo el fragmento de código que he copiado a continuación: -(ORIG_EAX * 4) en ptrace llama

#include <sys/ptrace.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <unistd.h> 
#include <linux/user.h> /* For constants 
            ORIG_EAX etc */ 
int main() 
{ pid_t child; 
    long orig_eax; 
    child = fork(); 
    if(child == 0) { 
     ptrace(PTRACE_TRACEME, 0, NULL, NULL); 
     execl("/bin/ls", "ls", NULL); 
    } 
    else { 
     wait(NULL); 
     orig_eax = ptrace(PTRACE_PEEKUSER, 
          child, 4 * ORIG_EAX, 
          NULL); 
     printf("The child made a " 
       "system call %ld\n", orig_eax); 
     ptrace(PTRACE_CONT, child, NULL, NULL); 
    } 
    return 0; 
} 

Tengo una duda con respecto a lo ORIG_EAX es exactamente y por qué 4*ORIG_EAX se pasa a la llamada ptrace. Inicialmente asumí que ORIG_EAX, EBX, ECX etc. serían los desplazamientos en una estructura particular donde se almacenarían los valores de los registros.

Así que decidí imprimir el valor de ORIG_EAX justo después de la espera usando printf("origeax = %ld\n", ORIG_EAX);. El valor fue 11. Entonces, mi suposición anterior con respecto a las compensaciones era incorrecta.

Entiendo que la llamada wait finaliza cuando el niño tiene un cambio de estado (en este caso, emite una llamada al sistema) y que ORIG_EAX contendría el número de llamada del sistema.

Sin embargo, ¿por qué ORIG_EAX * 4 pasa a la llamada ptrace?

Respuesta

8

El parámetro es un desplazamiento en user_regs_struct. Tenga en cuenta que cada uno de estos es un unsigned long, por lo que para obtener la entrada número 11 (orig_eax) el desplazamiento en bytes es 44, (siempre que esté en una máquina x86, por supuesto).

+1

¿Qué pasa con las diferencias de 32 y 64 bits? ¿No deberíamos compilar-time-case en eso? –

+0

Además ..., ¿es este ptrace x86 solamente? Si no, necesitamos una forma más general e independiente de objetivos para hacerlo. –

+0

Definitivamente hay una definición para AMD64 'user_regs_struct', pero no estoy seguro si puedes mezclar y combinar arquitecturas. IIRC los comentarios en 'ptrace' mencionaron que los encabezados separados eran un problema. Como 'ptrace' es un syscall, debería funcionar (es posible que deba cambiar las compensaciones para cada arquitectura manualmente) pero no puedo decir que lo haya intentado alguna vez. –