Code:
// ConsoleApplication1.cpp : This file contains the "main" function. Program execution begins and ends here.
//
#include <iostream>
#include <windows.h>
#include <iostream>
#include <TlHelp32.h>
// Define NtCreateThreadEx function prototype
typedef NTSTATUS(NTAPI* pNtCreateThreadEx)(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
PVOID ObjectAttributes,
HANDLE ProcessHandle,
PVOID lpStartAddress,
PVOID lpParameter,
ULONG Flags,
SIZE_T StackZeroBits,
SIZE_T SizeOfStackCommit,
SIZE_T SizeOfStackReserve,
PVOID lpBytesBuffer
);
// Get process ID by process name
DWORD GetProcessIdByName(const char* processName) {
PROCESSENTRY32 processEntry = { 0 };
processEntry.dwSize = sizeof(PROCESSENTRY32);
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (snapshot == INVALID_HANDLE_VALUE) {
std::cerr << "CreateToolhelp32Snapshot failed: " << GetLastError() << std::endl;
return 0;
}
if (Process32First(snapshot, &processEntry)) {
do {
if (_stricmp(processEntry.szExeFile, processName) == 0) {
CloseHandle(snapshot);
return processEntry.th32ProcessID;
}
} while (Process32Next(snapshot, &processEntry));
}
CloseHandle(snapshot);
return 0;
}
bool InjectDLL(DWORD processId, const char* dllPath) {
// Open target process
HANDLE hProcess = OpenProcess(
PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION |
PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,
FALSE, processId);
if (hProcess == NULL) {
std::cerr << "OpenProcess failed: " << GetLastError() << std::endl;
return false;
}
// Get address of LoadLibraryA function
LPVOID loadLibraryAddr = (LPVOID)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
if (loadLibraryAddr == NULL) {
std::cerr << "GetProcAddress(LoadLibraryA) failed: " << GetLastError() << std::endl;
CloseHandle(hProcess);
return false;
}
// Allocate memory in target process
SIZE_T dllPathSize = strlen(dllPath) + 1;
LPVOID dllPathAddr = VirtualAllocEx(hProcess, NULL, dllPathSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (dllPathAddr == NULL) {
std::cerr << "VirtualAllocEx failed: " << GetLastError() << std::endl;
CloseHandle(hProcess);
return false;
}
// Write DLL path into target process memory
if (!WriteProcessMemory(hProcess, dllPathAddr, dllPath, dllPathSize, NULL)) {
std::cerr << "WriteProcessMemory failed: " << GetLastError() << std::endl;
VirtualFreeEx(hProcess, dllPathAddr, 0, MEM_RELEASE);
CloseHandle(hProcess);
return false;
}
// Get address of NtCreateThreadEx function
HMODULE ntdllModule = GetModuleHandleA("ntdll.dll");
pNtCreateThreadEx ntCreateThreadEx = (pNtCreateThreadEx)GetProcAddress(ntdllModule, "NtCreateThreadEx");
if (ntCreateThreadEx == NULL) {
std::cerr << "GetProcAddress(NtCreateThreadEx) failed: " << GetLastError() << std::endl;
// Try alternative method
ntCreateThreadEx = (pNtCreateThreadEx)GetProcAddress(ntdllModule, "ZwCreateThreadEx");
if (ntCreateThreadEx == NULL) {
std::cerr << "GetProcAddress(ZwCreateThreadEx) failed: " << GetLastError() << std::endl;
VirtualFreeEx(hProcess, dllPathAddr, 0, MEM_RELEASE);
CloseHandle(hProcess);
return false;
}
}
// Create remote thread
HANDLE hThread = NULL;
NTSTATUS status = ntCreateThreadEx(
&hThread,
GENERIC_EXECUTE,
NULL,
hProcess,
(LPTHREAD_START_ROUTINE)loadLibraryAddr,
dllPathAddr,
FALSE,
0,
0,
0,
NULL
);
if (status != 0 || hThread == NULL) {
std::cerr << "NtCreateThreadEx failed, status: " << status << ", error: " << GetLastError() << std::endl;
// Try using CreateRemoteThread as fallback
hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)loadLibraryAddr, dllPathAddr, 0, NULL);
if (hThread == NULL) {
std::cerr << "CreateRemoteThread failed: " << GetLastError() << std::endl;
VirtualFreeEx(hProcess, dllPathAddr, 0, MEM_RELEASE);
CloseHandle(hProcess);
return false;
}
else {
std::cout << "Fallback to CreateRemoteThread succeeded." << std::endl;
}
}
// Wait for thread to complete and clean up
WaitForSingleObject(hThread, INFINITE);
// Get LoadLibrary return value (DLL handle)
DWORD dllHandle = 0;
GetExitCodeThread(hThread, &dllHandle);
CloseHandle(hThread);
VirtualFreeEx(hProcess, dllPathAddr, 0, MEM_RELEASE);
CloseHandle(hProcess);
if (dllHandle != 0) {
std::cout << "DLL injected successfully. DLL handle: " << std::hex << dllHandle << std::endl;
return true;
}
else {
std::cerr << "DLL injection failed. LoadLibrary returned 0." << std::endl;
return false;
}
}
int main() {
const char* processName = "WowT.exe"; // Target process name
const char* dllPath = "test.dll";// Full DLL path
// Check if DLL file exists
if (GetFileAttributesA(dllPath) == INVALID_FILE_ATTRIBUTES) {
std::cerr << "DLL file not found: " << dllPath << std::endl;
return 1;
}
// Get target process ID
DWORD processId = GetProcessIdByName(processName);
if (processId == 0) {
std::cerr << "Process not found: " << processName << std::endl;
return 1;
}
std::cout << "Found process " << processName << " with PID: " << processId << std::endl;
// Elevate privileges (if needed)
HANDLE hToken;
TOKEN_PRIVILEGES tokenPrivileges;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tokenPrivileges.Privileges[0].Luid);
tokenPrivileges.PrivilegeCount = 1;
tokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, FALSE, &tokenPrivileges, 0, NULL, NULL);
CloseHandle(hToken);
}
// Perform injection
if (InjectDLL(processId, dllPath)) {
std::cout << "Injection successful!" << std::endl;
return 0;
}
else {
std::cerr << "Injection failed!" << std::endl;
return 1;
}
}
SetWindowsHookEx Injector:
Code:
#include <Windows.h>
#include <iostream>
using namespace std;
int main() {
// Finding target window
//HWND hwnd = FindWindow(NULL, L"Apex Legends"); //<------------------------------------ game window
HWND hwnd = FindWindow(NULL, L"World of Warcraft"); //<------------------------------------ game window
if (hwnd == NULL) {
cout << "[ FAILED ] Could not find target window." << endl;
system("pause");
return EXIT_FAILURE;
}
// Getting the thread of the window and the PID
DWORD pid = NULL;
DWORD tid = GetWindowThreadProcessId(hwnd, &pid);
if (tid == NULL) {
cout << "[ FAILED ] Could not get thread ID of the target window." << endl;
system("pause");
return EXIT_FAILURE;
}
// Loading DLL
HMODULE dll = LoadLibraryEx(L"test.dll", NULL, DONT_RESOLVE_DLL_REFERENCES); //<------------------------------------ DLL
if (dll == NULL) {
cout << "[ FAILED ] The DLL could not be found." << endl;
system("pause");
return EXIT_FAILURE;
}
// Getting exported function address
HOOKPROC addr = (HOOKPROC)GetProcAddress(dll, "NextHook"); //<------------------------------------ export see dllmain.cpp "C" __declspec(dllexport) int NextHook(int code, WPARAM wParam, LPARAM lParam)
if (addr == NULL) {
cout << "[ FAILED ] The function was not found." << endl;
system("pause");
return EXIT_FAILURE;
}
// Setting the hook in the hook chain
HHOOK handle = SetWindowsHookEx(WH_GETMESSAGE, addr, dll, tid); // Or WH_KEYBOARD if you prefer to trigger the hook manually
if (handle == NULL) {
cout << "[ FAILED ] Couldn't set the hook with SetWindowsHookEx." << endl;
system("pause");
return EXIT_FAILURE;
}
// Triggering the hook
PostThreadMessage(tid, WM_NULL, NULL, NULL);
// Waiting for user input to remove the hook
cout << "[ OK ] Hook set and triggered." << endl;
cout << "[ >> ] Press any key to unhook (This will unload the DLL)." << endl;
system("pause > nul");
// Unhooking
BOOL unhook = UnhookWindowsHookEx(handle);
if (unhook == FALSE) {
cout << "[ FAILED ] Could not remove the hook." << endl;
system("pause");
return EXIT_FAILURE;
}
cout << "[ OK ] Done. Press any key to exit." << endl;
system("pause > nul");
return EXIT_SUCCESS;
}