API hook 技术

// hook.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <Windows.h>
#include <dbghelp.h>
#pragma comment( lib, "dbghelp.lib")

ULONG ReplaceIATEntryInOneMod( PCSTR pszCalleeModName,
							 PROC pfnCurent, PROC pfnNew, HMODULE hmodCaller)
{
	ULONG ulSize = 0;
	PIMAGE_IMPORT_DESCRIPTOR pImportDesc = ( PIMAGE_IMPORT_DESCRIPTOR )
		ImageDirectoryEntryToData( hmodCaller, TRUE,
		IMAGE_DIRECTORY_ENTRY_IMPORT, &ulSize );

	if ( NULL == pImportDesc )
		return 0;

	for ( ; pImportDesc->Name; pImportDesc++)
	{
		PSTR pszModName = (PSTR)
			((PBYTE)  hmodCaller + pImportDesc->Name );
		if ( 0 == lstrcmpiA( pszModName, pszCalleeModName) )
			break;
	}

	if ( 0 == pImportDesc->Name )
	{
		return 0;
	}

	PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA)
		((PBYTE) hmodCaller + pImportDesc->FirstThunk );
	for (; pThunk->u1.Function; pThunk++ )
	{
		PROC *ppfn = ( PROC *)&pThunk->u1.Function;

		BOOL bFound = (*ppfn == pfnCurent );
		if ( bFound )
		{
			MEMORY_BASIC_INFORMATION    mbi                = { 0 };
			VirtualQuery( pfnCurent, &mbi, sizeof(mbi) );
			DWORD dwOldProtect = 0;
			VirtualProtect( pfnCurent, sizeof(PROC), PAGE_READWRITE, &dwOldProtect );
			ULONG upfAddress = 0;
			ReadProcessMemory( GetCurrentProcess(),
				ppfn,
				&upfAddress,
				sizeof(PROC), 
				NULL );
			WriteProcessMemory( GetCurrentProcess(),
				ppfn,
				&pfnNew,
				sizeof(pfnNew),
				NULL );

			VirtualProtect( ppfn, sizeof(PROC), dwOldProtect, 0 );
			return upfAddress;
		}
	}


	return 0;
}

typedef int(
WINAPI
*PMyMessageBoxW)(
			  __in_opt HWND hWnd,
			  __in_opt LPCWSTR lpText,
			  __in_opt LPCWSTR lpCaption,
			  __in UINT uType);

PROC g_Proc = NULL;
int
WINAPI
MyMessageBoxW(
			__in_opt HWND hWnd,
			__in_opt LPCWSTR lpText,
			__in_opt LPCWSTR lpCaption,
			__in UINT uType)
{
	wprintf(L"%s\n", lpText );
	wprintf(L"%s\n", lpCaption );
	return ((PMyMessageBoxW)g_Proc)(
		hWnd,
		lpText,
		lpCaption,
		uType);
}
extern "C" IMAGE_DOS_HEADER __ImageBase;





int _tmain(int argc, _TCHAR* argv[])
{

	g_Proc = (PROC)ReplaceIATEntryInOneMod(
		"user32.dll", 
		(PROC)MessageBoxW, 
		(PROC)MyMessageBoxW, 
		(HMODULE)&__ImageBase);

	MessageBoxW(NULL, L"TEST", L"HOOK", MB_OK );

	return 0;
}

1. 在调用模块中的导入表中,查找调用函数,如果存在,那么就进行地址保护的修改


你可能感兴趣的:(api,null,import,hook,Descriptor,winapi)