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:
Edward Jakubowski
2014-06-03 06:28:14 -04:00
parent 05748b4582
commit d100d23259
41 changed files with 1232 additions and 72 deletions

2
.gitignore vendored
View File

@@ -8,4 +8,4 @@ native/uiabridge/release
native/uiabridge/Debug
!native/uiabridge/bin
!native/MsgHook/bin
!native/MsgHookTest/bin
!native/SetMsgHook/bin

35
native/MsgHook.sln Normal file
View File

@@ -0,0 +1,35 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MsgHook", "MsgHook\MsgHook.vcxproj", "{8E038A94-7D02-49E9-B9F6-5224D9D11225}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SetMsgHook", "SetMsgHook\SetMsgHook.vcxproj", "{34A73B55-8A93-4FB5-83CE-7759C1D23348}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{8E038A94-7D02-49E9-B9F6-5224D9D11225}.Debug|Win32.ActiveCfg = Debug|Win32
{8E038A94-7D02-49E9-B9F6-5224D9D11225}.Debug|Win32.Build.0 = Debug|Win32
{8E038A94-7D02-49E9-B9F6-5224D9D11225}.Debug|x64.ActiveCfg = Debug|x64
{8E038A94-7D02-49E9-B9F6-5224D9D11225}.Debug|x64.Build.0 = Debug|x64
{8E038A94-7D02-49E9-B9F6-5224D9D11225}.Release|Win32.ActiveCfg = Release|Win32
{8E038A94-7D02-49E9-B9F6-5224D9D11225}.Release|Win32.Build.0 = Release|Win32
{8E038A94-7D02-49E9-B9F6-5224D9D11225}.Release|x64.ActiveCfg = Release|x64
{8E038A94-7D02-49E9-B9F6-5224D9D11225}.Release|x64.Build.0 = Release|x64
{34A73B55-8A93-4FB5-83CE-7759C1D23348}.Debug|Win32.ActiveCfg = Debug|Win32
{34A73B55-8A93-4FB5-83CE-7759C1D23348}.Debug|Win32.Build.0 = Debug|Win32
{34A73B55-8A93-4FB5-83CE-7759C1D23348}.Debug|x64.ActiveCfg = Debug|Win32
{34A73B55-8A93-4FB5-83CE-7759C1D23348}.Release|Win32.ActiveCfg = Release|Win32
{34A73B55-8A93-4FB5-83CE-7759C1D23348}.Release|Win32.Build.0 = Release|Win32
{34A73B55-8A93-4FB5-83CE-7759C1D23348}.Release|x64.ActiveCfg = Release|Win32
{34A73B55-8A93-4FB5-83CE-7759C1D23348}.Release|x64.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -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
}

View File

@@ -0,0 +1,5 @@
LIBRARY MsgHook
EXPORTS
CwpHookProc @1
MsgHookProc @2

View File

@@ -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" />

View File

@@ -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.

View File

@@ -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);

View 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.

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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.

View File

@@ -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

129
native/SetMsgHook/MsgHook.h Normal file
View File

@@ -0,0 +1,129 @@
/*
* Copyright 2014, Synthuse.org
* Released under the Apache Version 2.0 License.
*
* last modified by ejakubowski7@gmail.com
*/
#include <windows.h>
typedef struct
{
HHOOK g_CwpHook;
HHOOK g_MsgHook;
//HHOOK g_hHook;
HWND g_hWnd;
HANDLE g_hInstance;
HOOKPROC g_CwpHookProc;
}GLOBALDATA;
//#define MSGHOOKER_FILE TEXT("MsgHook.dll")
TCHAR MSGHOOK_DLL_NAME[MAX_NAME_SIZE] = _T("MsgHook.dll");
HINSTANCE msgHookDll;
//void CreateMsgHookWindow(LPTSTR lpCmdLine)
typedef VOID (* CREATEMSGHOOKWINDOW)(LPTSTR);
CREATEMSGHOOKWINDOW CreateMsgHookWindow;
//BOOL SetCustomMsgHookDll(const TCHAR * hookDll, const char * hookDllProcName)
typedef BOOL (* SETCUSTOMMSGHOOKDLL)(LPCTSTR, LPCSTR);
SETCUSTOMMSGHOOKDLL SetCustomMsgHookDll;
//BOOL SetMsgHook(HWND callerHWnd, DWORD threadId)
typedef BOOL (* SETMSGHOOK)(HWND, DWORD);
SETMSGHOOK SetMsgHook;
//HHOOK GetCurrentHookHandle()
typedef HHOOK (* GETCURRENTHOOKHANDLE)(VOID);
GETCURRENTHOOKHANDLE GetCurrentHookHandle;
//void SetGlobalDLLInstance(HANDLE dllInstance)
typedef VOID (* SETGLOBALDLLINSTANCE)(HANDLE);
SETGLOBALDLLINSTANCE SetGlobalDLLInstance;
//BOOL RemoveHook()
typedef BOOL (* REMOVEHOOK)(VOID);
REMOVEHOOK RemoveHook;
// DWORD GetProcessMainThreadId(DWORD procId)
typedef DWORD (* GETPROCESSMAINTHREADID)(DWORD);
GETPROCESSMAINTHREADID GetProcessMainThreadId;
typedef struct
{
HWND hWnd;
int nCode;
DWORD dwHookType;
WPARAM wParam;
LPARAM lParam;
TCHAR wParamStr[25];
TCHAR lParamStr[25];
}HEVENT;
/*
typedef struct {
DWORD vkCode;
DWORD scanCode;
DWORD flags;
DWORD time;
ULONG_PTR dwExtraInfo;
} KBDLLHOOKSTRUCT, *PKBDLLHOOKSTRUCT;
*/
void MsgHook_CreateMsgHookWindow(LPTSTR args)
{
msgHookDll = LoadLibrary(MSGHOOK_DLL_NAME);
if (msgHookDll != NULL)
{
CreateMsgHookWindow = (CREATEMSGHOOKWINDOW)GetProcAddress(msgHookDll, "CreateMsgHookWindow");
if (CreateMsgHookWindow)
{
CreateMsgHookWindow(args);
}
}
}
BOOL MsgHook_SetMsgHook(HWND hw, int threadId)
{
msgHookDll = LoadLibrary(MSGHOOK_DLL_NAME);
if (msgHookDll != NULL)
{
SetMsgHook = (SETMSGHOOK)GetProcAddress(msgHookDll, "SetMsgHook");
GetCurrentHookHandle = (GETCURRENTHOOKHANDLE)GetProcAddress(msgHookDll, "GetCurrentHookHandle");
SetGlobalDLLInstance = (SETGLOBALDLLINSTANCE)GetProcAddress(msgHookDll, "SetGlobalDLLInstance");
RemoveHook = (REMOVEHOOK)GetProcAddress(msgHookDll, "RemoveHook");
if (SetMsgHook)
{
//printf("LoadLibrary MSGHOOK %ld\n", (long)msgHookDll);
SetGlobalDLLInstance(msgHookDll);
return SetMsgHook(hw, threadId);
}
}
return false;
}
void MsgHook_RemoveHook()
{
if (RemoveHook)
RemoveHook();
if (msgHookDll != NULL)
FreeLibrary(msgHookDll);
}
DWORD MsgHook_GetProcessMainThreadId(DWORD procId)
{
msgHookDll = LoadLibrary(MSGHOOK_DLL_NAME);
if (msgHookDll != NULL)
{
GetProcessMainThreadId = (GETPROCESSMAINTHREADID)GetProcAddress(msgHookDll, "GetProcessMainThreadId");
if (GetProcessMainThreadId)
{
return GetProcessMainThreadId(procId);
}
}
printf("error, failed loading library");
return 0;
}

View File

@@ -0,0 +1,40 @@
========================================================================
CONSOLE APPLICATION : SetMsgHook Project Overview
========================================================================
AppWizard has created this SetMsgHook application for you.
This file contains a summary of what you will find in each of the files that
make up your SetMsgHook application.
SetMsgHook.vcxproj
This is the main project file for VC++ projects generated using an Application Wizard.
It contains information about the version of Visual C++ that generated the file, and
information about the platforms, configurations, and project features selected with the
Application Wizard.
SetMsgHook.vcxproj.filters
This is the filters file for VC++ projects generated using an Application Wizard.
It contains information about the association between the files in your project
and the filters. This association is used in the IDE to show grouping of files with
similar extensions under a specific node (for e.g. ".cpp" files are associated with the
"Source Files" filter).
SetMsgHook.cpp
This is the main application source file.
/////////////////////////////////////////////////////////////////////////////
Other standard files:
StdAfx.h, StdAfx.cpp
These files are used to build a precompiled header (PCH) file
named SetMsgHook.pch and a precompiled types file named StdAfx.obj.
/////////////////////////////////////////////////////////////////////////////
Other notes:
AppWizard uses "TODO:" comments to indicate parts of the source code you
should add to or customize.
/////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,96 @@
/*
* Copyright 2014, Synthuse.org
* Released under the Apache Version 2.0 License.
*
* last modified by ejakubowski7@gmail.com
*/
// SetMsgHook.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "MsgHook.h"
int _tmain(int argc, _TCHAR* argv[])
{
if (argc == 1) //no args passed, show MsgHook Viewer gui
{
MsgHook_CreateMsgHookWindow(NULL);
return 0;
}
HWND hookHwnd = NULL;
long procId = 0;
TCHAR *stopStr;
for (int i = 1 ; i < argc ; i++)
{
if (_tcscmp(argv[i], _T("?")) == 0 || _tcscmp(argv[i], _T("-?")) == 0 || argc == 3 || argc > 4)
{
printf("SetMsgHook version 1.0 by Edward Jakubowski \n\n");
printf("Usage: SetMsgHook.exe [(MSG_HOOK_DLL) (MSG_HOOK_HWND_OR_ZERO) (TARGET_PID)] [MSG_HOOK_DLL] [?] \n\n");
printf(" Additional Notes:\n");
printf(" Message Hook Viewer Gui - To open the gui you must provide the path to the msg hook dll as the ");
printf("only argument when running SetMsgHook.exe. Also setting the (MSG_HOOK_HWND) argument to 0 (zero) ");
printf("will start the gui and message hook on the given Process Id.\n\n");
HWND currentHwnd = FindWindow(_T("MSGHOOKVIEW"), NULL);
printf(" Current MSG_HOOK_HWND: %ld\n", (long)currentHwnd);
return 0;
}
if (i == 1)
_tcsncpy_s(MSGHOOK_DLL_NAME, MAX_NAME_SIZE, argv[i], _TRUNCATE);
if (i == 2)
hookHwnd = (HWND)_tcstol(argv[i], &stopStr, 10);
if (i == 3)
procId = (long)_tcstol(argv[i], &stopStr, 10);
}
if (argc == 2) //one arg passed (dll), show MsgHook Viewer gui
{
printf("Starting msg hook viewer...");
MsgHook_CreateMsgHookWindow(NULL);
return 0;
}
if (argc == 4 && hookHwnd == 0)
{
printf("Starting msg hook viewer on pid %ld...", (long)procId);
TCHAR tmp[100];
_stprintf_s(tmp, _T("%ld"), (long)procId);
MsgHook_CreateMsgHookWindow(tmp);
return 0;
}
char tmp[MAX_NAME_SIZE];
size_t convertedCnt = 0;
wcstombs_s(&convertedCnt, tmp, MAX_NAME_SIZE, MSGHOOK_DLL_NAME, _TRUNCATE);
printf("MsgHook DLL: %s, HWND: %ld, PID: %ld", tmp, (long)hookHwnd, procId);
DWORD threadId = MsgHook_GetProcessMainThreadId(procId);
printf(", ThreadId: %ld\n", (long)threadId);
if (MsgHook_SetMsgHook(hookHwnd, threadId))
printf("Hook successfully initialized\n");
else
{
printf("Hook failed to initialize\n");
return -1;
}
//don't exit SetMsgHook until hooked process exits
HANDLE process = OpenProcess(SYNCHRONIZE, FALSE, procId);
while(WaitForSingleObject(process, 0) == WAIT_TIMEOUT)
{
Sleep(1000); //check once per second
if (GetCurrentHookHandle() == NULL)
{
printf("unhooked.");
break;
}
}
CloseHandle(process);
MsgHook_RemoveHook();
//_getch();
printf("done.");
return 0;
}

View File

@@ -0,0 +1,169 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{34A73B55-8A93-4FB5-83CE-7759C1D23348}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>SetMsgHook</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<PostBuildEvent>
<Command>mkdir "$(ProjectDir)bin"
copy /Y "$(TargetPath)" "$(ProjectDir)bin\SetMsgHook$(PlatformArchitecture)$(TargetExt)"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<PostBuildEvent>
<Command>mkdir "$(ProjectDir)bin"
copy /Y "$(TargetPath)" "$(ProjectDir)bin\SetMsgHook$(PlatformArchitecture)$(TargetExt)"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<PostBuildEvent>
<Command>mkdir "$(ProjectDir)bin"
copy /Y "$(TargetPath)" "$(ProjectDir)bin\SetMsgHook$(PlatformArchitecture)$(TargetExt)"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<PostBuildEvent>
<Command>mkdir "$(ProjectDir)bin"
copy /Y "$(TargetPath)" "$(ProjectDir)bin\SetMsgHook$(PlatformArchitecture)$(TargetExt)"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<None Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="MsgHook.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="SetMsgHook.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<None Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="targetver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="MsgHook.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SetMsgHook.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,6 @@
REM set path=C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin;%path%
%WinDir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe /p:configuration=release /p:platform=x64 %*
%WinDir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe /p:configuration=release /p:platform=win32 %*
pause

