bill marko
bill marko

Reputation: 1

Read strings with ptrace (linux)

I'm new to stack and relatively new to C. I try to read a process memory from another process with the use of ptrace. So far I managed to read and alter numbers from another process . But with strings I could not find a way. Here is my code:

int errno;
//the string we want to read is 8 bytes long
long len = 8;
const int buflen = (len / sizeof(long)) + 1;
void *buffer;
long *base;
char *data;
int i;
//the process pid i want to track
pid_t pid = 2984;
//the address that the string we want to read resides 
void *addr = (unsigned long int*) 0x7ffe03f6e088 ;

buffer = calloc(buflen, sizeof(long));
if (NULL == buffer)
{
    perror("Fault at allocation: ");    
}

base = (long *) buffer; 

ptrace(PTRACE_ATTACH, pid, NULL, NULL);

for (i = 0; i < buflen; i++) {
    if(ptrace(PTRACE_PEEKDATA, pid , addr + (sizeof(long) * i),NULL) !=  -1)
    {
    *(base + i) = ptrace(PTRACE_PEEKDATA, pid , addr + (sizeof(long) * i),
                     NULL);
    }else
    {
        fprintf(stderr, "Value of errno: %s\n", strerror(errno));
    }
}

ptrace(PTRACE_DETACH, pid, NULL, NULL);

/* Pop a null at the end, since we're printing this string. */
*((char *) buffer + len) = '\0';

data = (char *)buffer;  

printf("%p[\"%s\"]\n",addr, data);
free(buffer);

And the output:

Value of errno: No such process
Value of errno: No such process
0x7ffe03f6e088[""]

However the process id is correct and similar code works when the addr points to a number. Please help me.

[EDIT]
Bellow is the tracee process code:

char *a = "lala";
pid_t child;
printf("Char length: %ld\n", strlen(a));
printf("Char value: %s\n", a);
//the address I use to read variable
printf("Char address: %p\n", &a);
//make the process sleep so I can halt it manually
sleep(3);

Upvotes: 0

Views: 1973

Answers (2)

mlchen
mlchen

Reputation: 1

man pages says:

PTRACE_ATTACH Attach to the process specified in pid, making it a tracee of the calling process. The tracee is sent a SIGSTOP, but will not necessarily have stopped by the completion of this call; use waitpid(2) to wait for the tracee to stop. See the "Attaching and detaching" subsection for additional information. (addr and data are ignored.)

just append a wait() function to wait child enter stopped status.

Upvotes: 0

Armali
Armali

Reputation: 19375

Your tracee process is printing the address of the char* pointer itself, not the address of the beginning of the character string.

Here are two choices: (1) have the tracee print printf("Char address: %p\n", a); and run your tracer code as-is (2) leave the tracee code as-is and modify your tracer process so it reads in sizeof(char *) bytes from the target, stores that result (after appropriate numeric shifts if you needed to use several ptrace requests to read it all in) in addr, then continue as-is.

– Mark Plotnick

Upvotes: 1

Related Questions