Skip to content

Instantly share code, notes, and snippets.

@otms61
Last active March 15, 2016 09:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save otms61/ac694db2b6b6b55806da to your computer and use it in GitHub Desktop.
Save otms61/ac694db2b6b6b55806da to your computer and use it in GitHub Desktop.
Inspect process_vm_readv behavior
ALL: sandbox permtest
sandbox:
gcc -m32 -o sandbox sandbox.c
permtest:
gcc -m32 -o permtest permtest.c
clean:
rm sandbox permtest
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#define MMAPED_ADDR_RW 0x08080000
#define MMAPED_ADDR_W 0x08090000
char test1[] = "Hello world from permission RW\n";
char test2[] = "Hello world from permission W\n";
int main(int argc, char const *argv[])
{
/*
0x08048000 0x08049000 r-xp permtest
0x08049000 0x0804a000 r--p permtest
0x0804a000 0x0804b000 rw-p permtest
0x08080000 0x08081000 rw-p mapped <---- MMAPED_ADDR_RW
0x08090000 0x08091000 -w-p mapped <---- MMAPED_ADDR_W
0xf7e08000 0xf7e09000 rw-p mapped
0xf7e09000 0xf7fb1000 r-xp libc-2.19.so
0xf7fb1000 0xf7fb3000 r--p libc-2.19.so
0xf7fb3000 0xf7fb4000 rw-p libc-2.19.so
0xf7fb4000 0xf7fb7000 rw-p mapped
0xf7fd9000 0xf7fdb000 rw-p mapped
0xf7fdb000 0xf7fdc000 r-xp [vdso]
0xf7fdc000 0xf7ffc000 r-xp ld-2.19.so
0xf7ffc000 0xf7ffd000 r--p ld-2.19.so
0xf7ffd000 0xf7ffe000 rw-p ld-2.19.so
0xfffdd000 0xffffe000 rw-p [stack]
*/
mmap((void *)MMAPED_ADDR_RW, 0x1000, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
mmap((void *)MMAPED_ADDR_W, 0x1000, PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
memcpy((void *)MMAPED_ADDR_RW, test1, strlen(test1));
memcpy((void *)MMAPED_ADDR_W, test2, strlen(test2));
write(1, (void *)MMAPED_ADDR_RW, strlen(test1));
write(1, (void *)MMAPED_ADDR_W, strlen(test2));
return 0;
}
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ptrace.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/user.h>
#include <sys/uio.h>
int main() {
int pid;
pid_t w;
int status;
char progname[] = "./permtest";
char *command[2];
struct user_regs_struct regs;
char buf[255];
int i;
int nread;
long data;
struct iovec local[1];
struct iovec remote[1];
char iov_buf[255];
local[0].iov_base = iov_buf;
local[0].iov_len = 255;
command[0] = progname;
command[1] = NULL;
pid = fork();
if (pid == 0) {
// child
ptrace(PTRACE_TRACEME, NULL, NULL, NULL);
execve(command[0], command, NULL);
exit(1);
} else {
// parent
while(1) {
w = waitpid(pid, &status, __WALL);
if (w != pid)
exit(1);
if (WIFSTOPPED(status)) {
ptrace(PTRACE_GETREGS, pid, NULL, &regs);
if(regs.orig_eax > 0 && regs.orig_eax == 4) {
// before execute system call
remote[0].iov_base = (void *) regs.ecx;
remote[0].iov_len = regs.edx;
// read remote memory by process_vm_readv
nread = process_vm_readv(pid, local, 1, remote, 1, 0);
if (nread > -1) {
iov_buf[nread] = '\0';
printf("[*] process_vm_readv buf: %s", iov_buf);
} else {
printf("[*] process_vm_readv fail\n");
}
// read remote memory by ptrace
for (i = 0; i < regs.edx; i += 4) {
data = ptrace(PTRACE_PEEKDATA, pid, regs.ecx+i, NULL);
buf[i] = (char) (data & 0xff);
buf[i+1] = (char) ((data >> 8) & 0xff);
buf[i+2] = (char) ((data >> 16) & 0xff);
buf[i+3] = (char) ((data >> 24) & 0xff);
}
buf[regs.edx] = '\0';
printf("[*] ptrace buf: %s", buf);
ptrace(PTRACE_SYSCALL, pid, NULL, NULL);
// after execute system call
waitpid(pid, &status, __WALL);
}
}
// restrat child process
ptrace(PTRACE_SYSCALL, pid, NULL, NULL);
}
}
}
@otms61
Copy link
Author

otms61 commented Mar 15, 2016

$ ./sandbox                              
[*] process_vm_readv buf: Hello world from permission RW
[*] ptrace buf: Hello world from permission RW
Hello world from permission RW
[*] process_vm_readv fail
[*] ptrace buf: Hello world from permission W
Hello world from permission W

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment