#include #include #include #include #include #include #include #include #include #include #define SYSCT_FBSD 588 extern void trap(gregset_t); extern void cat(int fd, long sz); extern uint32_t trapsz; extern uint8_t sel; uint16_t scmap[SYSCT_FBSD] = { -1, // SYS_syscall needs args shifted SYS_exit, -1, // SYS_fork needs sud reset SYS_read, SYS_write, SYS_open, SYS_close, -1, // wait4 -1, // [old] creat SYS_link, SYS_unlink, -1, // [obsolete] execv SYS_chdir, SYS_fchdir }; void ftrp(int n, siginfo_t* s, ucontext_t* c) { sel = SYSCALL_DISPATCH_FILTER_ALLOW; c->uc_mcontext.gregs[13] = syscall( scmap[s->si_syscall], c->uc_mcontext.gregs[8], c->uc_mcontext.gregs[9], c->uc_mcontext.gregs[12] ); //for(int i = 0; i < 23; i++) printf("%i: %lX\n", i, c->uc_mcontext.gregs[i]); //printf("%u\n", s->si_arch); sel = SYSCALL_DISPATCH_FILTER_BLOCK; //trap(c->uc_mcontext.gregs); } typedef struct { uint8_t magic[4]; uint8_t bits; uint8_t endian; uint8_t hdrver; uint8_t abi; uint8_t pad[8]; uint16_t type; uint16_t isa; uint32_t ver; uint64_t ep; uint64_t phtable; uint64_t shtable; uint32_t flags; uint16_t hsz; uint16_t phtesz; uint16_t phtct; uint16_t shtesz; uint16_t shtct; uint16_t nameind; } __attribute__((packed)) elf; char** getmaps(int* tsz) { int fd = open("/proc/self/maps", O_RDONLY); char c; *tsz = 0; int p = 0, s = 128; char** t = malloc(sizeof(char*)); t[0] = malloc(s); while(read(fd, &c, 1)) { if(c == '\n') c = 0; t[*tsz][p++] = c; if(p >= s) t[*tsz] = realloc(t[*tsz], s += 8); if(!c) { t = realloc(t, ((++(*tsz)) + 1) * sizeof(char*)); t[*tsz] = malloc(s = 128); p = 0; } } (*tsz)++; close(fd); return t; } typedef struct { uint64_t start; uint64_t len; uint8_t rwx; char* name; } map; void stomap(char* s, map* m) { m->start = 0; m->len = 0; m->rwx = 0; while(*s != '-') { m->start <<= 4; if(*s >= '0' && *s <= '9') m->start |= *s - '0'; else m->start |= *s - 'a' + 10; s++; } s++; while(*s != ' ') { m->len <<= 4; if(*s >= '0' && *s <= '9') m->len |= *s - '0'; else m->len |= *s - 'a' + 10; s++; } s++; for(int i = 0; i < 3; i++) { m->rwx <<= 1; m->rwx |= (*(s++) != '-'); } s += 2; while(*(s++) != ':'); while(*(s++) != ' '); while(*s >= '0' && *s <= '9') s++; while(*(++s) == ' '); int d = strlen(s) + 1; m->name = memcpy(malloc(d), s, d); m->len -= m->start; } int main(int argc, char** argv) { struct sigaction a, oa; sigemptyset(&a.sa_mask); a.sa_flags = SA_SIGINFO; a.sa_sigaction = ftrp; sigaction(SIGSYS, &a, &oa); sel = SYSCALL_DISPATCH_FILTER_ALLOW; int nm; char** smaps = getmaps(&nm); map maps[nm-1]; for(int i = 0; i < nm-1; i++) { stomap(smaps[i], maps + i); /* printf( "map:\t%s\n" "name:\t%s\n" "start:\t%016lX\n" "length:\t%016lX\n" "access:\t%c%c%c\n" , smaps[i], maps[i].name, maps[i].start, maps[i].len, ".R"[(maps[i].rwx >> 2) & 1], ".W"[(maps[i].rwx >> 1) & 1], ".X"[(maps[i].rwx >> 0) & 1] ); */ if( ( strstr(maps[i].name, "libc") //||strstr(maps[i].name, "ld-linux") || //strstr(maps[i].name, "fl") || //!strcmp(maps[i].name, "[vdso]") || //!strcmp(maps[i].name, "[vsyscall]") ) && (maps[i].rwx & 1) ) { prctl(PR_SET_SYSCALL_USER_DISPATCH, PR_SYS_DISPATCH_ON, maps[i].start, maps[i].len, &sel); // printf("enable sud bypass\n"); } //printf("\n"); } for(int i = 0; i < nm; i++) free(smaps[i]); free(smaps); if(argc < 2) return printf("no file provided\n"); int fd = open(argv[1], O_RDONLY); struct stat s; fstat(fd, &s); //printf("start cat() with freebsd syscalls\n"); //prctl(PR_SET_SYSCALL_USER_DISPATCH, PR_SYS_DISPATCH_ON, trap, trapsz, &sel); //write(1, "fghgfgfg\n", 9); sel = SYSCALL_DISPATCH_FILTER_BLOCK; cat(fd, s.st_size); }