From 2bc387b2cfe6455354cccbfa688a51b27ac1bbdc Mon Sep 17 00:00:00 2001 From: mothcompute Date: Wed, 22 Nov 2023 11:22:58 -0800 Subject: [PATCH] initial commit --- README.md | 1 + build | 2 + main.c | 188 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ th.s | 100 +++++++++++++++++++++++++++++ 4 files changed, 291 insertions(+) create mode 100644 README.md create mode 100755 build create mode 100644 main.c create mode 100644 th.s diff --git a/README.md b/README.md new file mode 100644 index 0000000..d37e466 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# freebsd layer for linux diff --git a/build b/build new file mode 100755 index 0000000..ee7d2a9 --- /dev/null +++ b/build @@ -0,0 +1,2 @@ +nasm -felf64 th.s +cc -ggdb3 main.c th.o -o fl -pie #-fno-PIC diff --git a/main.c b/main.c new file mode 100644 index 0000000..f60a3c3 --- /dev/null +++ b/main.c @@ -0,0 +1,188 @@ +#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); +} diff --git a/th.s b/th.s new file mode 100644 index 0000000..3499db3 --- /dev/null +++ b/th.s @@ -0,0 +1,100 @@ +bits 64 +default rel + +global trap +global trapsz +global cat +global sel + +extern scmap + +section .data +sel: db 1 +trapsz: dd cat-trap; +buf: db 0 + +section .text + +trap: + ;mov rax, 60 + ;syscall + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 + push rsi + push rbp + push rbx + push rdx + push rcx + + mov r8, [rdi] + mov r9, [rdi+8] + mov r10, [rdi+16] + mov r11, [rdi+24] + mov r12, [rdi+32] + mov r13, [rdi+40] + mov r14, [rdi+48] + mov r15, [rdi+56] + mov rsi, [rdi+72] + mov rbp, [rdi+80] + mov rbx, [rdi+88] + mov rdx, [rdi+96] + mov rax, [rdi+104] + mov rcx, [rdi+112] + + mov rdi, [rdi+64] + syscall + + pop rcx + pop rdx + pop rbx + pop rbp + pop rsi + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + ret + + + + push rbx + ;mov ax, word [rel scmap + 2*eax] + lea rbx, [scmap] + lea rax, [rbx + 2*rax] + movzx eax, ax + pop rbx + ret +cat: + push r12 + push rbx + mov r12, rdi ; fd to read + mov rbx, rsi ; bytes to read + +.l: mov eax, 3 ; read + mov rdi, r12 + lea rsi, [buf] + mov rdx, 1 + syscall + + mov eax, 4 ; write + mov rdi, 1 + lea rsi, [buf] + mov rdx, 1 + syscall + + dec rbx + jnz .l + + pop rbx + pop r12 + ret