add a lot of stuff uh i got a bit to excited
This commit is contained in:
parent
96619b66eb
commit
f0ec001801
@ -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 $<TARGET_FILE:lsmss> lindows_c/Windows/System32/lsmss.exe
|
||||
COMMAND ${CoreUtils_Copy_EXECUTABLE} ARGS $<TARGET_FILE:lrss> lindows_c/Windows/System32/lrss.exe
|
||||
COMMAND ${CoreUtils_Copy_EXECUTABLE} ARGS $<TARGET_FILE:lrssclient> lindows_c/Windows/System32/liblrssclient.so
|
||||
|
||||
COMMAND ${CoreUtils_Copy_EXECUTABLE} ARGS $<TARGET_FILE:lexecutive> lindows_c/Windows/System32/lexecutive.exe
|
||||
COMMAND ${CoreUtils_Copy_EXECUTABLE} ARGS $<TARGET_FILE:lcrash> 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)
|
||||
|
6
README
6
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
|
||||
|
11
executive/CMakeLists.txt
Normal file
11
executive/CMakeLists.txt
Normal file
@ -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)
|
21
executive/src/bugcheck.cxx
Normal file
21
executive/src/bugcheck.cxx
Normal file
@ -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;
|
||||
}
|
||||
}
|
3
executive/src/bugcheck.hxx
Normal file
3
executive/src/bugcheck.hxx
Normal file
@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void InitializeBugCheckHandler();
|
4
executive/src/logging.cxx
Normal file
4
executive/src/logging.cxx
Normal file
@ -0,0 +1,4 @@
|
||||
#include "logging.hxx"
|
||||
|
||||
char ExecutiveLogStringBuffer[4096] = {};
|
||||
char ExecutiveLogFormatOptions[128] = {};
|
132
executive/src/logging.hxx
Normal file
132
executive/src/logging.hxx
Normal file
@ -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<class _Type>
|
||||
inline void ExecutiveLogFormatValue(const _Type* Value, int& BufferPos, const char* Args) = delete;
|
||||
|
||||
/**
|
||||
* Type has a format function
|
||||
*/
|
||||
template<class _Type>
|
||||
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<ExecutiveLogCanFormat... _Type>
|
||||
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<void (*)(const void*, int&, const char*)>(static_cast<void (*)(const _Type*, int&, const char*)>(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<long>(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<char>(Absolute * 10 / TheBiggest);
|
||||
Absolute %= TheBiggest / 10;
|
||||
TheBiggest /= 10;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void ExecutiveLogFormatValue<int>(const int* Value, int& BufferPos, const char* Args) {
|
||||
long LongValue = *Value;
|
||||
ExecutiveLogFormatValue(&LongValue, BufferPos, Args);
|
||||
return;
|
||||
}
|
16
executive/src/main.cxx
Normal file
16
executive/src/main.cxx
Normal file
@ -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);
|
||||
}
|
51
executive/src/metaprogramming.hxx
Normal file
51
executive/src/metaprogramming.hxx
Normal file
@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
// reimplementation of std::integral_constant
|
||||
template<class _Type, _Type _Value>
|
||||
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<bool, true>;
|
||||
using MphFalseType = MphIntegralConstant<bool, false>;
|
||||
|
||||
// reimplementation of std::is_same
|
||||
template<class _Type1, class _Type2>
|
||||
struct MphIsSame : MphFalseType {};
|
||||
|
||||
template<class _Type>
|
||||
struct MphIsSame<_Type, _Type> : MphTrueType {};
|
||||
|
||||
// reimplementation of std::same_as
|
||||
template<class _Type1, class _Type2>
|
||||
concept MphSameAs = MphIsSame<_Type1, _Type2>::value
|
||||
&& MphIsSame<_Type2, _Type1>::value;
|
||||
|
||||
// reimplementation of std::is_pointer
|
||||
template<class _Type>
|
||||
struct MphIsPointer : MphFalseType {};
|
||||
|
||||
template<class _Type>
|
||||
struct MphIsPointer<_Type*> : MphTrueType {};
|
||||
|
||||
template<class _Type>
|
||||
struct MphIsPointer<_Type* const> : MphTrueType {};
|
||||
|
||||
template<class _Type>
|
||||
struct MphIsPointer<_Type* volatile> : MphTrueType {};
|
||||
|
||||
template<class _Type>
|
||||
struct MphIsPointer<_Type* const volatile> : MphTrueType {};
|
||||
|
||||
// checks if something can be static casted to something else
|
||||
template<class _From, class _To>
|
||||
concept MphStaticCastableTo = requires(_From&& val) {
|
||||
static_cast<_To>(val);
|
||||
};
|
2
executive/src/syscall.cxx
Normal file
2
executive/src/syscall.cxx
Normal file
@ -0,0 +1,2 @@
|
||||
#include "./syscall.hxx"
|
||||
|
90
executive/src/syscall.hxx
Normal file
90
executive/src/syscall.hxx
Normal file
@ -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<class _Type>
|
||||
concept LnxSystemCallArgumentType = MphStaticCastableTo<_Type, long> || MphIsPointer<_Type>::value;
|
||||
|
||||
/**
|
||||
* Cast something to a long for a syscall
|
||||
*
|
||||
* \internal
|
||||
*/
|
||||
template<class _Type>
|
||||
inline long LnxSystemCallCast(_Type arg) {
|
||||
if constexpr (MphIsPointer<decltype(arg)>::value) {
|
||||
return reinterpret_cast<long>(arg);
|
||||
} else {
|
||||
return static_cast<long>(arg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do a system call with only long arguments. This probably isn't memory safe.
|
||||
*
|
||||
* \internal
|
||||
*/
|
||||
template<MphSameAs<long>... _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<LnxSystemCallArgumentType... _ArgTypes>
|
||||
inline int LnxSystemCall(LnxSystemOp op, _ArgTypes... args) noexcept {
|
||||
return LnxSystemCallInternal(static_cast<long>(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();
|
||||
}
|
17
lcrash/CMakeLists.txt
Normal file
17
lcrash/CMakeLists.txt
Normal file
@ -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
|
||||
$<TARGET_FILE:lcrashld>
|
||||
$<TARGET_FILE:LindowsCompilerSpec>
|
||||
)
|
||||
set_property(TARGET lcrash PROPERTY LINK_OPTIONS -nostdlib -Wl,-T,${CMAKE_CURRENT_SOURCE_DIR}/lcrash.ld)
|
129
lcrash/lcrash.c
Normal file
129
lcrash/lcrash.c
Normal file
@ -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");
|
||||
}
|
26
lcrash/lcrash.ld
Normal file
26
lcrash/lcrash.ld
Normal file
@ -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/ : {
|
||||
*(*);
|
||||
}
|
||||
}
|
156
lcrash/lnxboot.h
Normal file
156
lcrash/lnxboot.h
Normal file
@ -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];
|
||||
};
|
@ -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)
|
||||
|
24
scripts/hivex/system.hivex
Normal file
24
scripts/hivex/system.hivex
Normal file
@ -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
|
188
scripts/mkhive
Executable file
188
scripts/mkhive
Executable file
@ -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"
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user