-1

Here, I explain my problem, I am a beginner on the ptrace function and I would like to succeed in recovering the hard information of a structure. For example with this command, I will have strace -e trace = fstat ls a line: fstat (3, {st_mode = ..., st_size = ...} and I would like to successfully retrieve the contents of the structure (st_mode) and (st_size). I try this but to no avail:

int buffer(unsigned long long addr, pid_t child, size_t size, void *buffer)
{
    size_t byte = 0;
    size_t data;
    unsigned long tmp;

    while (byte < size) {
        tmp = ptrace(PTRACE_PEEKDATA, child, addr + byte);
        if ((size - byte) / sizeof(tmp))
            data = sizeof(tmp);
        else
          data = size % sizeof(tmp);
        memcpy((void *)(buffer + byte), &tmp, data);
        byte += data;
    }
}

and in params :

struct stat stat_i;
buffer(addr, pid, sizeof(stat_i), &stat_i);
printf("%lu", stat_i.st_size); -> fake value :/

Thank'ks !

g0blin
  • 25
  • 5

1 Answers1

0

From the man page,

PTRACE_PEEKTEXT, PTRACE_PEEKDATA
      Read a word at the address addr in the tracee's memory,
      returning the word as the result of the ptrace() call.  Linux
      does not have separate text and data address spaces, so these
      two requests are currently equivalent.  (data is ignored; but
      see NOTES.)

Thus you must understand that tmp would hold the actually value that was read.

Your checks are wrong - you should set errno = 0 before the call and then check if it has changed. If it has - you've got an error. If it hasn't - you can be assured that tmp has the word from the remote process.

Try something like this:

int buffer(unsigned long long addr, pid_t child, size_t size, void *buffer)
{
    size_t byte = 0;
    size_t data;
    unsigned long tmp;

    // support for word aligned sizes only
    if (size % sizeof(long) != 0)
        return -1;

    long * buffer_int = (long*) buffer;

    while (byte < size) {
        errno = 0;
        tmp = ptrace(PTRACE_PEEKDATA, child, addr + byte);
        if (errno)
            return -1;
        buffer_int[byte / sizeof(long)] = tmp;

        byte += sizeof(long);
    }
}
Mark Segal
  • 5,427
  • 4
  • 31
  • 69