IP过滤驱动可以广泛的应用于网络安全产品的研发,NDIS和TDI的驱动资料很多,有比较成熟的代码可以参考,但是使用IPFIREWALL.h开发的IP过滤驱动的资料非常少,这次自己做一个软件的时候参考VCKBASE上的一篇文章《开发Windows 2000/XP下的防火墙》(作者:Jesús O)的基础上,写了一个驱动,代码都做了详细的注释了,只要稍微有点驱动设计基础的都可以看得懂,我把自己的特殊的回调函数去掉了,保留了基本的完整框架,牛人就不需要看了,初学者都可以在此基础上继续快速开发。
1 SmatrixIPDiv.cpp文件
2 protocol.h头文件
3 SmatrixIPDiv.h头文件
* Copyright (c) 2007 ,安全矩阵(Security Matrix)
* All rights reserved.
*
* 文件名称:SmatrixIPDiv.cpp
* 文件标识:S
* 摘 要:IP过滤驱动,利用ipfirewall捕获包、分析包、过滤包
* 开始时间:2006年12月26日
*/
extern " C "
... {
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ntddk.h>
#include <ntddndis.h>
#include <pfhook.h>
#include <ndis.h>
#include <ipfirewall.h>
}
#include " SmatrixIPDiv.h "
#include " protocol.h "
/ 自定义函数的声明 // /
// 关闭打开驱动函数
NTSTATUS DispatchCreateClose(PDEVICE_OBJECT pDevObj, PIRP pIrp);
// 驱动卸载函数
void DriverUnload(PDRIVER_OBJECT pDriverObj);
// IO控制派遣函数(内核消息处理)
NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp);
// 向过滤列表中添加一个过滤规则
NTSTATUS AddFilterToList(CIPFilter * pFilter);
// 清除过滤列表
void ClearFilterList();
// 注册钩子回调函数
NTSTATUS SetFilterFunction(IPPacketFirewallPtr filterFunction, BOOLEAN load);
// 包过滤函数
FORWARD_ACTION FilterPacket(unsigned char * PacketHeader,
unsigned char * Packet,
unsigned int PacketLength,
DIRECTION_E direction,
unsigned int RecvInterfaceIndex,
unsigned int SendInterfaceIndex);
// IP过滤器函数
FORWARD_ACTION IPFilterFunction(VOID ** pData,
UINT RecvInterfaceIndex,
UINT * pSendInterfaceIndex,
UCHAR * pDestinationType,
VOID * pContext,
UINT ContextLength,
struct IPRcvBuf ** pRcvBuf);
// 过滤列表首地址
struct CFilterList * g_pHeader = NULL;
// 驱动内部名称和符号连接名称
#define DEVICE_NAME L " /Device/DevSMFltIP "
#define LINK_NAME L " /DosDevices/DrvSMFltIp "
// 驱动入口函数
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString)
... {
NTSTATUS status = STATUS_SUCCESS;
// 初始化各个派遣例程
pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreateClose;
pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchCreateClose;
pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl;
pDriverObj->DriverUnload = DriverUnload;
// 创建、初始化设备对象
// 设备名称
UNICODE_STRING ustrDevName;
RtlInitUnicodeString(&ustrDevName, DEVICE_NAME);
// 创建设备对象
PDEVICE_OBJECT pDevObj;
status = IoCreateDevice(pDriverObj,
0,
&ustrDevName,
FILE_DEVICE_DRVFLTIP,
0,
FALSE,
&pDevObj);
if(!NT_SUCCESS(status))
...{
return status;
}
// 创建符号连接名称
// 符号连接名称
UNICODE_STRING ustrLinkName;
RtlInitUnicodeString(&ustrLinkName, LINK_NAME);
// 创建关联
status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName);
if(!NT_SUCCESS(status))
...{
IoDeleteDevice(pDevObj);
return status;
}
return STATUS_SUCCESS;
}
void DriverUnload(PDRIVER_OBJECT pDriverObj)
... {
// 卸载过滤函数
SetFilterFunction(IPFilterFunction,FALSE);
// 释放所有资源
ClearFilterList();
// 删除符号连接名称
UNICODE_STRING strLink;
RtlInitUnicodeString(&strLink, LINK_NAME);
IoDeleteSymbolicLink(&strLink);
// 删除设备对象
IoDeleteDevice(pDriverObj->DeviceObject);
}
// 处理IRP_MJ_CREATE、IRP_MJ_CLOSE功能代码
NTSTATUS DispatchCreateClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
... {
pIrp->IoStatus.Status = STATUS_SUCCESS;
// pIrp->IoStatus.Information = 0;
// 完成此请求
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
// I/O控制派遣例程
NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
... {
NTSTATUS status = STATUS_SUCCESS;
// 取得此IRP(pIrp)的I/O堆栈指针
PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
// 取得I/O控制代码
ULONG uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
// 取得I/O缓冲区指针和它的长度
PVOID pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;
ULONG uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
// 响应用户的命令
switch(uIoControlCode)
...{
case START_IP_HOOK: // 开始过滤
status = SetFilterFunction(IPFilterFunction,TRUE);
break;
case STOP_IP_HOOK: // 停止过滤
status = SetFilterFunction(IPFilterFunction,FALSE);
break;
case ADD_FILTER: // 添加一个过滤规则
if(uInSize == sizeof(CIPFilter))
status = AddFilterToList((CIPFilter*)pIoBuffer);
else
status = STATUS_INVALID_DEVICE_REQUEST;
break;
case CLEAR_FILTER: // 释放过滤规则列表
ClearFilterList();
break;
default:
status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
// 完成请求
pIrp->IoStatus.Status = status;
pIrp->IoStatus.Information = 0;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status;
}
// /
// 过滤列表
// 向过滤列表中添加一个过滤规则
NTSTATUS AddFilterToList(CIPFilter * pFilter)
... {
// 为新的过滤规则申请内存空间
CFilterList* pNew = (CFilterList*)ExAllocatePool(NonPagedPool, sizeof(CFilterList));
if(pNew == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
// 填充这块内存
RtlCopyMemory(&pNew->ipf, pFilter, sizeof(CIPFilter));
// 连接到过滤列表中
pNew->pNext = g_pHeader;
g_pHeader = pNew;
return STATUS_SUCCESS;
}
// 清除过滤列表
void ClearFilterList()
... {
CFilterList* pNext;
// 释放过滤列表占用的所有内存
while(g_pHeader != NULL)
...{
pNext = g_pHeader->pNext;
// 释放内存
ExFreePool(g_pHeader);
g_pHeader = pNext;
}
}
// 包过滤函数
FORWARD_ACTION FilterPacket(unsigned char * PacketHeader,
unsigned char * Packet,
unsigned int PacketLength,
DIRECTION_E direction,
unsigned int RecvInterfaceIndex,
unsigned int SendInterfaceIndex)
... {
// 提取IP头
IPHeader* pIPHdr = (IPHeader*)PacketHeader;
TCPHeader *pTCPHdr = NULL;
UDPHeader *pUDPHdr = NULL;
if(pIPHdr->ipProtocol == 6) // 是TCP协议
...{
// 提取TCP头
pTCPHdr = (TCPHeader*)Packet;
// 我们接受所有已经建立连接的TCP封包
if(!(pTCPHdr->flags & 0x02))
...{
return FORWARD;
}
}
// 与过滤规则相比较,决定采取的行动
CFilterList* pList = g_pHeader;
while(pList != NULL)
...{
// 比较协议
if(pList->ipf.protocol == 0 || pList->ipf.protocol == pIPHdr->ipProtocol)
...{
// 查看源IP地址
if(pList->ipf.sourceIP != 0 &&
(pList->ipf.sourceIP & pList->ipf.sourceMask) != pIPHdr->ipSource)
...{
pList = pList->pNext;
continue;
}
// 查看目标IP地址
if(pList->ipf.destinationIP != 0 &&
(pList->ipf.destinationIP & pList->ipf.destinationMask) != pIPHdr->ipDestination)
...{
pList = pList->pNext;
continue;
}
// 如果是TCP封包,查看端口号
if(pIPHdr->ipProtocol == 6)
...{
pTCPHdr = (TCPHeader*)Packet;
if(pList->ipf.sourcePort == 0 || pList->ipf.sourcePort == pTCPHdr->sourcePort)
...{
if(pList->ipf.destinationPort == 0
|| pList->ipf.destinationPort == pTCPHdr->destinationPort)
...{
// 现在决定如何处理这个封包
if(pList->ipf.bDrop)
return DROP;
else
return FORWARD;
}
}
}
// 如果是UDP封包,查看端口号
else if(pIPHdr->ipProtocol == 17)
...{
pUDPHdr = (UDPHeader*)Packet;
if(pList->ipf.sourcePort == 0 || pList->ipf.sourcePort == pUDPHdr->sourcePort)
...{
if(pList->ipf.destinationPort == 0
|| pList->ipf.destinationPort == pUDPHdr->destinationPort)
...{
// 现在决定如何处理这个封包
if(pList->ipf.bDrop)
return DROP;
else
return FORWARD;
}
}
}
else
...{
// 对于其它封包,我们直接处理
if(pList->ipf.bDrop)
return DROP;
else
return FORWARD;
}
}
// 比较下一个规则
pList = pList->pNext;
}
// 我们接受所有没有注册的封包
return FORWARD;
}
// 注册钩子回调函数
NTSTATUS SetFilterFunction(IPPacketFirewallPtr filterFunction, BOOLEAN load)
... {
//{变量定义BEGIN}
NTSTATUS status = STATUS_SUCCESS; //内核状态
NTSTATUS waitStatus = STATUS_SUCCESS; //受信状态
PDEVICE_OBJECT pDeviceObj = NULL; //pDeviceObj变量将指向IP过滤驱动设备对象
PFILE_OBJECT pFileObj = NULL; //内核过滤器设备
IP_SET_FIREWALL_HOOK_INFO filterData; //IP_SET_FIREWALL_HOOK_INFO结构
UNICODE_STRING ustrFilterDriver; // IP过滤驱动的名称
KEVENT event; //
IO_STATUS_BLOCK ioStatus; //
PIRP pIrp; //
//{变量定义END}
// 初始化IP过滤驱动的名称
RtlInitUnicodeString(&ustrFilterDriver, DD_IP_DEVICE_NAME);
// 取得设备对象指针
status = IoGetDeviceObjectPointer(&ustrFilterDriver, STANDARD_RIGHTS_ALL, &pFileObj, &pDeviceObj);
if(!NT_SUCCESS(status))
...{
return status;
}
/// 使用到IP过滤驱动中设备对象的指针创建一个IRP///
// 填充IP_SET_FIREWALL_HOOK_INFO结构
filterData.FirewallPtr = filterFunction;
filterData.Priority = 1;
filterData.Add = load;
// 我们需要初始化一个事件对象。
// 构建IRP时需要使用这个事件内核对象,当IP过滤取得接受到此IRP,完成工作以后会将它置位
KeInitializeEvent(&event, NotificationEvent, FALSE);
// 为设备控制请求申请和构建一个IRP
pIrp = IoBuildDeviceIoControlRequest(IOCTL_IP_SET_FIREWALL_HOOK, // io control code
pDeviceObj,
(PVOID) &filterData,
sizeof(IP_SET_FIREWALL_HOOK_INFO),
NULL,
0,
FALSE,
&event,
&ioStatus);
if(NULL==pIrp)
...{
// 如果不能申请空间得到pIrp,返回对应的错误代码
return STATUS_INSUFFICIENT_RESOURCES;
}
/// 请求安装钩子回调函数/
// 发送此IRP到IP过滤驱动
status = IoCallDriver(pDeviceObj, pIrp);
// 等待IP过滤驱动的通知
if(status == STATUS_PENDING)
...{
waitStatus=KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
if (!NT_SUCCESS(waitStatus)) //受信状态不成功,返回
...{
return waitStatus;
}
}
status = ioStatus.Status;
if(!NT_SUCCESS(status))//状态不成功,返回
...{
return status;
}
/
// 清除内核资源/
if(pFileObj != NULL)
ObDereferenceObject(pFileObj);
pDeviceObj = NULL; //避免产生野指针
pFileObj = NULL; //避免产生野指针
return status;
}
// IP过滤器函数
FORWARD_ACTION IPFilterFunction(VOID ** pData,
UINT RecvInterfaceIndex,
UINT * pSendInterfaceIndex,
UCHAR * pDestinationType,
VOID * pContext,
UINT ContextLength,
struct IPRcvBuf ** pRcvBuf)
... {
FORWARD_ACTION result = FORWARD;
unsigned char *packet = NULL;
int bufferSize = 0;
struct IPRcvBuf *buffer =(struct IPRcvBuf *) *pData;
PFIREWALL_CONTEXT_T fwContext = (PFIREWALL_CONTEXT_T)pContext;
DIRECTION_E direction=IP_RECEIVE;
//如果包指针不为空,IPRcvBuf中存在数据
if(buffer != NULL)
...{
bufferSize = buffer->ipr_size;
while(buffer->ipr_next != NULL) //得到整个IPRcvBuf缓冲链中数据总长度
...{
buffer = buffer->ipr_next;
bufferSize += buffer->ipr_size;
}
//分配一个不分页的内存,将整个IPRcvBuf缓冲链放入其中
packet = (unsigned char *) ExAllocatePool(NonPagedPool, bufferSize);
if(packet != NULL)
...{
IPHeader *ipp = (IPHeader *)packet;
unsigned int offset = 0;
buffer = (struct IPRcvBuf *) *pData;
memcpy(packet, buffer->ipr_buffer, buffer->ipr_size);
while(buffer->ipr_next != NULL)
...{
offset += buffer->ipr_size;
buffer = buffer->ipr_next;
memcpy(packet + offset, buffer->ipr_buffer, buffer->ipr_size);
}
if (NULL != fwContext)
...{
direction=fwContext->Direction;
}
else
...{
direction=(DIRECTION_E)0;
}
//调用包检测函数,通过返回FORWARD,否则返回DROP
result = FilterPacket(packet,
packet + (ipp->ipHeaderLength * 4),
bufferSize - (ipp->ipHeaderLength * 4),
direction,
RecvInterfaceIndex,
(pSendInterfaceIndex != NULL) ? *pSendInterfaceIndex : 0);
}
}
//释放分配的临时包缓存
if(NULL != packet) ExFreePool(packet);
return result;
}
2 定义常见的封包结构信息
// 文件名称:protocol.h
typedef struct IPHeader
... { UCHAR ipHeaderLength:4; // 头长度
UCHAR ipVersion:4; // 版本号
UCHAR ipTOS; // 服务类型
USHORT ipLength; // 封包总长度,即整个IP报的长度
USHORT ipID; // 封包标识,惟一标识发送的每一个数据报
USHORT ipFlags; // 标志
UCHAR ipTTL; // 生存时间,就是TTL
UCHAR ipProtocol; // 协议,可能是TCP、UDP、ICMP等
USHORT ipChecksum; // 校验和
ULONG ipSource; // 源IP地址
ULONG ipDestination; // 目标IP地址
} IPPacket;
typedef struct _TCPHeader
... {
USHORT sourcePort; // 源端口号
USHORT destinationPort; // 目的端口号
ULONG sequenceNumber; // 序号
ULONG acknowledgeNumber; // 确认序号
UCHAR dataoffset; // 数据指针
UCHAR flags; // 标志
USHORT windows; // 窗口大小
USHORT checksum; // 校验和
USHORT urgentPointer; // 紧急指针
} TCPHeader;
typedef struct _UDPHeader
... {
USHORT sourcePort; // 源端口号
USHORT destinationPort; // 目的端口号
USHORT len; // 封包长度
USHORT checksum; // 校验和
} UDPHeader;
enum
... {
IPPROTO_IP = 0, // Dummy protocol for TCP.
IPPROTO_HOPOPTS = 0, // IPv6 Hop-by-Hop options. */
IPPROTO_ICMP = 1, // Internet Control Message Protocol. */
IPPROTO_IGMP = 2, // Internet Group Management Protocol. */
IPPROTO_IPIP = 4, // IPIP tunnels (older KA9Q tunnels use 94). */
IPPROTO_TCP = 6, // Transmission Control Protocol. */
IPPROTO_EGP = 8, // Exterior Gateway Protocol. */
IPPROTO_PUP = 12, // PUP protocol. */
IPPROTO_UDP = 17, // User Datagram Protocol. */
IPPROTO_IDP = 22, // XNS IDP protocol. */
IPPROTO_TP = 29, // SO Transport Protocol Class 4. */
IPPROTO_IPV6 = 41, // IPv6 header. */
IPPROTO_ROUTING = 43, // IPv6 routing header. */
IPPROTO_FRAGMENT = 44, // IPv6 fragmentation header. */
IPPROTO_RSVP = 46, // Reservation Protocol. */
IPPROTO_GRE = 47, // General Routing Encapsulation. */
IPPROTO_ESP = 50, // encapsulating security payload. */
IPPROTO_AH = 51, // authentication header. */
IPPROTO_ICMPV6 = 58, // ICMPv6. */
IPPROTO_NONE = 59, /**//* IPv6 no next header. */
IPPROTO_DSTOPTS = 60, /**//* IPv6 destination options. */
IPPROTO_MTP = 92, /**//* Multicast Transport Protocol. */
IPPROTO_ENCAP = 98, /**//* Encapsulation Header. */
IPPROTO_PIM = 103, /**//* Protocol Independent Multicast. */
IPPROTO_COMP = 108, /**//* Compression Header Protocol. */
IPPROTO_RAW = 255, /**//* Raw IP packets. */
IPPROTO_MAX
} ;
3 IP过滤驱动相关结构和宏定义
// 文件名称:SmatrixIPDiv.h
#ifndef __SMATRIXIPDIV_H__
#define __SMATRIXIPDIV_H__
// 自定义设备类型,在创建设备对象时使用
// 注意,自定义值的范围是32768-65535
#define FILE_DEVICE_DRVFLTIP 0x00654322
// 自定义的IO控制代码,用于区分不同的设备控制请求
// 注意,自定义值的范围是2048-4095
#define DRVFLTIP_IOCTL_INDEX 0x830
//
// 定义各种设备控制代码。分别是开始过滤、停止过滤、添加过滤规则、清除过滤规则
//
#define START_IP_HOOK CTL_CODE(FILE_DEVICE_DRVFLTIP,
DRVFLTIP_IOCTL_INDEX, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define STOP_IP_HOOK CTL_CODE(FILE_DEVICE_DRVFLTIP,
DRVFLTIP_IOCTL_INDEX + 1 , METHOD_BUFFERED, FILE_ANY_ACCESS)
#define ADD_FILTER CTL_CODE(FILE_DEVICE_DRVFLTIP,
DRVFLTIP_IOCTL_INDEX + 2 , METHOD_BUFFERED, FILE_WRITE_ACCESS)
#define CLEAR_FILTER CTL_CODE(FILE_DEVICE_DRVFLTIP,
DRVFLTIP_IOCTL_INDEX + 3 , METHOD_BUFFERED, FILE_ANY_ACCESS)
// 定义过滤规则的结构
struct CIPFilter
... {
USHORT protocol; // 使用的协议
ULONG sourceIP; // 源IP地址
ULONG destinationIP; // 目标IP地址
ULONG sourceMask; // 源地址屏蔽码
ULONG destinationMask; // 目的地址屏蔽码
USHORT sourcePort; // 源端口号
USHORT destinationPort; // 目的端口号
BOOLEAN bDrop; // 是否丢弃此封包
} ;
// 过滤列表
struct CFilterList
... {
CIPFilter ipf; // 过滤规则
CFilterList* pNext; // 指向下一个CFilterList结构
} ;
#endif // __SMATRIXIPDIV_H__
HHOOK g_hHook;
HINSTANCE g_hinstDll;
FARPROC pfMessageBoxA;
int WINAPI MyMessageBoxA(HWND hWnd, LPCTSTR lpText,LPCTSTR lpCaption,UINT uType);
BYTE OldMessageBoxACode[ 5 ],NewMessageBoxACode[ 5 ];
HMODULE hModule ;
DWORD dwIdOld,dwIdNew;
BOOL bHook = false ;
void HookOn();
void HookOff();
BOOL init();
LRESULT WINAPI MousHook( int nCode,WPARAM wParam,LPARAM lParam);
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
... {
switch (ul_reason_for_call)
...{
case DLL_PROCESS_ATTACH:
if(!init())
...{
MessageBoxA(NULL,"Init","ERROR",MB_OK);
return(false);
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
if(bHook) UnintallHook();
break;
}
return TRUE;
}
LRESULT WINAPI Hook( int nCode,WPARAM wParam,LPARAM lParam) // 空的钩子函数
... {
return(CallNextHookEx(g_hHook,nCode,wParam,lParam));
}
HOOKAPI2_API BOOL InstallHook() // 输出安装空的钩子函数
... {
g_hinstDll=LoadLibrary("HookApi2.dll");
g_hHook=SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)Hook,g_hinstDll,0);
if (!g_hHook)
...{
MessageBoxA(NULL,"SET ERROR","ERROR",MB_OK);
return(false);
}
return(true);
}
HOOKAPI2_API BOOL UninstallHook() // 输出御在钩子函数
... {
return(UnhookWindowsHookEx(g_hHook));
}
BOOL init() // 初始化得到MessageBoxA的地址,并生成Jmp XXX(MyMessageBoxA)的跳转指令
... {
hModule=LoadLibrary("user32.dll");
pfMessageBoxA=GetProcAddress(hModule,"MessageBoxA");
if(pfMessageBoxA==NULL)
return false;
_asm
...{
lea edi,OldMessageBoxACode
mov esi,pfMessageBoxA
cld
movsd
movsb
}
NewMessageBoxACode[0]=0xe9;//jmp MyMessageBoxA的相对地址的指令
_asm
...{
lea eax,MyMessageBoxA
mov ebx,pfMessageBoxA
sub eax,ebx
sub eax,5
mov dword ptr [NewMessageBoxACode+1],eax
}
dwIdNew=GetCurrentProcessId(); //得到所属进程的ID
dwIdOld=dwIdNew;
HookOn();//开始拦截
return(true);
}
int WINAPI MyMessageBoxA(HWND hWnd, LPCTSTR lpText,LPCTSTR lpCaption, UINT uType ) // 首先关闭拦截,然后才能调用被拦截的Api 函数
... {
int nReturn=0;
HookOff();
nReturn=MessageBoxA(hWnd,"Hook",lpCaption,uType);
HookOn();
return(nReturn);
}
void HookOn()
... {
HANDLE hProc;
dwIdOld=dwIdNew;
hProc=OpenProcess(PROCESS_ALL_ACCESS,0,dwIdOld);//得到所属进程的句柄
VirtualProtectEx(hProc,pfMessageBoxA,5,PAGE_READWRITE,&dwIdOld);//修改所属进程中MessageBoxA的前5个字节的属性为可写
WriteProcessMemory(hProc,pfMessageBoxA,NewMessageBoxACode,5,0);//将所属进程中MessageBoxA的前5个字节改为JMP 到MyMessageBoxA
VirtualProtectEx(hProc,pfMessageBoxA,5,dwIdOld,&dwIdOld);//修改所属进程中MessageBoxA的前5个字节的属性为原来的属性
bHook=true;
}
void HookOff() // 将所属进程中JMP MyMessageBoxA的代码改为Jmp MessageBoxA
... {
HANDLE hProc;
dwIdOld=dwIdNew;
hProc=OpenProcess(PROCESS_ALL_ACCESS,0,dwIdOld);
VirtualProtectEx(hProc,pfMessageBoxA,5,PAGE_READWRITE,&dwIdOld);
WriteProcessMemory(hProc,pfMessageBoxA,OldMessageBoxACode,5,0);
VirtualProtectEx(hProc,pfMessageBoxA,5,dwIdOld,&dwIdOld);
bHook=false;
}
// 测试文件:
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
... {
if(!InstallHook())
...{
MessageBoxA(NULL,"Hook Error!","Hook",MB_OK);
return 1;
}
MessageBoxA(NULL,"TEST","TEST",MB_OK);//可以看见Test变成了Hook,也可以在其他进程中看见
if(!UninstallHook())
...{
MessageBoxA(NULL,"Uninstall Error!","Hook",MB_OK);
return 1;
}
return 0;
}