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