您的位置:首页 > 其它

windows api hook

2011-04-26 10:28 447 查看
了解了一下 windows 下的 api hook,写了一个简单的测试程序,直接代码。



HookApi.h

#ifndef __HookApi_h__
#define __HookApi_h__

#ifdef	DLL_EXPORT
#define	DLLAPI	__declspec(dllexport)
#else
#define	DLLAPI	__declspec(dllimport)
#endif

#include <Windows.h>

#ifdef	__cplusplus
extern "C" {
#endif

	BOOL	DLLAPI	set_hook	( HMODULE hMod );
	BOOL	DLLAPI	remove_hook	();

#ifdef	__cplusplus
}
#endif

#endif // __HookApi_h__




HookApi.c

#define DLL_EXPORT
#include "HookApi.h"
#include <string.h>
#include <ImageHlp.h>
#include <TlHelp32.h>
#pragma comment( lib, "ImageHlp.lib" )

#pragma data_seg( "share" )
HINSTANCE		g_hInstance	= NULL;
HHOOK			g_hHook		= NULL;
HMODULE			g_hMod		= NULL;
#pragma data_seg()

#pragma comment( linker, "/section:share,RWS" )

//////////////////////////////////////////////////////////////////////////

BOOL	WINAPI		message_box_a	( HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType );
BOOL	WINAPI		message_box_w	( HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType );

BOOL	CALLBACK	hook_api	( const char *lpszModuleName, PROC procOrg, PROC procDst );
BOOL	CALLBACK	unhook_api	( const char *lpszModuleName, PROC procOrg, PROC procDst );

LRESULT CALLBACK	hook_proc	( UINT nCode, WPARAM wParam, LPARAM lParam );

//////////////////////////////////////////////////////////////////////////

int APIENTRY DllMain( HINSTANCE hInst, DWORD dwReason, LPVOID lpReserved )
{
	switch( dwReason ) {
		case DLL_PROCESS_ATTACH:
			g_hInstance = hInst;
			break;
		case DLL_PROCESS_DETACH:
			remove_hook();
			break;
		default:
			break;
	}
	return TRUE;
}

BOOL DLLAPI set_hook( HMODULE hMod )
{
	if( NULL == hMod || NULL != g_hHook )
		return FALSE;

	g_hMod = hMod;
	g_hHook = SetWindowsHookEx( WH_GETMESSAGE, (HOOKPROC)hook_proc, g_hInstance, 0 );
	if( NULL == g_hHook )
		return FALSE;

	hook_api( "User32.dll", GetProcAddress(GetModuleHandle("User32.dll"), "MessageBoxA"),
		(PROC)&message_box_a );
	hook_api( "User32.dll", GetProcAddress(GetModuleHandle("User32.dll"), "MessageBoxW"),
		(PROC)&message_box_w );

	return TRUE;
}

BOOL DLLAPI remove_hook()
{
	if( NULL == g_hMod || NULL == g_hHook )
		return FALSE;

	unhook_api( "User32.dll", GetProcAddress(GetModuleHandle("User32.dll"), "MessageBoxA"),
		(PROC)&message_box_a );
	unhook_api( "User32.dll", GetProcAddress(GetModuleHandle("User32.dll"), "MessageBoxW"),
		(PROC)&message_box_w );

	UnhookWindowsHookEx( g_hHook );
	g_hHook = NULL;
	g_hMod	= NULL;

	return TRUE;
}

LRESULT CALLBACK hook_proc( UINT nCode, WPARAM wParam, LPARAM lParam )
{
	return CallNextHookEx( g_hHook, nCode, wParam, lParam );
}

//////////////////////////////////////////////////////////////////////////

BOOL WINAPI message_box_a( HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType )
{
	const char *caption = "hooked caption";
	return MessageBoxA( hWnd, lpText, caption, uType );
}

BOOL WINAPI message_box_w( HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType )
{
	const wchar_t *caption = L"HOOKED CAPTION";
	return MessageBoxW( hWnd, lpText, caption, uType );
}

//////////////////////////////////////////////////////////////////////////

BOOL CALLBACK hook_api( const char *lpszModuleName, PROC procOrg, PROC procDst )
{
	char						*pszDllName		= NULL;
	IMAGE_DOS_HEADER			*pDosHeader		= NULL;
	IMAGE_OPTIONAL_HEADER		*pOptHeader		= NULL;
	IMAGE_IMPORT_DESCRIPTOR		*pImportDesc	= NULL;
	IMAGE_THUNK_DATA			*pThunk			= NULL;
	PROC						*lpAddr			= NULL;
	PROC						*lpNewAddr		= NULL;
	DWORD						dwOldProtect	= 0;
	MEMORY_BASIC_INFORMATION	mbi				= { 0 };

	if( NULL == lpszModuleName || NULL == procOrg || NULL == procDst || NULL == g_hMod )
		return FALSE;

	pDosHeader = (IMAGE_DOS_HEADER*)g_hMod;
	pOptHeader = (IMAGE_OPTIONAL_HEADER*)( (PBYTE)g_hMod + pDosHeader->e_lfanew + 24 );
	pImportDesc = (IMAGE_IMPORT_DESCRIPTOR*)( (PBYTE)g_hMod + pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress );

	while( pImportDesc->FirstThunk ) {
		pszDllName = (char*)( (PBYTE)g_hMod + pImportDesc->Name );
		if( 0 == _stricmp(pszDllName, lpszModuleName) )
			break;
		pImportDesc++;
	}

	if( pImportDesc->FirstThunk ) {
		pThunk = (IMAGE_THUNK_DATA*)( (PBYTE)g_hMod + pImportDesc->FirstThunk );
		while( pThunk->u1.Function ) {
			lpAddr = (PROC*)&(pThunk->u1.Function);
			if( *lpAddr == procOrg ) {
				VirtualQuery( lpAddr, &mbi, sizeof(mbi) );
				VirtualProtect( lpAddr, sizeof(PROC), PAGE_READWRITE, &dwOldProtect );
				lpNewAddr = (PROC*)&procDst;
				WriteProcessMemory( GetCurrentProcess(), lpAddr, lpNewAddr, sizeof(PROC), NULL );
				VirtualProtect( lpAddr, sizeof(PROC), dwOldProtect, 0 );
				return TRUE;
			}
			pThunk++;
		}
	}

	return FALSE;
}

BOOL CALLBACK unhook_api( const char *lpszModuleName, PROC procOrg, PROC procDst )
{
	PROC temp = procOrg;
	procOrg = procDst;
	procDst = temp;
	return hook_api( lpszModuleName, procOrg, procDst );
}




测试代码:

//
//	Hook
//
void CHookApiTestDlg::OnBnClickedHook()
{
	if( !set_hook(GetModuleHandle(NULL)) )
		AfxMessageBox( _T("set_hook() failed !") );
}

//
//	Unhook
//
void CHookApiTestDlg::OnBnClickedUnhook()
{
	remove_hook();
}

//
//	Test
//
void CHookApiTestDlg::OnBnClickedTest()
{
	::MessageBoxA( m_hWnd, "test string A", "caption", MB_OK );
	::MessageBoxW( m_hWnd, L"test string W", L"caption", MB_OK );
}






效果如下:





内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: