/* * 2015 by Marek Behun * Only for Linux x86_64 * gcc -nostdlib -nostdinc -o sys sys.c */ /* nadefinujeme si typy size_t a ssize_t */ typedef unsigned long int size_t; typedef long int ssize_t; /* toto bude funkcia na pristup do kernelu */ long (*syscall) (long int, ...); void init_syscall (void) { /* a tu je jej kod, skompilovany assembler pre x86_64 pre Linux */ static const char syscall_code[] = { 0x48, 0x89, 0xf8, // mov %rdi, %rax 0x48, 0x89, 0xf7, // mov %rsi, %rdi 0x48, 0x89, 0xd6, // mov %rdx, %rsi 0x48, 0x89, 0xca, // mov %rcx, %rdx 0x4d, 0x89, 0xc2, // mov %r8, %r10 0x4d, 0x89, 0xc8, // mov %r9, %r8 0x4c, 0x8b, 0x4c, 0x24, 0x08, // mov 0x8(%rsp), %r9 0x0f, 0x05, // syscall 0xc3, // retq }; /* nastavime, aby pointer syscall ukazoval na zaciatok kodu */ syscall = (void *) &syscall_code[0]; } ssize_t sys_read (int fd, void * buf, size_t count) { return syscall (0, fd, buf, count); } ssize_t sys_write (int fd, void * buf, size_t count) { return syscall (1, fd, buf, count); } void sys_exit (int status) { syscall (60, status); } void _start (int argc, char ** argv, char ** envp) { init_syscall (); sys_write (1, "abc\n", 4); sys_exit (0); }