From c8cd18d21ce8763b7aed18b510ef9a96ed36ac29 Mon Sep 17 00:00:00 2001 From: pathetic Date: Mon, 12 May 2025 23:10:28 +0100 Subject: [PATCH] Correctly structured project & implemented required functions --- build/build.sh => build.sh | 1 + build/main | Bin 0 -> 9616 bytes build/syscalls.o | Bin 0 -> 976 bytes "build/syscalls.o\r" | Bin 0 -> 768 bytes main.c | 8 - src/assembly/syscalls.asm | 45 ++++ nstdo.h => src/headers/nstdo.h | 105 +++++----- src/main.c | 52 +++++ syscalls.asm | 16 -- syscalls.txt | 362 +++++++++++++++++++++++++++++++++ 10 files changed, 513 insertions(+), 76 deletions(-) rename build/build.sh => build.sh (75%) create mode 100644 build/main create mode 100644 build/syscalls.o create mode 100644 "build/syscalls.o\r" delete mode 100644 main.c create mode 100644 src/assembly/syscalls.asm rename nstdo.h => src/headers/nstdo.h (94%) create mode 100644 src/main.c delete mode 100644 syscalls.asm create mode 100644 syscalls.txt diff --git a/build/build.sh b/build.sh similarity index 75% rename from build/build.sh rename to build.sh index b1db3fb..75edf63 100644 --- a/build/build.sh +++ b/build.sh @@ -1,3 +1,4 @@ +#!/usr/bin/env bash set -e nasm -f elf64 ./src/assembly/syscalls.asm -o ./build/syscalls.o diff --git a/build/main b/build/main new file mode 100644 index 0000000000000000000000000000000000000000..ff6b6e21cbfc2d53ffdc5e78d48b501ba38aa045 GIT binary patch literal 9616 zcmeHNU1%It6uz_VHc8d&)*mRe%FygXt7JBbLE>Loh?5Q?H41^C)^&Dw(p}x3xHF@> z#cCxj|3+FrKi2hjFx?%KSu)u?4pq92Qo@VGLf={5;c2j539d z&>bPdA{WOqSDjQ3Ti((vZU^J=kP1izqyka_sen{KDj*e*3j7BOtYD5%aBT&ji_t#J?W5d2&h2B=);|Vg zc(oO_y&k&n_bJ1>YIrAGhUYdL1ID7>3N44hG(*c|?1IxnD>NQ5=Jb{VQ&V9SGGBFW za*oPn7dLQ=RuOUMYsen{KDj*e*3P=T{0#X5~fK)&#AQkvu6i8dySuEU#3soId zQyF_UYnD|fov~F4<}BMbk6XJ*pH<2@$f4FrTdEC&>~4a4etP_$HxA{*vqUL{m3_DO z^e(}J@_xYZy7*hWokW7(A3hxzzhhV6Ibbj!zEjxKY_}im_PW*yF(0Er^T$2MWUU1jl=Q{9_y!eHwy) zl;f(8KTUDyN{Gb-mD&`{cS7BtIG<_@SO%^zc1-yA_+|Mg+@*Mc?Df?>#qonaoM=(I zn2egXZRHZ#a?~!{Ni&s6fNSu0O~5uYg(U!jYlWv1xj^GacZzvx#H^ifz~yr{q3U&9zr3L>}g)4gHfZ@4>t zQjJmnq)H7bG1Hm-@e|;|_@NGiEjCnUAMoMG#nEj$XJ;-tw^X({#fhjf_8*D*dzl-0 knpn>c-*!yt09$$;ge^o}0q=nY_WbyVGQg0heGY&8-+B$_6951J literal 0 HcmV?d00001 diff --git a/build/syscalls.o b/build/syscalls.o new file mode 100644 index 0000000000000000000000000000000000000000..5ce8c9c530a41d8890a857002097e38d2a83c314 GIT binary patch literal 976 zcmbV~Jxc>Y5QgWH7}FU$Ed;d^l)DsKh#Ia@6zpt;usK&eyi?d+Os=x_-&kH5u<)J08g`X~KpV1+P zjQ5#dwz|!jlXSE_mg9F@wfUx73<&n9p=0ZCPmkuUkzXfHvUV{YDyc~o@cmmB<7{rP z)bID8#9qF?#Kx7Sw-S@+56K^qKOukY{D=L9^OyIsl2(L9P7Q?mP8(&!*hWQOdD2Q| zqAJ4PzYN!R;B(%TZ#TTC4O__nOYGft9H;%ZT`T)`j=#Up9uViV@ZDg&|NVUZ1@TP} z$X^lPVf>nS#CR>kNUJ0gTFZQ#6_GA0NkK2LlTU-QZc!#687Q-J^g literal 0 HcmV?d00001 diff --git "a/build/syscalls.o\r" "b/build/syscalls.o\r" new file mode 100644 index 0000000000000000000000000000000000000000..f9314ab0a1e8f45bd85f9920c58f08d3db5ddd7c GIT binary patch literal 768 zcmb<-^>JfjWMqH=Mg}_u1P><4z~F#jLfH-sYz$0DqU13_c7ZS(n)U-wM~I_|3!w4Y zfqZ5(F%b6wRKE_I98?%CDhOm@^MwFZZ~{~%3y=oc!vW<>Kxs*+IFt*g7C`kI!$lwr zbo&*7!XUHJ!2_s%m^~o7L3+{c-vJWjXFdD^WPnHK@f|i`K8ObadL^k9B@BAS8O0?< zC5cHuR%I@PhVqM2a}ptnU|O)zAZu6{KK{oh#|(BEs*Eg7grW1C+6f7>m?TFGUO&^<}m<8;>(LNOHvu)i%SxV XO5i%d3{EH)6r7+i{PQ0Ipu!9Qg;F?O literal 0 HcmV?d00001 diff --git a/main.c b/main.c deleted file mode 100644 index 7e2442f..0000000 --- a/main.c +++ /dev/null @@ -1,8 +0,0 @@ -#include "headers/nstdo.h" -extern long sys_write(int fd, const void *buf, size_t count); - -int main(void) { - const char msg[] = "Hello, World!\n"; - sys_write(1, msg, sizeof(msg)-1); - return 0; -} diff --git a/src/assembly/syscalls.asm b/src/assembly/syscalls.asm new file mode 100644 index 0000000..144aaa2 --- /dev/null +++ b/src/assembly/syscalls.asm @@ -0,0 +1,45 @@ +global _start +global sys_read +global sys_write +global sys_fork +global sys_execve +global sys_wait4 +global sys_exit +extern main + +section .text + +sys_read: + mov rax, 0 + syscall + ret + +sys_write: + mov rax, 1 + syscall + ret + +sys_fork: + mov rax, 57 + syscall + ret + +sys_execve: + mov rax, 59 + syscall + ret + +sys_wait4: + mov rax, 61 + syscall + ret + +sys_exit: + mov rax, 60 + syscall + +_start: + call main + mov rdi, rax + mov rax, 60 + syscall diff --git a/nstdo.h b/src/headers/nstdo.h similarity index 94% rename from nstdo.h rename to src/headers/nstdo.h index 919274e..3cd7aab 100644 --- a/nstdo.h +++ b/src/headers/nstdo.h @@ -1,52 +1,53 @@ -#ifndef MINI_STDIO_H -#define MINI_STDIO_H - -#ifdef __cplusplus -extern "C" { -#endif - -typedef unsigned long size_t; -typedef long off_t; - -#define O_RDONLY 0 -#define O_WRONLY 1 -#define O_RDWR 2 -#define O_CREAT 64 -#define O_TRUNC 512 -#define O_APPEND 1024 -#define O_CLOEXEC 02000000 - -typedef __builtin_va_list va_list; -#define va_start(ap,last) __builtin_va_start(ap,last) -#define va_arg(ap,type) __builtin_va_arg(ap,type) -#define va_end(ap) __builtin_va_end(ap) - -#define SYS_READ 0 -#define SYS_WRITE 1 -#define SYS_OPEN 2 -#define SYS_CLOSE 3 -#define SYS_LSEEK 8 - -static inline long _syscall3(long nr,long a1,long a2,long a3){long ret;asm volatile("syscall":"=a"(ret):"a"(nr),"D"(a1),"S"(a2),"d"(a3):"rcx","r11","memory");return ret;} - -#ifndef MY_BUFSIZ -#define MY_BUFSIZ 4096 -#endif - -typedef struct{int fd;char buf[MY_BUFSIZ];size_t pos;size_t len;int mode;}MY_FILE; - -MY_FILE* my_fopen(const char* path,int flags,int mode); -int my_fclose(MY_FILE* f); -size_t my_fread(void* ptr,size_t size,size_t nmemb,MY_FILE* f); -size_t my_fwrite(const void* ptr,size_t size,size_t nmemb,MY_FILE* f); -int my_putc(int c,MY_FILE* f); -int my_puts(const char* s,MY_FILE* f); -off_t my_seek(MY_FILE* f,off_t offset,int whence); -int my_printf(MY_FILE* f,const char* fmt,...); -int my_vprintf(MY_FILE* f,const char* fmt,va_list ap); - -#ifdef __cplusplus -} -#endif - -#endif +#ifndef MINI_STDIO_H +#define MINI_STDIO_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned long size_t; +typedef long off_t; +#define NULL ((void*)0) + +#define O_RDONLY 0 +#define O_WRONLY 1 +#define O_RDWR 2 +#define O_CREAT 64 +#define O_TRUNC 512 +#define O_APPEND 1024 +#define O_CLOEXEC 02000000 + +typedef __builtin_va_list va_list; +#define va_start(ap,last) __builtin_va_start(ap,last) +#define va_arg(ap,type) __builtin_va_arg(ap,type) +#define va_end(ap) __builtin_va_end(ap) + +#define SYS_READ 0 +#define SYS_WRITE 1 +#define SYS_OPEN 2 +#define SYS_CLOSE 3 +#define SYS_LSEEK 8 + +static inline long _syscall3(long nr,long a1,long a2,long a3){long ret;asm volatile("syscall":"=a"(ret):"a"(nr),"D"(a1),"S"(a2),"d"(a3):"rcx","r11","memory");return ret;} + +#ifndef MY_BUFSIZ +#define MY_BUFSIZ 4096 +#endif + +typedef struct{int fd;char buf[MY_BUFSIZ];size_t pos;size_t len;int mode;}MY_FILE; + +MY_FILE* my_fopen(const char* path,int flags,int mode); +int my_fclose(MY_FILE* f); +size_t my_fread(void* ptr,size_t size,size_t nmemb,MY_FILE* f); +size_t my_fwrite(const void* ptr,size_t size,size_t nmemb,MY_FILE* f); +int my_putc(int c,MY_FILE* f); +int my_puts(const char* s,MY_FILE* f); +off_t my_seek(MY_FILE* f,off_t offset,int whence); +int my_printf(MY_FILE* f,const char* fmt,...); +int my_vprintf(MY_FILE* f,const char* fmt,va_list ap); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..c01ee8a --- /dev/null +++ b/src/main.c @@ -0,0 +1,52 @@ +#include "headers/nstdo.h" +extern long sys_read(int fd, void *buf, size_t cnt); +extern long sys_write(int fd, const void *buf, size_t cnt); +extern long sys_fork(void); +extern long sys_execve(const char *filename, char *const argv[], char *const envp[]); +extern long sys_wait4(int pid, int *wstatus, int options, void *rusage); +extern void sys_exit(int status); + +static int streq(const char *a, const char *b) { + while (*a && *b) { + if (*a != *b) return 0; + a++; b++; + } + return *a == *b; +} + +static long str_len(const char *s) { + long len = 0; + while (s[len]) len++; + return len; +} + +int main(int argc, char *argv[], char *envp[]) { + (void)argc; (void)argv; + const char prompt[] = "$ "; + char buf[512]; + while (1) { + sys_write(1, prompt, sizeof(prompt)-1); + long n = sys_read(0, buf, sizeof(buf)-1); + if (n <= 0) break; + buf[n-1] = '\0'; + if (streq(buf, "help")) { + const char *h1 = " help - display this help message\n"; + const char *h2 = " exit - exit the shell\n"; + sys_write(1, h1, str_len(h1)); + sys_write(1, h2, str_len(h2)); + continue; + } + if (streq(buf, "exit")) { + break; + } + char *args[] = { buf, NULL }; + long pid = sys_fork(); + if (pid == 0) { + sys_execve(buf, args, envp); + sys_exit(1); + } else { + sys_wait4(pid, 0, 0, 0); + } + } + return 0; +} diff --git a/syscalls.asm b/syscalls.asm deleted file mode 100644 index 1e3e39d..0000000 --- a/syscalls.asm +++ /dev/null @@ -1,16 +0,0 @@ -global _start -global sys_write -extern main - -section .text - -sys_write: - mov rax, 1 - syscall - ret - -_start: - call main - mov rdi, rax - mov rax, 60 - syscall \ No newline at end of file diff --git a/syscalls.txt b/syscalls.txt new file mode 100644 index 0000000..3e2b974 --- /dev/null +++ b/syscalls.txt @@ -0,0 +1,362 @@ +Using x86_64 syscall table: +0 read +1 write +2 open +3 close +4 stat +5 fstat +6 lstat +7 poll +8 lseek +9 mmap +10 mprotect +11 munmap +12 brk +13 rt_sigaction +14 rt_sigprocmask +15 rt_sigreturn +16 ioctl +17 pread +18 pwrite +19 readv +20 writev +21 access +22 pipe +23 select +24 sched_yield +25 mremap +26 msync +27 mincore +28 madvise +29 shmget +30 shmat +31 shmctl +32 dup +33 dup2 +34 pause +35 nanosleep +36 getitimer +37 alarm +38 setitimer +39 getpid +40 sendfile +41 socket +42 connect +43 accept +44 sendto +45 recvfrom +46 sendmsg +47 recvmsg +48 shutdown +49 bind +50 listen +51 getsockname +52 getpeername +53 socketpair +54 setsockopt +55 getsockopt +56 clone +57 fork +58 vfork +59 execve +60 exit +61 wait4 +62 kill +63 uname +64 semget +65 semop +66 semctl +67 shmdt +68 msgget +69 msgsnd +70 msgrcv +71 msgctl +72 fcntl +73 flock +74 fsync +75 fdatasync +76 truncate +77 ftruncate +78 getdents +79 getcwd +80 chdir +81 fchdir +82 rename +83 mkdir +84 rmdir +85 creat +86 link +87 unlink +88 symlink +89 readlink +90 chmod +91 fchmod +92 chown +93 fchown +94 lchown +95 umask +96 gettimeofday +97 getrlimit +98 getrusage +99 sysinfo +100 times +101 ptrace +102 getuid +103 syslog +104 getgid +105 setuid +106 setgid +107 geteuid +108 getegid +109 setpgid +110 getppid +111 getpgrp +112 setsid +113 setreuid +114 setregid +115 getgroups +116 setgroups +117 setresuid +118 getresuid +119 setresgid +120 getresgid +121 getpgid +122 setfsuid +123 setfsgid +124 getsid +125 capget +126 capset +127 rt_sigpending +128 rt_sigtimedwait +129 rt_sigqueueinfo +130 rt_sigsuspend +131 sigaltstack +132 utime +133 mknod +134 uselib +135 personality +136 ustat +137 statfs +138 fstatfs +139 sysfs +140 getpriority +141 setpriority +142 sched_setparam +143 sched_getparam +144 sched_setscheduler +145 sched_getscheduler +146 sched_get_priority_max +147 sched_get_priority_min +148 sched_rr_get_interval +149 mlock +150 munlock +151 mlockall +152 munlockall +153 vhangup +154 modify_ldt +155 pivot_root +156 _sysctl +157 prctl +158 arch_prctl +159 adjtimex +160 setrlimit +161 chroot +162 sync +163 acct +164 settimeofday +165 mount +166 umount2 +167 swapon +168 swapoff +169 reboot +170 sethostname +171 setdomainname +172 iopl +173 ioperm +174 create_module +175 init_module +176 delete_module +177 get_kernel_syms +178 query_module +179 quotactl +180 nfsservctl +181 getpmsg +182 putpmsg +183 afs_syscall +184 tuxcall +185 security +186 gettid +187 readahead +188 setxattr +189 lsetxattr +190 fsetxattr +191 getxattr +192 lgetxattr +193 fgetxattr +194 listxattr +195 llistxattr +196 flistxattr +197 removexattr +198 lremovexattr +199 fremovexattr +200 tkill +201 time +202 futex +203 sched_setaffinity +204 sched_getaffinity +205 set_thread_area +206 io_setup +207 io_destroy +208 io_getevents +209 io_submit +210 io_cancel +211 get_thread_area +212 lookup_dcookie +213 epoll_create +214 epoll_ctl_old +215 epoll_wait_old +216 remap_file_pages +217 getdents64 +218 set_tid_address +219 restart_syscall +220 semtimedop +221 fadvise64 +222 timer_create +223 timer_settime +224 timer_gettime +225 timer_getoverrun +226 timer_delete +227 clock_settime +228 clock_gettime +229 clock_getres +230 clock_nanosleep +231 exit_group +232 epoll_wait +233 epoll_ctl +234 tgkill +235 utimes +236 vserver +237 mbind +238 set_mempolicy +239 get_mempolicy +240 mq_open +241 mq_unlink +242 mq_timedsend +243 mq_timedreceive +244 mq_notify +245 mq_getsetattr +246 kexec_load +247 waitid +248 add_key +249 request_key +250 keyctl +251 ioprio_set +252 ioprio_get +253 inotify_init +254 inotify_add_watch +255 inotify_rm_watch +256 migrate_pages +257 openat +258 mkdirat +259 mknodat +260 fchownat +261 futimesat +262 newfstatat +263 unlinkat +264 renameat +265 linkat +266 symlinkat +267 readlinkat +268 fchmodat +269 faccessat +270 pselect6 +271 ppoll +272 unshare +273 set_robust_list +274 get_robust_list +275 splice +276 tee +277 sync_file_range +278 vmsplice +279 move_pages +280 utimensat +281 epoll_pwait +282 signalfd +283 timerfd_create +284 eventfd +285 fallocate +286 timerfd_settime +287 timerfd_gettime +288 accept4 +289 signalfd4 +290 eventfd2 +291 epoll_create1 +292 dup3 +293 pipe2 +294 inotify_init1 +295 preadv +296 pwritev +297 rt_tgsigqueueinfo +298 perf_event_open +299 recvmmsg +300 fanotify_init +301 fanotify_mark +302 prlimit64 +303 name_to_handle_at +304 open_by_handle_at +305 clock_adjtime +306 syncfs +307 sendmmsg +308 setns +309 getcpu +310 process_vm_readv +311 process_vm_writev +312 kcmp +313 finit_module +314 sched_setattr +315 sched_getattr +316 renameat2 +317 seccomp +318 getrandom +319 memfd_create +320 kexec_file_load +321 bpf +322 execveat +323 userfaultfd +324 membarrier +325 mlock2 +326 copy_file_range +327 preadv2 +328 pwritev2 +329 pkey_mprotect +330 pkey_alloc +331 pkey_free +332 statx +333 io_pgetevents +334 rseq +424 pidfd_send_signal +425 io_uring_setup +426 io_uring_enter +427 io_uring_register +428 open_tree +429 move_mount +430 fsopen +431 fsconfig +432 fsmount +433 fspick +434 pidfd_open +435 clone3 +436 close_range +437 openat2 +438 pidfd_getfd +439 faccessat2 +440 process_madvise +441 epoll_pwait2 +442 mount_setattr +443 quotactl_fd +444 landlock_create_ruleset +445 landlock_add_rule +446 landlock_restrict_self +447 memfd_secret +448 process_mrelease +449 futex_waitv