Hook.cpp
上传用户:yitai_qhd
上传日期:2008-04-24
资源大小:31k
文件大小:3k
- #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;
- }