Permalink
Browse files

Checkpoint attach work-in-progress.

  • Loading branch information...
1 parent 35d826e commit f5d1d89c2afcc699c30840049cddfaaf7f9aae62 @nelhage committed Jan 18, 2011
Showing with 98 additions and 3 deletions.
  1. +1 −1 Makefile
  2. +73 −0 attach.c
  3. +22 −2 reptyr.c
  4. +2 −0 stub.c
View
@@ -3,7 +3,7 @@ STUB_CFLAGS=$(CFLAGS) -nostdlib -Wl,-r -fomit-frame-pointer
all: reptyr stub.o
-reptyr: reptyr.o ptrace.o
+reptyr: reptyr.o ptrace.o attach.o
stub.o: stub.c
$(CC) -c $(STUB_CFLAGS) -o $@ $^
View
@@ -0,0 +1,73 @@
+#include <sys/types.h>
+#include <dirent.h>
+#include <sys/syscall.h>
+#include <sys/mman.h>
+#include <stdio.h>
+
+#include "ptrace.h"
+
+extern void debug(const char *msg, ...);
+
+static void do_unmap(struct ptrace_child *child, unsigned long addr, int pages) {
+ if (addr == (unsigned long)-1)
+ return;
+ ptrace_remote_syscall(child, __NR_munmap, addr, pages, 0, 0, 0, 0);
+}
+
+extern char child_stub_begin[], child_stub_end[];
+
+int attach_child(pid_t pid, const char *pty) {
+ struct ptrace_child child;
+ unsigned long arg_page = -1,
+ stack_page = -1,
+ code_map = -1;
+ int code_pages = 1;
+
+ if (ptrace_attach_child(&child, pid)) {
+ perror("attach");
+ return -1;
+ }
+ if (ptrace_advance_to_state(&child, ptrace_at_syscall))
+ goto out_detach;
+ if (ptrace_save_regs(&child))
+ goto out_detach;
+
+ arg_page = ptrace_remote_syscall(&child, mmap_syscall, 0,
+ PAGE_SIZE, PROT_READ|PROT_WRITE,
+ MAP_ANONYMOUS|MAP_PRIVATE, 0, 0);
+
+ debug("Allocated argument page: %lx", arg_page);
+
+ stack_page = ptrace_remote_syscall(&child, mmap_syscall, 0,
+ PAGE_SIZE, PROT_READ|PROT_WRITE,
+ MAP_ANONYMOUS|MAP_PRIVATE, 0, 0);
+ debug("Allocated stack page: %lx", stack_page);
+
+ code_map = ptrace_remote_syscall(&child, mmap_syscall, 0,
+ code_pages * PAGE_SIZE,
+ PROT_READ|PROT_WRITE,
+ MAP_ANONYMOUS|MAP_PRIVATE, 0, 0);
+ debug("Allocated code buffer: %lx", code_map);
+
+ if (arg_page == (unsigned long)-1
+ || stack_page == (unsigned long)-1
+ || code_map == (unsigned long)-1)
+ goto out_unmap;
+
+ if (ptrace_memcpy_to_child(&child, arg_page, pty, strlen(pty) + 1))
+ goto out_unmap;
+ if (ptrace_memcpy_to_child(&child, code_map, child_stub_begin,
+ child_stub_end - child_stub_begin + 1))
+ goto out_unmap;
+
+ out_unmap:
+ do_unmap(&child, arg_page, 1);
+ do_unmap(&child, stack_page, 1);
+ do_unmap(&child, code_map, code_pages);
+
+ ptrace_restore_regs(&child);
+ out_detach:
+ ptrace_detach_child(&child);
+
+ return -1;
+}
View
@@ -12,6 +12,8 @@
#include <termios.h>
#include <signal.h>
+int attach_child(pid_t pid, const char *pty);
+
void die(const char *msg, ...) {
char buf[8192];
va_list ap;
@@ -23,6 +25,16 @@ void die(const char *msg, ...) {
exit(1);
}
+void debug(const char *msg, ...) {
+ char buf[8192];
+ va_list ap;
+ va_start(ap, msg);
+ vsnprintf(buf, sizeof buf, msg, ap);
+ va_end(ap);
+
+ fprintf(stderr, "[+] %s\n", buf);
+}
+
void setup_raw(struct termios *save) {
struct termios set;
if (tcgetattr(0, save) < 0)
@@ -106,15 +118,23 @@ int main(int argc, char **argv) {
die("Unable to unlockpt: %m");
if (grantpt(pty) < 0)
die("Unable to unlockpt: %m");
- printf("Opened a new pty: %s\n", ptsname(pty));
+
+ if (argc > 1) {
+ if (attach_child(atoi(argv[1]),
+ ptsname(pty))) {
+ perror("Attaching to child");
+ return 1;
+ }
+ } else {
+ printf("Opened a new pty: %s\n", ptsname(pty));
+ }
setup_raw(&saved_termios);
resize_pty(pty);
memset(&act, 0, sizeof act);
act.sa_handler = do_winch;
act.sa_flags = 0;
sigaction(SIGWINCH, &act, NULL);
-
do_proxy(pty);
tcsetattr(0, TCSANOW, &saved_termios);
View
@@ -4,6 +4,8 @@
#define _FCNTL_H
#include <bits/fcntl.h>
+
+
static inline unsigned long __syscall(unsigned long sysno,
unsigned long p0, unsigned long p1,
unsigned long p2, unsigned long p3,

0 comments on commit f5d1d89

Please sign in to comment.