inlinehook NtCreateFile

来源:互联网 发布:思科软件技术培训 编辑:程序博客网 时间:2024/06/16 05:59

#include "Driver.h"

 

unsigned char OrgCode[5];//原函数开头5个字节的代码

unsigned char HookJmp[5] = {0xe9,0,0,0,0};//放入原函数开头的Hook跳转

INT old_cr0;//存放cr0寄存器的内容

ULONG CreateAddr;//存放NtCreateFile的地址

#pragma LOCKEDCODE

/******************************************

打开写保护

*******************************************/

VOID WOpen(){

_asm{

cli

push eax

mov eax,old_cr0

mov cr0,eax

pop eax

}

return;

}

#pragma LOCKEDCODE

/******************************************

关闭写保护

*******************************************/

VOID WClose(){

_asm{

push eax

mov eax,cr0

mov old_cr0,eax

and eax,0xfffeffff

mov cr0,eax

pop eax

sti

}

}

#pragma LOCKEDCODE

/******************************************

获得NtCreateFile函数地址

*******************************************/

ULONG MyGetFunctionAddress(){

UNICODE_STRING FunctionName;

RtlInitUnicodeString(&FunctionName,L"NtCreateFile");

return (ULONG)MmGetSystemRoutineAddress(&FunctionName);

}

#pragma LOCKEDCODE

/******************************************

实现中继函数,用来在hook成功后调用原函数开头

的8个字节并完成原函数的功能

*******************************************/

_declspec (naked) NTSTATUS OriginalNtCreateFile(PHANDLE FileHandle,

ACCESS_MASK DesiredAccess,

POBJECT_ATTRIBUTES ObjectAttributes,

PIO_STATUS_BLOCK IoStatusBlock,

PLARGE_INTEGER AllocationSize,

ULONG FileAttributes,

ULONG ShareAccess,

ULONG CreateDisposition,

ULONG CreateOptions,

PVOID EaBuffer,

ULONG EaLength){

_asm{

mov edi,edi

push ebp

mov ebp,esp

mov eax,CreateAddr

add eax,5

jmp eax

}

}

#pragma LOCKEDCODE

/******************************************

构造hook函数

*******************************************/

NTSTATUS

NTAPI DetourNtCreateFile(PHANDLE FileHandle,

 ACCESS_MASK DesiredAccess,

 POBJECT_ATTRIBUTES ObjectAttributes,

 PIO_STATUS_BLOCK IoStatusBlock,

 PLARGE_INTEGER AllocationSize,

 ULONG FileAttributes,

 ULONG ShareAccess,

 ULONG CreateDisposition,

 ULONG CreateOptions,

 PVOID EaBuffer,

 ULONG EaLength){

 

UNICODE_STRING FilePath;

RtlInitUnicodeString(&FilePath,L"//??//C://test.txt");

//若生成的文件名等于C:/test.txt则禁止生成

if(!RtlCompareUnicodeString(ObjectAttributes->ObjectName,&FilePath,0)){

KdPrint(("ObjectAttributes->ObjectName:%wZ/n",ObjectAttributes->ObjectName));

KdPrint(("ObjectAttributes->RootDirectory:%wZ/n",ObjectAttributes->RootDirectory));

return STATUS_ACCESS_VIOLATION;

}

//否则调用原函数

NTSTATUS status = OriginalNtCreateFile(FileHandle,

DesiredAccess,

ObjectAttributes,

IoStatusBlock,

AllocationSize,

FileAttributes,

ShareAccess,

CreateDisposition,

CreateOptions,

EaBuffer,

EaLength);

 

return status;

 

}

#pragma LOCKEDCODE

/******************************************

开始Hook

*******************************************/

VOID HookNtCreateFile(){

KIRQL irql;

 

//获取函数地址

CreateAddr = MyGetFunctionAddress();

 

//关闭写保护

WClose();

 

//将pIofCallDriver函数开头前5个字节copy到OrgCode中

RtlCopyMemory(&OrgCode[0],(unsigned char *)CreateAddr,5);

 

//构造jmp指令

*(ULONG *)(HookJmp+1) = (ULONG)DetourNtCreateFile-((ULONG)CreateAddr+5);

 

//开始inline hook

//将中断请求级别提升到dpc

irql = KeRaiseIrqlToDpcLevel();

 

//将函数开头前8个字节替换成jmp

RtlCopyMemory((unsigned char *)CreateAddr,HookJmp,5);

//恢复irql

KeLowerIrql(irql);

//打开写保护

WOpen();

}

#pragma LOCKEDCODE

/******************************************

恢复被hook的函数

*******************************************/

VOID UnHook(){

 

KIRQL irql;

//关闭写保护

WClose();

//提升irql到dpc

irql = KeRaiseIrqlToDpcLevel();

//恢复

RtlCopyMemory((unsigned char *)CreateAddr,&OrgCode[0],5);

//恢复irql

KeLowerIrql(irql);

//开启写保护

WOpen();

 

}

/******************************************

卸载驱动时调用UnHook()来恢复NtCreateFile

******************************************/

VOID OnUnload(PDRIVER_OBJECT DriverObject){

UnHook();

}

/************************************************************************

* 函数名称:DriverEntry

* 功能描述:初始化驱动程序,定位和申请硬件资源,创建内核对象

* 参数列表:

      pDriverObject:从I/O管理器中传进来的驱动对象

      pRegistryPath:驱动程序在注册表的中的路径

* 返回 值:返回初始化驱动状态

*************************************************************************/

#pragma LOCKEDCODE

extern "C" NTSTATUS DriverEntry (

IN PDRIVER_OBJECT pDriverObject,

IN PUNICODE_STRING pRegistryPath

{

#ifdefDBG

_asm int 3

#endif

KdPrint(("进入驱动入口/n"));

//注册卸载驱动调用函数入口

pDriverObject->DriverUnload = OnUnload;

 

//开始HOOK

    HookNtCreateFile();

KdPrint(("DriverEntry end/n"));

 

return STATUS_SUCCESS;

}

原创粉丝点击