看到网上到 Inline Hook都是修改前 5 个字节 ,怀疑他们是不是互相抄来抄去,Win32下Hook前8个字节,然后在自己的函数里面先恢复再执行原来的函数,没有问题啊,我就是这样Hook 了
NtOpenProcess的,可以啊??这样的话好像也不是像RootKit专题中说的Win32 和 Ring0 中inline Hook有很多不同点啊。。。。
还是我什么地方理解不对呢??
顺便贴下我的代码啊:
/////DriverHeader.h
#ifdef __cplusplus
extern "C"
{
#endif
#include "ntddk.h"
#ifdef __cplusplus
}
#endif
#define INITCODE code_seg("INIT")
#define PAGECODE code_seg("PAGE")
#define LOCKCODE code_seg()
#define INITDATA date_seg("INIT")
#define PAGEDATA data_seg("PAGE")
#define LOCKDATA data_seg()
VOID MyDriverUnload(IN PDRIVER_OBJECT DriverObject);
//声明原始API
extern "C" NTSYSAPI NTSTATUS NTAPI NtOpenProcess(
OUT PHANDLE ProcessHandle, //返回进程句柄
IN ACCESS_MASK DesiredAccess, //进程访问请求
IN POBJECT_ATTRIBUTES ObjectAttributes, //对象属性
IN PCLIENT_ID ClientId); //传入进程的标识符的结构
//声明自己的函数
NTSTATUS MyNtOpenProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId);
//保存原ZwOpenProcess的地址
typedef NTSTATUS (*REALZEOPENPROCESS)(OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId);
REALZEOPENPROCESS SysNtOpenProcess;
VOID Hook();
VOID CancelPageProtection();
VOID RecoverPageProtection();
/////DriverSrc.cpp
#include "DriverHeader.h"
typedef unsigned char BYTE;
BYTE mNewBytesToJmp[8]={ 0xB8, 0x0, 0x0, 0x40, 0x0, 0xFF, 0xE0, 0x0 };//跳转语句
BYTE mOldBytes[8]={0};//保存函数原来的前8个字节
#pragma INITCODE
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{
//分配派遣函数
DriverObject->DriverUnload=MyDriverUnload;
KdPrint(("Driverload...\n"));
Hook();
return STATUS_SUCCESS;
}
#pragma PAGECODE
VOID MyDriverUnload(IN PDRIVER_OBJECT DriverObject)
{
CancelPageProtection();//恢复
KIRQL vOldIRQL=KeRaiseIrqlToDpcLevel();
RtlCopyMemory(SysNtOpenProcess,mOldBytes,8*sizeof(BYTE));
KeLowerIrql(vOldIRQL);
RecoverPageProtection();
KdPrint(("DriverUnload...\n"));
}
#pragma PAGECODE
VOID CancelPageProtection()
{
//取消SSDT的内存页面保护属性
_asm{
//去掉写保护
push eax
mov eax, cr0
and eax, 0FFFEFFFFh
mov cr0, eax
pop eax
}
}
#pragma PAGECODE
VOID RecoverPageProtection()
{
//恢复SSDT的内存页面保护属性
_asm{
//恢复写保护
push eax
mov eax, cr0
or eax, 10000h
mov cr0, eax
pop eax
}
}
#pragma PAGECODE
NTSTATUS MyNtOpenProcess(OUT PHANDLE ProcessHandle,IN ACCESS_MASK DesiredAccess,IN POBJECT_ATTRIBUTES ObjectAttributes,IN PCLIENT_ID ClientId)
{
//先恢复原来函数到前几个字节到内容
KdPrint(("NtOpenProcess Called!\n"));
CancelPageProtection();
KIRQL vOldIRQL=KeRaiseIrqlToDpcLevel();
RtlCopyMemory(SysNtOpenProcess,mOldBytes,8*sizeof(BYTE));
KeLowerIrql(vOldIRQL);
RecoverPageProtection();
if((LONG)ClientId->UniqueProcess==296)//保护一下RTX
return STATUS_ACCESS_DENIED;//拒绝访问
NTSTATUS status=NtOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId);
Hook();//再次Hook
return status;
}
#pragma PAGECODE
VOID Hook()
{
UNICODE_STRING strFunctionName;
RtlInitUnicodeString(&strFunctionName,L"NtOpenProcess");
SysNtOpenProcess=(REALZEOPENPROCESS)MmGetSystemRoutineAddress(&strFunctionName);
if(SysNtOpenProcess)
{
KdPrint(("Get Function Orignal Address OK...\n"));
KIRQL vOldIRQL=KeRaiseIrqlToDpcLevel();//提高代码的优先级等级
*(ULONG*)(mNewBytesToJmp+1)=(ULONG)MyNtOpenProcess;
CancelPageProtection();//取消内存写 保护
RtlCopyMemory(mOldBytes,SysNtOpenProcess,8*sizeof(BYTE));//保存原来的内容
RtlCopyMemory(SysNtOpenProcess,mNewBytesToJmp,8*sizeof(BYTE));//写入跳转语句
RecoverPageProtection();//恢复内存写保护
KeLowerIrql(vOldIRQL);
}
else
{
KdPrint(("Get Function Orignal Address Failed...\n"));
}
}
//////////////////////////
大家看看,还是这样有效率上的问题,这样可以和Win32下的Inline Hook 统一了
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课