Created
February 13, 2019 10:38
-
-
Save kmeaw/a15b7fb3c17142c849660473596e0c9f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static __inline long __syscall0(long n) | |
{ | |
unsigned long ret; | |
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n) : "rcx", "r11", "memory"); | |
return ret; | |
} | |
static __inline long __syscall1(long n, long a1) | |
{ | |
unsigned long ret; | |
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1) : "rcx", "r11", "memory"); | |
return ret; | |
} | |
static __inline long __syscall2(long n, long a1, long a2) | |
{ | |
unsigned long ret; | |
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2) | |
: "rcx", "r11", "memory"); | |
return ret; | |
} | |
static __inline long __syscall3(long n, long a1, long a2, long a3) | |
{ | |
unsigned long ret; | |
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2), | |
"d"(a3) : "rcx", "r11", "memory"); | |
return ret; | |
} | |
static __inline long __syscall4(long n, long a1, long a2, long a3, long a4) | |
{ | |
unsigned long ret; | |
register long r10 __asm__("r10") = a4; | |
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2), | |
"d"(a3), "r"(r10): "rcx", "r11", "memory"); | |
return ret; | |
} | |
static __inline long __syscall5(long n, long a1, long a2, long a3, long a4, long a5) | |
{ | |
unsigned long ret; | |
register long r10 __asm__("r10") = a4; | |
register long r8 __asm__("r8") = a5; | |
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2), | |
"d"(a3), "r"(r10), "r"(r8) : "rcx", "r11", "memory"); | |
return ret; | |
} | |
static __inline long __syscall6(long n, long a1, long a2, long a3, long a4, long a5, long a6) | |
{ | |
unsigned long ret; | |
register long r10 __asm__("r10") = a4; | |
register long r8 __asm__("r8") = a5; | |
register long r9 __asm__("r9") = a6; | |
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2), | |
"d"(a3), "r"(r10), "r"(r8), "r"(r9) : "rcx", "r11", "memory"); | |
return ret; | |
} | |
int errno; | |
int mystrlen(const char *str) | |
{ | |
int sz = 0; | |
while (*str++) sz++; | |
return sz; | |
} | |
void printnum(int fd, int e) | |
{ | |
char num[] = { 0,0,0,0,0,0,0,0,0,0 }; | |
char *ptr = num + sizeof(num) - 2; | |
*ptr = '0'; | |
for (; e > 0; e /= 10) | |
*ptr-- = '0' + (e % 10); | |
ptr++; | |
__syscall3(__NR_write, fd, (long) ptr, mystrlen(ptr)); | |
} | |
void myerror(const char *str) | |
{ | |
__syscall3(__NR_write, 2, (long) str, mystrlen(str)); | |
__syscall3(__NR_write, 2, (long) ": ", 2); | |
printnum(2, errno > 0 ? errno : -errno); | |
__syscall3(__NR_write, 2, (long) "\n", 1); | |
} | |
typedef uint64_t u64; | |
typedef int64_t s64; | |
typedef __u32 u32; | |
typedef __s32 s32; | |
typedef __u16 u16; | |
typedef __s16 s16; | |
typedef __u8 u8; | |
typedef __s8 s8; | |
struct linux_dirent64 { | |
u64 d_ino; | |
s64 d_off; | |
unsigned short d_reclen; | |
unsigned char d_type; | |
char d_name[0]; | |
}; | |
#ifndef MNT_DETACH | |
#define MNT_DETACH 2 | |
#endif | |
#ifndef CLONE_NEWCGROUP | |
#define CLONE_NEWCGROUP 0x02000000 | |
#endif | |
#define fdputs(fd, line) write(fd, line, mystrlen(line)) | |
void __attribute__((noreturn)) exit(int rc) | |
{ | |
__syscall1(__NR_exit, rc); | |
__builtin_unreachable(); | |
} | |
void abort() | |
{ | |
exit (0); | |
} | |
namespace std{ | |
void terminate() { abort(); } | |
} | |
#define myerror(x) myerror(xorstr(x).crypt_get()) | |
static int openat(int dirfd, const char *pathname, int flags, __mode_t mode) | |
{ | |
int r = __syscall4(__NR_openat, dirfd, (long) pathname, flags, mode); | |
if (r < 0) | |
{ | |
errno = r; | |
myerror ("openat"); | |
abort (); | |
} | |
return r; | |
} | |
int getdents64(unsigned int fd, struct linux_dirent64 *dirp, unsigned int count) | |
{ | |
int r = __syscall3(__NR_getdents64, fd, (long) dirp, count); | |
if (r < 0) | |
{ | |
errno = r; | |
myerror ("getdents64"); | |
abort (); | |
} | |
return r; | |
} | |
int mount(const char *source, const char *target, const char *fstype, unsigned long mountflags, const void *data) | |
{ | |
int r = __syscall5(__NR_mount, (long) source, (long) target, (long) fstype, mountflags, (long) data); | |
if (r < 0) | |
{ | |
errno = r; | |
myerror ("mount"); | |
abort (); | |
} | |
return r; | |
} | |
int umount2(const char *target, int flags) | |
{ | |
int r = __syscall2(__NR_umount2, (long) target, flags); | |
if (r < 0) | |
{ | |
errno = r; | |
myerror ("umount2"); | |
abort (); | |
} | |
return r; | |
} | |
int pivot_root(const char *new_root, const char *put_old) | |
{ | |
int r = __syscall2(__NR_pivot_root, (long) new_root, (long) put_old); | |
if (r < 0) | |
{ | |
errno = r; | |
myerror ("pivot_root"); | |
abort (); | |
} | |
return r; | |
} | |
int fstat (int fd, struct stat *statbuf) | |
{ | |
int r = __syscall2(__NR_fstat, fd, (long) statbuf); | |
if (r < 0) | |
{ | |
errno = r; | |
myerror ("fstat"); | |
abort (); | |
} | |
return r; | |
} | |
int fstatat (int dirfd, const char *pathname, struct stat *statbuf, int flags) | |
{ | |
int r = __syscall4(__NR_newfstatat, dirfd, (long) pathname, (long) statbuf, flags); | |
if (r < 0) | |
{ | |
errno = r; | |
myerror ("fstatat"); | |
abort (); | |
} | |
return r; | |
} | |
int close (int fd) | |
{ | |
int r = __syscall1(__NR_close, fd); | |
if (r < 0) | |
{ | |
errno = r; | |
myerror ("close"); | |
abort (); | |
} | |
return r; | |
} | |
int fork() | |
{ | |
int r = __syscall0(__NR_fork); | |
if (r < 0) | |
{ | |
errno = r; | |
myerror ("fork"); | |
abort (); | |
} | |
return r; | |
} | |
int unshare (int flags) | |
{ | |
int r = __syscall1(__NR_unshare, flags); | |
if (r < 0) | |
{ | |
errno = r; | |
myerror ("unshare"); | |
abort (); | |
} | |
return r; | |
} | |
int chdir(const char *path) | |
{ | |
int r = __syscall1(__NR_chdir, (long) path); | |
if (r < 0) | |
{ | |
errno = r; | |
myerror ("chdir"); | |
abort (); | |
} | |
return r; | |
} | |
int chroot(const char *path) | |
{ | |
int r = __syscall1(__NR_chroot, (long) path); | |
if (r < 0) | |
{ | |
errno = r; | |
myerror ("chroot"); | |
abort (); | |
} | |
return r; | |
} | |
ssize_t read(int fd, void *buf, size_t count) | |
{ | |
int r = __syscall3(__NR_read, fd, (long) buf, (long) count); | |
if (r < 0) | |
{ | |
errno = r; | |
myerror ("read"); | |
abort (); | |
} | |
return r; | |
} | |
ssize_t write(int fd, const void *buf, size_t count) | |
{ | |
int r = __syscall3(__NR_write, fd, (long) buf, (long) count); | |
if (r < 0) | |
{ | |
errno = r; | |
myerror ("write"); | |
abort (); | |
} | |
return r; | |
} | |
int symlinkat(const char *target, int newdirfd, const char *linkpath) | |
{ | |
int r = __syscall3(__NR_symlinkat, (long) target, newdirfd, (long) linkpath); | |
if (r < 0) | |
{ | |
errno = r; | |
myerror ("symlinkat"); | |
abort (); | |
} | |
return r; | |
} | |
ssize_t readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz) | |
{ | |
int r = __syscall4(__NR_readlinkat, dirfd, (long) pathname, (long) buf, (long) bufsiz); | |
if (r < 0) | |
{ | |
errno = r; | |
myerror ("readlinkat"); | |
abort (); | |
} | |
return r; | |
} | |
int mkdirat(int fd, const char *path, mode_t mode) | |
{ | |
int r = __syscall3(__NR_mkdirat, fd, (long) path, (long) mode); | |
if (r < 0) | |
{ | |
errno = r; | |
myerror ("mkdirat"); | |
abort (); | |
} | |
return r; | |
} | |
mode_t umask(mode_t mode) | |
{ | |
return __syscall1(__NR_umask, mode); | |
} | |
int unlinkat(int dirfd, const char *pathname, int flags) | |
{ | |
int r = __syscall3(__NR_unlinkat, dirfd, (long) pathname, flags); | |
if (r < 0) | |
{ | |
errno = r; | |
fdputs (2, pathname); | |
myerror ("unlinkat"); | |
abort (); | |
} | |
return r; | |
} | |
int nanosleep(const struct timespec *req, struct timespec *rem) | |
{ | |
int r = __syscall2(__NR_nanosleep, (long) req, (long) rem); | |
if (r < 0) | |
{ | |
errno = r; | |
myerror ("nanosleep"); | |
abort (); | |
} | |
return r; | |
} | |
int kill (pid_t pid, int sig) | |
{ | |
int r = __syscall2(__NR_kill, pid, sig); | |
if (r < 0) | |
{ | |
errno = r; | |
myerror ("kill"); | |
abort (); | |
} | |
return r; | |
} | |
int pause () | |
{ | |
return __syscall0(__NR_pause); | |
} | |
pid_t getpid () | |
{ | |
return __syscall0(__NR_getpid); | |
} | |
int sys_waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options, struct rusage *ru) | |
{ | |
int r = __syscall5(__NR_waitid, idtype, id, (long) infop, options, (long) ru); | |
if (r < 0) | |
{ | |
errno = r; | |
myerror ("waitid"); | |
abort (); | |
} | |
return r; | |
} | |
int link(const char *oldpath, const char *newpath) | |
{ | |
int r = __syscall2(__NR_link, (long) oldpath, (long) newpath); | |
if (r < 0) | |
{ | |
errno = r; | |
myerror ("link"); | |
abort (); | |
} | |
return r; | |
} | |
int execve(const char *filename, char *const argv[], | |
char *const envp[]) | |
{ | |
int r = __syscall3(__NR_execve, (long) filename, (long) argv, (long) envp); | |
if (r < 0) | |
{ | |
errno = r; | |
// myerror ("execve"); | |
abort (); | |
} | |
return r; | |
} | |
int reboot(int magic, int magic2, int cmd, void *arg) | |
{ | |
return __syscall4(__NR_reboot, (long) magic, (long) magic2, (long) cmd, (long) arg); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment