Win-specific: ScanPopup in 64-bit applications

This commit is contained in:
Abs62 2012-01-24 16:39:23 +04:00
parent fa60062fa4
commit c9192acef4
15 changed files with 509 additions and 106 deletions

View file

@ -281,10 +281,12 @@ SOURCES += folding.cc \
win32 {
SOURCES += mouseover_win32/ThTypes.c \
wordbyauto.cc \
guids.c
guids.c \
x64.cc
HEADERS += mouseover_win32/ThTypes.h \
wordbyauto.hh \
uiauto.hh
uiauto.hh \
x64.hh
}
RESOURCES += resources.qrc \
flags.qrc
@ -338,3 +340,5 @@ include( qtsingleapplication/src/qtsingleapplication.pri )

View file

@ -12,6 +12,7 @@
#include <aclapi.h>
#include "mouseover_win32/ThTypes.h"
#include "wordbyauto.hh"
#include "x64.hh"
#endif
MouseOver & MouseOver::instance()
@ -58,7 +59,6 @@ static void SetLowLabelToGDSynchroObjects()
BOOL fSaclDefaulted = FALSE;
LPCWSTR pwszMapFileName = L"GoldenDictTextOutHookSharedMem";
LPCWSTR pwszSpyMutexName = L"GoldenDictTextOutSpyMutex";
LPCWSTR pwszHookMutexName = L"GoldenDictTextOutHookMutex";
if( ConvertStringSecurityDescriptorToSecurityDescriptorW( LOW_INTEGRITY_SDDL_SACL_W, 1 /* SDDL_REVISION_1 */, &pSD, NULL ) )
{
@ -73,9 +73,6 @@ static void SetLowLabelToGDSynchroObjects()
dwErr = SetNamedSecurityInfoW( (LPWSTR)pwszSpyMutexName,
SE_KERNEL_OBJECT, LABEL_SECURITY_INFORMATION, NULL, NULL, NULL, pSacl);
dwErr = SetNamedSecurityInfoW( (LPWSTR)pwszHookMutexName,
SE_KERNEL_OBJECT, LABEL_SECURITY_INFORMATION, NULL, NULL, NULL, pSacl);
}
LocalFree(pSD);
}
@ -94,8 +91,9 @@ ChangeWindowMessageFilterExFunc changeWindowMessageFilterExFunc = NULL;
ThTypes_Init();
memset( GlobalData, 0, sizeof( TGlobalDLLData ) );
strcpy( GlobalData->LibName,
QDir::toNativeSeparators( QDir( QCoreApplication::applicationDirPath() ).filePath( "GdTextOutHook.dll" ) ).toLocal8Bit().data() );
// strcpy( GlobalData->LibName,
// QDir::toNativeSeparators( QDir( QCoreApplication::applicationDirPath() ).filePath( "GdTextOutHook.dll" ) ).toLocal8Bit().data() );
QDir::toNativeSeparators( QDir( QCoreApplication::applicationDirPath() ).filePath( "GdTextOutHook.dll" ) ).toWCharArray( GlobalData->LibName );
// Create the window to recive spying results to
@ -150,6 +148,7 @@ void MouseOver::enableMouseOver()
if ( !mouseOverEnabled && activateSpyFn )
{
activateSpyFn( true );
installx64Hooks();
mouseOverEnabled = true;
}
#endif
@ -161,6 +160,7 @@ void MouseOver::disableMouseOver()
if ( mouseOverEnabled && activateSpyFn )
{
activateSpyFn( false );
removex64Hooks();
mouseOverEnabled = false;
}
#endif
@ -338,7 +338,7 @@ MouseOver::~MouseOver()
UnregisterClass( className, GetModuleHandle( 0 ) );
Thtypes_End();
ThTypes_End();
#endif
}

View file

@ -50,17 +50,17 @@ static BOOL Is_XP_And_Later()
return (VER_PLATFORM_WIN32_NT == stOSVI.dwPlatformId && (5 < stOSVI.dwMajorVersion || (5 == stOSVI.dwMajorVersion && 1 <= stOSVI.dwMinorVersion)));
}
static char* ExtractWordFromRichEditPos(HWND WND, POINT Pt, int *BeginPos)
static char* ExtractWordFromRichEditPos(HWND WND, POINT Pt, DWORD *BeginPos)
{
return ExtractFromEverything(WND, Pt, BeginPos);
}
static char* ExtractWordFromEditPos(HWND hEdit, POINT Pt, int *BeginPos)
static char* ExtractWordFromEditPos(HWND hEdit, POINT Pt, DWORD *BeginPos)
{
return ExtractFromEverything(hEdit, Pt, BeginPos);
}
static char* ExtractWordFromIE(HWND WND, POINT Pt, int *BeginPos)
static char* ExtractWordFromIE(HWND WND, POINT Pt, DWORD *BeginPos)
{
return ExtractFromEverything(WND, Pt, BeginPos);
}
@ -116,7 +116,7 @@ static int GetWordFromConsolePack(TConsoleParams *params)
return WordLen;
}
static char* GetWordFromConsole(HWND WND, POINT Pt, int *BeginPos)
static char* GetWordFromConsole(HWND WND, POINT Pt, DWORD *BeginPos)
{
TConsoleParams *TP;
DWORD pid;
@ -169,9 +169,9 @@ static char* GetWordFromConsole(HWND WND, POINT Pt, int *BeginPos)
return Result;
}
char* TryGetWordFromAnyWindow(TKnownWndClass WndType, HWND WND, POINT Pt, int *BeginPos)
char* TryGetWordFromAnyWindow(TKnownWndClass WndType, HWND WND, POINT Pt, DWORD *BeginPos)
{
typedef char* (*GetWordFunction_t)(HWND, POINT, int*);
typedef char* (*GetWordFunction_t)(HWND, POINT, DWORD*);
const GetWordFunction_t GetWordFunction[]= {
ExtractFromEverything,
ExtractWordFromRichEditPos,

View file

@ -13,6 +13,6 @@ typedef enum TKnownWndClass {
} TKnownWndClass;
TKnownWndClass GetWindowType(HWND WND, const char* WNDClass);
char* TryGetWordFromAnyWindow(TKnownWndClass WndType, HWND WND, POINT Pt, int *BeginPos);
char* TryGetWordFromAnyWindow(TKnownWndClass WndType, HWND WND, POINT Pt, DWORD *BeginPos);
#endif

View file

@ -91,9 +91,9 @@ static BOOL HookImportFunction(HMODULE hModule, LPCSTR szImportModule, LPCSTR sz
if( !VirtualProtect(mbi_thunk.BaseAddress, mbi_thunk.RegionSize, PAGE_READWRITE, &mbi_thunk.Protect) )
return FALSE;
if (paOrigFuncs)
*paOrigFuncs = (PROC)InterlockedExchangePointer(&(pRealThunk->u1.Function), paHookFuncs);
*paOrigFuncs = (PROC)InterlockedExchangePointer((PVOID)&(pRealThunk->u1.Function), paHookFuncs);
else
InterlockedExchangePointer(&(pRealThunk->u1.Function), paHookFuncs);
InterlockedExchangePointer((PVOID)&(pRealThunk->u1.Function), paHookFuncs);
VirtualProtect(mbi_thunk.BaseAddress, mbi_thunk.RegionSize, mbi_thunk.Protect, &dwOldProtect);
return TRUE;

View file

@ -7,6 +7,10 @@
#include <oleacc.h>
#include <servprov.h>
#ifdef INTERFACE
#undef INTERFACE
#endif
#ifdef __cplusplus
extern "C" {
#endif

View file

@ -1,11 +1,14 @@
GCC:=gcc.exe -W -Wall -s -O2
GCC64:=x86_64-w64-mingw32-gcc.exe -W -Wall -s -O2
.PHONY: all clean
.PHONY: all x64 clean
all: GdTextOutHook.dll libGdTextOutHook.a GdTextOutSpy.dll libGdTextOutSpy.a
x64: x64helper.exe GdTextOutHook64.dll libGdTextOutHook64.a GdTextOutSpy64.dll libGdTextOutSpy64.a
clean:
rm -f *.o *.a *.dll
rm -f *.o *.a *.dll *.exe
TextOutHook.o: TextOutHook.c
$(GCC) -DBUILDING_DLL -c $<
@ -16,15 +19,6 @@ HookImportFunction.o: HookImportFunction.c
GetWord.o: GetWord.c
$(GCC) -c $<
IAccEx.o: IAccEx.c
$(GCC) -c $<
GetWordByIAccEx.o: GetWordByIAccEx.c
$(GCC) -c $<
guids.o: guids.c
$(GCC) -c $<
GdTextOutHook.dll libGdTextOutHook.a: TextOutHook.o HookImportFunction.o GetWord.o
$(GCC) -shared -o GdTextOutHook.dll $^ -lgdi32 -Wl,--out-implib,libGdTextOutHook.a
@ -34,5 +28,50 @@ TextOutSpy.o: TextOutSpy.c
ThTypes.o: ThTypes.c
$(GCC) -c $<
IAccEx.o: IAccEx.c
$(GCC) -c $<
GetWordByIAccEx.o: GetWordByIAccEx.c
$(GCC) -c $<
guids.o: guids.c
$(GCC) -c $<
GdTextOutSpy.dll libGdTextOutSpy.a: TextOutSpy.o ThTypes.o IAccEx.o guids.o GetWordByIAccEx.o
$(GCC) -shared -o GdTextOutSpy.dll $^ -lgdi32 -luuid -loleacc -loleaut32 -Wl,--out-implib,libGdTextOutSpy.a
x64helper.exe: x64hooks64.o ThTypes64.o
$(GCC64) -Wl,--subsystem,windows -mwindows -o $@ $^
x64hooks64.o: x64hooks.c
$(GCC64) -o $@ -c $<
TextOutHook64.o: TextOutHook.c
$(GCC64) -o $@ -DBUILDING_DLL -c $<
HookImportFunction64.o: HookImportFunction.c
$(GCC64) -o $@ -c $<
GetWord64.o: GetWord.c
$(GCC64) -o $@ -c $<
GdTextOutHook64.dll libGdTextOutHook64.a: TextOutHook64.o HookImportFunction64.o GetWord64.o
$(GCC64) -shared -o GdTextOutHook64.dll $^ -lgdi32 -Wl,--out-implib,libGdTextOutHook64.a
TextOutSpy64.o: TextOutSpy.c
$(GCC64) -o $@ -DBUILDING_DLL -c $<
ThTypes64.o: ThTypes.c
$(GCC64) -o $@ -c $<
IAccEx64.o: IAccEx.c
$(GCC64) -o $@ -c $<
GetWordByIAccEx64.o: GetWordByIAccEx.c
$(GCC64) -o $@ -c $<
guids64.o: guids.c
$(GCC64) -o $@ -c $<
GdTextOutSpy64.dll libGdTextOutSpy64.a: TextOutSpy64.o ThTypes64.o IAccEx64.o guids64.o GetWordByIAccEx64.o
$(GCC64) -shared -o GdTextOutSpy64.dll $^ -lgdi32 -luuid -loleacc -loleaut32 -Wl,--out-implib,libGdTextOutSpy64.a

View file

@ -11,13 +11,20 @@
#include "HookImportFunction.h"
typedef BOOL (WINAPI *TextOutANextHook_t)(HDC hdc, int nXStart, int nYStart, LPCSTR lpszString,int cbString);
TextOutANextHook_t TextOutANextHook __attribute__ ((aligned (4))) = NULL;
typedef BOOL (WINAPI *TextOutWNextHook_t)(HDC hdc, int nXStart, int nYStart, LPCWSTR lpszString,int cbString);
TextOutWNextHook_t TextOutWNextHook __attribute__ ((aligned (4))) = NULL;
typedef BOOL (WINAPI *ExtTextOutANextHook_t)(HDC hdc, int nXStart, int nYStart, UINT fuOptions, CONST RECT *lprc, LPCSTR lpszString, UINT cbString, CONST INT *lpDx);
ExtTextOutANextHook_t ExtTextOutANextHook __attribute__ ((aligned (4))) = NULL;
typedef BOOL (WINAPI *ExtTextOutWNextHook_t)(HDC hdc, int nXStart, int nYStart, UINT fuOptions, CONST RECT *lprc, LPCWSTR lpszString, UINT cbString, CONST INT *lpDx);
#ifdef __WIN64
TextOutANextHook_t TextOutANextHook __attribute__ ((aligned (8))) = NULL;
TextOutWNextHook_t TextOutWNextHook __attribute__ ((aligned (8))) = NULL;
ExtTextOutANextHook_t ExtTextOutANextHook __attribute__ ((aligned (8))) = NULL;
ExtTextOutWNextHook_t ExtTextOutWNextHook __attribute__ ((aligned (8))) = NULL;
#else
TextOutANextHook_t TextOutANextHook __attribute__ ((aligned (4))) = NULL;
TextOutWNextHook_t TextOutWNextHook __attribute__ ((aligned (4))) = NULL;
ExtTextOutANextHook_t ExtTextOutANextHook __attribute__ ((aligned (4))) = NULL;
ExtTextOutWNextHook_t ExtTextOutWNextHook __attribute__ ((aligned (4))) = NULL;
#endif
#define HOOKS_NUM 4
@ -192,7 +199,7 @@ static void GetWordTextOutHook (TEverythingParams *TP)
LeaveCriticalSection(&hookCS);
}
char* ExtractFromEverything(HWND WND, POINT Pt, int *BeginPos)
char* ExtractFromEverything(HWND WND, POINT Pt, DWORD *BeginPos)
{
TEverythingParams CParams;
@ -588,6 +595,8 @@ BOOL APIENTRY DllMain (HINSTANCE hInst /* Library instance handle. */ ,
DWORD reason /* Reason this function is being called. */ ,
LPVOID reserved /* Not used. */ )
{
(void) hInst;
(void) reserved;
switch (reason)
{
case DLL_PROCESS_ATTACH:

View file

@ -20,7 +20,7 @@ typedef struct TEverythingParams {
wchar_t MatchedWordW[256];
} TEverythingParams;
char* ExtractFromEverything(HWND WND, POINT Pt, int *BeginPos);
char* ExtractFromEverything(HWND WND, POINT Pt, DWORD *BeginPos);
DLLIMPORT void GetWord (TCurrentMode *P);

View file

@ -1,3 +1,5 @@
#include <tchar.h>
#include <windowsx.h>
#include "TextOutSpy.h"
#include "ThTypes.h"
#include "GDDataTranfer.h"
@ -31,17 +33,9 @@ HWND WndParent,WndChild;
static void SendWordToServer()
{
DWORD SendMsgAnswer, flags;
DWORD_PTR SendMsgAnswer;
DWORD flags;
LRESULT lr;
if (hGetWordLib == 0) {
hGetWordLib = LoadLibrary(GlobalData->LibName);
if (hGetWordLib) {
GetWordProc = (GetWordProc_t)GetProcAddress(hGetWordLib, "__gdGetWord");
}
else {
hGetWordLib = (HINSTANCE)-1;
}
}
if( !IsWindow( GlobalData->ServerWND ) )
return;
@ -51,10 +45,21 @@ LRESULT lr;
if( lr == 0 || SendMsgAnswer == 0) //No answer or no needing
return;
flags = SendMsgAnswer;
if (hGetWordLib == 0 && ( flags & GD_FLAG_METHOD_STANDARD ) ) {
hGetWordLib = LoadLibraryW(GlobalData->LibName);
if (hGetWordLib) {
GetWordProc = (GetWordProc_t)GetProcAddress(hGetWordLib, "__gdGetWord");
}
else {
hGetWordLib = INVALID_HANDLE_VALUE;
}
}
GlobalData->CurMod.MatchedWord[0] = 0;
GlobalData->CurMod.WordLen = 0;
GlobalData->CurMod.BeginPos = 0;
flags = SendMsgAnswer;
if( ( flags & GD_FLAG_METHOD_GD_MESSAGE ) != 0 && uGdAskMessage != 0 ) {
int n;
@ -71,8 +76,14 @@ LRESULT lr;
GlobalData->CurMod.WordLen = n;
GlobalData->CurMod.BeginPos = 0;
if(n > 0) {
if( IsWindow( GlobalData->ServerWND ) )
if( IsWindow( GlobalData->ServerWND ) ) {
#ifdef __WIN64
GlobalData32->CurMod.WordLen = n;
GlobalData32->CurMod.BeginPos = 0;
lstrcpyn( GlobalData32->CurMod.MatchedWord, GlobalData->CurMod.MatchedWord, sizeof( GlobalData32->CurMod.MatchedWord ) );
#endif
SendMessageTimeout(GlobalData->ServerWND, WM_MY_SHOW_TRANSLATION, 0, 0, SMTO_ABORTIFHUNG, MOUSEOVER_INTERVAL, &SendMsgAnswer);
}
}
return;
}
@ -81,10 +92,18 @@ LRESULT lr;
if( ( flags & GD_FLAG_METHOD_STANDARD ) != 0 && GetWordProc != 0 ) {
GlobalData->CurMod.WND = GlobalData->LastWND;
GlobalData->CurMod.Pt = GlobalData->LastPt;
GetWordProc(&(GlobalData->CurMod));
if (GlobalData->CurMod.WordLen > 0) {
if( IsWindow( GlobalData->ServerWND ) )
if( IsWindow( GlobalData->ServerWND ) ) {
#ifdef __WIN64
GlobalData32->CurMod.WordLen = GlobalData->CurMod.WordLen;
GlobalData32->CurMod.BeginPos = GlobalData->CurMod.BeginPos;
lstrcpyn( GlobalData32->CurMod.MatchedWord, GlobalData->CurMod.MatchedWord, sizeof( GlobalData32->CurMod.MatchedWord ) );
#endif
SendMessageTimeout(GlobalData->ServerWND, WM_MY_SHOW_TRANSLATION, 0, 0, SMTO_ABORTIFHUNG, MOUSEOVER_INTERVAL, &SendMsgAnswer);
}
return;
}
}
@ -92,8 +111,14 @@ LRESULT lr;
if( ( flags & GD_FLAG_METHOD_IACCESSIBLEEX ) != 0 ) {
getWordByAccEx( GlobalData->LastPt );
if (GlobalData->CurMod.WordLen > 0 ) {
if( IsWindow( GlobalData->ServerWND ) )
if( IsWindow( GlobalData->ServerWND ) ) {
#ifdef __WIN64
GlobalData32->CurMod.WordLen = GlobalData->CurMod.WordLen;
GlobalData32->CurMod.BeginPos = GlobalData->CurMod.BeginPos;
lstrcpyn( GlobalData32->CurMod.MatchedWord, GlobalData->CurMod.MatchedWord, sizeof( GlobalData32->CurMod.MatchedWord ) );
#endif
SendMessageTimeout(GlobalData->ServerWND, WM_MY_SHOW_TRANSLATION, 0, 0, SMTO_ABORTIFHUNG, MOUSEOVER_INTERVAL, &SendMsgAnswer);
}
return;
}
}
@ -103,8 +128,11 @@ LRESULT lr;
}
}
void CALLBACK TimerFunc(HWND hWnd,UINT nMsg,UINT nTimerid,DWORD dwTime)
void CALLBACK TimerFunc(HWND hWnd,UINT nMsg,UINT_PTR nTimerid,DWORD dwTime)
{
(void) hWnd;
(void) nMsg;
(void) dwTime;
DWORD wso;
wso = WaitForSingleObject(hSynhroMutex, 0);
if (wso == WAIT_OBJECT_0 || wso == WAIT_ABANDONED) {
@ -144,56 +172,93 @@ DWORD wso;
}
}
void HookProc( POINT *ppt )
{
HWND WND;
TCHAR wClassName[64];
DWORD winProcessID;
WND = GetWindowFromPoint( *ppt );
if(WND == NULL) return;
if ( !GetClassName(WND, wClassName, sizeof(wClassName) / sizeof(TCHAR)) )
return;
GetWindowThreadProcessId( WND, &winProcessID );
if( winProcessID != ourProcessID && lstrcmpi( wClassName, _T("ConsoleWindowClass") ) != 0 )
return;
if(TimerID && ( GlobalData->LastPt.x != ppt->x || GlobalData->LastPt.y != ppt->y ) )
{
KillTimer(0, TimerID);
TimerID = 0;
}
const char* DisableClasses[] = {
"gdkWindowChild",
"gdkWindowTemp",
"Progman",
"WorkerW",
};
int i;
for (i=0; i<4; i++) {
if (lstrcmp(wClassName, DisableClasses[i])==0)
break;
}
if (i<4) return;
if(GlobalData->LastPt.x != ppt->x || GlobalData->LastPt.y != ppt->y || GlobalData->LastWND != WND )
{
GlobalData->LastWND = WND;
GlobalData->LastPt = *ppt;
TimerID = SetTimer(0, TimerID, MOUSEOVER_INTERVAL, TimerFunc);
}
}
#ifdef __WIN64
LRESULT CALLBACK GetMessageHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
PMSG pMsg;
DWORD wso;
if( nCode == HC_ACTION && wParam == PM_REMOVE )
{
pMsg = (PMSG)lParam;
if( pMsg && ( pMsg->message == WM_MOUSEMOVE || pMsg->message == WM_NCMOUSEMOVE ) )
{
wso = WaitForSingleObject(hSynhroMutex, 0);
if (wso == WAIT_OBJECT_0 || wso == WAIT_ABANDONED)
{
POINT pt;
pt.x = GET_X_LPARAM( pMsg->lParam );
pt.y = GET_Y_LPARAM( pMsg->lParam );
if( pMsg->message == WM_MOUSEMOVE && pMsg->hwnd != NULL )
ClientToScreen( pMsg->hwnd, &pt );
HookProc( &pt );
ReleaseMutex(hSynhroMutex);
}
}
}
return CallNextHookEx(GlobalData->g_hHook, nCode, wParam, lParam);
}
#else
LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
DWORD wso;
if ((nCode == HC_ACTION) && ((wParam == WM_MOUSEMOVE) || (wParam == WM_NCMOUSEMOVE)) && (GlobalData != NULL)) {
if ( (nCode == HC_ACTION) && ((wParam == WM_MOUSEMOVE) || (wParam == WM_NCMOUSEMOVE)) ) {
wso = WaitForSingleObject(hSynhroMutex, 0);
if (wso == WAIT_OBJECT_0 || wso == WAIT_ABANDONED) {
HWND WND;
TCHAR wClassName[64];
if(TimerID && ( GlobalData->LastPt.x!=((PMOUSEHOOKSTRUCT)lParam)->pt.x || GlobalData->LastPt.y!=((PMOUSEHOOKSTRUCT)lParam)->pt.y ) ) {
KillTimer(0, TimerID);
TimerID = 0;
}
WND = GetWindowFromPoint(((PMOUSEHOOKSTRUCT)lParam)->pt);
if(WND == NULL) {
ReleaseMutex(hSynhroMutex);
return CallNextHookEx(GlobalData->g_hHookMouse, nCode, wParam, lParam);
}
if (GetClassName(WND, wClassName, sizeof(wClassName) / sizeof(TCHAR))) {
const char* DisableClasses[] = {
"gdkWindowChild",
"gdkWindowTemp",
"Progman",
"WorkerW",
};
int i;
for (i=0; i<4; i++) {
if (lstrcmp(wClassName, DisableClasses[i])==0)
break;
}
if (i<4) {
ReleaseMutex(hSynhroMutex);
return CallNextHookEx(GlobalData->g_hHookMouse, nCode, wParam, lParam);
}
}
if(GlobalData->LastPt.x!=((PMOUSEHOOKSTRUCT)lParam)->pt.x || GlobalData->LastPt.y!=((PMOUSEHOOKSTRUCT)lParam)->pt.y || GlobalData->LastWND != WND) {
GlobalData->LastWND = WND;
GlobalData->LastPt = ((PMOUSEHOOKSTRUCT)lParam)->pt;
TimerID = SetTimer(0, TimerID, MOUSEOVER_INTERVAL, TimerFunc);
}
HookProc( &(((PMOUSEHOOKSTRUCT)lParam)->pt) );
ReleaseMutex(hSynhroMutex);
}
}
return CallNextHookEx(GlobalData->g_hHookMouse, nCode, wParam, lParam);
return CallNextHookEx(GlobalData->g_hHook, nCode, wParam, lParam);
}
#endif
DLLIMPORT void ActivateTextOutSpying (int Activate)
{
// After call SetWindowsHookEx(), when you move mouse to a application's window,
@ -201,19 +266,23 @@ DLLIMPORT void ActivateTextOutSpying (int Activate)
// after call UnhookWindowsHookEx().
if(GlobalData == NULL) return;
if (Activate) {
if (GlobalData->g_hHookMouse != NULL) return;
GlobalData->g_hHookMouse = SetWindowsHookEx(WH_MOUSE, MouseHookProc, g_hInstance, 0);
if (GlobalData->g_hHook != NULL) return;
#ifdef __WIN64
GlobalData->g_hHook = SetWindowsHookEx(WH_GETMESSAGE, GetMessageHookProc, g_hInstance, 0);
#else
GlobalData->g_hHook = SetWindowsHookEx(WH_MOUSE, MouseHookProc, g_hInstance, 0);
#endif
}
else {
if (GlobalData->g_hHookMouse == NULL) return;
if (GlobalData->g_hHook == NULL) return;
WaitForSingleObject(hSynhroMutex, 2000);
UnhookWindowsHookEx(GlobalData->g_hHookMouse);
UnhookWindowsHookEx(GlobalData->g_hHook);
if (TimerID) {
KillTimer(0, TimerID);
TimerID=0;
}
ReleaseMutex(hSynhroMutex);
GlobalData->g_hHookMouse = NULL;
GlobalData->g_hHook = NULL;
}
}
@ -222,10 +291,20 @@ BOOL APIENTRY DllMain (HINSTANCE hInst /* Library instance handle. */ ,
DWORD reason /* Reason this function is being called. */ ,
LPVOID reserved /* Not used. */ )
{
(void) reserved;
switch (reason)
{
case DLL_PROCESS_ATTACH:
g_hInstance = hInst;
ThTypes_Init();
#ifdef __WIN64
if( GlobalData == NULL || GlobalData32 == NULL ) {
#else
if( GlobalData == NULL ) {
#endif
ThTypes_End();
return FALSE;
}
ourProcessID = GetCurrentProcessId();
if(hSynhroMutex==0) {
hSynhroMutex = CreateMutex(NULL, FALSE, "GoldenDictTextOutSpyMutex");
@ -233,7 +312,6 @@ BOOL APIENTRY DllMain (HINSTANCE hInst /* Library instance handle. */ ,
return(FALSE);
}
}
ThTypes_Init();
uGdAskMessage = RegisterWindowMessage(GD_MESSAGE_NAME);
FindGetPhysicalCursorPos();
break;
@ -254,10 +332,10 @@ BOOL APIENTRY DllMain (HINSTANCE hInst /* Library instance handle. */ ,
MSG msg ;
while (PeekMessage (&msg, 0, WM_TIMER, WM_TIMER, PM_REMOVE));
}
if ((hGetWordLib != 0)&&(hGetWordLib != (HINSTANCE)(-1))) {
if ( (hGetWordLib != 0) && (hGetWordLib != INVALID_HANDLE_VALUE) ) {
FreeLibrary(hGetWordLib);
}
Thtypes_End();
ThTypes_End();
break;
case DLL_THREAD_ATTACH:

View file

@ -3,19 +3,38 @@
HANDLE MMFHandle = 0;
TGlobalDLLData *GlobalData = NULL;
#ifdef __WIN64
HANDLE MMFHandle32 = 0;
TGlobalDLLData32 *GlobalData32 = NULL;
LPCSTR SHARE_NAME32 = "GoldenDictTextOutHookSharedMem";
LPCSTR SHARE_NAME = "GoldenDictTextOutHookSharedMem64";
#else
LPCSTR SHARE_NAME = "GoldenDictTextOutHookSharedMem";
#endif
void ThTypes_Init()
{
if (!MMFHandle) {
MMFHandle = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(TGlobalDLLData), "GoldenDictTextOutHookSharedMem");
MMFHandle = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(TGlobalDLLData), SHARE_NAME);
}
if (!MMFHandle) {
MMFHandle = OpenFileMappingA(FILE_MAP_READ | FILE_MAP_WRITE, 0, "GoldenDictTextOutHookSharedMem");
MMFHandle = OpenFileMappingA(FILE_MAP_READ | FILE_MAP_WRITE, 0, SHARE_NAME);
}
if (!GlobalData && MMFHandle != NULL)
GlobalData = MapViewOfFile(MMFHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
#ifdef __WIN64
if (!MMFHandle32) {
MMFHandle32 = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(TGlobalDLLData32), SHARE_NAME32);
}
if (!MMFHandle32) {
MMFHandle32 = OpenFileMappingA(FILE_MAP_READ | FILE_MAP_WRITE, 0, SHARE_NAME32);
}
if (!GlobalData32 && MMFHandle32 != NULL)
GlobalData32 = MapViewOfFile(MMFHandle32, FILE_MAP_ALL_ACCESS, 0, 0, 0);
#endif
}
void Thtypes_End()
void ThTypes_End()
{
if (GlobalData) {
UnmapViewOfFile(GlobalData);
@ -25,4 +44,14 @@ void Thtypes_End()
CloseHandle(MMFHandle);
MMFHandle = 0;
}
#ifdef __WIN64
if (GlobalData32) {
UnmapViewOfFile(GlobalData32);
GlobalData32 = NULL;
}
if (MMFHandle32) {
CloseHandle(MMFHandle32);
MMFHandle32 = 0;
}
#endif
}

View file

@ -13,29 +13,58 @@ extern "C"
{
#endif /* __cplusplus */
#pragma pack(push,4)
typedef struct TCurrentMode {
HWND WND;
POINT Pt;
size_t WordLen;
DWORD WordLen;
char MatchedWord[256];
int BeginPos;
DWORD BeginPos;
} TCurrentMode;
typedef struct TGlobalDLLData {
HWND ServerWND;
HHOOK g_hHookMouse;
UINT_PTR TimerID;
HHOOK g_hHook;
HWND LastWND;
POINT LastPt;
TCurrentMode CurMod;
char LibName[256];
WCHAR LibName[256];
} TGlobalDLLData;
#pragma pack(pop)
extern TGlobalDLLData *GlobalData;
#ifdef __WIN64
#pragma pack(push,4)
typedef struct TCurrentMode32 {
DWORD WND;
POINT Pt;
DWORD WordLen;
char MatchedWord[256];
DWORD BeginPos;
} TCurrentMode32;
typedef struct TGlobalDLLData32 {
DWORD ServerWND;
DWORD g_hHook;
DWORD LastWND;
POINT LastPt;
TCurrentMode32 CurMod;
WCHAR LibName[256];
} TGlobalDLLData32;
#pragma pack(pop)
extern TGlobalDLLData32 *GlobalData32;
#endif
void ThTypes_Init();
void Thtypes_End();
void ThTypes_End();
#ifdef __cplusplus
}

140
mouseover_win32/x64hooks.c Normal file
View file

@ -0,0 +1,140 @@
#define UNICODE
#define _UNICODE
#include <Windows.h>
#include <Tlhelp32.h>
#include <tchar.h>
#include <sddl.h>
#include <accctrl.h>
#include <aclapi.h>
#include <basetsd.h>
#include "thtypes.h"
typedef void ( *ActivateSpyFn )( BOOL );
BOOL parentIsGD()
{
HANDLE hSnapshot, hModuleSnapshot;
PROCESSENTRY32 pe;
MODULEENTRY32 me;
DWORD procID;
BOOL b;
procID = GetCurrentProcessId();
hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
if( hSnapshot == INVALID_HANDLE_VALUE )
return FALSE;
ZeroMemory( &pe, sizeof(pe) );
pe.dwSize = sizeof(pe);
b = Process32First( hSnapshot, &pe );
while(b) {
if( pe.th32ProcessID == procID ) {
hModuleSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, pe.th32ParentProcessID );
if( hModuleSnapshot == INVALID_HANDLE_VALUE ) {
b = FALSE;
break;
}
ZeroMemory( &me, sizeof(me) );
me.dwSize = sizeof(me);
b = Module32First( hModuleSnapshot, &me );
if( b ) {
int n = lstrlen( me.szExePath );
b = n >= 14 && lstrcmpi( me.szExePath + n - 14, _T("GoldenDict.exe") ) == 0;
}
CloseHandle( hModuleSnapshot );
break;
}
b = Process32Next( hSnapshot, &pe );
}
CloseHandle( hSnapshot );
return b;
}
void SetLowLabelToGDSynchroObjects()
{
// The LABEL_SECURITY_INFORMATION SDDL SACL to be set for low integrity
#define LOW_INTEGRITY_SDDL_SACL_W L"S:(ML;;NW;;;LW)"
PSECURITY_DESCRIPTOR pSD = NULL;
PACL pSacl = NULL; // not allocated
BOOL fSaclPresent = FALSE;
BOOL fSaclDefaulted = FALSE;
LPCWSTR pwszMapFileName = L"GoldenDictTextOutHookSharedMem64";
if( ConvertStringSecurityDescriptorToSecurityDescriptorW( LOW_INTEGRITY_SDDL_SACL_W, 1 /* SDDL_REVISION_1 */, &pSD, NULL ) )
{
if( GetSecurityDescriptorSacl(pSD, &fSaclPresent, &pSacl, &fSaclDefaulted))
{
// Note that psidOwner, psidGroup, and pDacl are
// all NULL and set the new LABEL_SECURITY_INFORMATION
SetNamedSecurityInfoW( (LPWSTR)pwszMapFileName, SE_KERNEL_OBJECT, LABEL_SECURITY_INFORMATION, NULL, NULL, NULL, pSacl);
}
LocalFree(pSD);
}
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
(void) hInstance;
(void) hPrevInstance;
(void) lpCmdLine;
(void) nCmdShow;
TCHAR dir[MAX_PATH], libName[MAX_PATH], *pch;
HWND hServerWnd;
ActivateSpyFn activateSpyFn = NULL;
HINSTANCE spyDll = NULL;
int ret = -1;
MSG msg;
if( !parentIsGD() )
return -1;
while( 1 ) {
ThTypes_Init();
if( GlobalData == NULL || GlobalData32 == NULL)
break;
hServerWnd = LongToHandle( GlobalData32->ServerWND );
GetModuleFileName( NULL, dir, MAX_PATH );
pch = dir + lstrlen( dir );
while( pch != dir && *pch != '\\' ) pch--;
*(pch + 1) = 0;
lstrcpy( libName, dir );
lstrcat( libName, _T("GdTextOutSpy64.dll") );
SetLowLabelToGDSynchroObjects();
memset( GlobalData, 0, sizeof( TGlobalDLLData ) );
lstrcpy( GlobalData->LibName, dir );
lstrcat( GlobalData->LibName, _T("GdTextOutHook64.dll") );
GlobalData->ServerWND = hServerWnd;
spyDll = LoadLibrary( libName );
if ( spyDll )
activateSpyFn = ( ActivateSpyFn ) GetProcAddress( spyDll, "ActivateTextOutSpying" );
if( !activateSpyFn ) {
ret = -2;
break;
}
activateSpyFn( TRUE );
while( GetMessage( &msg, 0, 0, 0 ) )
DispatchMessage( &msg );
activateSpyFn( FALSE );
ret = 0;
break;
}
if( spyDll )
FreeLibrary( spyDll );
ThTypes_End();
return ret;
}

63
x64.cc Normal file
View file

@ -0,0 +1,63 @@
#include <QCoreApplication>
#include <QDir>
#ifndef _UNICODE
#define _UNICODE
#endif
#include "x64.hh"
#include <windows.h>
#include <tchar.h>
typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
PROCESS_INFORMATION pInfo;
bool isWow64()
{
static LPFN_ISWOW64PROCESS fnIsWow64Process;
BOOL bIsWow64 = FALSE;
if( NULL == fnIsWow64Process )
fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress( GetModuleHandle( _T("kernel32") ), "IsWow64Process" );
if( NULL != fnIsWow64Process )
{
if ( !fnIsWow64Process( GetCurrentProcess(), &bIsWow64 ) )
return false;
}
return bIsWow64;
}
bool installx64Hooks()
{
STARTUPINFO startup;
if( !isWow64() )
return false;
if( pInfo.hProcess != NULL )
removex64Hooks();
QDir dir = QCoreApplication::applicationDirPath();
if( !dir.cd("x64") )
return false;
QString starterProc = QDir::toNativeSeparators( dir.filePath( "x64helper.exe" ) );
memset( &startup, 0, sizeof(startup) );
startup.cb = sizeof(startup);
BOOL b = CreateProcess( starterProc.toStdWString().c_str(), NULL, NULL, NULL, FALSE, CREATE_NO_WINDOW | DETACHED_PROCESS, NULL, NULL, &startup, &pInfo );
if( !b )
pInfo.hProcess = NULL;
return b;
}
void removex64Hooks()
{
if( pInfo.hProcess == NULL )
return;
PostThreadMessage( pInfo.dwThreadId, WM_QUIT, 0, 0 );
DWORD res = WaitForSingleObject( pInfo.hProcess, 3000 );
if( res == WAIT_TIMEOUT )
TerminateProcess( pInfo.hProcess, 1 );
CloseHandle( pInfo.hProcess );
CloseHandle( pInfo.hThread );
pInfo.hProcess = NULL;
}

8
x64.hh Normal file
View file

@ -0,0 +1,8 @@
#ifndef __X64_HH_INCLUDED__
#define __X64_HH_INCLUDED__
bool isWow64();
bool installx64Hooks();
void removex64Hooks();
#endif // __X64_HH_INCLUDED__