Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Jul 4th, 2005, 5:27 PM   #1
dc2000
Newbie
 
Join Date: Jun 2005
Location: Portland, OR
Posts: 12
Rep Power: 0 dc2000 is on a distinguished road
Windows Hook on Win9x system

Hi everyone:


I've reached a complete deadend trying to install a Windows hook on a Win9x system (Windows 95/98/Me). The following code works fine on any of the WinNT systems (Windows NT/2000/XP) but it does mysteriously nothing on neither of my Windows 95 or 98. Any help will be GREATLY appreciated!

Here's what this code is doing. It resides in a DLL, fnRunHook9x(...) is exported and called from the main app with two handles: one is a window handle to the main program and second is a window handle to collect info on (very much like PasswordSpy). fnRunHook9x once being loaded into a process space of the control (whose window handle it had received) retrieves it's module and image path, start-up parameters and returns it back to the main app. This functionality will be very useful on Win9x system as there are no APIs to retrieve module and image path, also start-up parameters by window handle if that window belongs to another process.

OK, now the code (I made it here as short as possible):


typedef struct _MY_SEND_DATA{	//Data is collected in a call to CollectData(...) from a hook proc
	TCHAR cmdLine[MAX_PATH];
	TCHAR modPath[MAX_PATH];
	TCHAR imgPath[MAX_PATH];
}MY_SEND_DATA, *LPMY_SEND_DATA;

typedef struct _MY_DATA{
	BOOL bRes;		//Set to TRUE if hook processed data
	HOOK hHook;		//Hook handle
	HWND hTgdWnd;		//Handle of target window
	HWND hCtlWnd;		//Main (control) window
	UINT uPrivMessage;	//Private message we trigger hook proc with
}MY_DATA, *LPMY_DATA;

//Global variables (loaded for each instance of DLL)
static MY_SEND_DATA MySendData = {0};
static HINSTANCE hDLLInst = NULL;
static HANDLE hFileMapping = NULL;
static MY_DATA* pMySharedMem = NULL;	//Pointer to shared memory segment


BOOL APIENTRY DllMain(HANDLE hModule, 
                      DWORD  ul_reason_for_call, 
                      LPVOID lpReserved)
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
		//Called once when this DLL is loaded and each time from SetWindowsHookEx(...)
		//in fnRunHook9x(...)
		hDLLInst = (HINSTANCE)hModule;

		//Open file mapping object
		pMySharedMem = NULL;
		hFileMapping = CreateFileMapping((HANDLE)INVALID_HANDLE_VALUE,
				NULL, PAGE_READWRITE, 0, sizeof(MY_DATA), _T("Name_My_File_Mapping_123"));
		if(hFileMapping)
		{
			//Map file into virtual memory
			pMySharedMem = (MY_MESSAGE_DATA1*)
				MapViewOfFile(hFileMapping, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(MY_DATA));
		}
		break;


	case DLL_PROCESS_DETACH:
		//Uninitialization of DLL
		if(pMySharedMem)
			UnmapViewOfFile(pMySharedMem);
		if(hFileMapping)
			CloseHandle(hFileMapping);
		break;
	}

    return TRUE;
}

WINIDHOOK_API BOOL fnRunHook9x(HWND hWndCaller, HWND hWndTarget)
{
	//EXPORTED -- called from the main (control) app
	//Installs and runs hook on Win9x system
	//(Sends data back in WM_COPYDATA message to hWndCaller window)
	//RETURN: - TRUE if success

	//Check if we have shared mem and it's accessible
	if(!pMySharedMem)
		return FALSE;
	if(IsBadReadPtr(pMySharedMem, sizeof(MY_DATA)) ||
		IsBadWritePtr(pMySharedMem, sizeof(MY_DATA)))
		return FALSE;

	//Get private message
	UINT uPrivateMsg = RegisterWindowMessage("My_Private_message_123");

	//Set up shared memory data
	pMySharedMem->bRes = FALSE;
	pMySharedMem->hTgdWnd = hWndTarget;
	pMySharedMem->hCtlWnd = hWndCaller;
	pMySharedMem->uPrivMessage = uPrivateMsg;

	//Set hook
	//(I'm using WH_CALLWNDPROCRET because of the way WH_CALLWNDPROC is called on Win9x:
	//See more details here: http://msdn.microsoft.com/library/de...allwndproc.asp)
	pMySharedMem->hHook = SetWindowsHookEx(WH_CALLWNDPROCRET, CallMyWndProc9x, hDLLInst, 
		GetWindowThreadProcessId(hWndTarget, NULL));

	if(!pMySharedMem->hHook)
		return FALSE;

	//Trigger hook with a message
	DWORD nMesRes;
	SendMessageTimeout(hWndTarget, uPrivateMsg, 0, 0,
		SMTO_ABORTIFHUNG | SMTO_NORMAL, 100, &nMesRes);

	//Check results
	BOOL bResult = pMySharedMem->bRes ? TRUE : FALSE;

	//Remove hook
	bResult &= UnhookWindowsHookEx(pMySharedMem->hHook);

	return bResult;
}


LRESULT CALLBACK CallMyWndProc9x(int nCode, WPARAM wParam, LPARAM lParam)
{
	//Hook callback procedure
	if(pMySharedMem)
	{
		//Only if we have pointer to shared memory
		CWPSTRUCT* pCwp = (CWPSTRUCT*)lParam;
		if(nCode == HC_ACTION)
		{
			if(pCwp)
				if(pCwp->message == pMySharedMem->uPrivMessage)
				{
					//Our hook -> Run data collecting routine
					CollectData(pMySharedMem);
					return 0;
				}
		}

		//Otherwise call next hook
		return CallNextHookEx(pMySharedMem->hHook, nCode, wParam, lParam);
	}
	else
	{
		//Lost shared memory
		ASSERT(NULL);
		return 0;
	}
}

void CollectData(MY_DATA* pSharedMem)
{
	//Collect data and send it back to the main app
	if(pSharedMem)
	{
		//Check if data is accessible in Shared mem
		if(IsBadReadPtr(pSharedMem, sizeof(MY_DATA)) ||
			IsBadWritePtr(&pSharedMem->bRes, sizeof(pSharedMem->bRes)))
			return;

		HWND hTrgWnd = pSharedMem->hTgdWnd;
		HWND hClrWnd = pSharedMem->hCtlWnd;

		//Get command line params
		LPTSTR pCmdLine = GetCommandLine();
		lstrcpyn(MySendData.cmdLine, pCmdLine ? pCmdLine : _T(""), MAX_PATH);

		//Get module path
		GetModuleFileName((HMODULE)GetClassLongPtr(hTrgWnd, GCLP_HMODULE), MySendData.modPath, MAX_PATH);

		//Get image path
		if(GetModuleFileName(NULL, MySendData.imgPath, MAX_PATH) == 0)
			MySendData.imgPath[0] = _T('\0');

		//Send data back
		COPYDATASTRUCT cds;
		cds.lpData = &MySendData;
		cds.dwData = 0x123;	//ID of the message
		cds.cbData = sizeof(MySendData);
		::SendMessage(hClrWnd, WM_COPYDATA, (WPARAM)hTrgWnd, (LPARAM)&cds);

		//Report success
		pSharedMem->bRes = TRUE;
	}
}
dc2000 is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 11:44 AM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC