C++ Code:
#include <windows.h>
#include <winternl.h>
#include <thread>
#include <chrono>
#include "detours.h"
#pragma comment(lib, "detours.lib")
typedef void(__stdcall *ExitProcess_t)(UINT uExitCode);
typedef HHOOK(__stdcall *SetWindowsHookEx_t)(int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId);
ExitProcess_t o_ExitProcess = NULL;
SetWindowsHookEx_t o_SetWindowsHookEx = NULL;
HOOKPROC oMouseHookedProc = NULL;
HOOKPROC oKeyHookedProc = NULL;
void* removedModule = NULL;
typedef struct _LDR_MODULE
{
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
PVOID BaseAddress;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
SHORT LoadCount;
SHORT TlsIndex;
LIST_ENTRY HashTableEntry;
ULONG TimeDateStamp;
} LDR_MODULE, *PLDR_MODULE;
typedef struct _ProcessModuleInfo
{
DWORD Size;
DWORD Initialized;
HANDLE SsHandle;
LIST_ENTRY LoadOrder;
LIST_ENTRY InitOrder;
LIST_ENTRY MemoryOrder;
} ProcessModuleInfo, *pProcessModuleInfo;
void LinkLocalProcessModule(LDR_MODULE* module)
{
auto AddLink = [&](LIST_ENTRY* Link)
{
Link->Flink->Blink = Link;
Link->Blink->Flink = Link;
};
AddLink(&module->InLoadOrderModuleList);
AddLink(&module->InMemoryOrderModuleList);
AddLink(&module->InInitializationOrderModuleList);
AddLink(&module->HashTableEntry);
}
void UnlinkLocalProcessModule(LDR_MODULE* module)
{
auto RemoveLink = [](LIST_ENTRY* Link)
{
Link->Blink->Flink = Link->Flink;
Link->Flink->Blink = Link->Blink;
};
RemoveLink(&module->InLoadOrderModuleList);
RemoveLink(&module->InMemoryOrderModuleList);
RemoveLink(&module->InInitializationOrderModuleList);
RemoveLink(&module->HashTableEntry);
}
void HideSelf(HMODULE self, LDR_MODULE** old)
{
auto GetModuleIterator = []() -> LDR_MODULE* {
ProcessModuleInfo *pmInfo = nullptr;
#if defined _WIN32
__asm
{
mov eax, fs:[0x30];
add eax, 0x0C;
mov eax, [eax];
mov pmInfo, eax;
};
#elif defined _WIN64
__asm
{
mov rax, gs:[0x60];
add rax, 0x18;
mov rax, [rax];
mov pmInfo, rax;
};
#endif
return reinterpret_cast<LDR_MODULE*>(pmInfo->LoadOrder.Flink);
};
LDR_MODULE* module = GetModuleIterator();
while (module->BaseAddress)
{
if (module->BaseAddress == self)
{
*old = module;
UnlinkLocalProcessModule(module);
}
module = reinterpret_cast<LDR_MODULE*>(module->InLoadOrderModuleList.Flink);
}
}
template<typename T, typename U>
void DetourFunction(T &OriginalFunction, U HookFunction)
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&reinterpret_cast<void*&>(OriginalFunction), reinterpret_cast<void*>(HookFunction));
DetourTransactionCommit();
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
}
void __stdcall mHookedExit(UINT uExitCode)
{
LinkLocalProcessModule(static_cast<LDR_MODULE*>(removedModule));
o_ExitProcess(uExitCode);
}
LRESULT __stdcall mHookedProc(int Code, WPARAM wParam, LPARAM lParam)
{
if (Code == HC_ACTION)
{
MSLLHOOKSTRUCT* Info = reinterpret_cast<MSLLHOOKSTRUCT*>(lParam);
Info->flags &= LLMHF_INJECTED;
}
return oMouseHookedProc(Code, wParam, lParam);
}
LRESULT __stdcall kHookedProc(int Code, WPARAM wParam, LPARAM lParam)
{
if (Code == HC_ACTION)
{
KBDLLHOOKSTRUCT* Info = reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam);
Info->flags &= LLKHF_INJECTED;
Info->flags &= 0x00000002;
}
return oKeyHookedProc(Code, wParam, lParam);
}
HHOOK __stdcall mSetWindowsHookEx(int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId)
{
if (idHook == WH_MOUSE_LL)
{
oMouseHookedProc = lpfn;
return o_SetWindowsHookEx(idHook, mHookedProc, hMod, dwThreadId);
}
else if (idHook == WH_KEYBOARD_LL)
{
oKeyHookedProc = lpfn;
return o_SetWindowsHookEx(idHook, kHookedProc, hMod, dwThreadId);
}
return o_SetWindowsHookEx(idHook, lpfn, hMod, dwThreadId);
}
DWORD __stdcall InitialiseHooks(void* param)
{
while (!GetModuleHandleW(L"User32.dll") && !GetModuleHandleW(L"Kernel32.dll"))
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
o_ExitProcess = (ExitProcess_t)GetProcAddress(GetModuleHandleW(L"Kernel32.dll"), "ExitProcess");
o_SetWindowsHookEx = (SetWindowsHookEx_t)GetProcAddress(GetModuleHandleW(L"User32.dll"), "SetWindowsHookExA");
DetourFunction(o_ExitProcess, mHookedExit);
DetourFunction(o_SetWindowsHookEx, mSetWindowsHookEx);
return 0;
}
extern "C" __declspec(dllexport) bool __stdcall DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hinstDLL);
HideSelf(hinstDLL, reinterpret_cast<LDR_MODULE**>(&removedModule));
CreateThread(NULL, 0, &InitialiseHooks, NULL, 0, NULL);
break;
case DLL_PROCESS_DETACH:
MessageBoxA(NULL, "Detaching", "", 0);
break;
}
return true;
}