Windows API Inline Hook示例(api钩子)

基于x86和amd64,用c++和vs开发的,兼容32位和64位的inline hook例子。

原理很简单,主要是分析机器跳转指令、指令插桩和替换,实现api劫持。

具体做法是:修改导入表函数入口指令,重新计算偏移地址,跳转到自己的函数接口地址。

略微有点意思,有兴趣的自己研究吧。

主要是留个纪念,省的丢了,用的时候乱巴拉,啥也找不到。

废话不说,示例代码如下:

	GetLogicalDrivesOld = (ptrGetLogicalDrives)hook(GetLogicalDrives, GetLogicalDrivesNew);
	FindFirstVolumeWOld = (ptrFindFirstVolumeW)hook(FindFirstVolumeW, FindFirstVolumeWNew);
	FindNextVolumeWOld = (ptrFindNextVolumeW)hook(FindNextVolumeW, FindNextVolumeWNew);
	GetLogicalDriveStringsWOld = (ptrGetLogicalDriveStringsW)hook(GetLogicalDriveStringsW, GetLogicalDriveStringsWNew);
	lpGetVolumeInformationWOld = (ptrGetVolumeInformationW)hook(GetVolumeInformationW, lpGetVolumeInformationWNew);

源码如下所示。

头文件:

#pragma once

#include <windows.h>

#define MAX_TRAMP_SIZE					128
#define TRAMP_BAR_LIMIT					128

#pragma pack(1)

typedef struct  
{
	unsigned char* oldaddr;
	char len;
}REPLACE_CODE;

typedef struct  _HOOK_TRAMPS
{
	_HOOK_TRAMPS * prev;
	_HOOK_TRAMPS * next;
	int valid;
	WCHAR apiName[32];
	//int apiTotal;
	
	BYTE code[MAX_TRAMP_SIZE];

	BYTE oldcode[MAX_TRAMP_SIZE];
	REPLACE_CODE replace;

}HOOK_TRAMPS;

#pragma pack()

//extern HOOK_TRAMPS *g_trump;

//extern HOOK_TRAMPS g_trump[MAX_TRAMP_SIZE];

HOOK_TRAMPS* searchTrump(const WCHAR* funcname);

int deleteTrump(const WCHAR* funcname);

HOOK_TRAMPS* addTrump(const WCHAR* funcname);

extern "C" __declspec(dllexport) int hook2(const WCHAR* modulename,const WCHAR* funcname, BYTE * newfuncaddr, PROC* keepaddr);

extern "C" __declspec(dllexport) int inlinehook64(BYTE * newfun, BYTE * oldfun, PROC* keepaddr, const WCHAR * funcname);

extern "C" __declspec(dllexport) int inlinehook32(BYTE * newfun, BYTE * oldfun, PROC* keepaddr, const WCHAR * funcname);

int unhook(CONST WCHAR* modulename, const WCHAR* wstrfuncname);

int  unhookall();

代码文件:


#include "functions.h"
#include "hookApi.h"
#include "log.h"

HOOK_TRAMPS g_trump[MAX_TRAMP_SIZE] = { 0 };

HOOK_TRAMPS* searchTrump(const WCHAR* funcname) {

	for (int i = 0; i < TRAMP_BAR_LIMIT; i++)
	{
		if (g_trump[i].valid)
		{
			if (lstrcmpiW(funcname, g_trump[i].apiName) == 0)
			{
				return &g_trump[i];
			}
		}
	}

	return 0;
}



int deleteTrump(const WCHAR* funcname) {
	for (int i = 0; i < TRAMP_BAR_LIMIT; i++)
	{
		if (g_trump[i].valid)
		{
			if (lstrcmpiW(funcname, g_trump[i].apiName) == 0)
			{
				g_trump[i].valid = FALSE;
				return TRUE;
			}
		}
	}
	return 0;
}



