Skip to content

Commit

Permalink
add lz4 compression
Browse files Browse the repository at this point in the history
  • Loading branch information
dumbasPL committed Jan 27, 2024
1 parent 60cd54f commit 13cc966
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 12 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.15 FATAL_ERROR)
project(fumo_loader)
project(fumo_loader VERSION 0.3.0)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

Expand Down
14 changes: 14 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# disable C4711, C5045, C4820 (caused by lz4)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4711 /wd5045 /wd4820")

CPMAddPackage(
NAME xorstr
GITHUB_REPOSITORY JustasMasiulis/xorstr
Expand All @@ -22,6 +25,17 @@ if (lazy_importer_ADDED)
target_include_directories(lazy_importer INTERFACE ${lazy_importer_SOURCE_DIR}/include)
endif()

CPMAddPackage(
NAME lz4
GITHUB_REPOSITORY lz4/lz4
VERSION 1.9.4
SOURCE_SUBDIR build/cmake
OPTIONS
"LZ4_BUILD_CLI OFF"
"LZ4_BUILD_LEGACY_LZ4C OFF"
)
find_package(lz4 REQUIRED)

CPMAddPackage("gh:SergiusTheBest/FindWDK#master")
list(APPEND CMAKE_MODULE_PATH "${FindWDK_SOURCE_DIR}/cmake")
find_package(WDK REQUIRED)
Expand Down
1 change: 1 addition & 0 deletions src/encoder/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ add_executable(fumo_encoder fumo_encoder.cpp)
target_compile_features(fumo_encoder PUBLIC c_std_17 cxx_std_20)
target_compile_definitions(fumo_encoder PRIVATE UNICODE _UNICODE)
target_include_directories(fumo_encoder PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../include)
target_link_libraries(fumo_encoder PRIVATE lz4_static)
29 changes: 21 additions & 8 deletions src/encoder/fumo_encoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <ctime>
#include <fomo_common.h>
#include <util.h>
#include <lz4.h>

int main(int argc, char** argv) {
// usage: [input_file] [process_name] [wait_for_module1,[wait_for_module2,...]] [output_file]
Expand Down Expand Up @@ -59,23 +60,33 @@ int main(int argc, char** argv) {
std::cerr << "Failed to open input file:" << input_file_name << std::endl;
return 1;
}
std::vector<unsigned char> data;
std::vector<char> data;
data.assign(std::istreambuf_iterator<char>(input_file), std::istreambuf_iterator<char>());

// compress data
std::vector<char> compressed_data;
compressed_data.resize(LZ4_compressBound(data.size()));
size_t compressed_size = LZ4_compress_default(data.data(), compressed_data.data(), data.size(), compressed_data.size());
if (compressed_size <= 0) {
std::cerr << "Failed to compress data" << std::endl;
return 1;
}
compressed_data.resize(compressed_size);

// generate xor key
std::srand(std::time(nullptr));
uint64_t xor_key = 0;
for (int i = 0; i < 8; i++)
xor_key |= (std::rand() % 256) << (i * 8);

// pad to 8 bytes
int padding = 8 - (data.size() % 8);
int padding = 8 - (compressed_data.size() % 8);
if (padding != 8)
data.insert(data.end(), padding, 0);
compressed_data.insert(compressed_data.end(), padding, 0);

// encrypt data
for (int i = 0; i < data.size(); i += sizeof(xor_key)) {
uint64_t* ptr = (uint64_t*)&data[i];
// encrypt compressed_data
for (int i = 0; i < compressed_data.size(); i += sizeof(xor_key)) {
uint64_t* ptr = (uint64_t*)&compressed_data[i];
*ptr ^= xor_key;
}

Expand Down Expand Up @@ -111,10 +122,12 @@ int main(int argc, char** argv) {
header.Version = FUMO_DATA_VERSION;
header.XorKey = xor_key;
header.SettingsSize = loader_settings_data.size();
header.DataSize = data.size();
header.DataSize = compressed_data.size();
header.CompressedDataSize = compressed_size;
header.DecompressedDataSize = data.size();
output_file.write((char*)&header, sizeof(header));
output_file.write((char*)loader_settings_data.data(), loader_settings_data.size());
output_file.write((char*)data.data(), data.size());
output_file.write((char*)compressed_data.data(), compressed_data.size());

output_file.close();

Expand Down
4 changes: 3 additions & 1 deletion src/include/fomo_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#define MIN_OS_BUILD_NUMBER 19041

#define FUMO_MAGIC 'OMUF'
#define FUMO_DATA_VERSION 0x00000001
#define FUMO_DATA_VERSION 0x00000002
#define FUMO_DRIVER_VERSION 0x00000002
#define FUMO_HOOKED_DRIVER_NAME L"\\Driver\\Null"
#define FUMO_HOOKED_DRIVER_NAME_USER L"\\\\.\\NUL"
Expand Down Expand Up @@ -58,6 +58,8 @@ typedef struct _FUMO_DATA_HEADER {
DWORDLONG XorKey;
DWORD SettingsSize;
DWORD DataSize;
DWORD CompressedDataSize;
DWORD DecompressedDataSize;
} FUMO_DATA_HEADER, *PFUMO_DATA_HEADER;

typedef struct _FUMO_EMBEDDED_DATA {
Expand Down
2 changes: 1 addition & 1 deletion src/stage2/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ target_include_directories(stage2 PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../include
target_compile_features(stage2 PUBLIC c_std_17 cxx_std_20)
target_compile_options(stage2 PRIVATE /O1 /GS- /sdl- /guard:cf- /Zc:threadSafeInit-)
target_compile_definitions(stage2 PRIVATE UNICODE _UNICODE)
target_link_libraries(stage2 PRIVATE driver_interface)
target_link_libraries(stage2 PRIVATE driver_interface lz4_static)
9 changes: 8 additions & 1 deletion src/stage2/stage2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <driver_interface.h>
#include <util.h>
#include <sstream>
#include <lz4.h>

std::wstring loader_process_name = L"";
STAGE2_LOADER_DATA loader_data;
Expand Down Expand Up @@ -154,8 +155,14 @@ int main(HANDLE loader_process) {
*ptr ^= xor_key;
}

// decompress the data
auto decompressed_data = std::make_unique<char[]>(header->DecompressedDataSize);
auto decompressed_size = LZ4_decompress_safe((char*)data, decompressed_data.get(), header->CompressedDataSize, header->DecompressedDataSize);
if (decompressed_size <= 0)
return fumo::error(ERR_STAGE2_FAILED_TO_DECOMPRESS_DATA, L"Failed to decompress data");

// let the magic happen
auto error = MapImage(&driver_ref, process_id, data);
auto error = MapImage(&driver_ref, process_id, decompressed_data.get());
if (error != ERROR_SUCCESS)
return error;

Expand Down
1 change: 1 addition & 0 deletions src/stage2/stage2.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#define ERR_STAGE2_INVALID_VERSION 101
#define ERR_STAGE2_FAILED_TO_CREATE_THREAD 102
#define ERR_STAGE2_FAILED_TO_WAIT_FOR_MODULE 103
#define ERR_STAGE2_FAILED_TO_DECOMPRESS_DATA 104
#define ERR_STAGE2_INVALID_PE_HEADER 200
#define ERR_STAGE2_FAILED_TO_ALLOCATE_MEMORY 201
#define ERR_STAGE2_FAILED_TO_MAP_FILE 202
Expand Down

0 comments on commit 13cc966

Please sign in to comment.