diff --git a/CMakeLists.txt b/CMakeLists.txt index 586381b..227bd4b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -323,6 +323,7 @@ add_custom_command(OUTPUT lindows_c.img COMMAND ${CoreUtils_Mkdir_EXECUTABLE} ARGS lindows_c/Windows COMMAND ${CoreUtils_Mkdir_EXECUTABLE} ARGS lindows_c/Windows/System32 COMMAND ${CoreUtils_Mkdir_EXECUTABLE} ARGS lindows_c/Windows/System32/LNXConfig + COMMAND ${CoreUtils_Mkdir_EXECUTABLE} ARGS lindows_c/Windows/System32/Config COMMAND ${CoreUtils_Mkdir_EXECUTABLE} ARGS lindows_c/Windows/GRUB COMMAND ${CoreUtils_Mkdir_EXECUTABLE} ARGS lindows_c/Windows/GRUB/x86_64-efi COMMAND ${CoreUtils_Mkdir_EXECUTABLE} ARGS 'lindows_c/Windows/Temporary Files' @@ -351,7 +352,13 @@ add_custom_command(OUTPUT lindows_c.img COMMAND ${CoreUtils_Copy_EXECUTABLE} ARGS $ lindows_c/Windows/System32/lsmss.exe COMMAND ${CoreUtils_Copy_EXECUTABLE} ARGS $ lindows_c/Windows/System32/lrss.exe COMMAND ${CoreUtils_Copy_EXECUTABLE} ARGS $ lindows_c/Windows/System32/liblrssclient.so - + COMMAND ${CoreUtils_Copy_EXECUTABLE} ARGS $ lindows_c/Windows/System32/lexecutive.exe + COMMAND ${CoreUtils_Copy_EXECUTABLE} ARGS $ lindows_c/Windows/System32/lcrash.exe + + # create registry hives + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/scripts/mkhive lindows_c/Windows/System32/Config/System + COMMAND hivexsh lindows_c/Windows/System32/Config/System -w -f ${CMAKE_CURRENT_SOURCE_DIR}/scripts/hivex/system.hivex + # create users folder COMMAND ${CoreUtils_Mkdir_EXECUTABLE} ARGS lindows_c/Users @@ -359,6 +366,7 @@ add_custom_command(OUTPUT lindows_c.img COMMAND "umount" ARGS lindows_c DEPENDS + lexecutive lcrash lsmss lrss lrssclient Linux-install GLibC-install @@ -368,6 +376,7 @@ add_custom_command(OUTPUT lindows_c.img src/grub/grub.cfg src/glibc/ld.so.conf scripts/copylib + scripts/mkhive scripts/hivex/system.hivex ) # this makes the efi system partition @@ -426,5 +435,7 @@ add_custom_command(OUTPUT lindows.img add_custom_target(lindows ALL DEPENDS lindows.img) +add_subdirectory(executive) add_subdirectory(lsmss) add_subdirectory(lrss) +add_subdirectory(lcrash) diff --git a/README b/README index e35a797..0300269 100644 --- a/README +++ b/README @@ -1,7 +1,13 @@ == NAMING == +Mph: Metaprogramming helpers +Lnx: Linux interaction Pii: Preinit internal core routines Lrc: Lindows Registry client == SUBSYSTEM IPC == When a subsystem starts, LSMSS will wait for it to send a SIGSTOP to itself, afterwards, it will send a continue signal then keep going. + +== TODO == +[ ] we need a program that mimics the tasks preformed by the nt executive to manage the object tree, lindows subsystems and core applications will use the object tree directly, linux applications will be chrooted into the drive they're running on, unaware of the objtree and windows applications will use the appropriate win32 apis and for the most part will not interact with the objtree directly. various subsystems will manage their parts of the object tree, think sysfs but in userspace +[ ] driver that causes random kernel panics when an xbox controller is connected diff --git a/executive/CMakeLists.txt b/executive/CMakeLists.txt new file mode 100644 index 0000000..652cfec --- /dev/null +++ b/executive/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 3.28) + +lw_project(executive + DESCRIPTION "Lindows Userspace Executive" + TARGET LINDOWS +) + +lw_add_executable(lexecutive + SOURCES src/main.cxx src/syscall.cxx src/logging.cxx src/bugcheck.cxx +) +target_link_options(lexecutive PRIVATE -static -nostdlib) diff --git a/executive/src/bugcheck.cxx b/executive/src/bugcheck.cxx new file mode 100644 index 0000000..e835c2f --- /dev/null +++ b/executive/src/bugcheck.cxx @@ -0,0 +1,21 @@ +#include "bugcheck.hxx" +#include "syscall.hxx" +#include "logging.hxx" + +void InitializeBugCheckHandler() { + int LnxError = 0; + + // Get file descriptor for crashkernel + int CrashKernel = LnxSystemCall(LnxSystemOp::OPEN, "/Windows/System32/lcrash.exe", 0, 4); + ExecutiveLog("Crashkernel fd: {}", CrashKernel); + + if ((LnxError = LnxSystemCall( + LnxSystemOp::KEXEC_FILE_LOAD, + CrashKernel, 0, + 0, "", // no cmdline + 6 // crash + no initramfs + )) < 0) { + ExecutiveLog("Failed to load bugcheck kernel, bad things might happen! (errno {})", -LnxError); + return; + } +} diff --git a/executive/src/bugcheck.hxx b/executive/src/bugcheck.hxx new file mode 100644 index 0000000..46e1e4f --- /dev/null +++ b/executive/src/bugcheck.hxx @@ -0,0 +1,3 @@ +#pragma once + +void InitializeBugCheckHandler(); diff --git a/executive/src/logging.cxx b/executive/src/logging.cxx new file mode 100644 index 0000000..cf382fe --- /dev/null +++ b/executive/src/logging.cxx @@ -0,0 +1,4 @@ +#include "logging.hxx" + +char ExecutiveLogStringBuffer[4096] = {}; +char ExecutiveLogFormatOptions[128] = {}; diff --git a/executive/src/logging.hxx b/executive/src/logging.hxx new file mode 100644 index 0000000..ef7fac2 --- /dev/null +++ b/executive/src/logging.hxx @@ -0,0 +1,132 @@ +#pragma once + +#include "syscall.hxx" + +extern char ExecutiveLogStringBuffer[4096]; + +/** + * Write formatted data to the executive log buffer with ExecutiveLogFormatOptions + * + * \param Value Value to format + * \param BufferPos Position in ExecutiveLogStringBuffer + * \param Args Specification + */ +template +inline void ExecutiveLogFormatValue(const _Type* Value, int& BufferPos, const char* Args) = delete; + +/** + * Type has a format function + */ +template +concept ExecutiveLogCanFormat = requires(const _Type* Value, int& BufferPos, const char* Args) { + ExecutiveLogFormatValue(Value, BufferPos, Args); +}; + + +/** + * Log something. + * + * Format strings use \{\} for substitutions, substitutions can contain a number that + * updates the substitution index and a 127 byte format specification for formatters + */ +template +inline void ExecutiveLog(const char* Format, const _Type&... Items) { + // Format items and other goodies + const void* FormatItems[sizeof...(_Type)] = { &Items... }; + void (*FormatFunctions[sizeof...(_Type)])(const void*, int&, const char*) = { + // !!! VERY UNSAFE STUPID DUMB PIECE OF SHIT HACK !!! + reinterpret_cast(static_cast(ExecutiveLogFormatValue))... + }; + + // Buffer for format spec + char FormatOptions[128] = {}; + + // Indicies + int bpos = 0; + int fpos = 0; + int apos = 0; + + // Fill out the log buffer + while (Format[fpos] != 0 && bpos < 4095) { + // Handle replacements + if (Format[fpos] == '{') { + // Clear format options + FormatOptions[0] = 0; + + // Pattern matching cant come soon enough + switch (Format[++fpos]) { + case 0: { // Me when the uh i uh + LnxWrite(1, "BAD FORMAT STRING: ", 19); + LnxWrite(1, Format, fpos); + LnxWrite(1, "\n", 1); + return; + } + case '{': { // Escape + ExecutiveLogStringBuffer[bpos++] = '{'; + fpos += 1; + break; + } + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': { + volatile auto a = *(char*)(nullptr); + } + case ':': + default: { + volatile auto a = *(char*)(nullptr); + } + case '}': { // Finish the thing + fpos += 1; + // TODO: unsafe + FormatFunctions[apos](FormatItems[apos], bpos, FormatOptions); + apos += 1; + } + } + } else { + ExecutiveLogStringBuffer[bpos++] = Format[fpos++]; + } + } + + // Add our newline. + ExecutiveLogStringBuffer[bpos++] = '\n'; + + // Write to stdout. + LnxWrite(1, ExecutiveLogStringBuffer, bpos); +} + +// Formatters for builtin types +template<> +inline void ExecutiveLogFormatValue(const long* Value, int& BufferPos, const char* Args) { + // We only work with absolutes here. + long Absolute = *Value < 0 ? -*Value : *Value; + + // Find the biggest thing i dont fucking know i hate code comments + long TheBiggest = 1; + while (TheBiggest <= Absolute) TheBiggest *= 10; + + // Sign + if (*Value < 0 && BufferPos < 4095) ExecutiveLogStringBuffer[BufferPos++] = '-'; + + // The number + while (Absolute != 0 && BufferPos < 4095) { + ExecutiveLogStringBuffer[BufferPos++] = '0' + static_cast(Absolute * 10 / TheBiggest); + Absolute %= TheBiggest / 10; + TheBiggest /= 10; + } + + return; +} + +template<> +inline void ExecutiveLogFormatValue(const int* Value, int& BufferPos, const char* Args) { + long LongValue = *Value; + ExecutiveLogFormatValue(&LongValue, BufferPos, Args); + return; +} diff --git a/executive/src/main.cxx b/executive/src/main.cxx new file mode 100644 index 0000000..0d73457 --- /dev/null +++ b/executive/src/main.cxx @@ -0,0 +1,16 @@ +#include "./syscall.hxx" +#include "./logging.hxx" +#include "./bugcheck.hxx" + +/** + * We don't have libc as we're running below the rest of the userspace, we can't use the dynamic linker to load it as we run outside of the SystemRoot chroot. + * If we need something, we will need to implement it ourselves. + */ +extern "C" void _start() { + ExecutiveLog("Lindows OS Executive started"); + + ExecutiveLog("Loading bugcheck kernel"); + InitializeBugCheckHandler(); + + LnxExitProcess(42); +} diff --git a/executive/src/metaprogramming.hxx b/executive/src/metaprogramming.hxx new file mode 100644 index 0000000..90a4cb2 --- /dev/null +++ b/executive/src/metaprogramming.hxx @@ -0,0 +1,51 @@ +#pragma once + +// reimplementation of std::integral_constant +template +struct MphIntegralConstant { + using value_type = _Type; + using type = MphIntegralConstant; + + static constexpr _Type value = _Value; + + constexpr operator value_type() const noexcept { return value; } + constexpr value_type operator()() const noexcept { return value; } +}; + +// reimplementation of std::true_type and std::false_type +using MphTrueType = MphIntegralConstant; +using MphFalseType = MphIntegralConstant; + +// reimplementation of std::is_same +template +struct MphIsSame : MphFalseType {}; + +template +struct MphIsSame<_Type, _Type> : MphTrueType {}; + +// reimplementation of std::same_as +template +concept MphSameAs = MphIsSame<_Type1, _Type2>::value + && MphIsSame<_Type2, _Type1>::value; + +// reimplementation of std::is_pointer +template +struct MphIsPointer : MphFalseType {}; + +template +struct MphIsPointer<_Type*> : MphTrueType {}; + +template +struct MphIsPointer<_Type* const> : MphTrueType {}; + +template +struct MphIsPointer<_Type* volatile> : MphTrueType {}; + +template +struct MphIsPointer<_Type* const volatile> : MphTrueType {}; + +// checks if something can be static casted to something else +template +concept MphStaticCastableTo = requires(_From&& val) { + static_cast<_To>(val); +}; diff --git a/executive/src/syscall.cxx b/executive/src/syscall.cxx new file mode 100644 index 0000000..ebaf26b --- /dev/null +++ b/executive/src/syscall.cxx @@ -0,0 +1,2 @@ +#include "./syscall.hxx" + diff --git a/executive/src/syscall.hxx b/executive/src/syscall.hxx new file mode 100644 index 0000000..75ab551 --- /dev/null +++ b/executive/src/syscall.hxx @@ -0,0 +1,90 @@ +/** + * Wrappers for various syscalls. + * + * WARNING: This file contains code that is known to the State of California to cause birth defects or reproductive harm + */ + +#pragma once + +#include "./metaprogramming.hxx" + +enum class LnxSystemOp : long { + READ = 0, + WRITE = 1, + OPEN = 2, + CLOSE = 3, + + EXIT = 60, + + KEXEC_FILE_LOAD = 320 +}; + +template +concept LnxSystemCallArgumentType = MphStaticCastableTo<_Type, long> || MphIsPointer<_Type>::value; + +/** + * Cast something to a long for a syscall + * + * \internal + */ +template +inline long LnxSystemCallCast(_Type arg) { + if constexpr (MphIsPointer::value) { + return reinterpret_cast(arg); + } else { + return static_cast(arg); + } +} + +/** + * Do a system call with only long arguments. This probably isn't memory safe. + * + * \internal + */ +template... _ArgTypes> +[[using gnu: naked]] +inline int LnxSystemCallInternal(long op, _ArgTypes... args) noexcept { + // Move arguments to where they belong + asm volatile ("mov %%rdi, %%rax" : : : "rax"); + if constexpr (sizeof...(args) >= 1) asm volatile ("mov %%rsi, %%rdi" : : : "rdi"); + if constexpr (sizeof...(args) >= 2) asm volatile ("mov %%rdx, %%rsi" : : : "rsi"); + if constexpr (sizeof...(args) >= 3) asm volatile ("mov %%rcx, %%rdx" : : : "rdx"); + if constexpr (sizeof...(args) >= 4) asm volatile ("mov %%r8, %%r10" : : : "r10"); + if constexpr (sizeof...(args) >= 5) asm volatile ("mov %%r9, %%r8" : : : "r8" ); + if constexpr (sizeof...(args) >= 6) asm volatile ("pop %%r9 " : : : "r9" ); + + // Call the system + asm volatile ("syscall"); + + // Return. + asm volatile ("ret"); +} + +/** + * Do a system call, heavily optimized + * + * \param op operation + * \param args the arguments + * \return system call return value + */ +template +inline int LnxSystemCall(LnxSystemOp op, _ArgTypes... args) noexcept { + return LnxSystemCallInternal(static_cast(op), LnxSystemCallCast(args)...); +} + +/** + * Write to a file descriptor + */ +inline int LnxWrite(int fileno, const char* path, long count) noexcept { + return LnxSystemCall(LnxSystemOp::WRITE, fileno, path, count); +} + +/** + * Exit. + */ +[[noreturn]] +inline int LnxExitProcess(int status) noexcept { + LnxSystemCall(LnxSystemOp::EXIT, status); + + __builtin_unreachable(); +} diff --git a/lcrash/CMakeLists.txt b/lcrash/CMakeLists.txt new file mode 100644 index 0000000..01ae86d --- /dev/null +++ b/lcrash/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.28) + +lw_project(lcrash + DESCRIPTION "Lindows BSOD" + TARGET LINDOWS +) + +lw_add_executable(lcrash + SOURCES lcrash.c +) +add_executable(lcrashld IMPORTED) +set_property(TARGET lcrashld PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/lcrash.ld) +set_property(TARGET lcrash PROPERTY LINK_DEPENDS + $ + $ +) +set_property(TARGET lcrash PROPERTY LINK_OPTIONS -nostdlib -Wl,-T,${CMAKE_CURRENT_SOURCE_DIR}/lcrash.ld) diff --git a/lcrash/lcrash.c b/lcrash/lcrash.c new file mode 100644 index 0000000..dc816e6 --- /dev/null +++ b/lcrash/lcrash.c @@ -0,0 +1,129 @@ +#include "lnxboot.h" + +extern void _start(); + +[[gnu::section(".lnxhead")]] +[[gnu::used]] +[[gnu::aligned(1)]] +[[gnu::unavailable("not present at runtime. use setup_info instead")]] +struct setup_info bzhead = { + .setup_sects = 1, // 1 512-byte sector + .boot_flag = 0xAA55, + .syssize = 16, + .jump_instruction = 0xEB, + .jump_offset = sizeof(struct setup_info) - __builtin_offsetof(struct setup_info, signature), + .signature = 0x53726448, + .version = 0x020F, + .loadflags = 0x01, // LOADED_HIGH, + .kernel_alignment = 1, + .relocatable_kernel = 1, + .xloadflags = 0x13, // XLF_KERNEL_64 | XLF_CAN_BE_LOADED_ABOVE_4G | XLF_5LEVEL + .cmdline_size = 255, // max command line size + .init_size = 0x10000 // we dont need THAT much memory +}; + +struct setup_info* setup_info; +struct boot_params* boot_params; + +unsigned short serial_port; + +void outb(unsigned short port, unsigned char value) { + asm volatile ( + "outb %b0, %1" + ::"a" (value) + ,"d" (port) + ); +} + +void serial_putc(char c) { + outb(serial_port, c); +} + +void serial_puts(const char* s) { + while (*s) serial_putc(*(s++)); +} + +void serial_put_formatted_u64(u64 v) { + if (v == 0) { + serial_putc('0'); + } else { + u64 max = 1; + + while (v > max) max *= 10; + + while (v) { + serial_putc('0' + (u8)(v / max)); + + v %= max; + max /= 10; + } + } +} + +[[gnu::section(".text._start"), gnu::naked]] +extern void _start() { + asm ( // grab the setup_info and boot_params locations + "mov %%rsi, %1\n" + "mov %%rsi, %0\n" + "addq $0x1f1, %0" + : "=m" (setup_info), + "=m" (boot_params) + ); + asm ("jmp entry"); +} + +[[gnu::section(".text._start")]] +void entry() { + // get the zero page + //boot_params = (struct boot_params*)( + // 0x202 - 0x1f1 + // + setup_info->jump_offset + // + (u64)setup_info); + + // orignally we would try to import the serial port from the kernel (see kexec tools) + // as you can see, we gave up! + // serial_port = (unsigned short)*(long*)&serial_base; + serial_port = 0x3f8; + + // construct pointers + u8* cmdline_ptr = (u8*)((u64)setup_info->cmd_line_ptr | ((u64)boot_params->ext_cmd_line_ptr << 32)); + + // check out command line + serial_puts(cmdline_ptr); + serial_putc('\r'); + serial_putc('\n'); + + // we dont have the privilege of getting a rodata segment. any reads off our stack cause a triple fault + // for some fucking reason. allocate our strings and shit on the stack. + //char s_you_fucked_up[] = "!!! YOU FUCKED UP !!!\n"; + //char s_vga_you_fucked_up[] = "YOU FUCKED UP.\n"; + //char s_description[] = "A SERIOUS ERROR HAS OCCURED AND LINDOWS HAS STOPPED TO PREVENT FURTHER DAMAGE."; + //char s_registers[] = "REGISTERS:"; + //char s_call_trace[] = "CALL TRACE:"; + //char s_dumpcore[] = "[(D)UMP CORE]"; + //char s_poweroff[] = "[(P)OWER OFF]"; + //char s_reboot[] = "[(R)EBOOT ]"; + + // You fucked up. + //serial_puts(s_you_fucked_up); + //serial_puts(s_description); + //serial_putc('\n'); + + // register dump + //serial_puts(s_registers); + //serial_putc('\n'); + //serial_putc('\n'); + + // call trace + //serial_puts(s_call_trace); + //serial_putc('\n'); + //serial_putc('\n'); + + // thing + // serial_puts("test\n"); + // serial_puts(bzhead.cmd_line_ptr); + + // Die. + asm ("cli"); + asm ("hlt"); +} diff --git a/lcrash/lcrash.ld b/lcrash/lcrash.ld new file mode 100644 index 0000000..b95e18f --- /dev/null +++ b/lcrash/lcrash.ld @@ -0,0 +1,26 @@ +OUTPUT_FORMAT(elf64-x86-64) + +SECTIONS { + .lnxhead 0x01f1 : ALIGN(1) { + *(.lnxhead); + } + + .rodata 0x900000 : ALIGN(1) { + *(.rodata); + } + + .text._start 0x80000000 : ALIGN(1) { + *(.text._start); + } + + .text : ALIGN(512) { *(.text); } + .bss : { *(.bss); } + + .kernel_imports 0xFFFFFFFF : { + *(.kernel_imports); + } + + /DISCARD/ : { + *(*); + } +} diff --git a/lcrash/lnxboot.h b/lcrash/lnxboot.h new file mode 100644 index 0000000..a745c50 --- /dev/null +++ b/lcrash/lnxboot.h @@ -0,0 +1,156 @@ +#pragma once + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; +typedef unsigned long long u64; + +struct [[gnu::packed]] setup_info { + u8 setup_sects; + u16 root_flags; + u32 syssize; + u16 ram_size; + u16 vid_mode; + u16 root_dev; + u16 boot_flag; + u8 jump_instruction; + u8 jump_offset; + u32 signature; + u16 version; + u32 realmode_switch; + u16 start_sys_seg; + u16 kernel_version; + u8 type_of_loader; + u8 loadflags; + u16 setup_move_size; + u64 code32_start; + // FUCK THE RAMDISK + u32 ramdisk_size; + u32 bootsect_kludge; + u16 heap_end_ptr; + u8 ext_loader_ver; + u8 ext_loader_type; + u32 cmd_line_ptr; + u32 initrd_addr_max; + u32 kernel_alignment; + u8 relocatable_kernel; + u8 min_alignment; + u16 xloadflags; + u32 cmdline_size; + u32 hardware_subarch; + u64 hardware_subarch_data; + u32 payload_offset; + u32 payload_length; + u64 setup_data; + u64 pref_address; + u32 init_size; + u32 handover_offset; + u32 kernel_info_offset; +}; + +struct [[gnu::packed]] screen_info { + u8 orig_x; + u8 orig_y; + u16 ext_mem_k; + u16 orig_video_page; + u8 orig_video_mode; + u8 orig_video_cols; + u8 flags; + u8 reserved; + u16 orig_video_ega_bx; + u16 reserved2; + u8 orig_video_lines; + u8 orig_video_isVGA; + u8 orig_video_points; + + // linear frame buffer + u16 lfb_width; + u16 lfb_height; + u16 lfb_depth; + u32 lfb_base; + u16 cl_magic; + u16 cl_offset; + u16 lfb_linelength; + u8 red_size; + u8 red_pos; + u8 green_size; + u8 green_pos; + u8 blue_size; + u8 blue_pos; + u8 reserved_size; + u8 reserved_pos; + u8 vesapm_seg; + u8 vesapm_off; + u16 pages; + u16 vesa_attributes; + u32 capabilities; + u32 ext_lfb_base; + u8 reserved3[0x2]; +}; + +struct [[gnu::packed]] apm_bios_info { + u8 pad[0x14]; +}; + +struct [[gnu::packed]] ist_info { + u8 pad[0x10]; +}; + +/// \deprecated +struct [[gnu::packed]] sys_desc_table { + u8 pad[0x10]; +}; + +struct [[gnu::packed]] edid_info { + u8 pad[0x80]; +}; + +struct [[gnu::packed]] efi_info { + u8 pad[0x20]; +}; + +struct [[gnu::packed]] e820_entry { + u8 pad; +}; + +struct [[gnu::packed]] edd_info { + u8 pad; +}; + +struct [[gnu::packed]] boot_params { + struct screen_info screen_info; + struct apm_bios_info apm_bios_info; + u8 reserved0[0x4]; + void* tboot_addr; + struct ist_info ist_info; + void* acpi_rsdp_addr; + u8 reserved1[0x2]; + u8 hd0_info[0x10]; + u8 hd1_info[0x10]; + struct sys_desc_table sys_desc_table; + u8 olpc_ofw_header[0x10]; + /// ramdisk_image high 32 bits + u32 ext_ramdisk_image; + /// ramdisk_size high 32 bits + u32 ext_ramdisk_size; + /// cmd_line_ptr high 32 bits + u32 ext_cmd_line_ptr; + u8 reserved2[0x70]; + void* cc_blob_address; + struct edid_info edid_info; + struct efi_info efi_info; + u32 alt_mem_k; + u32 scratch; + u8 e820_entries; + u8 eddbuf_entries; + u8 edd_mbr_sig_buf_entries; + u8 kbd_status; + u8 secure_boot; + u8 reserved3[0x2]; + u8 sentinel; + u8 reserved4[0xa0]; // setup_info lives here! + u8 edd_mbr_sig_buffer[0x40]; + u8 e20_table[0xa00]; + u8 reserved5[0x30]; + u8 eddbuf[0x1ec]; +}; diff --git a/lrss/CMakeLists.txt b/lrss/CMakeLists.txt index ef46f95..896c3c2 100644 --- a/lrss/CMakeLists.txt +++ b/lrss/CMakeLists.txt @@ -11,6 +11,6 @@ lw_add_executable(lrss target_link_libraries(lrss PRIVATE lrssclient) lw_add_library(lrssclient SHARED - SOURCES lib/library.cxx + SOURCES liblrssclient/src/library.cxx ) -target_include_directories(lrssclient PUBLIC include) +target_include_directories(lrssclient PUBLIC liblrssclient/include) diff --git a/lrss/include/lindows/lrss.h b/lrss/liblrssclient/include/lindows/lrss.h similarity index 100% rename from lrss/include/lindows/lrss.h rename to lrss/liblrssclient/include/lindows/lrss.h diff --git a/lrss/lib/library.cxx b/lrss/liblrssclient/src/library.cxx similarity index 100% rename from lrss/lib/library.cxx rename to lrss/liblrssclient/src/library.cxx diff --git a/scripts/hivex/system.hivex b/scripts/hivex/system.hivex new file mode 100644 index 0000000..6585d9b --- /dev/null +++ b/scripts/hivex/system.hivex @@ -0,0 +1,24 @@ +add Select +cd Select +setval 1 +Default +string:001 +cd .. + +add ControlSet001 +cd ControlSet001 +add Control +cd Control +add Session Manager +cd Session Manager +add Environment +cd Environment +setval 1 +PATH +expandstring:C:\Windows\System32\ +cd .. +cd .. +cd .. +cd .. + +commit diff --git a/scripts/mkhive b/scripts/mkhive new file mode 100755 index 0000000..07bf6b6 --- /dev/null +++ b/scripts/mkhive @@ -0,0 +1,188 @@ +#!/bin/bash +# PARAM 1: PATH + +SHITFILE="$(mktemp)" +HIVEPATH="$1"; + +# chararr length, format, args... +function chararr() { + printf "$2" "${@:3}" > "$SHITFILE"; + truncate "$SHITFILE" -s "$1"; + cat "$SHITFILE" >> "$HIVEPATH"; +} + +# wchararrle length, format, args +function wchararrle() { + printf "$2" "${@:3}" | iconv -t utf-16le > "$SHITFILE"; + truncate "$SHITFILE" -s "$1"; + cat "$SHITFILE" >> "$HIVEPATH"; +} + +# i1le value +function i1le() { + printf "\\$(printf "%o" $(( $1 & 255 )))" >> "$HIVEPATH"; +} + +# i2le value +function i2le() { + I1=$(printf "%o" $((($1 >> 8) & 255 ))); + I0=$(printf "%o" $((($1 ) & 255 ))); + + printf "\\$I0\\$I1" >> "$HIVEPATH"; +} + +# i4le value +function i4le() { + I3=$(printf "%o" $((($1 >> 24 ) & 255 )) ); + I2=$(printf "%o" $((($1 >> 16 ) & 255 )) ); + I1=$(printf "%o" $((($1 >> 8 ) & 255 )) ); + I0=$(printf "%o" $((($1 ) & 255 )) ); + + printf "\\$I0\\$I1\\$I2\\$I3" >> "$HIVEPATH"; +} + +# i8le value +function i8le() { + C1=$(( $1 >> 32 )); + C0=$(( $1 & 4294967295 )); + + i4le $C0; + i4le $C1; +} + +# i1lea values... +function i1lea() { + while [ -v 1 ]; do + i1le $1; + shift; + done; +} + +# i2lea values... +function i2lea() { + while [ -v 1 ]; do + i2le $1; + shift; + done; +} + +# i4lea values... +function i4lea() { + while [ -v 1 ]; do + i4le $1; + shift; + done +} + +# i8lea values... +function i8lea() { + while [ -v 1 ]; do + i8le $1; + shift; + done +} + +# pad count +function pad() { + >"$SHITFILE"; + truncate -s "$1" "$SHITFILE"; + cat "$SHITFILE" >> "$HIVEPATH"; +} + +if [ -n "$HIVEPATH" ]; then + echo "MAKE HIVE AT $1"; + + # clear file + >test.dat + + # base block + chararr 4 "regf" + i4lea 0 0 + i8le 0 + i4lea 1 6 0 1 352 4096 0 + wchararrle 64 "%s" "$(basename "$HIVEPATH")" + pad 396 + + for w in $(hexdump "$HIVEPATH" -v -e '"%i\n"'); do + if [ ! -v CHKSUM ]; then + CHKSUM=$w; + else + CHKSUM=$(( $CHKSUM ^ $w )); + fi + done + i4le $CHKSUM # checksum but fuck you we dont check the sum + + pad 3576 + i4lea 0 0 + + # hive bin + chararr 4 "hbin" + i4lea 0 4096 + i8lea 0 0 + i4le 0 + + # LRSS hive bin data block + i4le -16 + chararr 2 "Ld" # (!) non standard + i1le 1 # The tree alloc list be invalid + i1le 0 # reserved + i4le 1 # number of 4096 byte chunks (alloc list byte length is this * 128 + 24) + i4le 48 # offset from bin start to alloc list + + # LRSS hive bin alloc list + i4le -152 + chararr 2 "La" # (!) non standard + pad 2 + i2lea 70 71 73 77 85 101 133 # alloc list offsets + pad 130 + + for (( i=0; i < 19 ; i++ )); do + i8le 4294967288; + done + + # root key + i4le -80 + chararr 2 "nk" + i2le 0 + i8le 0 + i4le 0 + i4le 0 + i4le 0 + i4le 0 + i4le 432 + i4le 0 + i4le 0 + i4le 0 + i4le 440 + i4le 0 + i4le 0 + i4le 0 + i4le 0 + i4le 0 + i4le 0 + i2le 0 + i2le 0 + + # root key subkeys + i4le -8 + chararr 2 "li" + i2le 0 + + # root key security info B) + i4le -24 + chararr 2 "sk" + i2le 0 + i4le 440 # fuck the header just link to ourself, this will surely have no consequences in the future + i4le 440 + i4le 1 # referenced by root key + i4le 0 # descriptor length + + # fill with empty cells + for (( i=$(( (8192 - $(wc -c "$HIVEPATH" | cut -f 1 "-d ")) / 8 )); i > 0; i-- )); do + i4lea 8 0; + done +else + echo "ERR: Hive path not specified"; +fi + +rm "$SHITFILE" diff --git a/src/grub/grub.cfg b/src/grub/grub.cfg index 7dcf1cc..1f53518 100644 --- a/src/grub/grub.cfg +++ b/src/grub/grub.cfg @@ -2,5 +2,5 @@ clear # boot -linux /Windows/vmlinux.exe console=tty0 console=ttyS0 root=PARTUUID=48d29da8-2ff8-4f23-ba1a-0e8ccfc329e2 rootflags=force rw init=/Windows/System32/lsmss.exe +linux /Windows/vmlinux.exe console=tty0 console=ttyS0 root=PARTUUID=48d29da8-2ff8-4f23-ba1a-0e8ccfc329e2 rootflags=force rw init=/Windows/System32/lexecutive.exe loglevel=8 crashkernel=16M boot diff --git a/src/linux/config b/src/linux/config index 0e1c894..c002073 100644 --- a/src/linux/config +++ b/src/linux/config @@ -18,7 +18,7 @@ CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT=y CONFIG_TOOLS_SUPPORT_RELR=y CONFIG_CC_HAS_ASM_INLINE=y CONFIG_CC_HAS_NO_PROFILE_FN_ATTR=y -CONFIG_PAHOLE_VERSION=125 +CONFIG_PAHOLE_VERSION=126 CONFIG_IRQ_WORK=y CONFIG_BUILDTIME_TABLE_SORT=y CONFIG_THREAD_INFO_IN_TASK=y @@ -280,8 +280,9 @@ CONFIG_TRACEPOINTS=y CONFIG_CRASH_CORE=y CONFIG_KEXEC_CORE=y CONFIG_KEXEC=y -# CONFIG_KEXEC_FILE is not set -# CONFIG_KEXEC_JUMP is not set +CONFIG_KEXEC_FILE=y +# CONFIG_KEXEC_SIG is not set +CONFIG_KEXEC_JUMP=y CONFIG_CRASH_DUMP=y CONFIG_CRASH_HOTPLUG=y CONFIG_CRASH_MAX_MEMORY_RANGES=8192 @@ -452,6 +453,7 @@ CONFIG_HZ=1000 CONFIG_SCHED_HRTICK=y CONFIG_ARCH_SUPPORTS_KEXEC=y CONFIG_ARCH_SUPPORTS_KEXEC_FILE=y +CONFIG_ARCH_SELECTS_KEXEC_FILE=y CONFIG_ARCH_SUPPORTS_KEXEC_PURGATORY=y CONFIG_ARCH_SUPPORTS_KEXEC_SIG=y CONFIG_ARCH_SUPPORTS_KEXEC_SIG_FORCE=y @@ -1492,6 +1494,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # Firmware loader # CONFIG_FW_LOADER=y +CONFIG_FW_LOADER_DEBUG=y CONFIG_EXTRA_FIRMWARE="" # CONFIG_FW_LOADER_USER_HELPER is not set # CONFIG_FW_LOADER_COMPRESS is not set @@ -5059,8 +5062,8 @@ CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7 CONFIG_CONSOLE_LOGLEVEL_QUIET=4 CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 # CONFIG_BOOT_PRINTK_DELAY is not set -# CONFIG_DYNAMIC_DEBUG is not set -# CONFIG_DYNAMIC_DEBUG_CORE is not set +CONFIG_DYNAMIC_DEBUG=y +CONFIG_DYNAMIC_DEBUG_CORE=y CONFIG_SYMBOLIC_ERRNAME=y CONFIG_DEBUG_BUGVERBOSE=y # end of printk and dmesg options @@ -5377,6 +5380,7 @@ CONFIG_RUNTIME_TESTING_MENU=y # CONFIG_TEST_SYSCTL is not set # CONFIG_TEST_UDELAY is not set # CONFIG_TEST_STATIC_KEYS is not set +# CONFIG_TEST_DYNAMIC_DEBUG is not set # CONFIG_TEST_KMOD is not set # CONFIG_TEST_MEMCAT_P is not set # CONFIG_TEST_MEMINIT is not set