332 lines
9.8 KiB
C++
332 lines
9.8 KiB
C++
|
/*++
|
||
|
|
||
|
Copyright (c) 2000 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
EncompassMonitor.cpp
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Filters messages from the apps CBT WindowsHook.
|
||
|
|
||
|
Notes:
|
||
|
|
||
|
This is a general purpose shim.
|
||
|
|
||
|
History:
|
||
|
|
||
|
01/30/2001 a-larrsh Created
|
||
|
02/18/2002 robkenny Properly check the return value from GetTempPathA
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include "precomp.h"
|
||
|
|
||
|
IMPLEMENT_SHIM_BEGIN(EncompassMonitor)
|
||
|
#include "ShimHookMacro.h"
|
||
|
|
||
|
|
||
|
APIHOOK_ENUM_BEGIN
|
||
|
APIHOOK_ENUM_ENTRY(SetWindowsHookExA)
|
||
|
APIHOOK_ENUM_END
|
||
|
|
||
|
|
||
|
// Local Hook Information
|
||
|
HHOOK g_hCBTHook = NULL;
|
||
|
HOOKPROC g_OriginalEncompassMonitorCBTProc = NULL;
|
||
|
|
||
|
// Shared Data Infomation
|
||
|
|
||
|
#define SHARED_SECTION_NAME "EncompassMonitor_SharedMemoryData"
|
||
|
typedef struct
|
||
|
{
|
||
|
char szModuleFileName[MAX_PATH];
|
||
|
HANDLE hModule;
|
||
|
HOOKPROC pfnHookProc;
|
||
|
|
||
|
} SHARED_HOOK_INFO, *PSHARED_HOOK_INFO;
|
||
|
|
||
|
HANDLE g_hSharedMapping = NULL;
|
||
|
PSHARED_HOOK_INFO g_pSharedHookInfo = NULL;
|
||
|
|
||
|
|
||
|
// Creates Shared memory. Only called by the originial SHIM
|
||
|
void CreateSharedMemory(HMODULE hModule, HOOKPROC pfnHookProc)
|
||
|
{
|
||
|
HANDLE hSharedFile;
|
||
|
char szTempPath[MAX_PATH];
|
||
|
char szTempFileName[MAX_PATH];
|
||
|
|
||
|
// create the memory mapped file necessary to communicate between the original Instanace of SHIM
|
||
|
// and the following instances of SHIMS
|
||
|
DWORD dwTemp = GetTempPathA(sizeof(szTempPath), szTempPath);
|
||
|
if (dwTemp == 0 ||
|
||
|
dwTemp > sizeof(szTempPath))
|
||
|
{
|
||
|
DPFN( eDbgLevelError, "GetTempPath failed\n");
|
||
|
goto errCreateSharedSection;
|
||
|
}
|
||
|
|
||
|
if (GetTempFileNameA(szTempPath, "mem", NULL, szTempFileName) == 0)
|
||
|
{
|
||
|
DPFN( eDbgLevelError, "GetTempFileName failed\n");
|
||
|
goto errCreateSharedSection;
|
||
|
}
|
||
|
|
||
|
hSharedFile = CreateFileA( szTempFileName,
|
||
|
GENERIC_READ | GENERIC_WRITE,
|
||
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||
|
NULL,
|
||
|
CREATE_ALWAYS,
|
||
|
FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
|
||
|
NULL);
|
||
|
|
||
|
if (hSharedFile == NULL)
|
||
|
{
|
||
|
DPFN( eDbgLevelError, "CreateFile failed to create '%s'\n", szTempFileName);
|
||
|
goto errCreateSharedSection;
|
||
|
}
|
||
|
|
||
|
// Increase size of file (create the mapping)
|
||
|
g_hSharedMapping = CreateFileMappingA( hSharedFile,
|
||
|
NULL,
|
||
|
PAGE_READWRITE,
|
||
|
NULL,
|
||
|
sizeof(SHARED_HOOK_INFO),
|
||
|
SHARED_SECTION_NAME);
|
||
|
|
||
|
if (g_hSharedMapping == NULL)
|
||
|
{
|
||
|
DPFN( eDbgLevelError, "CreateFileMapping failed\n");
|
||
|
goto errCreateSharedSection;
|
||
|
}
|
||
|
|
||
|
g_pSharedHookInfo = (PSHARED_HOOK_INFO)MapViewOfFile(g_hSharedMapping,
|
||
|
FILE_MAP_ALL_ACCESS,
|
||
|
0,
|
||
|
0,
|
||
|
sizeof(SHARED_HOOK_INFO));
|
||
|
|
||
|
if (g_pSharedHookInfo == NULL)
|
||
|
{
|
||
|
DWORD dwErr = GetLastError();
|
||
|
DPFN( eDbgLevelError, "MapViewOfFile failed [%d]", (int)dwErr);
|
||
|
goto errCreateSharedSection;
|
||
|
}
|
||
|
|
||
|
CloseHandle(hSharedFile);
|
||
|
|
||
|
g_pSharedHookInfo->hModule = hModule;
|
||
|
g_pSharedHookInfo->pfnHookProc = pfnHookProc;
|
||
|
if (0 == GetModuleFileNameA(hModule, g_pSharedHookInfo->szModuleFileName, MAX_PATH))
|
||
|
{
|
||
|
DPFN( eDbgLevelError, "GetModuleFileNameA failed\n");
|
||
|
goto errCreateSharedSection;
|
||
|
}
|
||
|
|
||
|
if (!FlushViewOfFile(g_pSharedHookInfo, sizeof(SHARED_HOOK_INFO)))
|
||
|
{
|
||
|
DPFN( eDbgLevelError, "FlushViewOfFile failed\n");
|
||
|
goto errCreateSharedSection;
|
||
|
}
|
||
|
|
||
|
DPFN( eDbgLevelInfo, "WRITE::Shared Section Successful");
|
||
|
DPFN( eDbgLevelInfo, "WRITE::g_pSharedHookInfo->hModule=%x", g_pSharedHookInfo->hModule);
|
||
|
DPFN( eDbgLevelInfo, "WRITE::g_pSharedHookInfo->pfnHookProc=%x", g_pSharedHookInfo->pfnHookProc);
|
||
|
DPFN( eDbgLevelInfo, "WRITE::g_pSharedHookInfo->szModuleFileName=%s", g_pSharedHookInfo->szModuleFileName);
|
||
|
|
||
|
return;
|
||
|
|
||
|
errCreateSharedSection:
|
||
|
DPFN( eDbgLevelError, "WRITE::Shared Section FAILED");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Gets Shared Memory - Only called by injected versions of hook function
|
||
|
void GetSharedMemory()
|
||
|
{
|
||
|
HANDLE hSharedFileMapping = NULL;
|
||
|
|
||
|
hSharedFileMapping = OpenFileMappingA( FILE_MAP_ALL_ACCESS,
|
||
|
FALSE,
|
||
|
SHARED_SECTION_NAME);
|
||
|
|
||
|
if (hSharedFileMapping != NULL)
|
||
|
{
|
||
|
PSHARED_HOOK_INFO pSharedHookInfo = (PSHARED_HOOK_INFO)MapViewOfFile( hSharedFileMapping,
|
||
|
FILE_MAP_ALL_ACCESS,
|
||
|
0,
|
||
|
0,
|
||
|
0);
|
||
|
|
||
|
if (pSharedHookInfo)
|
||
|
{
|
||
|
DPFN( eDbgLevelInfo, "READ::pSharedHookInfo->hModule=%x", pSharedHookInfo->hModule);
|
||
|
DPFN( eDbgLevelInfo, "READ::pSharedHookInfo->pfnHookProc=%x", pSharedHookInfo->pfnHookProc);
|
||
|
DPFN( eDbgLevelInfo, "READ::pSharedHookInfo->szModuleFileName=%s", pSharedHookInfo->szModuleFileName);
|
||
|
|
||
|
// Load DLL with original CBT Proc in it.
|
||
|
HANDLE hMod = LoadLibraryA(pSharedHookInfo->szModuleFileName);
|
||
|
|
||
|
if (!hMod)
|
||
|
{
|
||
|
DPFN( eDbgLevelError, "LoadLibrary(\"%s\") - FAILED", pSharedHookInfo->szModuleFileName);
|
||
|
}
|
||
|
|
||
|
g_OriginalEncompassMonitorCBTProc = (HOOKPROC)((DWORD)hMod + ((DWORD)pSharedHookInfo->pfnHookProc) - (DWORD)pSharedHookInfo->hModule);
|
||
|
DPFN( eDbgLevelInfo, "READ::Shared Section Successful - Original Hook at %x", g_OriginalEncompassMonitorCBTProc);
|
||
|
|
||
|
CloseHandle(hSharedFileMapping);
|
||
|
UnmapViewOfFile(pSharedHookInfo);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DPFN( eDbgLevelError, "MapViewOfFile() Failed");
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DPFN( eDbgLevelError, "READ::Shared Section Failed");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Replacement CBT Hook function
|
||
|
LRESULT CALLBACK Filtered_EncompassMonitorCBTProc(
|
||
|
int nCode, // hook code
|
||
|
WPARAM wParam, // depends on hook code
|
||
|
LPARAM lParam // depends on hook code
|
||
|
)
|
||
|
{
|
||
|
LRESULT lResult = 0; // Allow operation to continue
|
||
|
bool bFilterMessage = false;
|
||
|
|
||
|
if (g_OriginalEncompassMonitorCBTProc == NULL)
|
||
|
{
|
||
|
GetSharedMemory();
|
||
|
}
|
||
|
|
||
|
if (nCode == HCBT_CREATEWND)
|
||
|
{
|
||
|
CBT_CREATEWNDA *pccw = (CBT_CREATEWNDA*)lParam;
|
||
|
|
||
|
if ( (IS_INTRESOURCE(pccw->lpcs->lpszClass)) )
|
||
|
{
|
||
|
char szBuf[256];
|
||
|
GetClassNameA((HWND)wParam, szBuf, 255);
|
||
|
|
||
|
bFilterMessage=true;
|
||
|
DPFN( eDbgLevelInfo, "[%x] - Filtered_EncompassMonitorCBTProc::HCBT_CREATEWND %s [ATOM CLASS FILTERED]", g_OriginalEncompassMonitorCBTProc, szBuf);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DPFN( eDbgLevelInfo, "[%x] - Filtered_EncompassMonitorCBTProc::HCBT_CREATEWND %s ", g_OriginalEncompassMonitorCBTProc, pccw->lpcs->lpszClass);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( g_OriginalEncompassMonitorCBTProc )
|
||
|
{
|
||
|
if (bFilterMessage)
|
||
|
{
|
||
|
lResult = CallNextHookEx(g_hCBTHook, nCode, wParam, lParam);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
lResult = g_OriginalEncompassMonitorCBTProc(nCode, wParam, lParam);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DPFN( eDbgLevelError, "Filtered_EncompassMonitorCBTProc:: ** BAD g_OriginalEncompassMonitorCBTProc2 **");
|
||
|
|
||
|
lResult = CallNextHookEx(g_hCBTHook, nCode, wParam, lParam);
|
||
|
}
|
||
|
|
||
|
return lResult;
|
||
|
}
|
||
|
|
||
|
|
||
|
// SHIMMED API
|
||
|
HHOOK APIHOOK(SetWindowsHookExA)(
|
||
|
int idHook, // hook type
|
||
|
HOOKPROC lpfn, // hook procedure
|
||
|
HINSTANCE hMod, // handle to application instance
|
||
|
DWORD dwThreadId // thread identifier
|
||
|
)
|
||
|
{
|
||
|
static int nNumCBThooks = 0;
|
||
|
|
||
|
HHOOK hHook;
|
||
|
|
||
|
if (idHook == WH_CBT)
|
||
|
{
|
||
|
nNumCBThooks++;
|
||
|
|
||
|
switch(nNumCBThooks)
|
||
|
{
|
||
|
case 1:
|
||
|
hHook = ORIGINAL_API(SetWindowsHookExA)(idHook, lpfn, hMod, dwThreadId);
|
||
|
DPFN( eDbgLevelInfo, "%x=SetWindowsHookEx(%d, %x, %x, %x) - Ignoring First Hook Call", hHook, idHook, lpfn, hMod, dwThreadId);
|
||
|
break;
|
||
|
|
||
|
case 2:
|
||
|
g_OriginalEncompassMonitorCBTProc = lpfn;
|
||
|
g_hCBTHook = hHook = ORIGINAL_API(SetWindowsHookExA)(idHook, Filtered_EncompassMonitorCBTProc, g_hinstDll, dwThreadId);
|
||
|
|
||
|
DPFN( eDbgLevelInfo, "%x=SetWindowsHookEx(%d, %x, %x, %x) - Replacing Hook with Filtered_EncompassMonitorCBTProc", hHook, idHook, lpfn, hMod, dwThreadId);
|
||
|
|
||
|
CreateSharedMemory(hMod, lpfn);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
hHook = ORIGINAL_API(SetWindowsHookExA)(idHook, lpfn, hMod, dwThreadId);
|
||
|
DPFN( eDbgLevelError, "SetWindowsHookEx -- More then 2 WH_CBT hooks [%d]", nNumCBThooks);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hHook = ORIGINAL_API(SetWindowsHookExA)(idHook, lpfn, hMod, dwThreadId);
|
||
|
}
|
||
|
|
||
|
return hHook;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
NOTIFY_FUNCTION(DWORD fdwReason)
|
||
|
{
|
||
|
if (fdwReason == DLL_PROCESS_DETACH)
|
||
|
{
|
||
|
if (g_hSharedMapping)
|
||
|
{
|
||
|
CloseHandle(g_hSharedMapping);
|
||
|
g_hSharedMapping = NULL;
|
||
|
}
|
||
|
|
||
|
if (g_pSharedHookInfo)
|
||
|
{
|
||
|
UnmapViewOfFile(g_pSharedHookInfo);
|
||
|
g_pSharedHookInfo = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Register hooked functions
|
||
|
|
||
|
--*/
|
||
|
|
||
|
HOOK_BEGIN
|
||
|
CALL_NOTIFY_FUNCTION
|
||
|
|
||
|
APIHOOK_ENTRY(USER32.DLL, SetWindowsHookExA)
|
||
|
HOOK_END
|
||
|
|
||
|
IMPLEMENT_SHIM_END
|
||
|
|