fix linux

This commit is contained in:
Simplxs 2024-05-07 15:50:03 +08:00
parent eefc172dbb
commit d4a43b89b3
No known key found for this signature in database
GPG Key ID: E23537FF14DD6507
13 changed files with 302 additions and 41 deletions

View File

@ -7,17 +7,24 @@ if("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
add_definitions(-D _WIN_PLATFORM_)
link_libraries(ws2_32)
enable_language(ASM)
SET(CMAKE_ASM_FLAGS "${CFLAGS} -x assembler-with-cpp")
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
add_definitions(-D _MAC_PLATFORM_)
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
add_definitions(-D _LINUX_PLATFORM_)
endif()
# CPP
set(CMAKE_CXX_STANDARD 17)
file(GLOB SOURCE_FILES "./src/*.cpp")
file(GLOB SOURCE_FILES "./src/*.cpp" "./src/*.asm")
add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} "./include/mongoose/mongoose.c")
if(MSVC)
target_link_options(SignerServer PRIVATE
/DEF:${CMAKE_CURRENT_SOURCE_DIR}/version.def
)
endif()

1
load.js Normal file
View File

@ -0,0 +1 @@
require("/opt/QQ/resources/app/wrapper.node");

4
signserver.sh Normal file
View File

@ -0,0 +1,4 @@
#!/bin/bash
SCRIPT_DIR=$(realpath $(dirname "${BASH_SOURCE[0]}"))
export ELECTRON_RUN_AS_NODE=1
LD_PRELOAD=./libSignerServer.so /opt/QQ/qq ${SCRIPT_DIR}/load.js $@

29
src/exports.cpp Normal file
View File

@ -0,0 +1,29 @@
#if defined(_WIN_PLATFORM_)
#include "exports.h"
#include <filesystem>
FARPROC OriginalFuncs_version[17];
void Exports::Load()
{
char szSystemDirectory[MAX_PATH]{};
GetSystemDirectoryA(szSystemDirectory, MAX_PATH);
std::string OriginalPath = szSystemDirectory;
OriginalPath += "\\version.dll";
HMODULE version = LoadLibraryA(OriginalPath.c_str());
// load version.dll from system32
if (!version)
throw std::runtime_error("Failed to load version.dll from system32\n");
// get addresses of original functions
for (int i = 0; i < 17; i++)
{
OriginalFuncs_version[i] = GetProcAddress(version, ExportNames_version[i].c_str());
if (!OriginalFuncs_version[i])
throw std::runtime_error("Failed to get address of " + ExportNames_version[i] + "\n");
}
}
#endif

31
src/exports.h Normal file
View File

@ -0,0 +1,31 @@
#pragma once
#include <Windows.h>
#include <vector>
#include <string>
extern "C" FARPROC OriginalFuncs_version[17];
inline std::vector<std::string> ExportNames_version = {
"GetFileVersionInfoA",
"GetFileVersionInfoByHandle",
"GetFileVersionInfoExA",
"GetFileVersionInfoExW",
"GetFileVersionInfoSizeA",
"GetFileVersionInfoSizeExA",
"GetFileVersionInfoSizeExW",
"GetFileVersionInfoSizeW",
"GetFileVersionInfoW",
"VerFindFileA",
"VerFindFileW",
"VerInstallFileA",
"VerInstallFileW",
"VerLanguageNameA",
"VerLanguageNameW",
"VerQueryValueA",
"VerQueryValueW"
};
namespace Exports
{
void Load();
}

23
src/hijacker.cpp Normal file
View File

@ -0,0 +1,23 @@
#if defined(_WIN_PLATFORM_)
#include "exports.h"
bool TlsOnce = false;
// this runs way before dllmain
void __stdcall TlsCallback(PVOID hModule, DWORD fdwReason, PVOID pContext)
{
if (!TlsOnce)
{
// for version.dll proxy
// load exports as early as possible
Exports::Load();
TlsOnce = true;
}
}
#pragma comment (linker, "/INCLUDE:_tls_used")
#pragma comment (linker, "/INCLUDE:tls_callback_func")
#pragma const_seg(".CRT$XLF")
EXTERN_C const PIMAGE_TLS_CALLBACK tls_callback_func = TlsCallback;
#endif

View File

@ -1,17 +1,3 @@
#include "sign.h"
#include "server.h"
#include <iostream>
int main()
{
try
{
sign::InitSignCall();
server::init(8080);
}
catch (const std::exception &e)
{
std::cerr << e.what() << std::endl;
}
}
Server server(8080);

View File

@ -1,9 +1,12 @@
#include "server.h"
#include "sign.h"
#include "../include/mongoose/mongoose.h"
#include "server.h"
#include "../include/rapidjson/document.h"
#include "../include/rapidjson/writer.h"
#include <thread>
Sign sign;
// HTTP server event handler function
void ev_handler(struct mg_connection *c, int ev, void *ev_data)
{
@ -21,7 +24,7 @@ void ev_handler(struct mg_connection *c, int ev, void *ev_data)
std::string_view src = doc["src"].GetString();
int seq = doc["seq"].GetInt64();
auto [signDataHex, extraDataHex, tokenDataHex] = sign::CallSign(cmd, src, seq);
auto [signDataHex, extraDataHex, tokenDataHex] = sign.Call(cmd, src, seq);
// Construct response
rapidjson::StringBuffer buffer;
@ -55,14 +58,21 @@ void ev_handler(struct mg_connection *c, int ev, void *ev_data)
}
}
void server::init(int port)
Server::Server(int port)
{
char url[32];
snprintf(url, sizeof(url), "http://0.0.0.0:%d", port);
struct mg_mgr mgr; // Declare event manager
mg_mgr_init(&mgr); // Initialise event manager
mg_mgr_init(&mgr); // Initialise event manager
mg_http_listen(&mgr, url, ev_handler, NULL); // Setup listener
// new thread to loop
std::thread t(&Server::Loop, this);
t.detach();
}
void Server::Loop()
{
for (;;)
{ // Run an infinite event loop
mg_mgr_poll(&mgr, 1000);

View File

@ -1,5 +1,13 @@
#include "../include/mongoose/mongoose.h"
namespace server
class Server
{
void init(const int port);
}
public:
Server(int port);
private:
struct mg_mgr mgr; // Declare event manager
private:
void Loop();
};

View File

@ -6,8 +6,10 @@
#include <vector>
#include <map>
// #define _LINUX_PLATFORM_
#define _WIN_PLATFORM_
#include <thread>
#define _LINUX_PLATFORM_
// #define _WIN_PLATFORM_
#define _X64_ARCH_
@ -60,11 +62,12 @@ std::vector<uint8_t> Hex2Bin(std::string_view str)
if (str.length() % 2 != 0)
throw std::invalid_argument("Hex string length must be even");
std::vector<uint8_t> bin(str.size() / 2);
std::string extract("00");
for (size_t i = 0; i < str.size() / 2; i++)
{
std::stringstream ss;
ss << std::hex << str.substr(i * 2, 2);
ss >> bin[i];
extract[0] = str[2 * i];
extract[1] = str[2 * i + 1];
bin[i] = std::stoi(extract, nullptr, 16);
}
return bin;
}
@ -82,10 +85,13 @@ std::string Bin2Hex(const uint8_t *ptr, size_t length)
return str;
}
typedef int (*SignFunctionType)(const char *cmd, const unsigned char *src, size_t src_len, int seq, unsigned char *result);
SignFunctionType SignFunction = nullptr;
Sign::Sign()
{
std::thread t(&Sign::InitEx, this);
t.detach();
}
void sign::InitSignCall()
void Sign::Init()
{
uint64_t HookAddress = 0;
#if defined(_WIN_PLATFORM_)
@ -124,7 +130,22 @@ void sign::InitSignCall()
SignFunction = reinterpret_cast<SignFunctionType>(HookAddress);
}
std::tuple<std::string, std::string, std::string> sign::CallSign(const std::string_view cmd, const std::string_view src, int seq)
void Sign::InitEx()
{
while (true)
try
{
Init();
break;
}
catch (const std::exception &e)
{
std::cerr << e.what() << '\n';
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
std::tuple<std::string, std::string, std::string> Sign::Call(const std::string_view cmd, const std::string_view src, int seq)
{
if (SignFunction == nullptr)
throw std::runtime_error("Sign function not initialized");

View File

@ -1,8 +1,17 @@
#include <string>
#include <tuple>
namespace sign
class Sign
{
void InitSignCall();
std::tuple<std::string, std::string, std::string> CallSign(const std::string_view cmd, const std::string_view src, int seq);
}
public:
Sign();
private:
typedef int (*SignFunctionType)(const char *cmd, const unsigned char *src, size_t src_len, int seq, unsigned char *result);
SignFunctionType SignFunction = nullptr;
void Init();
void InitEx();
public:
std::tuple<std::string, std::string, std::string> Call(const std::string_view cmd, const std::string_view src, int seq);
};

114
src/version.asm Normal file
View File

@ -0,0 +1,114 @@
ifdef _WIN_PLATFORM_
ifdef RAX
.code
extern OriginalFuncs_version:QWORD
GetFileVersionInfoA proc
jmp QWORD ptr OriginalFuncs_version[0 * 8]
GetFileVersionInfoA endp
GetFileVersionInfoByHandle proc
jmp QWORD ptr OriginalFuncs_version[1 * 8]
GetFileVersionInfoByHandle endp
GetFileVersionInfoExA proc
jmp QWORD ptr OriginalFuncs_version[2 * 8]
GetFileVersionInfoExA endp
GetFileVersionInfoExW proc
jmp QWORD ptr OriginalFuncs_version[3 * 8]
GetFileVersionInfoExW endp
GetFileVersionInfoSizeA proc
jmp QWORD ptr OriginalFuncs_version[4 * 8]
GetFileVersionInfoSizeA endp
GetFileVersionInfoSizeExA proc
jmp QWORD ptr OriginalFuncs_version[5 * 8]
GetFileVersionInfoSizeExA endp
GetFileVersionInfoSizeExW proc
jmp QWORD ptr OriginalFuncs_version[6 * 8]
GetFileVersionInfoSizeExW endp
GetFileVersionInfoSizeW proc
jmp QWORD ptr OriginalFuncs_version[7 * 8]
GetFileVersionInfoSizeW endp
GetFileVersionInfoW proc
jmp QWORD ptr OriginalFuncs_version[8 * 8]
GetFileVersionInfoW endp
VerFindFileA proc
jmp QWORD ptr OriginalFuncs_version[9 * 8]
VerFindFileA endp
VerFindFileW proc
jmp QWORD ptr OriginalFuncs_version[10 * 8]
VerFindFileW endp
VerInstallFileA proc
jmp QWORD ptr OriginalFuncs_version[11 * 8]
VerInstallFileA endp
VerInstallFileW proc
jmp QWORD ptr OriginalFuncs_version[12 * 8]
VerInstallFileW endp
VerLanguageNameA proc
jmp QWORD ptr OriginalFuncs_version[13 * 8]
VerLanguageNameA endp
VerLanguageNameW proc
jmp QWORD ptr OriginalFuncs_version[14 * 8]
VerLanguageNameW endp
VerQueryValueA proc
jmp QWORD ptr OriginalFuncs_version[15 * 8]
VerQueryValueA endp
VerQueryValueW proc
jmp QWORD ptr OriginalFuncs_version[16 * 8]
VerQueryValueW endp
else
.model flat, C
.stack 4096
.code
extern OriginalFuncs_version:DWORD
GetFileVersionInfoA proc
jmp DWORD ptr OriginalFuncs_version[0 * 4]
GetFileVersionInfoA endp
GetFileVersionInfoByHandle proc
jmp DWORD ptr OriginalFuncs_version[1 * 4]
GetFileVersionInfoByHandle endp
GetFileVersionInfoExA proc
jmp DWORD ptr OriginalFuncs_version[2 * 4]
GetFileVersionInfoExA endp
GetFileVersionInfoExW proc
jmp DWORD ptr OriginalFuncs_version[3 * 4]
GetFileVersionInfoExW endp
GetFileVersionInfoSizeA proc
jmp DWORD ptr OriginalFuncs_version[4 * 4]
GetFileVersionInfoSizeA endp
GetFileVersionInfoSizeExA proc
jmp DWORD ptr OriginalFuncs_version[5 * 4]
GetFileVersionInfoSizeExA endp
GetFileVersionInfoSizeExW proc
jmp DWORD ptr OriginalFuncs_version[6 * 4]
GetFileVersionInfoSizeExW endp
GetFileVersionInfoSizeW proc
jmp DWORD ptr OriginalFuncs_version[7 * 4]
GetFileVersionInfoSizeW endp
GetFileVersionInfoW proc
jmp DWORD ptr OriginalFuncs_version[8 * 4]
GetFileVersionInfoW endp
VerFindFileA proc
jmp DWORD ptr OriginalFuncs_version[9 * 4]
VerFindFileA endp
VerFindFileW proc
jmp DWORD ptr OriginalFuncs_version[10 * 4]
VerFindFileW endp
VerInstallFileA proc
jmp DWORD ptr OriginalFuncs_version[11 * 4]
VerInstallFileA endp
VerInstallFileW proc
jmp DWORD ptr OriginalFuncs_version[12 * 4]
VerInstallFileW endp
VerLanguageNameA proc
jmp DWORD ptr OriginalFuncs_version[13 * 4]
VerLanguageNameA endp
VerLanguageNameW proc
jmp DWORD ptr OriginalFuncs_version[14 * 4]
VerLanguageNameW endp
VerQueryValueA proc
jmp DWORD ptr OriginalFuncs_version[15 * 4]
VerQueryValueA endp
VerQueryValueW proc
jmp DWORD ptr OriginalFuncs_version[16 * 4]
VerQueryValueW endp
endif
endif
end

18
version.def Normal file
View File

@ -0,0 +1,18 @@
EXPORTS
GetFileVersionInfoA
GetFileVersionInfoByHandle
GetFileVersionInfoExA
GetFileVersionInfoExW
GetFileVersionInfoSizeA
GetFileVersionInfoSizeExA
GetFileVersionInfoSizeExW
GetFileVersionInfoSizeW
GetFileVersionInfoW
VerFindFileA
VerFindFileW
VerInstallFileA
VerInstallFileW
VerLanguageNameA
VerLanguageNameW
VerQueryValueA
VerQueryValueW