#include #include #include #include #include #define MAX_CMD 256 #define MAX_PIDS 64 // Maximum number of PIDs we will fetch at once // External Syscall Prototypes uint32_t SysGetProcessList(uint32_t* pidsOut, size_t maxCount, size_t* countOut); // --------------------------------------------------------------------------- // Output helpers // --------------------------------------------------------------------------- static void print(const char* s) { SYS_WRITE_CONSOLE_REQUEST req = { SysSvFromCstr(s) }; SysWriteConsole(&req); } static uint32_t open_file(const char* path, uint32_t* handleOut) { SYS_PATH_HANDLE_REQUEST req = { SysSvFromCstr(path), handleOut }; return SysOpenFile(&req); } static uint32_t create_file(const char* path, uint32_t* handleOut) { SYS_PATH_HANDLE_REQUEST req = { SysSvFromCstr(path), handleOut }; return SysCreateFile(&req); } static uint32_t open_dir(const char* path, uint32_t* handleOut) { SYS_PATH_HANDLE_REQUEST req = { SysSvFromCstr(path), handleOut }; return SysOpenDir(&req); } static uint32_t set_cwd(const char* path) { SYS_PATH_REQUEST req = { SysSvFromCstr(path) }; return SysSetCwd(&req); } static uint32_t delete_file(const char* path) { SYS_PATH_REQUEST req = { SysSvFromCstr(path) }; return SysDeleteFile(&req); } static uint32_t create_process(const char* path, uint32_t* handleOut, const char* cmdline) { SYS_CREATE_PROCESS_REQUEST req = { SysSvFromCstr(path), SysSvFromCstr(cmdline), handleOut }; return SysCreateProcess(&req); } static void printUInt(uint32_t n) { char buf[12]; int i = 0; if (n == 0) { print("0"); return; } while (n > 0) { buf[i++] = (char)('0' + n % 10); n /= 10; } while (i > 0) { char c[2] = { buf[--i], '\0' }; print(c); } } static void printInt(int32_t n) { if (n < 0) { print("-"); printUInt((uint32_t)-(n + 1) + 1); } else { printUInt((uint32_t)n); } } static void printUInt64(uint64_t n) { if (n == 0) { print("0"); return; } char buf[20]; int i = 0; while (n > 0) { buf[i++] = (char)('0' + (int)(n % 10)); n /= 10; } while (i > 0) { char c[2] = { buf[--i], '\0' }; print(c); } } // --------------------------------------------------------------------------- // Line editor // --------------------------------------------------------------------------- static void readLine(char* buf, int len) { int pos = 0; while (true) { char c = SysKbReadChar(); if (!c) { SysYield(); continue; } if (c == '\r' || c == '\n') { print("\n"); break; } if ((c == '\b' || c == 127) && pos > 0) { pos--; print("\b \b"); continue; } if (c < 0x20 || c == 127) continue; if (pos < len - 1) { buf[pos++] = c; char echo[2] = {c, '\0'}; print(echo); } } buf[pos] = '\0'; } static char* trim(char* s) { while (*s == ' ') s++; int len = (int)strlen(s); while (len > 0 && s[len - 1] == ' ') len--; s[len] = '\0'; return s; } // --------------------------------------------------------------------------- // Built-in commands // --------------------------------------------------------------------------- static void cmd_help() { print("Available commands:\n" " help - Show this list\n" " mem - Show memory usage\n" " ps - List running process IDs\n" " dir [path] - List directory contents\n" " cd - Change directory\n" " type - Display file contents\n" " del - Delete a file\n" " write - Create a file with text\n" " clear - Clear the screen\n" " exit - Close the shell\n"); } static void printSizeKiB(uint64_t bytes) { printUInt64(bytes / 1024u); print(" KiB"); } static void cmd_mem(void) { SYS_MEMORY_STATUS st; if (SysGetMemoryStatus(&st) != 0) { print("mem: failed\n"); return; } print("Memory Status:\n"); print(" Free physical: "); printSizeKiB(st.FreePhysicalBytes); print("\n Kernel pool: "); printSizeKiB(st.KernelPoolBytes); print("\n User heap: "); printSizeKiB(st.UserHeapBytes); print("\n"); } static void cmd_ps(void) { uint32_t pids[MAX_PIDS]; size_t count = 0; uint32_t status = SysGetProcessList(pids, MAX_PIDS, &count); if (status != 0) { print("ps: failed to retrieve process list\n"); return; } print("Running Processes (Count: "); printUInt((uint32_t)count); print("):\n"); size_t displayCount = count < MAX_PIDS ? count : MAX_PIDS; for (size_t i = 0; i < displayCount; i++) { print(" PID: "); printUInt(pids[i]); print("\n"); } if (count > MAX_PIDS) { print(" ... and "); printUInt((uint32_t)(count - MAX_PIDS)); print(" more processes.\n"); } } static void cmd_write(const char* args) { char filename[MAX_CMD]; int i = 0; while (args[i] != ' ' && args[i] != '\0' && i < MAX_CMD - 1) { filename[i] = args[i]; i++; } filename[i] = '\0'; if (args[i] == '\0' || args[i+1] == '\0') { print("write: usage: write \n"); return; } uint32_t hFile; if (create_file(filename, &hFile) != 0) { print("write: could not create file\n"); return; } size_t written; SysWriteFile(hFile, args + i + 1, strlen(args + i + 1), &written); SysCloseHandle(hFile); print("File written successfully.\n"); } static void cmd_dir(const char* path) { uint32_t hDir; const char* target = (path && *path != '\0') ? path : "."; if (open_dir(target, &hDir) != 0) { print("dir: failed to open directory\n"); return; } SYS_DIR_ENTRY ke; while (SysReadDir(hDir, &ke) == 0) { // Corrected Attribute Check: 0x10 is the Directory bit in FAT if (ke.Attr & 0x10) { print(" "); } else { print(" "); } print(ke.Name); // Optional: print file size for non-directories if (!(ke.Attr & 0x10)) { print(" ("); printUInt(ke.FileSize); print(" bytes)"); } print("\n"); } SysCloseHandle(hDir); } static void cmd_type(const char* filename) { uint32_t hFile; if (open_file(filename, &hFile) != 0) { print("type: cannot open file\n"); return; } char buffer[512]; size_t bytesRead; while (SysReadFile(hFile, buffer, sizeof(buffer) - 1, &bytesRead) == 0 && bytesRead > 0) { buffer[bytesRead] = '\0'; print(buffer); } SysCloseHandle(hFile); print("\n"); } static bool extractProgramPath(const char* cmdline, char* out, size_t outSize) { if (!cmdline || !out || outSize == 0) return false; while (*cmdline == ' ' || *cmdline == '\t') cmdline++; if (*cmdline == '\0') return false; size_t pos = 0; if (*cmdline == '"') { cmdline++; while (*cmdline && *cmdline != '"' && pos + 1 < outSize) out[pos++] = *cmdline++; } else { while (*cmdline && *cmdline != ' ' && *cmdline != '\t' && pos + 1 < outSize) out[pos++] = *cmdline++; } out[pos] = '\0'; return pos != 0; } // --------------------------------------------------------------------------- // Run one command // --------------------------------------------------------------------------- static int runCommand(const char* cmd) { if (!cmd || *cmd == '\0') return 0; if (strcmp(cmd, "exit") == 0) return 1; if (strcmp(cmd, "help") == 0) { cmd_help(); return 0; } if (strcmp(cmd, "clear") == 0) { SysScreenClear(0); return 0; } if (strncmp(cmd, "crash", 5) == 0) { // Check the sub-option trailing "crash " (offset 6) if (strcmp(cmd + 6, "void") == 0) { // Jumping into the void void (*invalid_func)(void) = NULL; invalid_func(); return 0; } else if (strcmp(cmd + 6, "noncanonical") == 0) { // Non-canonical pointer dereference volatile int *ptr = (volatile int*)0x4242424242424242ULL; *ptr = 1337; return 0; } else if (strcmp(cmd + 6, "ud2") == 0) { __ud2(); return 0; } else if (strcmp(cmd + 6, "nx") == 0) { // NX / DEP Violation unsigned char code[] = { 0xC3 }; void (*execute_stack)(void) = (void (*)(void))code; execute_stack(); return 0; } else if (strcmp(cmd + 6, "divzero") == 0) { // Division by zero volatile int zero = 0; volatile int result = 1 / zero; (void)result; return 0; } else { // Default fallback if just "crash" or an unknown sub-option is passed *(volatile int*)0 = 42; return 0; } } if (strcmp(cmd, "mem") == 0) { cmd_mem(); return 0; } if (strcmp(cmd, "ps") == 0) { cmd_ps(); return 0; } if (strcmp(cmd, "dir") == 0) { cmd_dir("."); return 0; } if (strncmp(cmd, "dir ", 4) == 0) { cmd_dir(cmd + 4); return 0; } if (strncmp(cmd, "cd ", 3) == 0) { if (set_cwd(cmd + 3) != 0) print("cd: failed\n"); return 0; } if (strncmp(cmd, "del ", 4) == 0) { delete_file(cmd + 4); return 0; } if (strncmp(cmd, "type ", 5) == 0) { cmd_type(cmd + 5); return 0; } if (strncmp(cmd, "write ", 6) == 0) { cmd_write(cmd + 6); return 0; } char program[MAX_CMD]; if (!extractProgramPath(cmd, program, sizeof(program))) return 0; uint32_t hProc; if (create_process(program, &hProc, cmd) == 0) { SysWaitForProcess(hProc); SysCloseHandle(hProc); while (SysKbPoll()) (void)SysKbReadChar(); } else { print("shell: launch failed\n"); } return 0; } int main(void) { const char* cmdline = SysGetPeb()->CommandLine.Data; char lineBuf[MAX_CMD]; print("shell: command line: "); print(cmdline); print("\n"); print("shell: ready\n"); while (true) { print("> "); readLine(lineBuf, MAX_CMD); if (runCommand(trim(lineBuf))) break; } print("shell: goodbye\n"); SysExitProcess(0); return 0; }