HOOK_TRAMPS* addTrump(const WCHAR* funcname) {
	int result = 0;
	for (int i = 0; i < MAX_TRAMP_SIZE; i++)
	{
		if (g_trump[i].valid == FALSE)
		{
			g_trump[i].valid = TRUE;
			lstrcpyW(g_trump[i].apiName, funcname);
			DWORD oldprotect = 0;
			result = VirtualProtect(&g_trump[i], sizeof(HOOK_TRAMPS), PAGE_EXECUTE_READWRITE, &oldprotect);
			return &g_trump[i];
		}
	}
	return 0;
}

#ifdef _WIN64
#include "hde/hde64.h"

#define ADDRESS64_HIGI_MASK				0xffffffff00000000L

#define ADDRESS64_LOW_MASK				0xffffffffL

#define AMD64_INLINE_HOOK_STUB_SIZE		14

int inlinehook64(BYTE* newfun, BYTE* hookaddr, PROC* keepaddr, const WCHAR* funcname) {
	int result = 0;

	if (hookaddr == newfun)
	{
		log(L"inlinehook64 function:%ws already exist\r\n", funcname);
		return FALSE;
	}

	HOOK_TRAMPS* trump = addTrump(funcname);
	if (trump <= 0)
	{
		log(L"inlinehook64 addTrump function:%ws error\r\n", funcname);
		return FALSE;
	}

	//DebugBreak();

	ULONGLONG offset = 0;

	int codelen = 0;

	BYTE* oldcode = hookaddr;

	BYTE* oldfun = oldcode;

	int total = 0;

	ULONGLONG minimum = AMD64_INLINE_HOOK_STUB_SIZE;

	hde64s asm64 = { 0 };

	while (codelen < minimum)
	{
		int instructionlen = hde64_disasm(oldfun, &asm64);
		if (instructionlen <= 0)
		{
			log(L"inlinehook64 function:%ws address:%p hde64_disasm error\r\n", funcname, oldfun);
			deleteTrump(funcname);
			return FALSE;
		}

		if (total == 0)
		{
			if ((*oldfun == 0xff && *(oldfun + 1) == 0x25) || (*oldfun == 0xff && *(oldfun + 1) == 0x15))
			{
				offset = *(DWORD*)(oldfun + 2);
				offset = ((offset + 6 + (ULONGLONG)oldfun) & ADDRESS64_LOW_MASK) + ((ULONGLONG)oldfun & ADDRESS64_HIGI_MASK);
				offset = *(ULONGLONG*)offset;
				oldfun = (BYTE*)(offset);
				oldcode = oldfun;
				codelen = 0;

				continue;
			}
			else if ((*oldfun == 0x48 && *(oldfun + 1) == 0xff && *(oldfun + 2) == 0x25) ||
				(*oldfun == 0x48 && *(oldfun + 1) == 0xff && *(oldfun + 2) == 0x15))
			{
				offset = *(DWORD*)(oldfun + 3);
				offset = ((offset + 7 + (ULONGLONG)oldfun) & ADDRESS64_LOW_MASK) + ((ULONGLONG)oldfun & ADDRESS64_HIGI_MASK);
				offset = *(ULONGLONG*)offset;
				oldfun = (BYTE*)(offset);
				oldcode = oldfun;
				codelen = 0;
				continue;
			}
			else if (*oldfun == 0xeb)
			{
				offset = *(oldfun + 1);
				oldfun = (BYTE*)((offset + 2 + (ULONGLONG)oldfun) & ADDRESS64_LOW_MASK) + ((ULONGLONG)oldfun & ADDRESS64_HIGI_MASK);
				oldcode = oldfun;
				codelen = 0;
				continue;
			}
			else if (*oldfun == 0xe9 || *oldfun == 0xe8)		//if hooked by others ,how to find lost 5 bytes?
			{
				offset = *(DWORD*)(oldfun + 1);
				oldfun = (BYTE*)(((ULONGLONG)oldfun + 5 + offset) & ADDRESS64_LOW_MASK) + ((ULONGLONG)oldfun & ADDRESS64_HIGI_MASK);

				oldcode = oldfun;
				codelen = 0;
				continue;
			}

			else if (*oldfun == 0x83 && *(oldfun + 1) == 0x3d)
				//0000000180026130 83 3D 35 C8 08 00 05                    cmp     cs:?g_systemCallFilterId@@3KA, 5
				//0000000180026137 74 0C                                   jz      short loc_180026145
			{
				memcpy(trump->code + codelen, oldfun, instructionlen);

				offset = *(DWORD*)(oldfun + 2);

				ULONGLONG offsetlow = ((offset + 7 + (ULONGLONG)oldfun) & ADDRESS64_LOW_MASK);
				ULONGLONG offsethigh = ((ULONGLONG)oldfun & ADDRESS64_HIGI_MASK);

				ULONGLONG delta = (offsetlow - ((ULONGLONG)trump->code + codelen + instructionlen)) & ADDRESS64_LOW_MASK;
				*(DWORD*)(trump->code + codelen + 2) = (DWORD)delta;
			}
			else {
				memcpy(trump->code + codelen, oldfun, instructionlen);
			}
		}
		else {

			if ((*oldfun == 0xff && *(oldfun + 1) == 0x25) || (*oldfun == 0xff && *(oldfun + 1) == 0x15))
			{
				memcpy(trump->code + codelen, oldfun, instructionlen);

				offset = *(DWORD*)(oldfun + 2);

				ULONGLONG offsetlow = ((offset + 6 + (ULONGLONG)oldfun) & ADDRESS64_LOW_MASK);
				ULONGLONG offsethigh = ((ULONGLONG)oldfun & ADDRESS64_HIGI_MASK);

				ULONGLONG delta = (offsetlow - ((ULONGLONG)trump->code + codelen + instructionlen)) & ADDRESS64_LOW_MASK;
				*(DWORD*)(trump->code + codelen + 2) = (DWORD)delta;

			}
			else if (*oldfun == 0x83 && *(oldfun + 1) == 0x3d)
				//GetDC in user32.dll in win10 and win11 x64
				//0000000180026130 83 3D 35 C8 08 00 05                    cmp     cs:?g_systemCallFilterId@@3KA, 5
				//0000000180026137 74 0C                                   jz      short loc_180026145
			{
				memcpy(trump->code + codelen, oldfun, instructionlen);

				offset = *(DWORD*)(oldfun + 2);

				ULONGLONG offsetlow = ((offset + 7 + (ULONGLONG)oldfun) & ADDRESS64_LOW_MASK);
				ULONGLONG offsethigh = ((ULONGLONG)oldfun & ADDRESS64_HIGI_MASK);

				ULONGLONG delta = (offsetlow - ((ULONGLONG)trump->code + codelen + instructionlen)) & ADDRESS64_LOW_MASK;
				*(DWORD*)(trump->code + codelen + 2) = (DWORD)delta;
			}
			else if (*oldfun == 0x48 && *(oldfun + 1) == 0x8b && *(oldfun + 2) == 0x05)
				//OpenPrinterW in win10 and win11 x64,winspool.drv
				//0000000180003294 48 8B 05 E5 30 07 00		mov     rax, cs:qword_180076380
				//000000018000329B 
			{
				memcpy(trump->code + codelen, oldfun, instructionlen);

				offset = *(DWORD*)(oldfun + 3);

				ULONGLONG offsetlow = ((offset + 7 + (ULONGLONG)oldfun) & ADDRESS64_LOW_MASK);
				ULONGLONG offsethigh = ((ULONGLONG)oldfun & ADDRESS64_HIGI_MASK);

				ULONGLONG delta = (offsetlow - ((ULONGLONG)trump->code + codelen + instructionlen)) & ADDRESS64_LOW_MASK;
				*(DWORD*)(trump->code + codelen + 3) = (DWORD)delta;
			}
			else if ((*oldfun == 0x48 && *(oldfun + 1) == 0xff && *(oldfun + 2) == 0x25) ||
				(*oldfun == 0x48 && *(oldfun + 1) == 0xff && *(oldfun + 2) == 0x15))
			{
				memcpy(trump->code + codelen, oldfun, instructionlen);

				offset = *(DWORD*)(oldfun + 3);
				ULONGLONG offsetlow = ((offset + 7 + (ULONGLONG)oldfun) & ADDRESS64_LOW_MASK);
				ULONGLONG offsethigh = ((ULONGLONG)oldfun & ADDRESS64_HIGI_MASK);

				ULONGLONG delta = (offsetlow - ((ULONGLONG)trump->code + codelen + instructionlen)) & ADDRESS64_LOW_MASK;
				*(DWORD*)(trump->code + codelen + 3) = (DWORD)delta;
			}
			else if (*oldfun == 0xe9 || *oldfun == 0xe8 || *oldfun == 0xea)		//if hooked by others ,how to find lost 5 bytes?
			{
				memcpy(trump->code + codelen, oldfun, instructionlen);

				offset = *(DWORD*)(oldfun + 1);
				ULONGLONG offsetlow = ((offset + 5 + (ULONGLONG)oldfun) & ADDRESS64_LOW_MASK);
				ULONGLONG offsethigh = ((ULONGLONG)oldfun & ADDRESS64_HIGI_MASK);

				ULONGLONG delta = (offsetlow - ((ULONGLONG)trump->code + codelen + instructionlen)) & ADDRESS64_LOW_MASK;
				*(DWORD*)(trump->code + codelen + 1) = (DWORD)delta;
			}
			else if (*oldfun == 0xeb)
			{
				offset = *(oldfun + 1);
				byte* next_instruction = (BYTE*)((offset + 2 + (ULONGLONG)oldfun) & ADDRESS64_LOW_MASK) + ((ULONGLONG)oldfun & ADDRESS64_HIGI_MASK);
				minimum = next_instruction - oldcode + 1;
				if (minimum > MAX_TRAMP_SIZE - AMD64_INLINE_HOOK_STUB_SIZE || minimum <= 0)
				{
					log(L"inlinehook64 function:%ws jump to target address:%p out of range on base:%p\r\n", funcname, oldfun, oldcode);
					deleteTrump(funcname);
					return FALSE;
				}
				memcpy(trump->code + codelen, oldfun, instructionlen);
			}
			else if (*oldfun == 0x0f && (*(oldfun + 1) >= 0x80 && *(oldfun + 1) <= 0x8f))
			{
				log(L"inlinehook64 function:%ws address:%p found irregular jump instruction: %02x %02x\r\n", funcname, oldfun, *oldfun, *(oldfun + 1));

				memcpy(trump->code + codelen, oldfun, instructionlen);

				offset = *(WORD*)(oldfun + 2);
				byte* next_instruction = (BYTE*)((offset + 4 + (ULONGLONG)oldfun) & ADDRESS64_LOW_MASK) + ((ULONGLONG)oldfun & ADDRESS64_HIGI_MASK);

				minimum = next_instruction - oldcode + 1;
				if (minimum > MAX_TRAMP_SIZE - AMD64_INLINE_HOOK_STUB_SIZE || minimum <= 0)
				{
					log(L"inlinehook64 function:%ws jump to target address:%p out of range on base:%p\r\n", funcname, oldfun, oldcode);
					deleteTrump(funcname);
					return FALSE;
				}

				//oldfun = oldfun + 4;
			}
			else if (*oldfun >= 0x70 && *oldfun <= 0x7f)		//jump with flag range in 128 bytes
			{
				memcpy(trump->code + codelen, oldfun, instructionlen);

				offset = *(oldfun + 1);

				byte* next_instruction = oldfun + 2 + offset;

				minimum = next_instruction - oldcode + 1;
				if (minimum > MAX_TRAMP_SIZE - AMD64_INLINE_HOOK_STUB_SIZE || minimum <= 0)
				{
					log(L"inlinehook64 function:%ws jump to target address:%p out of range on base:%p\r\n", funcname, oldfun, oldcode);
					deleteTrump(funcname);
					return FALSE;
				}
				//oldfun += 2;
			}
			// 			else if (*oldfun == 0xc3 )
			// 			{
			// 
			// 			}
			else {
				memcpy(trump->code + codelen, oldfun, instructionlen);
			}
		}

		total++;
		if (total >= 1024)
		{
			log(L"inlinehook64 function:%ws something error!\r\n", funcname);
			//__debugbreak();
			return FALSE;
		}
		codelen += instructionlen;
		oldfun += instructionlen;
	}

	DWORD oldprotect = 0;
	result = VirtualProtect(oldcode, codelen, PAGE_EXECUTE_READWRITE, &oldprotect);
	if (result == 0)
	{
		log(L"inlinehook64 VirtualProtect function:%ws address:%p error\r\n", funcname, oldcode);
		deleteTrump(funcname);
		return FALSE;
	}

	memcpy(trump->oldcode, oldcode, codelen);

	oldcode[0] = 0xff;
	oldcode[1] = 0x25;
	*(DWORD*)(oldcode + 2) = 0;
	*(ULONGLONG*)(oldcode + 6) = (ULONGLONG)newfun;

	trump->code[codelen] = 0xff;
	trump->code[codelen + 1] = 0x25;
	*(DWORD*)(trump->code + codelen + 2) = 0;
	*(ULONGLONG*)(trump->code + codelen + 6) = (ULONGLONG)(oldcode + codelen);

	*keepaddr = (FARPROC) & (trump->code);

	DWORD dummyprotect = 0;
	result = VirtualProtect(oldcode, codelen, oldprotect, &dummyprotect);

	trump->replace.oldaddr = oldcode;
	trump->replace.len = codelen;


	log(L"inlinehook64 function:%ws, hook size:%d ,tramp address:%p, instruction address:%p,new func address:%p,keep address:%p",
		funcname, codelen, trump->code, oldcode, newfun, *keepaddr);
	WCHAR szout[1024];
	WCHAR* loginfo = szout;
	int len = 0;

	for (int i = 0; i < 14; i++)
	{
		len = wsprintfW(loginfo, L" %02X ", *(oldcode + i));
		loginfo = loginfo + len;
	}
	*loginfo = 0;
	log(szout);

	loginfo = szout;
	for (int i = 0; i < codelen + 14; i++)
	{
		len = wsprintfW(loginfo, L" %02X ", *(trump->code + i));
		loginfo = loginfo + len;
	}
	*loginfo = 0;
	log(szout);

	return result;
}
#else
#include "hde/hde32.h"

#define IA32_INLINE_HOOK_STUB_SIZE		5

int inlinehook32(BYTE* newfun, BYTE* hookaddr, PROC* keepaddr, const WCHAR* funcname) {
	int result = 0;

	if (hookaddr == newfun)
	{
		log(L"inlinehook32 function:%ws already exist\r\n", funcname);
		return FALSE;
	}

	HOOK_TRAMPS* trump = addTrump(funcname);
	if (trump <= 0)
	{
		log(L"inlinehook32 addTrump function:%ws error\r\n", funcname);
		return FALSE;
	}

	DWORD offset = 0;

	int codelen = 0;

	hde32s asm32 = { 0 };

	BYTE* oldcode = hookaddr;

	BYTE* oldfun = oldcode;

	int total = 0;

	int minimum = IA32_INLINE_HOOK_STUB_SIZE;

	while (codelen < minimum)
	{
		int instructionlen = hde32_disasm(oldfun, &asm32);
		if (instructionlen <= 0)
		{
			log(L"inlinehook32 function:%ws address:%p hde64_disasm error\r\n", funcname, oldfun);
			deleteTrump(funcname);
			return FALSE;
		}

		if (total == 0)
		{
			if ((*oldfun == 0xff && *(oldfun + 1) == 0x25) || (*oldfun == 0xff && *(oldfun + 1) == 0x15))
			{
				//FF 25 D4 0F B1 76
				//76b10fd4:76 1e a4 70
				//70a41e76:CreateFileA
				offset = *(DWORD*)(oldfun + 2);
				offset = *(DWORD*)offset;
				oldfun = (BYTE*)offset;

				oldcode = oldfun;
				codelen = 0;
				continue;
			}
			else if (*oldfun == 0xe9 || *oldfun == 0xe8)		//if hooked by others ,how to find lost 5 bytes?
			{
				offset = *(DWORD*)(oldfun + 1);
				oldfun += offset + 5;

				oldcode = oldfun;
				codelen = 0;
				continue;
			}
			else if (*oldfun == 0xeb)
			{
				offset = *(oldfun + 1);
				oldfun += offset + 2;

				oldcode = oldfun;
				codelen = 0;
				continue;
			}
			else {
				memcpy(trump->code + codelen, oldfun, instructionlen);
			}
		}
		else {
			if ((*oldfun == 0xff && *(oldfun + 1) == 0x25) || (*oldfun == 0xff && *(oldfun + 1) == 0x15))
			{
				memcpy(trump->code + codelen, oldfun, instructionlen);

				//FF 25 D4 0F B1 76
				//76b10fd4:76 1e a4 70
				//70a41e76:CreateFileA
			}
			else if (*oldfun == 0xe9 || *oldfun == 0xe8 || *oldfun == 0xea)		//if hooked by others ,how to find lost 5 bytes?
			{
				memcpy(trump->code + codelen, oldfun, instructionlen);

				offset = *(DWORD*)(oldfun + 1);

				offset = (DWORD)oldfun + offset + 5;

				DWORD delta = offset - ((DWORD)trump->code + codelen + instructionlen);

				*(DWORD*)(trump->code + codelen + 1) = delta;
			}

			else if (*oldfun == 0xeb)
			{
				memcpy(trump->code + codelen, oldfun, instructionlen);

				offset = *(oldfun + 1);
				byte* next_instruction = oldfun + offset + 2;

				minimum = next_instruction - oldcode + 1;
				if (minimum > MAX_TRAMP_SIZE - IA32_INLINE_HOOK_STUB_SIZE || minimum <= 0)
				{
					log(L"inlinehook32 function:%ws jump to target address:%p out of range on base:%p\r\n", funcname, oldfun, oldcode);
					deleteTrump(funcname);
					return FALSE;
				}
			}

			else if (*oldfun == 0x0f && (*(oldfun + 1) >= 0x80 && *(oldfun + 1) <= 0x8f))
			{
				log(L"inlinehook32 function:%ws address:%p found irregular jump instruction: %02x %02x\r\n", funcname, oldfun, *oldfun, *(oldfun + 1));

				memcpy(trump->code + codelen, oldfun, instructionlen);
				offset = *(WORD*)(oldfun + 2);
				byte* next_instruction = (BYTE*)(offset + 4 + oldfun);

				minimum = next_instruction - oldcode + 1;
				if (minimum > MAX_TRAMP_SIZE - IA32_INLINE_HOOK_STUB_SIZE || minimum <= 0)
				{
					log(L"inlinehook32 function:%ws jump to target address:%p out of range on base:%p\r\n", funcname, oldfun, oldcode);
					deleteTrump(funcname);
					return FALSE;
				}
				//oldfun += 4;
			}
			else if (*oldfun >= 0x70 && *oldfun <= 0x7f)		//jump with flag range in 128 bytes
			{
				memcpy(trump->code + codelen, oldfun, instructionlen);

				offset = *(oldfun + 1);

				byte* next_instruction = oldfun + 2 + offset;

				minimum = next_instruction - oldcode + 1;
				if (minimum > MAX_TRAMP_SIZE - IA32_INLINE_HOOK_STUB_SIZE || minimum <= 0)
				{
					log(L"inlinehook32 function:%ws jump to target address:%p out of range on base:%p\r\n", funcname, oldfun, oldcode);
					deleteTrump(funcname);
					return FALSE;
				}
				//oldfun += 2;
			}
			else {
				memcpy(trump->code + codelen, oldfun, instructionlen);
			}
		}
		codelen += instructionlen;
		oldfun += instructionlen;
		total++;
	}

	DWORD oldprotect = 0;
	result = VirtualProtect(oldcode, codelen, PAGE_EXECUTE_READWRITE, &oldprotect);
	if (result == 0)
	{
		log(L"inlinehook32 VirtualProtect function:%ws address:%p error\r\n", funcname, oldcode);
		deleteTrump(funcname);
		return FALSE;
	}

	memcpy(trump->oldcode, oldcode, codelen);

	oldcode[0] = 0xe9;

	*(DWORD*)(oldcode + 1) = newfun - (oldcode + 5);

	trump->code[codelen] = 0xe9;

	*(DWORD*)(trump->code + codelen + 1) = oldcode + codelen - (trump->code + codelen + 5);

	*keepaddr = (FARPROC) & (trump->code);

	DWORD dummyprotect = 0;
	result = VirtualProtect(oldcode, codelen, oldprotect, &dummyprotect);

	trump->replace.oldaddr = oldcode;
	trump->replace.len = codelen;


	log(L"inlinehook32 function:%ws,hook size:%d,tramp address:%p,instruction address:%p,new func address:%p,keep address:%p",
		funcname, codelen, trump->code, oldcode, newfun, keepaddr);
	WCHAR szout[1024];
	WCHAR* loginfo = szout;
	int len = 0;

	for (int i = 0; i < 5; i++)
	{
		len = wsprintfW(loginfo, L" %02X ", *(oldcode + i));
		loginfo = loginfo + len;
	}
	*loginfo = 0;
	log(szout);

	loginfo = szout;
	for (int i = 0; i < codelen + 5; i++)
	{
		len = wsprintfW(loginfo, L" %02X ", *(trump->code + i));
		loginfo = loginfo + len;
	}
	*loginfo = 0;
	log(szout);

	return result;
}

#endif

int hook2(CONST WCHAR* modulename, const WCHAR* wstrfuncname, BYTE* newfuncaddr, PROC* keepaddr) {
	int result = 0;
	HMODULE h = GetModuleHandleW(modulename);
	if (h)
	{
		CHAR funcname[MAX_PATH];
		result = WideCharToMultiByte(CP_ACP, 0, wstrfuncname, -1, funcname, MAX_PATH, 0, 0);
		if (result)
		{
			LPBYTE  oldfunc = (LPBYTE)GetProcAddress(h, funcname);
			if (oldfunc)
			{
#ifdef _WIN64
				result = inlinehook64(newfuncaddr, oldfunc, keepaddr, wstrfuncname);
#else
				result = inlinehook32(newfuncaddr, oldfunc, (FARPROC*)keepaddr, wstrfuncname);
#endif
				log(L"[LYSM]inlinehook finish %ws %ws ok\r\n", modulename, wstrfuncname);
				if (result)
				{
					log(L"[LYSM]hook %ws %ws ok\r\n", modulename, wstrfuncname);
				}
				return result;
			}
			else {
				log(L"[LYSM]function %ws not found in %ws", wstrfuncname, modulename);
			}
		}
		else {
			log(L"[LYSM]WideCharToMultiByte function %ws error", wstrfuncname);
		}
	}
	else {
		log(L"[LYSM]module %ws not found", modulename);
	}
	return FALSE;
}


int unhook(CONST WCHAR* modulename, const WCHAR* wstrfuncname) {
	int result = 0;

	for (int i = 0; i < TRAMP_BAR_LIMIT; i++)
	{
		if (g_trump[i].valid)
		{
			if (lstrcmpiW(wstrfuncname, g_trump[i].apiName) == 0)
			{
				unsigned char* oldcode = g_trump[i].replace.oldaddr;
				int oldcodelen = g_trump[i].replace.len;
				DWORD oldprotect = 0;
				result = VirtualProtect(oldcode, oldcodelen, PAGE_EXECUTE_READWRITE, &oldprotect);
				memcpy(oldcode, g_trump[i].oldcode, oldcodelen);
				DWORD dummyprotect = 0;
				result = VirtualProtect(oldcode, oldcodelen, oldprotect, &dummyprotect);

				g_trump[i].valid = FALSE;

				log(L"delete hooked function:%ws ok", wstrfuncname);
				return TRUE;
			}
		}
	}

	return FALSE;
}


int  unhookall() {
	int result = 0;

	for (int i = 0; i < TRAMP_BAR_LIMIT; i++)
	{
		if (g_trump[i].valid != 0 && g_trump[i].valid != 1) {
			log(L"funciton :%d error", i);
		}
		if (g_trump[i].valid == TRUE /*&& g_trump[i].apiName[0]*/)
		{
			unsigned char* oldcode = g_trump[i].replace.oldaddr;

			int oldcodelen = g_trump[i].replace.len;
			result = IsBadReadPtr(oldcode, oldcodelen);
			if (result == 0)
			{
				DWORD oldprotect = 0;
				result = VirtualProtect(oldcode, oldcodelen, PAGE_EXECUTE_READWRITE, &oldprotect);

				memcpy(oldcode, g_trump[i].oldcode, oldcodelen);
				DWORD dummyprotect = 0;
				result = VirtualProtect(oldcode, oldcodelen, oldprotect, &dummyprotect);
				log(L"delete hooked function:%ws ok", g_trump[i].apiName);
			}
			else {
				log(L"funciton:%ws address:%p can not be write,maybe the dll has been unload?", g_trump[i].apiName, oldcode);
			}

			g_trump[i].valid = FALSE;
		}
		else {

		}
	}

	return TRUE;
}




PUCHAR allocTrampAddress(PUCHAR  module) {
	IMAGE_NT_HEADERS64* hdr = (IMAGE_NT_HEADERS64*)module;
	PUCHAR* address = (PUCHAR*)hdr->OptionalHeader.ImageBase + hdr->OptionalHeader.SizeOfImage;

	PUCHAR* alloc = (PUCHAR*)VirtualAlloc(address, 0x4000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
	if (alloc)
	{
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Windows API Hook 是一种技术,用于截获和修改 Microsoft Windows 操作系统中的 API 调用。API 是应用程序与操作系统之间进行交互的接口,通过 Hook 技术,我们可以在 API 被调用前或者调用后注入自定义的代码来监控、修改甚至完全替换原本的 API 行为。 Windows API Hook 技术通常用于以下几个方面: 1. 监控和记录:通过 Hook 技术,我们可以截获特定 API 的调用,并记录下来,以供后续分析使用。这对于软件调试、异常捕获和性能分析非常有用,可以帮助开发人员定位和解决问题。 2. 行为修改:通过修改 API 调用的参数或返回值,我们可以改变原本的行为逻辑。可以用于对软件进行自定义的增强或者修改,提供特定的功能或者保护隐私等。 3. 恶意行为检测与防范:通过 Hook 技术,可以监控系统中的 API 调用,检测和阻止恶意软件的行为。例如,可以截获网络 API 调用,检测恶意软件的通信行为,并阻止其传输敏感信息。 4. 系统级别功能拓展:通过 Hook 技术,可以在系统层面为应用程序提供额外的功能。例如,可以通过 Hook 来添加全局热键、截获鼠标事件、自定义窗口样式等。 需要注意的是,Windows API Hook 是一项强大但也易被滥用的技术。如果不正确使用,可能会导致系统不稳定、性能下降甚至安全问题。因此,在使用 API Hook 技术时,开发人员需要谨慎设计和测试,确保对系统的干扰和风险最小化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值