Skip to content

Instantly share code, notes, and snippets.

@Zheaoli
Last active June 17, 2022 07:26
Show Gist options
  • Select an option

  • Save Zheaoli/95be0a61d549ae64f3a7b3171c4e9cc3 to your computer and use it in GitHub Desktop.

Select an option

Save Zheaoli/95be0a61d549ae64f3a7b3171c4e9cc3 to your computer and use it in GitHub Desktop.
#ifndef PTRACE_H
#define PTRACE_H
#include <errno.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ptrace.h>
#include <sys/reg.h>
#include <sys/uio.h>
#include <sys/user.h>
#include <sys/wait.h>
#include <syscall.h>
#include <unistd.h>
typedef struct strbs {
long len;
char *str;
struct strbs *next;
} strb;
int startWith(const char *prefix, const char *str) {
size_t len_pre = strlen(prefix);
size_t len_str = strlen(str);
return len_str < len_pre ? 0 : memcmp(prefix, str, len_pre) == 0;
}
strb *initBuilder() { return NULL; }
strb *initBuildStrb(char *init) {
strb *str = (strb *)malloc(sizeof(strb));
str->len = strlen(init);
str->str = init;
str->next = NULL;
return str;
}
strb *buildStr(strb *str, char *add) {
if (str == NULL) {
return initBuildStrb(add);
}
strb *s2 = initBuildStrb(add);
s2->len = str->len + s2->len;
s2->next = str;
return s2;
}
char *getStr(strb *src) {
char *dest = (char *)malloc(src->len + 1);
dest[src->len] = '\0';
char *write = (char *)((long)dest + src->len);
while (src->next != NULL) {
long off = (src->len - src->next->len);
write = (char *)(long)write - off;
memcpy(write, src->str, src->len - src->next->len);
src = src->next;
}
memcpy(dest, src->str, src->len);
return dest;
}
void printStr(strb *a) {
while (a != NULL) {
printf("{len: %ld, str: %s}->", a->len, a->str);
a = a->next;
}
printf("NULL\n");
}
char *readParmStringFromAddress(pid_t child, void *addr) {
strb *str = initBuilder();
int endOfStr = 1;
int offset = 0;
while (endOfStr == 1) {
char *nStr = (char *)malloc(sizeof(long));
long r =
ptrace(PTRACE_PEEKTEXT, child,
(void *)((unsigned long long)addr + offset * sizeof(long)), 0);
memcpy((void *)nStr, (void *)&r, sizeof(long));
str = buildStr(str, nStr);
int i = 0;
while (i < sizeof(long)) {
if (nStr[i] == '\0') {
endOfStr = 0;
break;
}
i++;
}
offset++;
}
return getStr(str);
}
int traceProcess(pid_t ch, char *protectedPath) {
ptrace(PTRACE_ATTACH, 193091, 0, 0);
int inSysCall = 0;
int status ;
while (1) {
wait(&status);
if (WIFEXITED(status)) {
break;
}
int orig_rax = ptrace(PTRACE_PEEKUSER, ch, 8 * ORIG_RAX, NULL);
if (orig_rax == SYS_open || orig_rax == SYS_openat) {
struct user_regs_struct regs;
ptrace(PTRACE_GETREGS, ch, NULL, &regs);
char *openstr;
if (orig_rax == SYS_open) {
openstr = readParmStringFromAddress(ch, (void *)regs.rdi);
} else {
openstr = readParmStringFromAddress(ch, (void *)regs.rsi);
}
if (startWith(protectedPath, openstr)) {
if (inSysCall == 0) {
inSysCall = 1;
} else {
struct user_regs_struct return_regs;
ptrace(PTRACE_GETREGS, ch, NULL, &return_regs);
printf("Write returned with %ld\n", (long)return_regs.rax);
return_regs.rax = -EACCES;
ptrace(PTRACE_SETREGS, ch, NULL, &return_regs);
inSysCall = 0;
}
}
}
ptrace(PTRACE_SYSCALL, ch, NULL, NULL);
}
return 0;
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment