From 52fcb1fcfa0440ff9d0a45f9258ad4e1936c79dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=88=9A=28noham=29=C2=B2?= <100566912+NohamR@users.noreply.github.com> Date: Thu, 7 May 2026 16:41:31 +0200 Subject: [PATCH] Add Qt network stack hooking --- paho-mqtt3as-proxy/common.h | 4 + paho-mqtt3as-proxy/hook.cpp | 236 +++++++++++++++++++++++++++++++++++- paho-mqtt3as-proxy/main.cpp | 2 - 3 files changed, 239 insertions(+), 3 deletions(-) diff --git a/paho-mqtt3as-proxy/common.h b/paho-mqtt3as-proxy/common.h index 3fa028c..bec2b7d 100644 --- a/paho-mqtt3as-proxy/common.h +++ b/paho-mqtt3as-proxy/common.h @@ -1,6 +1,8 @@ #pragma once #include +#include "MinHook.h" + struct paho_mqtt3as_dll { HMODULE dll; FARPROC OrignalMQTTAsync_connect; @@ -57,3 +59,5 @@ struct paho_mqtt3as_dll { extern paho_mqtt3as_dll paho_mqtt3as; extern "C" FARPROC PA; + +void InstallHooks(); diff --git a/paho-mqtt3as-proxy/hook.cpp b/paho-mqtt3as-proxy/hook.cpp index 94126fd..b2c80b2 100644 --- a/paho-mqtt3as-proxy/hook.cpp +++ b/paho-mqtt3as-proxy/hook.cpp @@ -1,3 +1,237 @@ #include #include -#include "MinHook.h" \ No newline at end of file +#include "MinHook.h" +#include +#include + +#include +#include +#include + +#include + +#include +#include + + +static std::string GetLogPath() +{ + char localAppData[MAX_PATH]; + if (SUCCEEDED(SHGetFolderPathA( + NULL, + CSIDL_LOCAL_APPDATA, + NULL, + 0, + localAppData))) + { + std::filesystem::path dir = + std::filesystem::path(localAppData) / "RMHook"; + std::filesystem::create_directories(dir); + return (dir / "rmhook.log").string(); + } + return "rmhook.log"; +} + +// ------------------------------------------------------------ +// Logging +// ------------------------------------------------------------ + +static void Log(const std::string& msg) +{ + std::ofstream file(GetLogPath(), std::ios::app); + if (file.is_open()) + { + file << msg << std::endl; + } +} + +// ------------------------------------------------------------ +// Original typedefs +// ------------------------------------------------------------ + +typedef QNetworkReply* (__fastcall* QNAM_CreateRequest_t)( + QNetworkAccessManager* self, + QNetworkAccessManager::Operation op, + const QNetworkRequest& req, + QIODevice* outgoingData +); + +typedef void (__fastcall* QWebSocket_Open_t)( + QWebSocket* self, + const QNetworkRequest& req +); + +// ------------------------------------------------------------ +// Originals +// ------------------------------------------------------------ + +static QNAM_CreateRequest_t originalCreateRequest = nullptr; +static QWebSocket_Open_t originalWebSocketOpen = nullptr; + +// ------------------------------------------------------------ +// Hooked createRequest +// ------------------------------------------------------------ + +QNetworkReply* __fastcall hookedCreateRequest( + QNetworkAccessManager* self, + QNetworkAccessManager::Operation op, + const QNetworkRequest& req, + QIODevice* outgoingData +) +{ + QString host = req.url().host(); + + Log("[HTTP] " + host.toStdString()); + + return originalCreateRequest( + self, + op, + req, + outgoingData + ); +} + +// ------------------------------------------------------------ +// Hooked websocket open +// ------------------------------------------------------------ + +void __fastcall hookedWebSocketOpen( + QWebSocket* self, + const QNetworkRequest& req +) +{ + QString host = req.url().host(); + + Log("[WS] " + host.toStdString()); + + originalWebSocketOpen( + self, + req + ); +} + +// ------------------------------------------------------------ +// Helpers +// ------------------------------------------------------------ + +void* ResolveExport(HMODULE module, const char* symbol) +{ + void* addr = (void*)GetProcAddress(module, symbol); + + if (!addr) + { + Log("[ERROR] Failed to resolve symbol"); + Log(symbol); + } + + return addr; +} + +// ------------------------------------------------------------ +// InstallHooks +// ------------------------------------------------------------ + +void InstallHooks() +{ + // std::string logPath = GetLogPath(); + // std::string message = "Proxy Hook Started.\nLog file: " + logPath; + // MessageBoxA(NULL, message.c_str(), "reMarkable Proxy", MB_OK | MB_ICONINFORMATION); + + Log("[*] Initializing MinHook"); + + if (MH_Initialize() != MH_OK) + { + Log("[ERROR] MH_Initialize failed"); + return; + } + + // -------------------------------------------------------- + // Wait for Qt DLLs + // -------------------------------------------------------- + + HMODULE qtNetwork = nullptr; + HMODULE qtWebSockets = nullptr; + + while (!qtNetwork) + { + qtNetwork = GetModuleHandleA("Qt6Network.dll"); + Sleep(100); + } + + while (!qtWebSockets) + { + qtWebSockets = GetModuleHandleA("Qt6WebSockets.dll"); + Sleep(100); + } + + Log("[+] Qt DLLs loaded"); + + // -------------------------------------------------------- + // Resolve symbols + // -------------------------------------------------------- + + void* createRequestAddr = ResolveExport( + qtNetwork, + "?createRequest@QNetworkAccessManager@@MEAAPEAVQNetworkReply@@W4Operation@1@AEBVQNetworkRequest@@PEAVQIODevice@@@Z" + ); + + void* webSocketOpenAddr = ResolveExport( + qtWebSockets, + "?open@QWebSocket@@QEAAXAEBVQNetworkRequest@@@Z" + ); + + if (!createRequestAddr || !webSocketOpenAddr) + { + Log("[ERROR] Failed to resolve one or more symbols"); + return; + } + + Log("[+] Symbols resolved"); + + // -------------------------------------------------------- + // Hook QNetworkAccessManager::createRequest + // -------------------------------------------------------- + + if (MH_CreateHook( + createRequestAddr, + &hookedCreateRequest, + reinterpret_cast(&originalCreateRequest) + ) != MH_OK) + { + Log("[ERROR] Failed to hook createRequest"); + } + else + { + Log("[+] Hooked createRequest"); + } + + // -------------------------------------------------------- + // Hook QWebSocket::open + // -------------------------------------------------------- + + if (MH_CreateHook( + webSocketOpenAddr, + &hookedWebSocketOpen, + reinterpret_cast(&originalWebSocketOpen) + ) != MH_OK) + { + Log("[ERROR] Failed to hook QWebSocket::open"); + } + else + { + Log("[+] Hooked QWebSocket::open"); + } + + // -------------------------------------------------------- + // Enable all hooks + // -------------------------------------------------------- + + if (MH_EnableHook(MH_ALL_HOOKS) != MH_OK) + { + Log("[ERROR] Failed to enable hooks"); + } + else + { + Log("[+] Hooks enabled"); + } +} \ No newline at end of file diff --git a/paho-mqtt3as-proxy/main.cpp b/paho-mqtt3as-proxy/main.cpp index bbeeff4..c4d7307 100644 --- a/paho-mqtt3as-proxy/main.cpp +++ b/paho-mqtt3as-proxy/main.cpp @@ -67,8 +67,6 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv { DisableThreadLibraryCalls(hModule); - MH_Initialize(); - paho_mqtt3as.dll = LoadLibrary("paho-mqtt3as_orig.dll"); if (paho_mqtt3as.dll == NULL) {