framework for LRSS
This commit is contained in:
parent
e0b69fe182
commit
96619b66eb
@ -93,6 +93,46 @@ function(lw_add_executable NAME)
|
|||||||
set_property(SOURCE TARGET_DIRECTORY ${NAME} APPEND PROPERTY OBJECT_DEPENDS
|
set_property(SOURCE TARGET_DIRECTORY ${NAME} APPEND PROPERTY OBJECT_DEPENDS
|
||||||
GCC-install
|
GCC-install
|
||||||
)
|
)
|
||||||
|
|
||||||
|
target_include_directories(${NAME} PUBLIC "${CMAKE_SOURCE_DIR}/common/include")
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "LW_TARGET not defined, are you in a lw_project?")
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# defines a library target. this must be used if lw_project is used
|
||||||
|
function(lw_add_library NAME)
|
||||||
|
set(cpa_flag SHARED)
|
||||||
|
set(cpa_single)
|
||||||
|
set(cpa_multi SOURCES)
|
||||||
|
cmake_parse_arguments(PARSE_ARGV 1 ARG "${cpa_flag}" "${cpa_single}" "${cpa_multi}")
|
||||||
|
|
||||||
|
if (ARG_SHARED)
|
||||||
|
add_library(${NAME} SHARED)
|
||||||
|
else()
|
||||||
|
add_library(${NAME})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(ARG_SOURCES)
|
||||||
|
target_sources(${NAME} PRIVATE ${ARG_SOURCES})
|
||||||
|
target_compile_options(${NAME} PRIVATE
|
||||||
|
$<$<COMPILE_LANGUAGE:C>:${LW_CROSS_CFLAGS}>
|
||||||
|
$<$<COMPILE_LANGUAGE:CXX>:${LW_CROSS_CXXFLAGS}>
|
||||||
|
)
|
||||||
|
target_link_options(${NAME} PRIVATE ${LW_CROSS_LDFLAGS})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(LW_TARGET)
|
||||||
|
set_property(TARGET ${NAME} APPEND PROPERTY LINK_DEPENDS
|
||||||
|
$<TARGET_FILE:LindowsLinkerScript>
|
||||||
|
$<TARGET_FILE:LindowsCompilerSpec>
|
||||||
|
)
|
||||||
|
|
||||||
|
set_property(SOURCE TARGET_DIRECTORY ${NAME} APPEND PROPERTY OBJECT_DEPENDS
|
||||||
|
GCC-install
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(${NAME} PUBLIC "${CMAKE_SOURCE_DIR}/common/include")
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "LW_TARGET not defined, are you in a lw_project?")
|
message(FATAL_ERROR "LW_TARGET not defined, are you in a lw_project?")
|
||||||
endif()
|
endif()
|
||||||
@ -133,6 +173,7 @@ ExternalProject_Add(GCC
|
|||||||
--disable-bootstrap
|
--disable-bootstrap
|
||||||
BUILD_COMMAND make
|
BUILD_COMMAND make
|
||||||
INSTALL_COMMAND make install
|
INSTALL_COMMAND make install
|
||||||
|
COMMAND cp -r ${CMAKE_BINARY_DIR}/gcc/prefix/lib64 ${CMAKE_BINARY_DIR}/gcc/lib64
|
||||||
STEP_TARGETS install
|
STEP_TARGETS install
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -267,7 +308,7 @@ add_custom_command(OUTPUT lindows_c.img
|
|||||||
if=/dev/zero
|
if=/dev/zero
|
||||||
of=lindows_c.img
|
of=lindows_c.img
|
||||||
bs=1M
|
bs=1M
|
||||||
count=256
|
count=512
|
||||||
# format disk with new NTFS filesystem
|
# format disk with new NTFS filesystem
|
||||||
COMMAND "${NTFS3g_Mkfs_EXECUTABLE}" ARGS -F # scary!
|
COMMAND "${NTFS3g_Mkfs_EXECUTABLE}" ARGS -F # scary!
|
||||||
-L Windows
|
-L Windows
|
||||||
@ -303,8 +344,13 @@ add_custom_command(OUTPUT lindows_c.img
|
|||||||
# copy curses to system32
|
# copy curses to system32
|
||||||
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/scripts/copylib ncurses
|
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/scripts/copylib ncurses
|
||||||
|
|
||||||
# copy lsmss
|
# continuedd
|
||||||
|
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/scripts/copylib gcc lib64
|
||||||
|
|
||||||
|
# copy lindows binaries
|
||||||
COMMAND ${CoreUtils_Copy_EXECUTABLE} ARGS $<TARGET_FILE:lsmss> lindows_c/Windows/System32/lsmss.exe
|
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
|
||||||
|
|
||||||
# create users folder
|
# create users folder
|
||||||
COMMAND ${CoreUtils_Mkdir_EXECUTABLE} ARGS lindows_c/Users
|
COMMAND ${CoreUtils_Mkdir_EXECUTABLE} ARGS lindows_c/Users
|
||||||
@ -313,7 +359,7 @@ add_custom_command(OUTPUT lindows_c.img
|
|||||||
COMMAND "umount" ARGS lindows_c
|
COMMAND "umount" ARGS lindows_c
|
||||||
|
|
||||||
DEPENDS
|
DEPENDS
|
||||||
lsmss
|
lsmss lrss lrssclient
|
||||||
Linux-install
|
Linux-install
|
||||||
GLibC-install
|
GLibC-install
|
||||||
Bash-install
|
Bash-install
|
||||||
@ -351,12 +397,12 @@ add_custom_command(OUTPUT lindows.img
|
|||||||
COMMAND echo ARGS label: gpt > disk.sfdisk
|
COMMAND echo ARGS label: gpt > disk.sfdisk
|
||||||
COMMAND echo ARGS unit: sectors >> disk.sfdisk
|
COMMAND echo ARGS unit: sectors >> disk.sfdisk
|
||||||
COMMAND echo ARGS start=1MiB, size=33MiB, type=C12A7328-F81F-11D2-BA4B-00A0C93EC93B >> disk.sfdisk
|
COMMAND echo ARGS start=1MiB, size=33MiB, type=C12A7328-F81F-11D2-BA4B-00A0C93EC93B >> disk.sfdisk
|
||||||
COMMAND echo ARGS start=34MiB, size=256MiB, type=EBD0A0A2-B9E5-4433-87C0-68B6B72699C7, uuid=48D29DA8-2FF8-4F23-BA1A-0E8CCFC329E2 >> disk.sfdisk
|
COMMAND echo ARGS start=34MiB, size=512MiB, type=EBD0A0A2-B9E5-4433-87C0-68B6B72699C7, uuid=48D29DA8-2FF8-4F23-BA1A-0E8CCFC329E2 >> disk.sfdisk
|
||||||
COMMAND "${CoreUtils_dd_EXECUTABLE}" ARGS
|
COMMAND "${CoreUtils_dd_EXECUTABLE}" ARGS
|
||||||
if=/dev/zero
|
if=/dev/zero
|
||||||
of=lindows.img
|
of=lindows.img
|
||||||
bs=1M
|
bs=1M
|
||||||
count=300
|
count=600
|
||||||
# partition disk
|
# partition disk
|
||||||
COMMAND sfdisk ARGS lindows.img < disk.sfdisk
|
COMMAND sfdisk ARGS lindows.img < disk.sfdisk
|
||||||
# write partitions
|
# write partitions
|
||||||
@ -371,7 +417,7 @@ add_custom_command(OUTPUT lindows.img
|
|||||||
if=lindows_c.img
|
if=lindows_c.img
|
||||||
of=lindows.img
|
of=lindows.img
|
||||||
bs=1M
|
bs=1M
|
||||||
count=256
|
count=512
|
||||||
seek=34
|
seek=34
|
||||||
conv=notrunc
|
conv=notrunc
|
||||||
DEPENDS lindows_c.img lindows_efi.img
|
DEPENDS lindows_c.img lindows_efi.img
|
||||||
@ -381,3 +427,4 @@ add_custom_command(OUTPUT lindows.img
|
|||||||
add_custom_target(lindows ALL DEPENDS lindows.img)
|
add_custom_target(lindows ALL DEPENDS lindows.img)
|
||||||
|
|
||||||
add_subdirectory(lsmss)
|
add_subdirectory(lsmss)
|
||||||
|
add_subdirectory(lrss)
|
||||||
|
4
README
4
README
@ -1,3 +1,7 @@
|
|||||||
== NAMING ==
|
== NAMING ==
|
||||||
|
|
||||||
Pii: Preinit internal core routines
|
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.
|
||||||
|
11
common/include/lindows/ntstatus.h
Normal file
11
common/include/lindows/ntstatus.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Windows NT Error code
|
||||||
|
*/
|
||||||
|
typedef uint32_t NTSTATUS;
|
||||||
|
|
||||||
|
#define STATUS_SUCCESS 0x00000000
|
||||||
|
#define STATUS_INTERNAL_ERROR 0xC00000E5
|
16
lrss/CMakeLists.txt
Normal file
16
lrss/CMakeLists.txt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.28)
|
||||||
|
|
||||||
|
lw_project(lrss
|
||||||
|
DESCRIPTION "Lindows Registry Subsystem"
|
||||||
|
TARGET LINDOWS
|
||||||
|
)
|
||||||
|
|
||||||
|
lw_add_executable(lrss
|
||||||
|
SOURCES main.cxx
|
||||||
|
)
|
||||||
|
target_link_libraries(lrss PRIVATE lrssclient)
|
||||||
|
|
||||||
|
lw_add_library(lrssclient SHARED
|
||||||
|
SOURCES lib/library.cxx
|
||||||
|
)
|
||||||
|
target_include_directories(lrssclient PUBLIC include)
|
2
lrss/README
Normal file
2
lrss/README
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
== Lindows Registry Subsystem ==
|
||||||
|
The lindows registry subsystem preforms all operations related to the windows registry, when a linux program runs, it connects to LRSS, authenticates and then communicates to it via a unix domain socket, when a windows program runs, it connects to the wineserver, which is patched to use LRSS instead of it's builtin registry code.
|
27
lrss/include/lindows/lrss.h
Normal file
27
lrss/include/lindows/lrss.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <lindows/ntstatus.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the address of the LRSS socket
|
||||||
|
* \param buffer (out) buffer to write the address to
|
||||||
|
* \return status code:
|
||||||
|
* STATUS_SUCCESS: I really hope this function always succeeds
|
||||||
|
*/
|
||||||
|
extern NTSTATUS LrcSocketAddress(char Buffer[108]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a connection to LRSS
|
||||||
|
* \return status code
|
||||||
|
* STATUS_SUCCESS: Registry connection has been established
|
||||||
|
* STATUS_INTERNAL_ERROR: Something went wrong
|
||||||
|
*/
|
||||||
|
extern NTSTATUS LrcOpenRegistry();
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
63
lrss/lib/library.cxx
Normal file
63
lrss/lib/library.cxx
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
#include <cstring>
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <lindows/lrss.h>
|
||||||
|
|
||||||
|
static const char SOCKET_ADDRESS[108] = {
|
||||||
|
0, 'L', 'R', 'S', 'S', 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
static int REGISTRY_SOCKET = -1;
|
||||||
|
|
||||||
|
NTSTATUS LrcSocketAddress(char Buffer[108]) {
|
||||||
|
std::memcpy(Buffer, SOCKET_ADDRESS, 108);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS LrcOpenRegistry() {
|
||||||
|
// This may not work if the thing got closed somehow :>
|
||||||
|
if (REGISTRY_SOCKET == -1) {
|
||||||
|
REGISTRY_SOCKET = socket(AF_UNIX, SOCK_SEQPACKET, 0);
|
||||||
|
if (REGISTRY_SOCKET < 0) {
|
||||||
|
REGISTRY_SOCKET = -1;
|
||||||
|
return STATUS_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tmp = 1;
|
||||||
|
if (setsockopt(REGISTRY_SOCKET, SOL_SOCKET, SO_PASSCRED, &tmp, sizeof(tmp)) < 0) {
|
||||||
|
close(REGISTRY_SOCKET);
|
||||||
|
REGISTRY_SOCKET = -1;
|
||||||
|
return STATUS_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sockaddr_un sockaddr {
|
||||||
|
.sun_family = AF_UNIX,
|
||||||
|
.sun_path = {}
|
||||||
|
};
|
||||||
|
LrcSocketAddress(sockaddr.sun_path);
|
||||||
|
if (connect(REGISTRY_SOCKET, reinterpret_cast<struct sockaddr*>(&sockaddr), sizeof(sockaddr)) < 0) {
|
||||||
|
close(REGISTRY_SOCKET);
|
||||||
|
REGISTRY_SOCKET = -1;
|
||||||
|
return STATUS_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
} else return STATUS_SUCCESS;
|
||||||
|
}
|
103
lrss/main.cxx
Normal file
103
lrss/main.cxx
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <poll.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
#include <lindows/lrss.h>
|
||||||
|
|
||||||
|
class ConnectionState {
|
||||||
|
// -- general --
|
||||||
|
int socket;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// -- constructors --
|
||||||
|
ConnectionState(int sock) : socket(sock) {};
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int tmp;
|
||||||
|
|
||||||
|
// Hi
|
||||||
|
std::cout << "Starting Lindows Registry Subsystem\n";
|
||||||
|
|
||||||
|
// Set up handshake socket (used to be used for a handshake, kept the name, sry)
|
||||||
|
struct sockaddr_un theSockAddr {
|
||||||
|
.sun_family = AF_UNIX,
|
||||||
|
.sun_path = {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get the listening address
|
||||||
|
if (auto err = LrcSocketAddress(theSockAddr.sun_path)) {
|
||||||
|
std::cerr << "Failed to get LRSS socket address: " << err << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the socket
|
||||||
|
int handshakeSocket = socket(AF_UNIX, SOCK_SEQPACKET, 0);
|
||||||
|
if (handshakeSocket < 0) {
|
||||||
|
perror("socket");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure the socket
|
||||||
|
tmp = 1;
|
||||||
|
if (setsockopt(handshakeSocket, SOL_SOCKET, SO_PASSCRED, &tmp, sizeof(tmp)) < 0) {
|
||||||
|
perror("setsockopt");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bind to the socket
|
||||||
|
if (bind(handshakeSocket, reinterpret_cast<sockaddr*>(&theSockAddr), sizeof(theSockAddr)) < 0) {
|
||||||
|
perror("bind");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listen on da socket
|
||||||
|
if (listen(handshakeSocket, 20) < 0) {
|
||||||
|
perror("listen");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for LSMSS
|
||||||
|
raise(SIGSTOP);
|
||||||
|
|
||||||
|
// Main loop
|
||||||
|
std::unordered_map<int, ConnectionState> connections {};
|
||||||
|
std::vector<pollfd> pollfds {{ handshakeSocket, POLLIN, 0 }};
|
||||||
|
while (true) {
|
||||||
|
// Poll for whateversies
|
||||||
|
if (poll(pollfds.data(), pollfds.size(), -1) < 0) {
|
||||||
|
perror("poll");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// First fd is our handshake socket
|
||||||
|
if (pollfds[0].revents) {
|
||||||
|
if (pollfds[0].revents & POLLIN) {
|
||||||
|
// Accept the connection and add it to our client list
|
||||||
|
int sock = accept(handshakeSocket, nullptr, nullptr);
|
||||||
|
if (sock < 0) {
|
||||||
|
perror("accept");
|
||||||
|
}
|
||||||
|
|
||||||
|
connections.emplace(sock, sock);
|
||||||
|
pollfds.emplace(pollfds.end(), sock, POLLIN | POLLHUP, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
pollfds[0].revents = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate over client sockets
|
||||||
|
for (auto it = ++pollfds.begin(); it < pollfds.end(); it++) {
|
||||||
|
std::cout << it->fd << " " << it->revents << "\n";
|
||||||
|
it->revents = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
@ -9,5 +9,5 @@ lw_project(lsmss
|
|||||||
lw_add_executable(lsmss
|
lw_add_executable(lsmss
|
||||||
SOURCES main.cxx
|
SOURCES main.cxx
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_options(lsmss PRIVATE "-static")
|
target_link_options(lsmss PRIVATE "-static")
|
||||||
|
target_include_directories(lsmss PRIVATE $<TARGET_PROPERTY:lrssclient,INCLUDE_DIRECTORIES>)
|
||||||
|
126
lsmss/main.cxx
126
lsmss/main.cxx
@ -3,19 +3,100 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
#include <lindows/lrss.h>
|
||||||
|
|
||||||
|
void PiiLog(const std::string& message);
|
||||||
|
[[noreturn]] void PiiAbortBoot();
|
||||||
|
|
||||||
|
/**
|
||||||
|
i* State for a subsystem managed by LSMSS
|
||||||
|
*/
|
||||||
|
class PiiSubsystemState {
|
||||||
|
// -- General info --
|
||||||
|
std::string SubsystemName; // Subsystem display name in debug logs
|
||||||
|
|
||||||
|
bool Running = false; // Subsystem is running
|
||||||
|
|
||||||
|
// -- Linux information --
|
||||||
|
pid_t LnxPid = 0; // PID
|
||||||
|
std::filesystem::path LnxPath; // Binary path
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// -- Constructors --
|
||||||
|
PiiSubsystemState(const std::string& name, const std::filesystem::path& path) {
|
||||||
|
this->SubsystemName = name;
|
||||||
|
this->LnxPath = path;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- General --
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start the subsystem process
|
||||||
|
*/
|
||||||
|
void Start() {
|
||||||
|
PiiLog("Starting subsystem " + this->SubsystemName);
|
||||||
|
if (pid_t child = fork()) {
|
||||||
|
// save the process id
|
||||||
|
this->LnxPid = child;
|
||||||
|
this->Running = true;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
int status;
|
||||||
|
if (waitpid(this->LnxPid, &status, WUNTRACED) < 0) {
|
||||||
|
perror("waitpid");
|
||||||
|
PiiLog("Failed to start " + this->SubsystemName);
|
||||||
|
this->Running = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WIFEXITED(status)) {
|
||||||
|
PiiLog("Failed to start " + this->SubsystemName + " (Exit code " + std::to_string(WEXITSTATUS(status)) + ")");
|
||||||
|
this->Running = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WIFSTOPPED(status)) {
|
||||||
|
if (kill(this->LnxPid, SIGCONT) < 0) {
|
||||||
|
perror("kill");
|
||||||
|
PiiLog("Failed to start " + this->SubsystemName + ". Unknown state, boot process cannot continue.");
|
||||||
|
PiiAbortBoot();
|
||||||
|
}
|
||||||
|
|
||||||
|
PiiLog("Started subsystem " + this->SubsystemName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
char* args[] = { strdup(this->LnxPath.c_str()), nullptr };
|
||||||
|
execv(args[0], args);
|
||||||
|
|
||||||
|
// this should never happen
|
||||||
|
std::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log something.
|
* Log something.
|
||||||
*
|
*
|
||||||
* \param message to log
|
* \param message to log
|
||||||
*/
|
*/
|
||||||
void Pii_Log(const std::string& message) {
|
void PiiLog(const std::string& message) {
|
||||||
std::cout << message << "\n";
|
std::cout << message << "\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -26,7 +107,7 @@ void Pii_Log(const std::string& message) {
|
|||||||
* \param path absolute path to program (duh)
|
* \param path absolute path to program (duh)
|
||||||
* \return program return value, 1 if it does not exist or -1 on error
|
* \return program return value, 1 if it does not exist or -1 on error
|
||||||
*/
|
*/
|
||||||
int Pii_ExecuteProgram(const std::string& path) {
|
int PiiExecuteProgram(const std::string& path) {
|
||||||
if (pid_t child = fork()) {
|
if (pid_t child = fork()) {
|
||||||
int exitcode = -1;
|
int exitcode = -1;
|
||||||
waitpid(child, &exitcode, 0);
|
waitpid(child, &exitcode, 0);
|
||||||
@ -45,36 +126,53 @@ int Pii_ExecuteProgram(const std::string& path) {
|
|||||||
* Abort the boot process and drop the user into a recovery shell
|
* Abort the boot process and drop the user into a recovery shell
|
||||||
*/
|
*/
|
||||||
[[noreturn]]
|
[[noreturn]]
|
||||||
void Pii_AbortBoot() {
|
void PiiAbortBoot() {
|
||||||
Pii_Log("Unable to complete preinitialization. You have been dropped into a minimal recovery environment. Good luck.");
|
PiiLog("Unable to complete preinitialization. You have been dropped into a minimal recovery environment. Good luck.");
|
||||||
Pii_ExecuteProgram("/Windows/System32/bash.exe");
|
PiiExecuteProgram("/Windows/System32/bash.exe");
|
||||||
std::exit(1);
|
std::exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
std::vector<PiiSubsystemState> subsystems {};
|
||||||
|
|
||||||
// -- just print shit --
|
// -- just print shit --
|
||||||
Pii_Log("Starting Lindows Session Manager Subsystem");
|
PiiLog("Starting Lindows Session Manager Subsystem");
|
||||||
|
|
||||||
|
|
||||||
// -- dynamic linking fun --
|
// -- dynamic linking fun --
|
||||||
Pii_Log("Regenerating dynamic linker cache");
|
PiiLog("Regenerating dynamic linker cache");
|
||||||
Pii_ExecuteProgram("/Windows/System32/ldconfig.exe");
|
PiiExecuteProgram("/Windows/System32/ldconfig.exe");
|
||||||
|
|
||||||
// -- registry --
|
// -- registry --
|
||||||
Pii_Log("Starting Lindows Registry Subsystem");
|
PiiLog("Starting Lindows Registry Subsystem");
|
||||||
// TODO
|
subsystems.emplace(subsystems.end(), "Lindows Registry Subsystem", "/Windows/System32/lrss.exe")
|
||||||
Pii_Log("Loading Lindows registry");
|
->Start(); // We don't actually know if this started, we aren't in the mainloop. We just have to pray :>
|
||||||
|
|
||||||
|
PiiLog("Loading Lindows registry");
|
||||||
|
auto liblrssclient = dlopen("/Windows/System32/liblrssclient.so", RTLD_NOW);
|
||||||
|
auto pLrcOpenRegistry = reinterpret_cast<decltype(LrcOpenRegistry)*>(dlsym(liblrssclient, "LrcOpenRegistry"));
|
||||||
|
if (auto error = dlerror()) {
|
||||||
|
PiiLog(error);
|
||||||
|
PiiAbortBoot();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pLrcOpenRegistry()) {
|
||||||
|
PiiLog("Failed to connect to registry subsystem.");
|
||||||
|
PiiAbortBoot();
|
||||||
|
}
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
|
|
||||||
// -- swap --
|
// -- swap --
|
||||||
Pii_Log("Creating pagefiles");
|
PiiLog("Creating pagefiles");
|
||||||
// TODO
|
// TODO
|
||||||
|
|
||||||
// -- env --
|
// -- env --
|
||||||
Pii_Log("Setting environment variables");
|
PiiLog("Setting environment variables");
|
||||||
// TODO
|
// TODO
|
||||||
|
|
||||||
// we are never ok
|
// we are never ok
|
||||||
Pii_AbortBoot();
|
PiiAbortBoot();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,17 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# ARG 1: LIB PATH
|
# ARG 1: LIB PATH
|
||||||
|
# ARG 2: LIB DIR
|
||||||
|
|
||||||
# copy libs
|
main() {
|
||||||
find $1/bin $1/lib -type d | sed -r 's/'$1'\/(bin|lib)\///;Tn;s/^/mkdir lindows_c\/Windows\/System32\//;by;:n;d;:y;e' > /dev/null;
|
# copy libs
|
||||||
find $1/bin -type f | sed -r 's/'$1'\/bin\/(.*)/cp '$1'\/bin\/\1 lindows_c\/Windows\/System32\/\1.exe/;e' > /dev/null
|
find $1/bin $1/$2 -type d | sed -r 's/'$1'\/(bin|'$2')\///;Tn;s/^/mkdir lindows_c\/Windows\/System32\//;by;:n;d;:y;e' > /dev/null;
|
||||||
find $1/lib -type f | sed -r 's/'$1'\/lib\/(.*)/cp '$1'\/lib\/\1 lindows_c\/Windows\/System32\/\1/;e' > /dev/null
|
find $1/bin -type f | sed -r 's/'$1'\/bin\/(.*)/cp '$1'\/bin\/\1 lindows_c\/Windows\/System32\/\1.exe/;e' > /dev/null
|
||||||
|
find $1/$2 -type f | sed -r 's/'$1'\/'$2'\/(.*)/cp '$1'\/'$2'\/\1 lindows_c\/Windows\/System32\/\1/;e' > /dev/null
|
||||||
|
|
||||||
# ntfs-3g cant seem to figure out ntfs symlinks, its 1500 lines of code for reparse points dont even work
|
# ntfs-3g cant seem to figure out ntfs symlinks, its 1500 lines of code for reparse points dont even work
|
||||||
# with symlinks, so we have to build the reparse point and do it ourselves
|
# with symlinks, so we have to build the reparse point and do it ourselves
|
||||||
for lib in $(cd $1/lib && find -type l); do
|
for lib in $(cd $1/$2 && find -type l); do
|
||||||
WPATH="$(echo -n $(readlink "$1/lib/$lib"))"
|
WPATH="$(echo -n $(readlink "$1/$2/$lib"))"
|
||||||
LPATH="$(echo -n '/Windows/System32/'"$WPATH" | sed -E 's/(.)/\1\\x00/g;s/\//\\\\/g')" # sed -E 's/(.)/\\0\1/g');
|
LPATH="$(echo -n '/Windows/System32/'"$WPATH" | sed -E 's/(.)/\1\\x00/g;s/\//\\\\/g')" # sed -E 's/(.)/\\0\1/g');
|
||||||
LPATHL=$(( 36 + ${#WPATH} * 2 ));
|
LPATHL=$(( 36 + ${#WPATH} * 2 ));
|
||||||
|
|
||||||
@ -27,4 +29,10 @@ for lib in $(cd $1/lib && find -type l); do
|
|||||||
"lindows_c/Windows/System32/$lib";
|
"lindows_c/Windows/System32/$lib";
|
||||||
|
|
||||||
#ln -sr "lindows_c/Windows/System32/$(readlink $1/lib/$lib)" "lindows_c/Windows/System32/$lib"
|
#ln -sr "lindows_c/Windows/System32/$(readlink $1/lib/$lib)" "lindows_c/Windows/System32/$lib"
|
||||||
done
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
[ -z "$2" ] && main "$1" lib;
|
||||||
|
[ -n "$2" ] && main "$1" "$2";
|
||||||
|
|
||||||
|
exit 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user