I'm trying to read the stack of another process that has the same user
credentials.  Here is my program, I am stuck with this, it doesn't work
for me.  Printing 0's is rewrapped to '.' and you should use this program
with hexdump like so:  ./memtest [pid] | hexdump -C | less
Sometimes I get a bit of the stack but it seems random, dunno what the 
deal is.


#include <sys/types.h>
#include <sys/ptrace.h>

#include <machine/vmparam.h>
#include <machine/reg.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>

#include <unistd.h>

int
main(int argc, char *argv[])
{
        int64_t stackend =  USRSTACK;
        int64_t offset;
        int64_t memsize;
        char page[4096];
        int pid, i;
        size_t len;
        int status;
        
        char *p;

        struct ptrace_io_desc ptid;
        struct reg myreg;
        
        if (argc < 2) {
                perror("args");
                exit(1);
        }

        fprintf(stderr, "stackend = %llx\n", stackend);

        pid = atoi(argv[1]);

        if (ptrace(PT_ATTACH, pid, NULL, 0) < 0) {
                perror("ptrace");
                exit(1);
        }
        
        waitpid(pid, NULL, 0);

        
        if (ptrace(PT_GETREGS, pid, (caddr_t)&myreg, sizeof(myreg)) < 0) {
                perror("ptrace getregs");
                exit(1);
        }

        offset = myreg.r_rsp;

        fprintf(stderr, "bottom of stack = %llx\n", offset);

        memsize = stackend - offset;
        p = calloc(1, memsize);
        if (p == NULL) {
                perror("malloc");
                exit(1);
        }

        fprintf(stderr, "memsize = %llx\n", memsize);

        memset(&ptid, 0, sizeof(ptid));
        ptid.piod_op = PIOD_READ_I;
        ptid.piod_offs = (void*)&offset; 
        ptid.piod_addr = (void*)p;
        ptid.piod_len = memsize;

        status = ptrace(PT_IO, pid, (caddr_t)&ptid, sizeof(ptid));

        for (i = 0; i < ptid.piod_len; i++) {
                printf("%c", ((p[i] != 0) ? p[i] : '.'));
        }

        status = ptrace(PT_DETACH, pid, NULL, 0);
        if (status < 0) {
                perror("ptrace detach");
                exit(1);
        }       

        exit(0);
}       

Thanks for any hints,

-peter

Reply via email to