2012-06-19 17 views
5

stavo attraversando un articolo here e stava cercando il frammento di codice che ho copiato qui di seguito: -(ORIG_EAX * 4) in ptrace chiama

#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; 
} 

ho un dubbio riguardo a ciò che ORIG_EAX è esattamente e perché 4*ORIG_EAX viene passato alla chiamata ptrace. Inizialmente pensavo che ORIG_EAX, EBX, ECX ecc. Sarebbero gli offset in una particolare struttura in cui i valori dei registri sarebbero stati memorizzati.

Quindi ho deciso di stampare il valore di ORIG_EAX subito dopo l'attesa utilizzando printf("origeax = %ld\n", ORIG_EAX);. Il valore era 11. Quindi, la mia precedente ipotesi riguardo gli offset era sbagliata.

Capisco che la chiamata wait viene terminata quando il bambino ha una modifica di stato (in questo caso, emette una chiamata di sistema) e che ORIG_EAX conterrà il numero di chiamata di sistema.

Tuttavia, perché ORIG_EAX * 4 è passato alla chiamata ptrace?

risposta

8

Il parametro è un offset in user_regs_struct. Si noti che ognuno di questi è uno unsigned long, quindi per ottenere l'undicesima voce (orig_eax) l'offset in byte è 44, (a condizione che si sia su una macchina x86, ovviamente).

+1

E i dfferenze tra 32 e 64 bit? Non dovremmo compilare-time-case su questo? –

+0

Inoltre ..., è solo questo ptrace x86? Se no, abbiamo bisogno di un modo più generale e indipendente dal target per farlo! –

+0

Esiste sicuramente una definizione per un AMD64 'user_regs_struct', ma non sono sicuro che sia possibile combinare le architetture. IIRC i commenti nel 'ptrace' menzionavano le intestazioni separate erano un problema. Dato che 'ptrace' è un syscall, dovrebbe funzionare (potresti dover cambiare manualmente gli offset per ogni architettura) ma non posso dire di averlo mai provato. –