Support for showing if app is 32bit vs 64bit, and support for doing message hooks on both
Added support for message hook viewer to hook both 32 and 64 bit applications. Fixed filtering on the msg hook viewer Added custom filtering on msg hook viewer Added Process Id targetting on msg hook viewer Added SetMsgHook.exe command line app as an alternative way of starting msg hook viewer.
This commit is contained in:
@@ -8,10 +8,9 @@
|
||||
|
||||
// MsgHook.cpp : Defines the exported functions for the DLL application.
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
|
||||
//to fix export declaration had to add .def file
|
||||
LRESULT CALLBACK CwpHookProc(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
COPYDATASTRUCT CDS;
|
||||
@@ -55,7 +54,11 @@ LRESULT CALLBACK CwpHookProc(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
}
|
||||
}
|
||||
|
||||
BOOL bRes = (BOOL)SendMessage(pData->g_hWnd, WM_COPYDATA, 0, (LPARAM)(VOID*)&CDS); // ask the controlling program if the hook should be passed
|
||||
//printf("debug: sending to hwnd (%ld) msg %d, wParam %ld, lParam %ld\n", pData->g_hWnd, Event.nCode, Event.wParam, Event.lParam);
|
||||
if (cwps->hwnd != pData->g_hWnd)
|
||||
{
|
||||
BOOL bRes = (BOOL)SendMessage(pData->g_hWnd, WM_COPYDATA, 0, (LPARAM)(VOID*)&CDS); // ask the controlling program if the hook should be passed
|
||||
}
|
||||
}
|
||||
return CallNextHookEx(pData->g_CwpHook, nCode, wParam, lParam); // pass hook to next handler
|
||||
//return bRes; // Don't tell the other hooks about this message.
|
||||
@@ -70,7 +73,7 @@ LRESULT CALLBACK MsgHookProc(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
CDS.cbData = sizeof(Event);
|
||||
CDS.lpData = &Event;
|
||||
|
||||
//if (nCode == HC_ACTION)
|
||||
if (nCode >=0 && nCode == HC_ACTION)
|
||||
{
|
||||
//For WH_GETMESSAGE hook a pointer to a MSG structure that contains details about the message.
|
||||
MSG *msg = (MSG *)lParam;
|
||||
@@ -84,19 +87,48 @@ LRESULT CALLBACK MsgHookProc(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
//if (msg->message == WM_SETTEXT && msg->lParam != 0)
|
||||
// _tcscpy_s(Event.lParamStr, 25, (const wchar_t*)Event.lParam);
|
||||
//if (msg->message == WM_COMMAND || msg->message == WM_MENUCOMMAND) //infinite loop?
|
||||
BOOL bRes = (BOOL)SendMessage(pData->g_hWnd, WM_COPYDATA, 0, (LPARAM)(VOID*)&CDS); // ask the controlling program if the hook should be passed
|
||||
if (msg->hwnd != pData->g_hWnd)
|
||||
{
|
||||
BOOL bRes = (BOOL)SendMessage(pData->g_hWnd, WM_COPYDATA, 0, (LPARAM)(VOID*)&CDS); // ask the controlling program if the hook should be passed
|
||||
}
|
||||
}
|
||||
|
||||
return CallNextHookEx(pData->g_MsgHook, nCode, wParam, lParam); // pass hook to next handler
|
||||
//return bRes; // Don't tell the other hooks about this message.
|
||||
}
|
||||
|
||||
//support for 32-bit/64-bit apps means the dll might be different to match the process we want to see
|
||||
extern "C" __declspec(dllexport) BOOL SetCustomMsgHookDll(const TCHAR * hookDll, const char * hookDllProcName)
|
||||
{
|
||||
HMODULE dll = LoadLibrary(hookDll); //should provide full dll path and filename
|
||||
if (dll == NULL)
|
||||
{
|
||||
TCHAR errorStr[200];
|
||||
_stprintf_s(errorStr, _T("Error loading hook library %s"), hookDll);
|
||||
MessageBox(0, errorStr, _T("Set Hook Dll Error"), 0);
|
||||
return false;
|
||||
}
|
||||
HOOKPROC addr = (HOOKPROC)GetProcAddress(dll, hookDllProcName); //should provide the 'CwpHookProc'
|
||||
if (addr == NULL)
|
||||
{
|
||||
char errorStr[200];
|
||||
sprintf_s(errorStr, "Error loading hook library procedure %s", hookDllProcName);
|
||||
MessageBoxA(0, errorStr, "Set Hook Dll Error", 0);
|
||||
return false;
|
||||
}
|
||||
pData->g_hInstance = dll;
|
||||
pData->g_CwpHookProc = addr;
|
||||
return true;
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) BOOL SetMsgHook(HWND callerHWnd, DWORD threadId)
|
||||
{
|
||||
if(bStartingProcess) // if we're just starting the DLL for the first time,
|
||||
// if(bStartingProcess) // if we're just starting the DLL for the first time,
|
||||
{
|
||||
pData->g_hWnd = callerHWnd; // remember the windows and hook handle for further instances
|
||||
pData->g_CwpHook = SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)CwpHookProc, (HINSTANCE)pData->g_hInstance, threadId);
|
||||
if (pData->g_CwpHookProc == NULL)
|
||||
pData->g_CwpHookProc = (HOOKPROC)CwpHookProc;
|
||||
pData->g_CwpHook = SetWindowsHookEx(WH_CALLWNDPROC, pData->g_CwpHookProc, (HINSTANCE)pData->g_hInstance, threadId);
|
||||
//pData->g_MsgHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)MsgHookProc, (HINSTANCE)pData->g_hInstance, threadId);
|
||||
if (pData->g_CwpHook == NULL) {
|
||||
TCHAR tmp[100];
|
||||
@@ -106,11 +138,21 @@ extern "C" __declspec(dllexport) BOOL SetMsgHook(HWND callerHWnd, DWORD threadId
|
||||
|
||||
return (pData->g_CwpHook != NULL); //pData->g_CwpHook != NULL &&
|
||||
}
|
||||
else
|
||||
/*else
|
||||
{
|
||||
//MessageBox(0, _T("Error: Not starting process"), _T("Set Hook Error"), 0);
|
||||
return false;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) HHOOK GetCurrentHookHandle()
|
||||
{
|
||||
return pData->g_CwpHook; //if NULL hook isn't running
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) void SetGlobalDLLInstance(HANDLE dllInstance)
|
||||
{
|
||||
pData->g_hInstance = dllInstance;
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) BOOL RemoveHook()
|
||||
@@ -127,7 +169,93 @@ extern "C" __declspec(dllexport) BOOL RemoveHook()
|
||||
BOOL ret = UnhookWindowsHookEx(pData->g_CwpHook);
|
||||
pData->g_hWnd = NULL; // reset data
|
||||
pData->g_CwpHook = NULL;
|
||||
pData->g_CwpHookProc = NULL;
|
||||
return ret;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//testing if process 64 bit, needed to verify this dll can hook & attach to target process
|
||||
typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
|
||||
LPFN_ISWOW64PROCESS fnIsWow64Process;
|
||||
|
||||
extern "C" __declspec(dllexport) BOOL IsCurrentProcess64Bit()
|
||||
{
|
||||
return IsProcess64Bit(_getpid());
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) BOOL IsProcess64Bit(DWORD procId)
|
||||
{
|
||||
SYSTEM_INFO stInfo;
|
||||
GetNativeSystemInfo(&stInfo); // if native system is x86 skip wow64 test
|
||||
if (stInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
|
||||
return false; //printf( "Processor Architecture: Intel x86\n");
|
||||
|
||||
BOOL bIsWow64 = FALSE;
|
||||
//IsWow64Process is not available on all supported versions of Windows.
|
||||
//Use GetModuleHandle to get a handle to the DLL that contains the function
|
||||
//and GetProcAddress to get a pointer to the function if available.
|
||||
|
||||
fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(TEXT("kernel32")),"IsWow64Process");
|
||||
if(fnIsWow64Process != NULL)
|
||||
{
|
||||
HANDLE procHandle = NULL;//GetCurrentProcess();
|
||||
procHandle = OpenProcess(PROCESS_QUERY_INFORMATION, false, procId);
|
||||
if (!fnIsWow64Process(procHandle, &bIsWow64))
|
||||
{
|
||||
//handle error
|
||||
}
|
||||
CloseHandle(procHandle);
|
||||
if (bIsWow64) // NOT a native 64bit process
|
||||
return false;
|
||||
return true;// is a native 64bit process
|
||||
}
|
||||
return false; //some error finding function "IsWow64Process" assume not 64-bit
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) DWORD GetProcessMainThreadId(DWORD procId)
|
||||
{
|
||||
|
||||
#ifndef MAKEULONGLONG
|
||||
#define MAKEULONGLONG(ldw, hdw) ((ULONGLONG(hdw) << 32) | ((ldw) & 0xFFFFFFFF))
|
||||
#endif
|
||||
#ifndef MAXULONGLONG
|
||||
#define MAXULONGLONG ((ULONGLONG)~((ULONGLONG)0))
|
||||
#endif
|
||||
|
||||
DWORD dwMainThreadID = 0;
|
||||
ULONGLONG ullMinCreateTime = MAXULONGLONG;
|
||||
//includes all threads in the system
|
||||
HANDLE hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
|
||||
if (hThreadSnap != INVALID_HANDLE_VALUE) {
|
||||
THREADENTRY32 th32;
|
||||
th32.dwSize = sizeof(THREADENTRY32);
|
||||
BOOL bOK = TRUE;
|
||||
//Enumerate all threads in the system and filter on th32OwnerProcessID = pid
|
||||
for (bOK = Thread32First(hThreadSnap, &th32); bOK ; bOK = Thread32Next(hThreadSnap, &th32)) {
|
||||
//if (th32.dwSize >= FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(th32.th32OwnerProcessID)) {
|
||||
if (th32.th32OwnerProcessID == procId && (th32.dwSize >= FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(th32.th32OwnerProcessID))) {
|
||||
//_tprintf(_T("DEBUG Enumerate Process (%ld) Thread Id: %ld\n"), procId, th32.th32ThreadID);
|
||||
HANDLE hThread = OpenThread(THREAD_QUERY_INFORMATION, TRUE, th32.th32ThreadID);
|
||||
if (hThread) {
|
||||
FILETIME afTimes[4] = {0};
|
||||
if (GetThreadTimes(hThread, &afTimes[0], &afTimes[1], &afTimes[2], &afTimes[3])) {
|
||||
ULONGLONG ullTest = MAKEULONGLONG(afTimes[0].dwLowDateTime, afTimes[0].dwHighDateTime);
|
||||
if (ullTest && ullTest < ullMinCreateTime) { //check each thread's creation time
|
||||
ullMinCreateTime = ullTest;
|
||||
dwMainThreadID = th32.th32ThreadID; // let it be main thread
|
||||
}
|
||||
}
|
||||
CloseHandle(hThread); //must close opened thread
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifndef UNDER_CE
|
||||
CloseHandle(hThreadSnap); //close thread snapshot
|
||||
#else
|
||||
CloseToolhelp32Snapshot(hThreadSnap); //close thread snapshot
|
||||
#endif
|
||||
}
|
||||
return dwMainThreadID; //returns main thread id or returns 0 if can't find it
|
||||
}
|
||||
5
native/MsgHook/MsgHook.def
Normal file
5
native/MsgHook/MsgHook.def
Normal file
@@ -0,0 +1,5 @@
|
||||
LIBRARY MsgHook
|
||||
|
||||
EXPORTS
|
||||
CwpHookProc @1
|
||||
MsgHookProc @2
|
||||
@@ -87,6 +87,7 @@
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ModuleDefinitionFile>MsgHook.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
@@ -99,6 +100,7 @@
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ModuleDefinitionFile>MsgHook.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
@@ -115,6 +117,7 @@
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<ModuleDefinitionFile>MsgHook.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>mkdir "$(ProjectDir)bin"
|
||||
@@ -135,6 +138,7 @@ copy /Y "$(TargetPath)" "$(ProjectDir)bin\MsgHook$(PlatformArchitecture)$(Target
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<ModuleDefinitionFile>MsgHook.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>mkdir "$(ProjectDir)bin"
|
||||
@@ -142,6 +146,10 @@ copy /Y "$(TargetPath)" "$(ProjectDir)bin\MsgHook$(PlatformArchitecture)$(Target
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\SetMsgHook\bin\SetMsgHook32.exe" />
|
||||
<None Include="..\SetMsgHook\bin\SetMsgHook64.exe" />
|
||||
<None Include="binary1.bin" />
|
||||
<None Include="MsgHook.def" />
|
||||
<None Include="MsgHookTest.ico" />
|
||||
<None Include="ReadMe.txt" />
|
||||
<None Include="small.ico" />
|
||||
@@ -149,6 +157,7 @@ copy /Y "$(TargetPath)" "$(ProjectDir)bin\MsgHook$(PlatformArchitecture)$(Target
|
||||
<ItemGroup>
|
||||
<ClInclude Include="MsgLookup.h" />
|
||||
<ClInclude Include="org_synthuse_MsgHook.h" />
|
||||
<ClInclude Include="ResExtract.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
|
||||
@@ -22,6 +22,14 @@
|
||||
<None Include="small.ico">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
<None Include="MsgHook.def">
|
||||
<Filter>Source Files</Filter>
|
||||
</None>
|
||||
<None Include="binary1.bin">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
<None Include="..\SetMsgHook\bin\SetMsgHook64.exe" />
|
||||
<None Include="..\SetMsgHook\bin\SetMsgHook32.exe" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h">
|
||||
@@ -39,6 +47,9 @@
|
||||
<ClInclude Include="MsgLookup.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ResExtract.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -11,6 +11,7 @@
|
||||
#include "stdafx.h"
|
||||
#include "resource.h"
|
||||
#include "MsgLookup.h"
|
||||
#include "ResExtract.h"
|
||||
//#include "MsgHookTest.h"
|
||||
//#include "MsgHook.h"
|
||||
|
||||
@@ -24,18 +25,25 @@ HWND mainHwnd = NULL;
|
||||
HMENU mainMenu = NULL;
|
||||
HWND txtbox = NULL;
|
||||
HWND targetHwnd = NULL;
|
||||
DWORD targetPid = 0;
|
||||
const int txtboxSpacing = 2;
|
||||
|
||||
long msgCount = 0;
|
||||
|
||||
bool filterWmCommand = true;
|
||||
//message filters flags
|
||||
bool filterWmCommand = false;
|
||||
bool filterWmNotify = false;
|
||||
bool filterCustom = false;
|
||||
bool filterAbove = false;
|
||||
|
||||
TCHAR dll32bitName[500] = _T("");
|
||||
TCHAR dll64bitName[500] = _T("");
|
||||
char dllProcName[500] = "CwpHookProc";
|
||||
|
||||
//#define MAX_TEST_SIZE 100
|
||||
//TCHAR targetClassname[MAX_TEST_SIZE] = _T("Notepad");
|
||||
TCHAR targetClassname[MAX_TEST_SIZE] = _T("WordPadClass");
|
||||
TCHAR targetProcessId[MAX_TEST_SIZE] = _T("");
|
||||
TCHAR targetClassname[MAX_TEST_SIZE] = _T("");
|
||||
TCHAR targetHwndStr[MAX_TEST_SIZE] = _T("");
|
||||
TCHAR testWmSettextL[MAX_TEST_SIZE] = _T("This is a test");
|
||||
TCHAR testWmSettextW[MAX_TEST_SIZE] = _T("0");
|
||||
@@ -117,30 +125,75 @@ void InitMsgFiltersAndLookup()
|
||||
void StartMessageHook()
|
||||
{
|
||||
AppendText(txtbox, _T("Starting Message Hook\r\n"));
|
||||
targetHwnd = FindWindow(targetClassname, NULL);
|
||||
|
||||
if (_tcscmp(targetHwndStr, _T("")) != 0) //if target HWND was used then override classname hwnd
|
||||
//targetHwnd = FindWindow(targetClassname, NULL);
|
||||
|
||||
TCHAR tmp[500];
|
||||
|
||||
DWORD tid = 0;
|
||||
if (_tcscmp(targetHwndStr, _T("")) != 0) //if target HWND was used
|
||||
{
|
||||
TCHAR *stopStr;
|
||||
targetHwnd = (HWND)_tcstol(targetHwndStr, &stopStr, 10);
|
||||
tid = GetWindowThreadProcessId(targetHwnd, NULL);
|
||||
_stprintf_s(tmp, _T("Target Handle: %ld, and Thread Id: %ld\r\n"), targetHwnd, tid);
|
||||
}
|
||||
|
||||
DWORD tid = GetWindowThreadProcessId(targetHwnd, NULL);
|
||||
|
||||
targetPid = 0;
|
||||
if (_tcscmp(targetProcessId, _T("")) != 0) //if target pid was used
|
||||
{
|
||||
TCHAR *stopStr;
|
||||
targetPid = (DWORD)_tcstol(targetProcessId, &stopStr, 10);
|
||||
tid = GetProcessMainThreadId(targetPid);
|
||||
_stprintf_s(tmp, _T("Target PId: %ld, and Thread Id: %ld\r\n"), targetPid, tid);
|
||||
}
|
||||
|
||||
InitMsgFiltersAndLookup();
|
||||
//InitializeMsgLookup();
|
||||
|
||||
TCHAR tmp[50];
|
||||
_stprintf_s(tmp, _T("Target Handle: %ld, and Thread Id: %ld\r\n"), targetHwnd, tid);
|
||||
AppendText(txtbox, tmp);
|
||||
|
||||
//block self/global msg hook
|
||||
if (targetHwnd == NULL || tid == 0) {
|
||||
AppendText(txtbox, _T("Target window not found\r\n"));
|
||||
if (tid == 0) {
|
||||
AppendText(txtbox, _T("Target thread not found\r\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
//if (InitMsgHook(mainHwnd, tid))
|
||||
if (targetPid != 0) // handle various types of bit matching
|
||||
{
|
||||
BOOL current64bit = IsCurrentProcess64Bit();
|
||||
if (IsProcess64Bit(targetPid) && current64bit)
|
||||
{
|
||||
_stprintf_s(tmp, _T("Target PId (%ld) is a matching 64 bit process\r\n"), targetPid);
|
||||
SetCustomMsgHookDll(dll64bitName, dllProcName);
|
||||
}
|
||||
else if(!IsProcess64Bit(targetPid) && !current64bit)
|
||||
{
|
||||
_stprintf_s(tmp, _T("Target PId (%ld) is a matching 32 bit process\r\n"), targetPid);
|
||||
SetCustomMsgHookDll(dll32bitName, dllProcName);
|
||||
}
|
||||
else
|
||||
{
|
||||
_stprintf_s(tmp, _T("Target PId (%ld) is a not matching bit process\r\n"), targetPid);
|
||||
AppendText(txtbox, tmp);
|
||||
TCHAR *dllname = dll32bitName;
|
||||
TCHAR *exename = _T("SetMsgHook32.exe");
|
||||
int setMsgHookRes = IDR_SETMH32;
|
||||
if (IsProcess64Bit(targetPid))
|
||||
{
|
||||
dllname = dll64bitName;
|
||||
exename = _T("SetMsgHook64.exe");
|
||||
setMsgHookRes = IDR_SETMH64;
|
||||
}
|
||||
_stprintf_s(tmp, _T("%s %s 0 %d"), exename, dllname, targetPid);
|
||||
RunResource(setMsgHookRes, tmp);
|
||||
//EnableMenuItem(mainMenu, ID_FILE_STOPHOOK, MF_ENABLED);
|
||||
//EnableMenuItem(mainMenu, ID_FILE_STARTHOOK, MF_DISABLED | MF_GRAYED);
|
||||
_tcscat_s(tmp, 500, _T("\r\n"));
|
||||
AppendText(txtbox, tmp);
|
||||
return;
|
||||
}
|
||||
AppendText(txtbox, tmp);
|
||||
}
|
||||
if (SetMsgHook(mainHwnd, tid))
|
||||
{
|
||||
EnableMenuItem(mainMenu, ID_FILE_STOPHOOK, MF_ENABLED);
|
||||
@@ -158,6 +211,7 @@ void StopMessageHook()
|
||||
AppendText(txtbox, TEXT("Stopping Message Hook\r\n"));
|
||||
//KillHook();
|
||||
RemoveHook();
|
||||
msgCount = 0;
|
||||
}
|
||||
|
||||
bool OnCopyData(COPYDATASTRUCT* pCopyDataStruct) // WM_COPYDATA lParam will have this struct
|
||||
@@ -193,10 +247,11 @@ bool OnCopyData(COPYDATASTRUCT* pCopyDataStruct) // WM_COPYDATA lParam will have
|
||||
}
|
||||
if (_tcscmp(msgName, _T("")) != 0)
|
||||
{
|
||||
++msgCount;
|
||||
TCHAR msgHwndClassname[20];
|
||||
GetClassName(Event.hWnd, msgHwndClassname, 20);
|
||||
TCHAR tmp[200];
|
||||
_stprintf_s(tmp, _T("hwnd: %ld (%s), msg: %s (%ld), wparam: '%s'[%ld], lparam: '%s'{%ld}\r\n"), Event.hWnd, msgHwndClassname, msgName, Event.nCode, Event.wParamStr, Event.wParam, Event.lParamStr,Event.lParam);
|
||||
_stprintf_s(tmp, _T("<%07ld> hwnd: %ld (%s), msg: %s (%ld), wparam: '%s'[%ld], lparam: '%s'{%ld}\r\n"), msgCount, Event.hWnd, msgHwndClassname, msgName, Event.nCode, Event.wParamStr, Event.wParam, Event.lParamStr,Event.lParam);
|
||||
AppendText(txtbox, tmp);
|
||||
}
|
||||
}
|
||||
@@ -225,6 +280,11 @@ void SendWmCommand() //ID_TESTMSGS_WM
|
||||
long wparam = _tcstol(testWmCommandW, &stopStr, 10);
|
||||
long lparam = _tcstol(testWmCommandL, &stopStr, 10);
|
||||
SendMessage(sendHwnd, WM_COMMAND, wparam, lparam);
|
||||
|
||||
/*
|
||||
TCHAR tmp[500];
|
||||
_stprintf_s(tmp, _T("hook handle %ld\r\n"), (long)GetCurrentHookHandle());
|
||||
AppendText(txtbox, tmp); */
|
||||
}
|
||||
|
||||
void HotKeyPressed(WPARAM wParam)
|
||||
@@ -254,6 +314,19 @@ extern "C" __declspec(dllexport) void CreateMsgHookWindow(LPTSTR lpCmdLine)
|
||||
|
||||
int APIENTRY StartWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
|
||||
{
|
||||
// get this Dlls path, by default set both 32 and 64 bit names the same
|
||||
if (_tcscmp(dll32bitName, _T("")) == 0 && _tcscmp(dll64bitName, _T("")) == 0)
|
||||
{
|
||||
HMODULE hm = NULL;
|
||||
if (!GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,(LPCWSTR) &StartWinMain, &hm))
|
||||
{
|
||||
int ret = GetLastError();
|
||||
fprintf(stderr, "GetModuleHandle returned %d\n", ret);
|
||||
}
|
||||
GetModuleFileName(hm, dll32bitName, sizeof(dll32bitName));
|
||||
GetModuleFileName(hm, dll64bitName, sizeof(dll64bitName));
|
||||
//MessageBox(0, dll32bitname, dll64bitname, 0);
|
||||
}
|
||||
|
||||
UNREFERENCED_PARAMETER(hPrevInstance);
|
||||
UNREFERENCED_PARAMETER(lpCmdLine);
|
||||
@@ -275,6 +348,17 @@ int APIENTRY StartWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR l
|
||||
|
||||
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_MSGHOOKTEST));
|
||||
|
||||
if (lpCmdLine != NULL) //process command line args
|
||||
{
|
||||
if (_tcslen(lpCmdLine) > 0)
|
||||
{
|
||||
TCHAR *stopStr;
|
||||
targetPid = (DWORD)_tcstol(lpCmdLine, &stopStr, 10);
|
||||
_stprintf_s(targetProcessId, _T("%ld"), (long)targetPid);
|
||||
StartMessageHook();
|
||||
}
|
||||
}
|
||||
|
||||
// Main message loop:
|
||||
while (GetMessage(&msg, NULL, 0, 0))
|
||||
{
|
||||
@@ -315,7 +399,7 @@ ATOM MyRegisterClass(HINSTANCE hInstance)
|
||||
wcex.cbClsExtra = 0;
|
||||
wcex.cbWndExtra = 0;
|
||||
wcex.hInstance = hInstance;
|
||||
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MSGHOOKTEST));
|
||||
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MSGHOOKICO));
|
||||
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
|
||||
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_MSGHOOKTEST);
|
||||
@@ -419,6 +503,29 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
case ID_TESTMSGS_WMCOM:
|
||||
SendWmCommand();
|
||||
break;
|
||||
case ID_PROC64TEST:
|
||||
if (_tcscmp(targetProcessId, _T("")) != 0) //if target pid was used
|
||||
{
|
||||
TCHAR tmp[500];
|
||||
TCHAR *stopStr;
|
||||
targetPid = (DWORD)_tcstol(targetProcessId, &stopStr, 10);
|
||||
BOOL current64bit = IsCurrentProcess64Bit();
|
||||
if (IsProcess64Bit(targetPid) && current64bit)
|
||||
_stprintf_s(tmp, _T("Target pid (%ld) is a matching 64 bit process\r\n"), targetPid);
|
||||
else if(!IsProcess64Bit(targetPid) && !current64bit)
|
||||
_stprintf_s(tmp, _T("Target pid (%ld) is a matching 32 bit process\r\n"), targetPid);
|
||||
else if (IsProcess64Bit(targetPid))
|
||||
_stprintf_s(tmp, _T("Target pid (%ld) is 64 bit process\r\n"), targetPid);
|
||||
else
|
||||
_stprintf_s(tmp, _T("Target pid (%ld) is 32 bit process\r\n"), targetPid);
|
||||
AppendText(txtbox, tmp);
|
||||
//ExtractResource(IDR_SETMH32, _T("SetMsgHook32.exe"));
|
||||
//_stprintf_s(tmp, _T(" %s %ld %d"), dll32bitName, (long)mainHwnd, targetPid);
|
||||
//RunResource(IDR_SETMH32, tmp);
|
||||
|
||||
//MessageBox(0, , _T("64 bit Test"), 0);
|
||||
}
|
||||
break;
|
||||
case ID_FILE_SETTINGS:
|
||||
DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, DlgProc);
|
||||
break;
|
||||
@@ -468,7 +575,8 @@ INT_PTR CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
//IDC_EDIT1
|
||||
SendDlgItemMessage(hDlg, IDC_EDIT1, WM_SETTEXT, 0 , (LPARAM)targetClassname);
|
||||
//SendDlgItemMessage(hDlg, IDC_EDIT1, WM_SETTEXT, 0 , (LPARAM)targetClassname);
|
||||
SendDlgItemMessage(hDlg, IDC_TARGETPID, WM_SETTEXT, 0 , (LPARAM)targetProcessId);
|
||||
if (filterWmCommand)
|
||||
SendDlgItemMessage(hDlg, IDC_CHECK_CMD, BM_SETCHECK, BST_CHECKED, 0);
|
||||
if (filterWmNotify)
|
||||
@@ -489,7 +597,8 @@ INT_PTR CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
case WM_COMMAND:
|
||||
if (LOWORD(wParam) == IDOK) //only save on OK
|
||||
{
|
||||
GetDlgItemText(hDlg, IDC_EDIT1, targetClassname, 100);
|
||||
//GetDlgItemText(hDlg, IDC_EDIT1, targetClassname, MAX_TEST_SIZE);
|
||||
GetDlgItemText(hDlg, IDC_TARGETPID, targetProcessId, MAX_TEST_SIZE);
|
||||
GetDlgItemText(hDlg, IDC_WMCOMW, testWmCommandW, MAX_TEST_SIZE);
|
||||
GetDlgItemText(hDlg, IDC_WMCOML, testWmCommandL, MAX_TEST_SIZE);
|
||||
GetDlgItemText(hDlg, IDC_WMSETW, testWmSettextW, MAX_TEST_SIZE);
|
||||
|
||||
86
native/MsgHook/ResExtract.h
Normal file
86
native/MsgHook/ResExtract.h
Normal file
@@ -0,0 +1,86 @@
|
||||
//This function will extract a binary resource.
|
||||
//
|
||||
//IDR_SETMH64 BINARY MOVEABLE PURE "..\\SetMsgHook\\bin\\SetMsgHook64.exe"
|
||||
//IDR_SETMH32 BINARY MOVEABLE PURE "..\\SetMsgHook\\bin\\SetMsgHook32.exe"
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
void ExtractResource(const WORD nID, LPCTSTR szFilename)
|
||||
{
|
||||
const HINSTANCE hInstance = (HINSTANCE)pData->g_hInstance;//GetModuleHandle(NULL);
|
||||
HRSRC hResource = FindResource(hInstance, MAKEINTRESOURCE(nID), _T("BINARY"));// _ASSERTE(hResource);
|
||||
if (hResource == NULL) // no resource found.
|
||||
{
|
||||
//MessageBoxA(0, "error, no resource found", "error", 0);
|
||||
printf("error, resource %d not found\n", nID);
|
||||
return;
|
||||
}
|
||||
HGLOBAL hFileResource = LoadResource(hInstance, hResource);// _ASSERTE(hFileResource);
|
||||
LPVOID lpFile = LockResource(hFileResource);
|
||||
|
||||
DWORD dwSize = SizeofResource(hInstance, hResource);
|
||||
|
||||
// Open the file and filemap
|
||||
HANDLE hFile = CreateFile(szFilename, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
HANDLE hFilemap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, dwSize, NULL);
|
||||
|
||||
// Get a pointer to write to
|
||||
LPVOID lpBaseAddress = MapViewOfFile(hFilemap, FILE_MAP_WRITE, 0, 0, 0);
|
||||
|
||||
// Write the file
|
||||
CopyMemory(lpBaseAddress, lpFile, dwSize);
|
||||
|
||||
// Unmap the file and close the handles
|
||||
UnmapViewOfFile(lpBaseAddress);
|
||||
CloseHandle(hFilemap);
|
||||
CloseHandle(hFile);
|
||||
|
||||
}
|
||||
|
||||
void RunResource(const WORD nID, LPWSTR params)
|
||||
{
|
||||
TCHAR tmpFilename[500];
|
||||
TCHAR tmpPath[500];
|
||||
GetTempPath(500, tmpPath);
|
||||
if (GetTempFileName(tmpPath, _T(""), 0, tmpFilename) == 0)
|
||||
{
|
||||
MessageBox(0,_T("Error getting temp file name"), _T("Error"), 0);
|
||||
return;
|
||||
}
|
||||
|
||||
ExtractResource(nID, tmpFilename);
|
||||
//MessageBox(0, tmpFilename, _T("tmp file2"), 0);
|
||||
|
||||
STARTUPINFO si;
|
||||
ZeroMemory( &si, sizeof(si) );
|
||||
si.cb = sizeof(si);
|
||||
|
||||
PROCESS_INFORMATION pi;
|
||||
ZeroMemory( &pi, sizeof(pi) );
|
||||
|
||||
si.wShowWindow = SW_MINIMIZE;
|
||||
|
||||
// Start the child process.
|
||||
if(!CreateProcess(tmpFilename, // No module name (use command line)
|
||||
params, // Command line
|
||||
NULL, // Process handle not inheritable
|
||||
NULL, // Thread handle not inheritable
|
||||
FALSE, // Set handle inheritance to FALSE
|
||||
0, // No creation flags
|
||||
NULL, // Use parent's environment block
|
||||
NULL, // Use parent's starting directory
|
||||
&si, // Pointer to STARTUPINFO structure
|
||||
&pi )) // Pointer to PROCESS_INFORMATION structure
|
||||
{
|
||||
MessageBox(0, _T("CreateProcess failed"), _T("error"), 0);
|
||||
printf( "CreateProcess failed (%d).\n", GetLastError() );
|
||||
return;
|
||||
}
|
||||
//MessageBox(0, tmpFilename, _T("tmp file3"), 0);
|
||||
|
||||
// Wait until child process exits.
|
||||
//WaitForSingleObject( pi.hProcess, INFINITE );
|
||||
// Close process and thread handles.
|
||||
//CloseHandle( pi.hProcess );
|
||||
//CloseHandle( pi.hThread );
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -15,6 +15,7 @@ BOOL APIENTRY DllMain( HMODULE hModule,
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
{
|
||||
//printf("debug DLL_PROCESS_ATTACH hModule: %ld\n", (long)hModule);
|
||||
TCHAR szBaseName[_MAX_FNAME], szTmp[_MAX_FNAME];
|
||||
memset((void *)&szBaseName, '\0', sizeof(TCHAR) * _MAX_FNAME);
|
||||
|
||||
@@ -23,6 +24,10 @@ BOOL APIENTRY DllMain( HMODULE hModule,
|
||||
//_wsplitpath(szTmp, NULL, NULL, szBaseName, NULL);
|
||||
|
||||
wcscat_s(szBaseName, TEXT("MsgHookSharedMem")); // add specifier string
|
||||
if (IsCurrentProcess64Bit())
|
||||
wcscat_s(szBaseName, TEXT("64")); // add bit specifier
|
||||
else
|
||||
wcscat_s(szBaseName, TEXT("32")); // add bit specifier
|
||||
|
||||
hMappedFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(GLOBALDATA), szBaseName);
|
||||
pData = (GLOBALDATA*)MapViewOfFile(hMappedFile, FILE_MAP_WRITE, 0, 0, 0);
|
||||
@@ -34,6 +39,13 @@ BOOL APIENTRY DllMain( HMODULE hModule,
|
||||
pData->g_hWnd = NULL; // and initialize the other handles
|
||||
pData->g_CwpHook = NULL;
|
||||
pData->g_MsgHook = NULL;
|
||||
pData->g_CwpHookProc = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
//open
|
||||
hMappedFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, szBaseName);
|
||||
pData = (GLOBALDATA*)MapViewOfFile(hMappedFile, FILE_MAP_ALL_ACCESS, 0, 0, 0);
|
||||
}
|
||||
DisableThreadLibraryCalls((HMODULE)hModule);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,30 @@
|
||||
#include "stdafx.h"
|
||||
#include "org_synthuse_MsgHook.h"
|
||||
|
||||
/*
|
||||
* Class: org_synthuse_MsgHook
|
||||
* Method: initialize
|
||||
* Signature: (Ljava/lang/String;Ljava/lang/String;)Z
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL Java_org_synthuse_MsgHook_initialize(JNIEnv *env, jobject obj, jstring jdll32bitname, jstring jdll64bitname)
|
||||
{
|
||||
const char *tdll32bitname = env->GetStringUTFChars(jdll32bitname, 0);//convert string
|
||||
|
||||
memset((void *)&dll32bitName, '\0', sizeof(TCHAR) * MAX_TEST_SIZE); // set TCHAR array to all 0
|
||||
int tstrLen = MultiByteToWideChar(CP_UTF8, 0, tdll32bitname, (int)strlen(tdll32bitname), NULL, 0); //get t len
|
||||
MultiByteToWideChar(CP_UTF8, 0, tdll32bitname, (int)strlen(tdll32bitname), dll32bitName, tstrLen); // convert char to tchar
|
||||
|
||||
env->ReleaseStringUTFChars(jdll32bitname, tdll32bitname); //release string
|
||||
|
||||
const char *tdll64bitname = env->GetStringUTFChars(jdll64bitname, 0);//convert string
|
||||
|
||||
memset((void *)&dll64bitName, '\0', sizeof(TCHAR) * MAX_TEST_SIZE); // set TCHAR array to all 0
|
||||
tstrLen = MultiByteToWideChar(CP_UTF8, 0, tdll64bitname, (int)strlen(tdll64bitname), NULL, 0); //get t len
|
||||
MultiByteToWideChar(CP_UTF8, 0, tdll64bitname, (int)strlen(tdll64bitname), dll64bitName, tstrLen); // convert char to tchar
|
||||
|
||||
env->ReleaseStringUTFChars(jdll64bitname, tdll64bitname); //release string
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_synthuse_MsgHook
|
||||
@@ -48,6 +72,12 @@ JNIEXPORT jboolean JNICALL Java_org_synthuse_MsgHook_setMsgHookWindowTargetClass
|
||||
return true;
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_synthuse_MsgHook_setMsgHookWindowTargetPid(JNIEnv *env, jobject obj, jint jpid)
|
||||
{
|
||||
_stprintf_s(targetProcessId, _T("%ld"), (long)jpid);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_synthuse_MsgHook
|
||||
* Method: setMessageHook
|
||||
|
||||
@@ -7,6 +7,14 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* Class: org_synthuse_MsgHook
|
||||
* Method: initialize
|
||||
* Signature: (Ljava/lang/String;Ljava/lang/String;)Z
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL Java_org_synthuse_MsgHook_initialize
|
||||
(JNIEnv *, jobject, jstring, jstring);
|
||||
|
||||
/*
|
||||
* Class: org_synthuse_MsgHook
|
||||
* Method: createMsgHookWindow
|
||||
@@ -25,11 +33,11 @@ JNIEXPORT jboolean JNICALL Java_org_synthuse_MsgHook_setMsgHookWindowTargetHwnd
|
||||
|
||||
/*
|
||||
* Class: org_synthuse_MsgHook
|
||||
* Method: setMsgHookWindowTargetClass
|
||||
* Signature: (Ljava/lang/String;)Z
|
||||
* Method: setMsgHookWindowTargetPid
|
||||
* Signature: (I)Z
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL Java_org_synthuse_MsgHook_setMsgHookWindowTargetClass
|
||||
(JNIEnv *, jobject, jstring);
|
||||
JNIEXPORT jboolean JNICALL Java_org_synthuse_MsgHook_setMsgHookWindowTargetPid
|
||||
(JNIEnv *, jobject, jint);
|
||||
|
||||
/*
|
||||
* Class: org_synthuse_MsgHook
|
||||
|
||||
Binary file not shown.
@@ -11,11 +11,14 @@
|
||||
// Windows Header Files:
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
#include <tchar.h>
|
||||
#include <Psapi.h>
|
||||
#include <stdlib.h>
|
||||
#include <tlhelp32.h> //CreateToolhelp32Snapshot
|
||||
|
||||
#pragma comment( lib, "psapi.lib" )
|
||||
//#pragma comment( lib, "kernel32.lib" )
|
||||
|
||||
// TODO: reference additional headers your program requires here
|
||||
|
||||
@@ -37,14 +40,23 @@ typedef struct
|
||||
//HHOOK g_hHook;
|
||||
HWND g_hWnd;
|
||||
HANDLE g_hInstance;
|
||||
HOOKPROC g_CwpHookProc;
|
||||
}GLOBALDATA;
|
||||
|
||||
#ifndef GLOBAL_VARS_H // header guards
|
||||
#define GLOBAL_VARS_H
|
||||
|
||||
extern "C" __declspec(dllexport) void CreateMsgHookWindow(LPTSTR lpCmdLine);
|
||||
extern "C" __declspec(dllexport) BOOL SetCustomMsgHookDll(const TCHAR * hookDll, const char * hookDllProcName);
|
||||
extern "C" __declspec(dllexport) BOOL SetMsgHook(HWND callerHWnd, DWORD threadId);
|
||||
extern "C" __declspec(dllexport) HHOOK GetCurrentHookHandle();
|
||||
extern "C" __declspec(dllexport) void SetGlobalDLLInstance(HANDLE dllInstance);
|
||||
extern "C" __declspec(dllexport) BOOL RemoveHook();
|
||||
extern "C" __declspec(dllexport) BOOL IsCurrentProcess64Bit();
|
||||
extern "C" __declspec(dllexport) BOOL IsProcess64Bit(DWORD procId);
|
||||
extern "C" __declspec(dllexport) DWORD GetProcessMainThreadId(DWORD procId);
|
||||
|
||||
//void ExtractResource(const WORD nID, LPCTSTR szFilename);
|
||||
|
||||
//Global variables , remember not to initialize here
|
||||
extern HANDLE hMappedFile;
|
||||
@@ -53,6 +65,10 @@ extern bool bStartingProcess;
|
||||
|
||||
#define MAX_TEST_SIZE 100
|
||||
extern TCHAR targetHwndStr[MAX_TEST_SIZE];
|
||||
extern TCHAR targetProcessId[MAX_TEST_SIZE];
|
||||
extern TCHAR targetClassname[MAX_TEST_SIZE];
|
||||
extern TCHAR dll32bitName[500];
|
||||
extern TCHAR dll64bitName[500];
|
||||
extern char dllProcName[500];
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user