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
|
||||
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()
|
||||
message(FATAL_ERROR "LW_TARGET not defined, are you in a lw_project?")
|
||||
endif()
|
||||
@ -133,6 +173,7 @@ ExternalProject_Add(GCC
|
||||
--disable-bootstrap
|
||||
BUILD_COMMAND make
|
||||
INSTALL_COMMAND make install
|
||||
COMMAND cp -r ${CMAKE_BINARY_DIR}/gcc/prefix/lib64 ${CMAKE_BINARY_DIR}/gcc/lib64
|
||||
STEP_TARGETS install
|
||||
)
|
||||
|
||||
@ -267,7 +308,7 @@ add_custom_command(OUTPUT lindows_c.img
|
||||
if=/dev/zero
|
||||
of=lindows_c.img
|
||||
bs=1M
|
||||
count=256
|
||||
count=512
|
||||
# format disk with new NTFS filesystem
|
||||
COMMAND "${NTFS3g_Mkfs_EXECUTABLE}" ARGS -F # scary!
|
||||
-L Windows
|
||||
@ -303,8 +344,13 @@ add_custom_command(OUTPUT lindows_c.img
|
||||
# copy curses to system32
|
||||
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/scripts/copylib ncurses
|
||||
|
||||
# copy lsmss
|
||||
COMMAND ${CoreUtils_Copy_EXECUTABLE} ARGS $<TARGET_FILE:lsmss> lindows_c/Windows/System32/lsmss.exe
|
||||
# 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:lrss> lindows_c/Windows/System32/lrss.exe
|
||||
COMMAND ${CoreUtils_Copy_EXECUTABLE} ARGS $<TARGET_FILE:lrssclient> lindows_c/Windows/System32/liblrssclient.so
|
||||
|
||||
# create users folder
|
||||
COMMAND ${CoreUtils_Mkdir_EXECUTABLE} ARGS lindows_c/Users
|
||||
@ -313,7 +359,7 @@ add_custom_command(OUTPUT lindows_c.img
|
||||
COMMAND "umount" ARGS lindows_c
|
||||
|
||||
DEPENDS
|
||||
lsmss
|
||||
lsmss lrss lrssclient
|
||||
Linux-install
|
||||
GLibC-install
|
||||
Bash-install
|
||||
@ -351,12 +397,12 @@ add_custom_command(OUTPUT lindows.img
|
||||
COMMAND echo ARGS label: gpt > 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=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
|
||||
if=/dev/zero
|
||||
of=lindows.img
|
||||
bs=1M
|
||||
count=300
|
||||
count=600
|
||||
# partition disk
|
||||
COMMAND sfdisk ARGS lindows.img < disk.sfdisk
|
||||
# write partitions
|
||||
@ -371,7 +417,7 @@ add_custom_command(OUTPUT lindows.img
|
||||
if=lindows_c.img
|
||||
of=lindows.img
|
||||
bs=1M
|
||||
count=256
|
||||
count=512
|
||||
seek=34
|
||||
conv=notrunc
|
||||
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_subdirectory(lsmss)
|
||||
add_subdirectory(lrss)
|
||||
|
4
README
4
README
@ -1,3 +1,7 @@
|
||||
== NAMING ==
|
||||
|
||||
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
|
||||
SOURCES main.cxx
|
||||
)
|
||||
|
||||
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 <string>
|
||||
#include <filesystem>
|
||||
#include <vector>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/wait.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.
|
||||
*
|
||||
* \param message to log
|
||||
*/
|
||||
void Pii_Log(const std::string& message) {
|
||||
void PiiLog(const std::string& message) {
|
||||
std::cout << message << "\n";
|
||||
return;
|
||||
}
|
||||
@ -26,7 +107,7 @@ void Pii_Log(const std::string& message) {
|
||||
* \param path absolute path to program (duh)
|
||||
* \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()) {
|
||||
int exitcode = -1;
|
||||
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
|
||||
*/
|
||||
[[noreturn]]
|
||||
void Pii_AbortBoot() {
|
||||
Pii_Log("Unable to complete preinitialization. You have been dropped into a minimal recovery environment. Good luck.");
|
||||
Pii_ExecuteProgram("/Windows/System32/bash.exe");
|
||||
void PiiAbortBoot() {
|
||||
PiiLog("Unable to complete preinitialization. You have been dropped into a minimal recovery environment. Good luck.");
|
||||
PiiExecuteProgram("/Windows/System32/bash.exe");
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::vector<PiiSubsystemState> subsystems {};
|
||||
|
||||
// -- just print shit --
|
||||
Pii_Log("Starting Lindows Session Manager Subsystem");
|
||||
PiiLog("Starting Lindows Session Manager Subsystem");
|
||||
|
||||
|
||||
// -- dynamic linking fun --
|
||||
Pii_Log("Regenerating dynamic linker cache");
|
||||
Pii_ExecuteProgram("/Windows/System32/ldconfig.exe");
|
||||
PiiLog("Regenerating dynamic linker cache");
|
||||
PiiExecuteProgram("/Windows/System32/ldconfig.exe");
|
||||
|
||||
// -- registry --
|
||||
Pii_Log("Starting Lindows Registry Subsystem");
|
||||
// TODO
|
||||
Pii_Log("Loading Lindows registry");
|
||||
PiiLog("Starting Lindows Registry Subsystem");
|
||||
subsystems.emplace(subsystems.end(), "Lindows Registry Subsystem", "/Windows/System32/lrss.exe")
|
||||
->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
|
||||
|
||||
// -- swap --
|
||||
Pii_Log("Creating pagefiles");
|
||||
PiiLog("Creating pagefiles");
|
||||
// TODO
|
||||
|
||||
// -- env --
|
||||
Pii_Log("Setting environment variables");
|
||||
PiiLog("Setting environment variables");
|
||||
// TODO
|
||||
|
||||
// we are never ok
|
||||
Pii_AbortBoot();
|
||||
PiiAbortBoot();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,30 +1,38 @@
|
||||
#!/bin/sh
|
||||
# ARG 1: LIB PATH
|
||||
# ARG 2: LIB DIR
|
||||
|
||||
# copy libs
|
||||
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;
|
||||
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/lib -type f | sed -r 's/'$1'\/lib\/(.*)/cp '$1'\/lib\/\1 lindows_c\/Windows\/System32\/\1/;e' > /dev/null
|
||||
main() {
|
||||
# copy libs
|
||||
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/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
|
||||
# with symlinks, so we have to build the reparse point and do it ourselves
|
||||
for lib in $(cd $1/lib && find -type l); do
|
||||
WPATH="$(echo -n $(readlink "$1/lib/$lib"))"
|
||||
LPATH="$(echo -n '/Windows/System32/'"$WPATH" | sed -E 's/(.)/\1\\x00/g;s/\//\\\\/g')" # sed -E 's/(.)/\\0\1/g');
|
||||
LPATHL=$(( 36 + ${#WPATH} * 2 ));
|
||||
# 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
|
||||
for lib in $(cd $1/$2 && find -type l); do
|
||||
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');
|
||||
LPATHL=$(( 36 + ${#WPATH} * 2 ));
|
||||
|
||||
LPATHL1=$(printf "%o" $((($LPATHL >> 8 ) & 255 )) );
|
||||
LPATHL0=$(printf "%o" $((($LPATHL ) & 255 )) );
|
||||
LPATHL1=$(printf "%o" $((($LPATHL >> 8 ) & 255 )) );
|
||||
LPATHL0=$(printf "%o" $((($LPATHL ) & 255 )) );
|
||||
|
||||
LBUF="\\x00\\x00\\$LPATHL0\\$LPATHL1\\x00\\x00\\$LPATHL0\\$LPATHL1\\x00\\x00\\x00\\x00$LPATH"
|
||||
LBUFL=$(( 12 + $LPATHL ))
|
||||
LBUFL1=$(printf "%o" $((($LBUFL >> 8) & 255 )) );
|
||||
LBUFL0=$(printf "%o" $((($LBUFL ) & 255 )) );
|
||||
LBUF="\\x00\\x00\\$LPATHL0\\$LPATHL1\\x00\\x00\\$LPATHL0\\$LPATHL1\\x00\\x00\\x00\\x00$LPATH"
|
||||
LBUFL=$(( 12 + $LPATHL ))
|
||||
LBUFL1=$(printf "%o" $((($LBUFL >> 8) & 255 )) );
|
||||
LBUFL0=$(printf "%o" $((($LBUFL ) & 255 )) );
|
||||
|
||||
touch "lindows_c/Windows/System32/$lib";
|
||||
setfattr -h -n system.ntfs_reparse_data \
|
||||
-v "0S$(printf "\x0C\\x00\\x00\xA0\\$LBUFL0\\$LBUFL1\\x00\\x00$LBUF" | base64 -w0)"\
|
||||
"lindows_c/Windows/System32/$lib";
|
||||
touch "lindows_c/Windows/System32/$lib";
|
||||
setfattr -h -n system.ntfs_reparse_data \
|
||||
-v "0S$(printf "\x0C\\x00\\x00\xA0\\$LBUFL0\\$LBUFL1\\x00\\x00$LBUF" | base64 -w0)"\
|
||||
"lindows_c/Windows/System32/$lib";
|
||||
|
||||
#ln -sr "lindows_c/Windows/System32/$(readlink $1/lib/$lib)" "lindows_c/Windows/System32/$lib"
|
||||
done
|
||||
#ln -sr "lindows_c/Windows/System32/$(readlink $1/lib/$lib)" "lindows_c/Windows/System32/$lib"
|
||||
done
|
||||
}
|
||||
|
||||
[ -z "$2" ] && main "$1" lib;
|
||||
[ -n "$2" ] && main "$1" "$2";
|
||||
|
||||
exit 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user