Skip to content

Instantly share code, notes, and snippets.

@robbmanes
Last active August 8, 2022 19:58
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 robbmanes/dd53dcb21cccbdedfeb49f24fc8adc50 to your computer and use it in GitHub Desktop.
Save robbmanes/dd53dcb21cccbdedfeb49f24fc8adc50 to your computer and use it in GitHub Desktop.
Bad Exit Ptracer
#include <stdio.h>
#include <stdlib.h>
#include <syscall.h>
#include <sys/user.h>
#include <sys/types.h>
#include <sys/ptrace.h>
#include <errno.h>
#define SYSCALL_EXIT 60
#define SYSCALL_EXIT_GROUP 231
int main(int argc, char **argv) {
pid_t p;
char *c;
if (argc <= 1) {
printf("too few arguments!\n");
exit(1);
}
p = strtol(argv[1], &c, 10);
printf("Got process information for PID %d. Beginning ptrace monitoring syscalls.\n", p);
if (ptrace(PTRACE_ATTACH, p, NULL, NULL) == -1) {
printf("Failed to attach ptrace, exiting.\n");
exit(1);
}
// We want, on exit, the tracee to not automatically close
if (ptrace(PTRACE_SETOPTIONS, p, NULL, PTRACE_O_TRACEEXIT) == -1) {
printf("Failed to set PTRACE_O_TRACEEXIT, exiting\n");
exit(1);
}
waitpid(p, NULL, WUNTRACED);
for (;;) {
if (ptrace(PTRACE_SYSCALL, p, 0, 0) == -1) {
printf("Failed to trace syscall.\n");
exit(1);
}
if (waitpid(p, 0, 0) == -1) {
printf("Failed to wait for state change of PID.\n");
exit(1);
}
// Check if the syscall will exit us
struct user_regs_struct regs;
if (ptrace(PTRACE_GETREGS, p, 0, &regs) == -1) {
printf("Failed to get register data for process.\n");
exit(1);
}
long syscall = regs.orig_rax;
if (syscall == SYSCALL_EXIT || syscall == SYSCALL_EXIT_GROUP) {
// This is the shutdown of the tracee, we intentionally
// don't want to catch this to cause a problem during shutdown
printf("Caught exit syscall, intentionally ignoring and exiting...\n");
exit(0);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment