📄 hook.cpp
字号:
#include <windows.h>
#include <winnt.h>
#include "hook.h"
unsigned long SAVECR0 = 0;
// 禁用Windows NT/2000的内存保护,使只读内存区可写
//
void DisableProtection()
{
__asm
{
mov eax,cr0
mov SAVECR0,eax
and eax,0fffeffffh
mov cr0,eax
}
}
//
// 启用Windows NT/2000的内存保护
//
void EnableProtection()
{
__asm
{
mov eax,SAVECR0
mov cr0,eax
}
}
//
// Hook 一个系统函数
// 参数:
// pBaseAddress: 要Hook函数所在文件在内存映象的基地址,比如NDIS.SYS的基地址
// Name: 要Hook的函数名
// InFunc: 自己的函数地址
// OutFunc: Hook后保存系统的函数地址
// 返回值:
// NULL: Hook失败
// Not NULL: 返回系统函数地址,与*OutFunc相同
//
//
PVOID HookFun(PVOID pBaseAddress, PCSTR Name, PVOID InFunc, ULONG* OutFunc)
{
//以下是PE文件中的结构
PIMAGE_DOS_HEADER pDosHeader = NULL;//DOS EXE文件头结构
PIMAGE_NT_HEADERS pNtHeader = NULL;//PE文件头结构
PIMAGE_DATA_DIRECTORY pDirectory = NULL;//
PIMAGE_EXPORT_DIRECTORY pExports = NULL;//导出表结构
ULONG nSize, Address, i;
PULONG pFunctions = NULL;
PSHORT pOrdinals = NULL;
PULONG pNames = NULL;
PVOID pFunction = NULL;
ULONG Ordinal = 0;
if(pBaseAddress == NULL)
return NULL;
pDosHeader = (PIMAGE_DOS_HEADER)pBaseAddress;
pNtHeader = (PIMAGE_NT_HEADERS)((PCHAR)pBaseAddress + pDosHeader->e_lfanew);//定位到PE文件头开始地址
pDirectory = pNtHeader->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_EXPORT;// 指向IMAGE_DIRECTORY_ENTRY_EXPORT开始处
nSize = pDirectory->Size;
Address = pDirectory->VirtualAddress;
pExports = (PIMAGE_EXPORT_DIRECTORY)((PCHAR)pBaseAddress + Address);//定位到导出表开始处
pFunctions = (PULONG)((PCHAR)pBaseAddress + pExports->AddressOfFunctions);//得到导出函数地址
pOrdinals = (PSHORT)((PCHAR)pBaseAddress + pExports->AddressOfNameOrdinals);//得到AddressOfNameOrdinals(RVA)
pNames = (PULONG)((PCHAR)pBaseAddress + pExports->AddressOfNames);//得到函数名
for(i = 0; i < pExports->NumberOfNames; i++)//开始查找
{
Ordinal = pOrdinals[i];
if(pFunctions[Ordinal] < Address || pFunctions[Ordinal] >= Address + nSize)
{
if(strcmp((PSTR)((PCHAR)pBaseAddress + pNames[i]), Name) == 0)
{
//
// 得到系统函数的地址
//
pFunction = (PCHAR)pBaseAddress + pFunctions[Ordinal];
*OutFunc = (ULONG)pFunction;
// 去除Windows内存保护
//
DisableProtection();
// 这里需要修改系统内存数据。
// 计算出自己函数地址的偏移量,并替换导出表中的偏移量
//
pFunctions[Ordinal] = (ULONG)((ULONG)InFunc - (ULONG)pBaseAddress);
// 恢复Windows内存保护
//
EnableProtection();
break;
}
}
}
return pFunction;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -