diff options
author | the lemons <citrons@mondecitronne.com> | 2023-02-07 22:43:58 -0600 |
---|---|---|
committer | the lemons <citrons@mondecitronne.com> | 2023-02-07 22:44:05 -0600 |
commit | 4a3429a96b5b5ea7468540349aeb4535d5738053 (patch) | |
tree | 41cb9eb453074cd68ec9ea1af548a799c1ae8500 | |
parent | 720f98b8ab509ae410840838b25a0e0337e50c92 (diff) |
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | evilize.c | 65 |
2 files changed, 67 insertions, 0 deletions
@@ -12,6 +12,8 @@ core.c: procfs.h memview.h memview.c: procfs.h memview.h procfs.c: procfs.h +evilize: evilize.o + .SUFFIXES: .c .o .c.o: $(CC) $(CFLAGS) -c -o $@ $< diff --git a/evilize.c b/evilize.c new file mode 100644 index 0000000..e3b13aa --- /dev/null +++ b/evilize.c @@ -0,0 +1,65 @@ +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> +#include <signal.h> +#include <sys/ptrace.h> + +#define ERRCHECK(E)\ + if ((E) == -1) {perror(argv[0]); kill(pid, SIGHUP); return -1;} + +int main(int argc, char *argv[]) { + if (argc < 2) { + fprintf(stderr, "usage: %s COMMAND [ARGS]...\n" , argv[0]); + return -1; + } + pid_t pid = fork(); + if (pid == -1) { + perror(argv[0]); + return -1; + } + if (pid == 0) { + ptrace(PTRACE_TRACEME, 0, NULL, NULL); + raise(SIGSTOP); + if (execvp(argv[1], argv + 1) == -1) { + perror(argv[0]); + return -1; + } + } else { + ERRCHECK(ptrace(PTRACE_ATTACH, pid, NULL, NULL)); + int status; + pid_t w = waitpid(pid, &status, __WALL); + ERRCHECK(w); + ERRCHECK(ptrace(PTRACE_CONT, pid, NULL, NULL)); + while (1) { + pid_t w = waitpid(pid, &status, __WALL); + ERRCHECK(w); + if (WIFEXITED(status)) + return WEXITSTATUS(status); + if (WIFSTOPPED(status)) { + if (WIFSIGNALED(status)) { + errno = 0; + switch (WSTOPSIG(status)) { + case SIGABRT: + case SIGBUS: + case SIGFPE: + case SIGILL: + case SIGSEGV: + ptrace(PTRACE_CONT, pid, NULL, NULL); + break; + default: + ptrace(PTRACE_CONT, pid, NULL, WSTOPSIG(status)); + break; + } + if (errno && errno != ESRCH) { + perror("ptrace"); + kill(pid, SIGHUP); + return -1; + } + } else ptrace(PTRACE_CONT, pid, NULL, NULL); + } + } + } +} |