View File

@@ -0,0 +1,8 @@
// stdafx.cpp : source file that includes just the standard includes
// SetMsgHook.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

View File

@@ -0,0 +1,23 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
#include <conio.h>
// TODO: reference additional headers your program requires here
#ifndef GLOBAL_VARS_H // header guards
#define GLOBAL_VARS_H
#define MAX_NAME_SIZE 500
extern TCHAR MSGHOOK_DLL_NAME[MAX_NAME_SIZE];
#endif

View File

@@ -0,0 +1,8 @@
#pragma once
// Including SDKDDKVer.h defines the highest available Windows platform.
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
#include <SDKDDKVer.h>

View File

@@ -20,12 +20,14 @@ import com.sun.jna.platform.win32.WinDef.*;
import com.sun.jna.platform.win32.Advapi32Util;
import com.sun.jna.platform.win32.BaseTSD.LONG_PTR;
import com.sun.jna.platform.win32.BaseTSD.ULONG_PTR;
import com.sun.jna.platform.win32.WinBase.SYSTEM_INFO;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinNT.HANDLE;
import com.sun.jna.platform.win32.WinReg;
import com.sun.jna.platform.win32.WinUser;
import com.sun.jna.platform.win32.WinNT.LARGE_INTEGER;
import com.sun.jna.platform.win32.WinUser.WNDENUMPROC;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;
import com.sun.jna.win32.StdCallLibrary.StdCallCallback;
import com.sun.jna.win32.W32APIOptions;
@@ -323,6 +325,9 @@ public class Api {
boolean GetDiskFreeSpaceEx(String lpDirectoryName, LARGE_INTEGER.ByReference lpFreeBytesAvailable, LARGE_INTEGER.ByReference lpTotalNumberOfBytes, LARGE_INTEGER.ByReference lpTotalNumberOfFreeBytes);
int GetLastError();
Pointer OpenProcess(int dwDesiredAccess, boolean bInheritHandle, Pointer pointer);
boolean CloseHandle(HANDLE hObject);
void GetNativeSystemInfo(SYSTEM_INFO lpSystemInfo);
boolean IsWow64Process(HANDLE hProcess, IntByReference Wow64Process);
}
@@ -627,6 +632,36 @@ public class Api {
return false;
}
public static boolean isProcess64bit(int pid)
{
try {
SYSTEM_INFO lpSystemInfo = new SYSTEM_INFO();
Kernel32.instance.GetNativeSystemInfo(lpSystemInfo);
if (lpSystemInfo.processorArchitecture.dwOemID.intValue() == 0)
{
System.out.println("intel x86"); //not a 64 bit os
return false;
}
Pointer process = Kernel32.instance.OpenProcess(Api.PROCESS_QUERY_INFORMATION | Api.PROCESS_VM_READ, false, new Pointer(pid));
IntByReference isWow64 = new IntByReference(0);
if (!Kernel32.instance.IsWow64Process(new HANDLE(process), isWow64))
{
//handle error
}
//System.out.println("isProcess64bit " + pid + " = " + isWow64.getValue());
Kernel32.instance.CloseHandle(new HANDLE(process));
if (isWow64.getValue() == 1)
return false;
return true;
//CloseHandle()
} catch(Exception ex)
{
ex.printStackTrace();
}
return false;
}
public static HWND FindMainWindowFromPid(final long targetProcessId) {
final List<HWND> resultList = new ArrayList<HWND>();

View File

@@ -117,6 +117,9 @@ public class CommandPopupMenu extends JPopupMenu {
CommandMenuItem mntmSendCommandMsg = new CommandMenuItem("sendCommandMsg", 4);
mnWinMessages.add(mntmSendCommandMsg);
CommandMenuItem mntmSendMessage = new CommandMenuItem("sendMessage", 5);
mnWinMessages.add(mntmSendMessage);
CommandMenuItem mntmSetcursorposition = new CommandMenuItem("setCursorPosition", 3);
mnWinMessages.add(mntmSetcursorposition);
@@ -232,6 +235,8 @@ public class CommandPopupMenu extends JPopupMenu {
actionStr += "with | |";
if (paramCount > 3)
actionStr += " and | |";
if (paramCount > 4)
actionStr += " and | |";
return actionStr;
}
}

View File

@@ -24,6 +24,7 @@ public class CommandProcessor implements Runnable{
public static boolean DEFAULT_QUIET = false; //by default is quiet enabled
protected CommandProcessor CommandProcessor = null;
public int executeCount = 0;
public int executeErrorCount;
public String lastError = "";
public String currentCommandText = "";
@@ -94,6 +95,7 @@ public class CommandProcessor implements Runnable{
events.statusChanged("Executing Test Script...");
//CommandProcessor cmdProcessor = new CommandProcessor();
scriptErrorCount = 0;
executeCount = 0;
lastError = "";
long startTime = System.nanoTime();
String[] lines = scriptStr.split("\n");
@@ -101,7 +103,7 @@ public class CommandProcessor implements Runnable{
if (!line.trim().startsWith("|"))
continue; //skip if it doesn't start with bar
String[] parsed = line.split("\\|");
String[] parsed = line.trim().split("\\|");
//
//System.out.println("line: " + line);
@@ -117,6 +119,8 @@ public class CommandProcessor implements Runnable{
execute(parsed[2].trim(), new String[] {parsed[4].trim(), parsed[6].trim()});
if (parsed.length == 9)
execute(parsed[2].trim(), new String[] {parsed[4].trim(), parsed[6].trim(), parsed[8].trim()});
if (parsed.length == 11)
execute(parsed[2].trim(), new String[] {parsed[4].trim(), parsed[6].trim(), parsed[8].trim(), parsed[10].trim()});
if (executeErrorCount > 0) //check if any errors occurred
++scriptErrorCount;
@@ -128,7 +132,7 @@ public class CommandProcessor implements Runnable{
String forcedStr = "Completed";
if (STOP_PROCESSOR.get())
forcedStr = "Stopped";
events.statusChanged("Script Execution " + forcedStr + " with " + scriptErrorCount + " error(s) in " + new DecimalFormat("#.###").format(seconds) + " seconds");
events.statusChanged("Script Execution " + forcedStr + " " + executeCount + " command(s) with " + scriptErrorCount + " error(s) in " + new DecimalFormat("#.###").format(seconds) + " seconds");
events.executionCompleted();
if (scriptErrorCount > 0 && !isQuiet)
{
@@ -142,6 +146,7 @@ public class CommandProcessor implements Runnable{
}
public Object execute(String command, String[] args) {
++executeCount;
executeErrorCount = 0;
currentCommandText = command;
String joinedArgs = "";
@@ -221,6 +226,8 @@ public class CommandProcessor implements Runnable{
return win.cmdSelectContextMenuId(args);
if (command.equals("sendCommandMsg"))
return win.cmdSendCommandMsg(args);
if (command.equals("sendMessage"))
return win.cmdSendMessage(args);
if (command.equals("windowMinimize"))
return win.cmdWindowMinimize(args);
if (command.equals("windowMaximize"))

View File

@@ -19,14 +19,23 @@ import javax.swing.JOptionPane;
public class MsgHook {
public static String targetdllName = "";
public static String dll64bitName = "";
public static String dll32bitName = "";
static
{
String loadFailedMsg = "Failed to load MsgHook library.\n";
//System.out.println("SynthuseDlg.config.disableUiaBridge: " + SynthuseDlg.config.disableUiaBridge);
String archDataModel = System.getProperty("sun.arch.data.model");//32 or 64 bit
try {
loadNativeLibraryFromJar("/MsgHook" + archDataModel + ".dll");
targetdllName = "/MsgHook" + archDataModel + ".dll";
dll64bitName = SaveNativeLibraryFromJar("/MsgHook64.dll"); //need to save both 32 and 64 bit dlls for hooking both types
dll32bitName = SaveNativeLibraryFromJar("/MsgHook32.dll");
if (archDataModel.equals("32"))
System.load(dll32bitName);
else
System.load(dll64bitName);
} catch (Exception ex) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
@@ -36,7 +45,7 @@ public class MsgHook {
}
}
public static void loadNativeLibraryFromJar(String path) {
public static String SaveNativeLibraryFromJar(String path) {
// Obtain filename from path
String[] parts = path.split("/");
String filename = (parts.length > 1) ? parts[parts.length - 1] : null;
@@ -58,7 +67,7 @@ public class MsgHook {
}
if (!temp.exists()) { //some reason the temp file wasn't create so abort
System.out.println("File " + temp.getAbsolutePath() + " does not exist.");
return;
return "";
}
// Prepare buffer for data copying
@@ -68,7 +77,7 @@ public class MsgHook {
InputStream is = MsgHook.class.getResourceAsStream(path);
if (is == null) { //check if valid
System.out.println("File " + path + " was not found inside JAR.");
return;
return "";
}
// Open output stream and copy data between source file in JAR and the temporary file
OutputStream os = null;
@@ -83,23 +92,25 @@ public class MsgHook {
e.printStackTrace();
}
// Finally, load the library
System.load(temp.getAbsolutePath());
return temp.getAbsolutePath();
}
//public native boolean initialize(int hwnd);
public native boolean initialize(String dll32bitName, String dll64bitName);
public native boolean createMsgHookWindow();
public native boolean setMsgHookWindowTargetHwnd(int hwnd);
public native boolean setMsgHookWindowTargetClass(String classname);
public native boolean setMsgHookWindowTargetPid(int pid);
public native boolean setMessageHook(int hwnd, int threadId);
public native boolean removeMessageHook();
//public native boolean shutdown();
public static Thread createMsgHookWinThread(final long targetHwnd)
public static Thread createMsgHookWinThread(final long targetHwnd, final int targetPid)
{
Thread t = new Thread() {
public void run() {
MsgHook mh = new MsgHook();
mh.setMsgHookWindowTargetClass("");
mh.initialize(dll32bitName, dll64bitName);
if (targetPid != 0)
mh.setMsgHookWindowTargetPid(targetPid);
if (targetHwnd != 0)
mh.setMsgHookWindowTargetHwnd((int)targetHwnd);
mh.createMsgHookWindow();

View File

@@ -29,6 +29,7 @@ import com.jgoodies.forms.layout.RowSpec;
import com.jgoodies.forms.factories.FormFactory;
*/
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.ptr.PointerByReference;
import java.awt.FlowLayout;
import java.awt.event.ActionListener;
@@ -50,7 +51,7 @@ public class SynthuseDlg extends JFrame {
/**
*
*/
public static String VERSION_STR = "1.2.1";
public static String VERSION_STR = "1.2.2";
public static String RES_STR_MAIN_ICON = "/org/synthuse/img/gnome-robots.png";
public static String RES_STR_REFRESH_IMG = "/org/synthuse/img/rapidsvn.png";
@@ -77,6 +78,7 @@ public class SynthuseDlg extends JFrame {
public static Config config = new Config(Config.DEFAULT_PROP_FILENAME);
private String dialogResult = "";
private String lastDragHwnd = "";
private int lastDragPid = 0;
private String lastRuntimeId ="";
private JComboBox<String> cmbXpath;
private JButton btnTestIde;
@@ -195,10 +197,10 @@ public class SynthuseDlg extends JFrame {
*/
long lastHwndLong = 0;
try {
lastHwndLong = Long.parseLong(lastDragHwnd);
//lastHwndLong = Long.parseLong(lastDragHwnd);
} catch (Exception ex) {
}
MsgHook.createMsgHookWinThread(lastHwndLong);
MsgHook.createMsgHookWinThread(lastHwndLong, lastDragPid);
}
}
@@ -510,6 +512,10 @@ public class SynthuseDlg extends JFrame {
String handleStr = Api.GetHandleAsString(hwnd);
String classStr = WindowsEnumeratedXml.escapeXmlAttributeValue(Api.getWindowClassName(hwnd));
String parentStr = Api.GetHandleAsString(User32.instance.GetParent(hwnd));
PointerByReference pointer = new PointerByReference();
User32.instance.GetWindowThreadProcessId(hwnd, pointer);
int pid = pointer.getPointer().getInt(0);
String enumProperties = "";
if (!SynthuseDlg.config.isUiaBridgeDisabled())
enumProperties = uiabridge.getWindowInfo(targetX, targetY, WindowInfo.UIA_PROPERTY_LIST_ADV);
@@ -524,6 +530,7 @@ public class SynthuseDlg extends JFrame {
}
lastDragHwnd = handleStr;
lastRuntimeId = runtimeId;
lastDragPid = pid;
//lastDragHwnd = (hwnd + "");
if (framework.equals(UiaBridge.FRAMEWORK_ID_WPF) || framework.equals(UiaBridge.FRAMEWORK_ID_SILVER))
{// WPF and Silverlight apps don't expose their child windows boundaries the same as win32 apps

View File

@@ -12,7 +12,9 @@ import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JToolBar;
import javax.swing.JButton;
import javax.swing.JScrollPane;
@@ -26,6 +28,7 @@ import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.Toolkit;
import java.io.*;
import javax.swing.JLabel;
@@ -36,7 +39,8 @@ public class TestIdeFrame extends JFrame {
public static String RES_STR_RUN_IMG = "/org/synthuse/img/arrow-right-3.png";
public static String RES_STR_CLEAR_IMG = "/org/synthuse/img/user-trash-2.png";
public static String RES_STR_COPY_IMG = "/org/synthuse/img/edit-copy-7.png";
public static String RES_STR_SAVE_IMG = "/org/synthuse/img/document-save-6.png";
public static String RES_STR_OPEN_IMG = "/org/synthuse/img/document-open-folder.png";
/**
*
*/
@@ -46,6 +50,8 @@ public class TestIdeFrame extends JFrame {
private JButton btnRun;
private JButton btnClear;
private JButton btnCopy;
private JButton btnSave;
private JButton btnOpen;
private JLabel lblStatus;
/**
@@ -68,32 +74,30 @@ public class TestIdeFrame extends JFrame {
btnRun = new JButton("Run");
btnRun.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if (btnRun.getText().equals("Run")) {
btnRun.setText("Stop");
btnRun.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_STOP_IMG)));
CommandProcessor.STOP_PROCESSOR.set(false);
CommandProcessor.executeThreaded(txtTest.getText(), new CommandProcessor.Events() {
@Override
public void statusChanged(String status) {
lblStatus.setText(status);
}
@Override
public void executionCompleted() {
btnRun.setText("Run");
btnRun.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_RUN_IMG)));
}
});
}
else {
CommandProcessor.STOP_PROCESSOR.set(true);
//btnRun.setText("Run");
//btnRun.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_RUN_IMG)));
}
runTestScript();
}
});
btnRun.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_RUN_IMG)));
toolBar.add(btnRun);
btnSave = new JButton("Save");
btnSave.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
saveTestScript();
}
});
btnSave.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_SAVE_IMG)));
toolBar.add(btnSave);
btnOpen = new JButton("Open");
btnOpen.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
openTestScript();
}
});
btnOpen.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_OPEN_IMG)));
toolBar.add(btnOpen);
btnClear = new JButton("Clear");
btnClear.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
@@ -135,5 +139,83 @@ public class TestIdeFrame extends JFrame {
});
super.setAlwaysOnTop(SynthuseDlg.config.isAlwaysOnTop());
}
public void runTestScript()
{
if (btnRun.getText().equals("Run")) {
btnRun.setText("Stop");
btnRun.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_STOP_IMG)));
CommandProcessor.STOP_PROCESSOR.set(false);
CommandProcessor.executeThreaded(txtTest.getText(), new CommandProcessor.Events() {
@Override
public void statusChanged(String status) {
lblStatus.setText(status);
}
@Override
public void executionCompleted() {
btnRun.setText("Run");
btnRun.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_RUN_IMG)));
}
});
}
else {
CommandProcessor.STOP_PROCESSOR.set(true);
//btnRun.setText("Run");
//btnRun.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_RUN_IMG)));
}
}
private void saveTestScript()
{
JFileChooser fChoose = new JFileChooser();
fChoose.setFileFilter(new FileNameExtensionFilter("Text Files", "txt", "text"));
int result = fChoose.showSaveDialog(this);
if (result == JFileChooser.CANCEL_OPTION)
return;
File file = fChoose.getSelectedFile();
if (fChoose.getFileFilter().getDescription().startsWith("Text") && !file.getAbsolutePath().toLowerCase().endsWith(".txt"))
file = new File(file.getAbsolutePath() + ".txt"); //append extension if not already there
FileWriter fw = null;
try {
fw = new FileWriter(file);
fw.write(txtTest.getText());
fw.flush();
fw.close();
fw = null;
} catch (Exception e) {
e.printStackTrace();
}
if (fw != null)
try { fw.close(); } catch (Exception e){ e.printStackTrace(); };
lblStatus.setText("Script Saved: " + file.getAbsolutePath());
}
private void openTestScript()
{
JFileChooser fChoose = new JFileChooser();
fChoose.setFileFilter(new FileNameExtensionFilter("Text Files", "txt", "text"));
int result = fChoose.showOpenDialog(this);
if (result == JFileChooser.CANCEL_OPTION)
return;
File file = fChoose.getSelectedFile();
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(file));
String line = "";
txtTest.setText("");
while((line = br.readLine()) != null){
txtTest.append(line + System.getProperty("line.separator"));
//System.out.println(line);
}
br.close();
br = null;
} catch (Exception e) {
e.printStackTrace();
}
if (br != null)
try { br.close(); } catch (Exception e){ e.printStackTrace(); };
lblStatus.setText("Script Loaded: " + file.getAbsolutePath());
}
}

View File

@@ -22,6 +22,7 @@ import com.sun.jna.platform.win32.WinDef.LPARAM;
import com.sun.jna.platform.win32.WinDef.LRESULT;
import com.sun.jna.platform.win32.WinDef.RECT;
import com.sun.jna.platform.win32.WinDef.WPARAM;
import com.sun.jna.platform.win32.WinNT.HANDLE;
import com.sun.jna.ptr.PointerByReference;
public class WindowInfo {
@@ -50,6 +51,7 @@ public class WindowInfo {
public int menus = 0;
public HMENU menu = null;
public boolean useUiaBridge = false;
public boolean is64bit = false;
public Map<String, String> extra = null;
@@ -146,13 +148,10 @@ public class WindowInfo {
useUiaBridge = true;
}
else {
PointerByReference pointer = new PointerByReference();
User32.instance.GetWindowThreadProcessId(hWnd, pointer);
pid = pointer.getPointer().getInt(0);
Pointer process = Kernel32.instance.OpenProcess(Api.PROCESS_QUERY_INFORMATION | Api.PROCESS_VM_READ, false, pointer.getValue());
Psapi.instance.GetModuleBaseNameW(process, null, buffer2, 512);
processName = Native.toString(buffer2);
getProcessInfo();
//test to see if uiaBridge should be used on this parent
if (this.className.startsWith("HwndWrapper") || this.className.startsWith("WindowsForms"))
useUiaBridge = true;
@@ -204,6 +203,8 @@ public class WindowInfo {
this.hwndStr = "";
//if (this.framework == null)
// this.framework = "na";
if(this.controlType.equals("window"))
this.isChild = false;
return;
}
// non-wildcard mode
@@ -234,7 +235,9 @@ public class WindowInfo {
value = value.substring(0, MAX_TEXT_SIZE);
if (this.hwndStr == null)
this.hwndStr = "";
getProcessInfo();
if(this.controlType.equals("window"))
this.isChild = false;
/*
this.rect = new RECT();
try {
@@ -250,6 +253,18 @@ public class WindowInfo {
*/
}
private void getProcessInfo()
{
if (pid == 0)
return;
char[] buffer = new char[1026];
Pointer process = Kernel32.instance.OpenProcess(Api.PROCESS_QUERY_INFORMATION | Api.PROCESS_VM_READ, false, new Pointer(pid));
Psapi.instance.GetModuleBaseNameW(process, null, buffer, 512);
processName = Native.toString(buffer);
Kernel32.instance.CloseHandle(new HANDLE(process));
is64bit = Api.isProcess64bit((int)pid);
}
public static String getRuntimeIdFromProperties(String enumProperties)
{

View File

@@ -195,6 +195,7 @@ public class WindowsEnumeratedXml implements Runnable{
if (!w.controlType.isEmpty())
win.setAttribute("type", w.controlType);
if (!w.isChild) {
//win.setAttribute("parent", "yes");
parentCount++;
if (w.processName != null && !w.processName.isEmpty()) {
if (!processList.containsKey(w.pid+""))
@@ -203,11 +204,20 @@ public class WindowsEnumeratedXml implements Runnable{
if (w.processName != null)
win.setAttribute("PROCESS", w.processName.toUpperCase());
}
if (w.pid != 0)
{
if (w.is64bit)
win.setAttribute("bits", "64");
else
win.setAttribute("bits", "32");
}
}
if (w.pid != 0)
win.setAttribute("pid", w.pid+"");
//else
//win.setAttribute("parent", w.parent + ""); // not really needed since child node is append to parent node
if (w.extra != null) {
for(String extraName: w.extra.keySet()) {
win.setAttribute(extraName, w.extra.get(extraName)+"");

View File

@@ -176,5 +176,23 @@ public class WindowsCommands extends BaseCommand {
return true;
}
public boolean cmdSendMessage(String[] args) {
if (!checkArgumentLength(args, 4))
return false;
WinPtr handle = findHandleWithXpath(args[0]); //xpath to HWND is first argument
if (handle.isEmpty())
return false;
int msg = Integer.parseInt(args[1]);
int id = Integer.parseInt(args[2]); //context menu id is supplied as second argument
int idLparam = Integer.parseInt(args[3]); //context menu id is supplied as second argument
handle.convertToNativeHwnd();
//LRESULT result =
//System.out.println("Send Message WM_COMMAND to " + handle.toString() + " PARAMS: " + id + ", " + idLparam);
//api.user32.PostMessage(handle.hWnd, Api.WM_COMMAND, new WPARAM(id), new LPARAM(0));
api.user32.SendMessage(handle.hWnd, msg, new WPARAM(id), new LPARAM(idLparam));
return true;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 852 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.