|
#include <ntddk.h>
#include <windef.h>
#include <ntstatus.h>
ULONG CR0VALUE;
BYTE OriginalBytes[5]={0}; //保存原始函数前五个字节
BYTE JmpAddress[5]={0xE9,0,0,0,0}; //跳转到HOOK函数的地址
extern POBJECT_TYPE *PsProcessType;
typedef NTSTATUS (__stdcall *NTOPENPROCESS)(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK AccessMask,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId );
//HOOK函数
NTSTATUS __stdcall MyNtOpenProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK AccessMask,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId );
void HookNtOpenProcess()
{
//赋值前面定义的数组
KIRQL Irql;
KdPrint(("[NtOpenProcess111] :0x%x",NtOpenProcess)); //地址验证
KdPrint(("[MyNtOpenProcess111] :0x%x",MyNtOpenProcess)); //地址验证
//保存函数前五个字节内容
RtlCopyMemory(OriginalBytes,(BYTE *)NtOpenProcess,5);
//保存新函数五个字节之后偏移
*(ULONG *)(JmpAddress+1)=(ULONG)MyNtOpenProcess-((ULONG)NtOpenProcess+5);
//开始inline hook
//关闭内存写保护
_asm
{
push eax
mov eax, cr0
mov CR0VALUE, eax
and eax, 0fffeffffh
mov cr0, eax
pop eax
}
//提升IRQL中断级
Irql=KeRaiseIrqlToDpcLevel();
//函数开头五个字节写JMP
RtlCopyMemory((BYTE *)NtOpenProcess,JmpAddress,5);
KdPrint(("JmpAddress :0x%x",JmpAddress));
KdPrint(("[MyNtOpenProcess222] :0x%x",MyNtOpenProcess));
//恢复Irql
KeLowerIrql(Irql);
//开启内存写保护
__asm
{
push eax
mov eax, CR0VALUE
mov cr0, eax
pop eax
}
}
NTSTATUS __stdcall OriginalNtOpenProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK AccessMask,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId )
{
/*_asm
{nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
}*/
return STATUS_SUCCESS;
}
NTSTATUS MyNtOpenProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK AccessMask,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId )
{
NTSTATUS rc;
ULONG PID;
//DbgPrint( "NtOpenProcess() called.\n" );
rc = (NTSTATUS)OriginalNtOpenProcess(
ProcessHandle,
AccessMask,
ObjectAttributes,
ClientId );
if( (ClientId != NULL) )
{
PID = (ULONG)ClientId->UniqueProcess;
//DbgPrint( "%d was opened,Handle is %d.\n", PID, (ULONG)ProcessHandle );
// 如果进程PID是1908,直接返回权限不足,并将句柄设置为空
if( PID == 1124 )
{
DbgPrint( "Some want to open pid 1520!\n" ); //调试输出 类似C语言的 Printf
ProcessHandle = NULL;
rc = STATUS_ACCESS_DENIED;
}
}
return rc;
}
void UnHookNtOpenProcess()
{
//把五个字节再写回到原函数
KIRQL Irql;
//关闭写保护
_asm
{
push eax
mov eax, cr0
mov CR0VALUE, eax
and eax, 0fffeffffh
mov cr0, eax
pop eax
}
//提升IRQL到Dpc
Irql=KeRaiseIrqlToDpcLevel();
RtlCopyMemory((BYTE *)NtOpenProcess,OriginalBytes,5);
KeLowerIrql(Irql);
//开启写保护
__asm
{
push eax
mov eax, CR0VALUE
mov cr0, eax
pop eax
}
}
VOID Unload(IN PDRIVER_OBJECT pDriverObj)
{
UnHookNtOpenProcess();
KdPrint(("[UnHookNtOpenProcess] Unloaded\n"));
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj,PUNICODE_STRING pRegistryString)
{
pDriverObj->DriverUnload = Unload;
HookNtOpenProcess();
return STATUS_SUCCESS;
} |
|