Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/user.h>
#include <sys/syscall.h>
#include <asm/ptrace-abi.h>
void
getdata (pid_t child, long addr, char * str, int len)
{
char * laddr;
int i, j;
int long_size = sizeof (long);
union
{
long val;
char chars[long_size];
} u;
for (i=0, j = len / long_size, laddr = str; i < j; i++, laddr += long_size)
{
u.val = ptrace (PTRACE_PEEKDATA, child, addr + i * 4, NULL);
memcpy (laddr, u.chars, long_size);
}
j = len % long_size;
if (j != 0)
{
u.val = ptrace (PTRACE_PEEKDATA, child, addr + i * 4, NULL);
memcpy (laddr, u.chars, j);
}
str[len] = '\0';
}
int
main (int argc, char * argv[])
{
pid_t child = atoi (argv[1]);
long orig_eax;
long params[3];
int status;
char *str, *laddr;
int toggle = 0;
ptrace (PTRACE_ATTACH, child, NULL, NULL);
while (1)
{
orig_eax = ptrace (PTRACE_PEEKUSER, child, 4 * ORIG_EAX, NULL);
if(orig_eax == SYS_read)
{
if (toggle == 0)
{
toggle = 1;
params[0] = ptrace (PTRACE_PEEKUSER, child, 4 * EBX, NULL);
params[1] = ptrace (PTRACE_PEEKUSER, child, 4 * ECX, NULL);
params[2] = ptrace (PTRACE_PEEKUSER, child, 4 * EDX, NULL);
str = (char *) malloc ((params[2]+1)* sizeof(char));
memset (str, 0x0, (params[2]+1) * sizeof (char));
getdata(child, params[1], str, params[2]);
/*
* handle your string here
*/
printf ("%s\n", str);
free (str);
}
else
{
toggle = 0;
}
}
ptrace(PTRACE_SYSCALL, child, NULL, NULL);
}
exit (0);
}