0

I am currently developing a tool in which I have to trace a program to know his system calls. For the moment, I am able to get numeric parameters of syscalls but I can't get properly address to the strings.

Here is the way I proceed :

  long addr = ptrace(PTRACE_PEEKDATA, pid, regs.ebx, NULL);
  printf("%s", (char *) &addr);

With that piece of code I can get the beginning of the string (3 or 4 first characters) but the end is corrupted, I don't know why.

Have you got any solution ? Thank you.

Jeffrey Muller
  • 850
  • 1
  • 15
  • 28
  • @Jeffey Muller: You trying to capture the arguments of a particular system call right? I built a similar application which is similar to strace but works for a fewer system calls. – kidd0 May 09 '12 at 11:22

3 Answers3

3
char *read_string (int child, unsigned long addr) {
    char *val = malloc(4096);
    if (!val)
        return NULL;

    int allocated = 4096, read = 0;
    unsigned long tmp =0;
    while(1) {
        if (read + sizeof (tmp) > allocated) {
            allocated *= 2;
            char *temp_val = realloc (val, allocated);
            if (!temp_val) {
                free(val);
                return NULL;
            }
            val = temp_val;
        }
        tmp = ptrace(PTRACE_PEEKDATA, child, addr + read);
        if(errno != 0) {
            val[read] = 0;
            break;
        }
        memcpy(val + read, &tmp, sizeof tmp);
        if (memchr(&tmp, 0, sizeof tmp) != NULL) break;
        read += sizeof tmp;
    }
    return val;
} // Don't forget to free the returned val.

Try using the following function, it was a part of something I wrote in my application:

reg_val[1] = ptrace (PTRACE_PEEKUSER, child, 4 * EBX, NULL);
char *filepath = read_string(child, reg_val[1]);

Child is the pid of the child process I am tracing. If this is not working do tell me?

nullp0tr
  • 485
  • 3
  • 11
kidd0
  • 731
  • 2
  • 8
  • 25
2

Are you sure that you don't want this instead?

printf("%lX", addr);

Šimon Tóth
  • 35,456
  • 20
  • 106
  • 151
  • I would like to print strings litteraly. For example, if the tracee binary do a write(1, "hello world", 14) , I would like to get the string "hello world" and not an address. – Jeffrey Muller Apr 30 '12 at 15:06
  • @JeffreyMuller Well ok, but the code you wrote doesn't make much sense, either you are getting the address of a string, in which case, you should ptrace that address, or you are getting part of the string, in which case you need to step through the string using ptrace until you read it entirely. – Šimon Tóth Apr 30 '12 at 15:10
  • In regs.ebx, I think I have the address of the string. So I use PTRACE_PEEKDATA to get the data pointed by ebx but the address that ptrace gave me is not ok. It is a segmentation fault. Here is an example : http://pastebin.com/p3rdCXDV – Jeffrey Muller Apr 30 '12 at 19:45
  • @JeffreyMuller `ptrace` returns the data, not an address, read the man page, specifically the section for `PTRACE_PEEKDATA`. – Šimon Tóth May 01 '12 at 12:28
0

With your posted code, you are only reading 4 bytes of data (i.e. 4 charaters) with the call to ptrace. You need to read the entire buffer from the debug process before you are able to print out the string in parent process. i.e, after you have read addr, you need to loop

   ptrace(PTRACE_PEEKTEXT, child, addr, NULL)
   addr+=4;

until you read the full string.

Then you can print it out using printf()

anon
  • 1