📄 irpfile.c
字号:
///////////////////////////////////////////////////////////////////////////////
//
// FileName : IrpFile.c
// Version : 0.10
// Author : embedlinux(E-mai:hqulyc@126.com QQ:5054-3533)
// Date : 2008-08-04
// Comment :
//
///////////////////////////////////////////////////////////////////////////////
#include "IrpFile.h"
NTSTATUS ZwSaveKey( HANDLE KeyHandle, HANDLE FileHandle );
NTSTATUS
IoCompletionRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context)
{
DbgPrint(("IoCompletionRoutine!\n"));
*Irp->UserIosb = Irp->IoStatus;
if (Irp->UserEvent)
KeSetEvent(Irp->UserEvent, IO_NO_INCREMENT, 0);
if (Irp->MdlAddress)
{
IoFreeMdl(Irp->MdlAddress);
Irp->MdlAddress = NULL;
}
IoFreeIrp(Irp);
return STATUS_MORE_PROCESSING_REQUIRED;
}
//IRP_MJ_CREATE
//NtCreateFile
//创建或新建文件返回句柄,不过发IRP返回的是FILE_OBJECT,线程无关的.
NTSTATUS
IrpCreateFile(
OUT PFILE_OBJECT *FileObject, //文件对象
IN ACCESS_MASK DesiredAccess,
IN PUNICODE_STRING FilePath, //文件路径
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER AllocationSize OPTIONAL,
IN ULONG FileAttributes,
IN ULONG ShareAccess,
IN ULONG CreateDisposition,
IN ULONG CreateOptions,
IN PVOID EaBuffer OPTIONAL,
IN ULONG EaLength)
{
NTSTATUS ntStatus;
HANDLE hFile;
PFILE_OBJECT pFileObj, pFileObject;
UNICODE_STRING UniDeviceNameString;
OBJECT_ATTRIBUTES ObjectAttributes;
PDEVICE_OBJECT DeviceObject, RealDevice; //设备对象
PIRP Irp;
KEVENT kEvent;
PIO_STACK_LOCATION IrpSp;
ACCESS_STATE AccessState;
AUX_ACCESS_DATA AuxData;
IO_SECURITY_CONTEXT SecurityContext;
if( FilePath->Length < 6 )
return STATUS_INVALID_PARAMETER;
RtlInitUnicodeString( &UniDeviceNameString, L"\\DosDevices\\*:\\" );
UniDeviceNameString.Buffer[12] = FilePath->Buffer[0];
InitializeObjectAttributes(&ObjectAttributes, &UniDeviceNameString, OBJ_KERNEL_HANDLE, NULL, NULL);
ntStatus = IoCreateFile(
&hFile,
GENERIC_READ | SYNCHRONIZE,
&ObjectAttributes,
IoStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0,
CreateFileTypeNone,
NULL,//Drivers must set this parameter to NULL
IO_NO_PARAMETER_CHECKING);
if( !NT_SUCCESS(ntStatus) )
return ntStatus;
//通过handle得到Object
ntStatus = ObReferenceObjectByHandle(
hFile, //Specifies an open handle for an object.
FILE_READ_ACCESS, //ACCESS_MASK
*IoFileObjectType, //Pointer to the object type.
KernelMode, //Lower-level drivers should specify KernelMode
&pFileObj, //OUT: PFILE_OBJECT
0);
NtClose(hFile);
if( !NT_SUCCESS(ntStatus) )
return ntStatus;
DeviceObject = pFileObj->Vpb->DeviceObject;
RealDevice = pFileObj->Vpb->RealDevice;
ObDereferenceObject(pFileObj);
InitializeObjectAttributes( &ObjectAttributes, NULL, OBJ_CASE_INSENSITIVE, 0, NULL );
ntStatus = ObCreateObject( //创建文件对象
KernelMode,
*IoFileObjectType,
&ObjectAttributes,
KernelMode,
NULL,
sizeof(FILE_OBJECT),
0,
0,
&pFileObject);
if ( !NT_SUCCESS(ntStatus) )
return ntStatus;
Irp = IoAllocateIrp( DeviceObject->StackSize, FALSE );
if(Irp == NULL)
{
ObDereferenceObject( pFileObject );
return STATUS_INSUFFICIENT_RESOURCES;
}
//创建一个Event, Synchronization事件(自动复位)
KeInitializeEvent(&kEvent, SynchronizationEvent, FALSE);
RtlZeroMemory( pFileObject, sizeof(FILE_OBJECT) );
pFileObject->Type = IO_TYPE_FILE;
pFileObject->Size = sizeof(FILE_OBJECT);
pFileObject->DeviceObject = RealDevice;
pFileObject->Flags = FO_SYNCHRONOUS_IO; //The file object is opened for synchronous I/O.
RtlInitUnicodeString( &pFileObject->FileName, &FilePath->Buffer[2] );
KeInitializeEvent( &pFileObject->Lock, SynchronizationEvent, FALSE );//自动复位
KeInitializeEvent( &pFileObject->Event, NotificationEvent, FALSE ); //手动复位
RtlZeroMemory( &AuxData, sizeof(AUX_ACCESS_DATA) );
ntStatus = SeCreateAccessState(
&AccessState,
&AuxData,
DesiredAccess,
IoGetFileObjectGenericMapping() );
if (!NT_SUCCESS(ntStatus))
{
IoFreeIrp(Irp);
ObDereferenceObject( pFileObject );
return ntStatus;
}
SecurityContext.SecurityQos = NULL; //Reserved for system use
SecurityContext.AccessState = &AccessState;
SecurityContext.DesiredAccess = DesiredAccess;
SecurityContext.FullCreateOptions = 0;
Irp->MdlAddress = NULL;
Irp->AssociatedIrp.SystemBuffer = EaBuffer;
Irp->Flags = IRP_CREATE_OPERATION | IRP_SYNCHRONOUS_API;
Irp->RequestorMode = KernelMode;
Irp->UserIosb = IoStatusBlock;
Irp->UserEvent = &kEvent;
Irp->PendingReturned = FALSE;
Irp->Cancel = FALSE;
Irp->CancelRoutine = NULL;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->Tail.Overlay.AuxiliaryBuffer = NULL;
Irp->Tail.Overlay.OriginalFileObject = pFileObject;
IrpSp = IoGetNextIrpStackLocation(Irp);
IrpSp->MajorFunction = IRP_MJ_CREATE; //创建文件
IrpSp->DeviceObject = DeviceObject;
IrpSp->FileObject = pFileObject;
IrpSp->Parameters.Create.SecurityContext = &SecurityContext;
IrpSp->Parameters.Create.Options = (CreateDisposition << 24) | CreateOptions;
IrpSp->Parameters.Create.FileAttributes = (USHORT)FileAttributes;
IrpSp->Parameters.Create.ShareAccess = (USHORT)ShareAccess;
IrpSp->Parameters.Create.EaLength = EaLength;
IoSetCompletionRoutine( Irp, IoCompletionRoutine, 0, TRUE, TRUE, TRUE );
ntStatus = IoCallDriver( DeviceObject, Irp );//最好自己实现IoCallDriver
if( ntStatus == STATUS_PENDING )
KeWaitForSingleObject( &kEvent, Executive, KernelMode, TRUE, 0 );
ntStatus = IoStatusBlock->Status;
if( !NT_SUCCESS(ntStatus) )
{
pFileObject->DeviceObject = NULL;
ObDereferenceObject( pFileObject );
}
else
{
InterlockedIncrement( &pFileObject->DeviceObject->ReferenceCount );
if ( pFileObject->Vpb )
InterlockedIncrement( &pFileObject->Vpb->ReferenceCount );
*FileObject = pFileObject;
}
return ntStatus;
}
NTSTATUS
IRPCreateFile(
IN PUNICODE_STRING FileName,
IN ACCESS_MASK DesiredAccess,
IN ULONG FileAttributes,
IN ULONG ShareAccess,
IN ULONG CreateDisposition,
IN ULONG CreateOptions,
IN PDEVICE_OBJECT DeviceObject,
IN PDEVICE_OBJECT RealDevice,
OUT PVOID *Object )
{
NTSTATUS status;
KEVENT event;
PIRP irp;
IO_STATUS_BLOCK ioStatus;
PIO_STACK_LOCATION irpSp;
IO_SECURITY_CONTEXT securityContext;
ACCESS_STATE accessState;
OBJECT_ATTRIBUTES objectAttributes;
PFILE_OBJECT fileObject;
AUX_ACCESS_DATA auxData;
RtlZeroMemory(&auxData, sizeof(AUX_ACCESS_DATA));
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (irp == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
InitializeObjectAttributes(&objectAttributes, NULL, OBJ_CASE_INSENSITIVE, 0, NULL);
status = ObCreateObject(KernelMode,
*IoFileObjectType,
&objectAttributes,
KernelMode,
NULL,
sizeof(FILE_OBJECT),
0,
0,
(PVOID *)&fileObject);
if (!NT_SUCCESS(status))
{
IoFreeIrp(irp);
return status;
}
RtlZeroMemory(fileObject, sizeof(FILE_OBJECT));
fileObject->Type = IO_TYPE_FILE;
fileObject->Size = sizeof(FILE_OBJECT);
fileObject->DeviceObject = RealDevice;
//fileObject->RelatedFileObject = NULL;
fileObject->Flags = FO_SYNCHRONOUS_IO;
fileObject->FileName.MaximumLength = FileName->MaximumLength;
fileObject->FileName.Buffer = ExAllocatePool(NonPagedPool, FileName->MaximumLength);
if (fileObject->FileName.Buffer == NULL)
{
IoFreeIrp(irp);
ObDereferenceObject(fileObject);
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlCopyUnicodeString(&fileObject->FileName, FileName);
KeInitializeEvent(&fileObject->Lock, SynchronizationEvent, FALSE);
KeInitializeEvent(&fileObject->Event, NotificationEvent, FALSE);
irp->MdlAddress = NULL;
irp->Flags |= IRP_CREATE_OPERATION | IRP_SYNCHRONOUS_API;
irp->RequestorMode = KernelMode;
irp->UserIosb = &ioStatus;
irp->UserEvent = &event;
irp->PendingReturned = FALSE;
irp->Cancel = FALSE;
irp->CancelRoutine = NULL;
irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();
irp->Tail.Overlay.AuxiliaryBuffer = NULL;
irp->Tail.Overlay.OriginalFileObject = fileObject;
status = SeCreateAccessState( &accessState,
&auxData,
DesiredAccess,
IoGetFileObjectGenericMapping());
if (!NT_SUCCESS(status))
{
IoFreeIrp(irp);
ExFreePool(fileObject->FileName.Buffer);
ObDereferenceObject(fileObject);
return status;
}
securityContext.SecurityQos = NULL;
securityContext.AccessState = &accessState;
securityContext.DesiredAccess = DesiredAccess;
securityContext.FullCreateOptions = 0;
irpSp = IoGetNextIrpStackLocation(irp);
irpSp->MajorFunction = IRP_MJ_CREATE;
irpSp->DeviceObject = DeviceObject;
irpSp->FileObject = fileObject;
irpSp->Parameters.Create.SecurityContext = &securityContext;
irpSp->Parameters.Create.Options = (CreateDisposition << 24) | CreateOptions;
irpSp->Parameters.Create.FileAttributes = (USHORT)FileAttributes;
irpSp->Parameters.Create.ShareAccess = (USHORT)ShareAccess;
irpSp->Parameters.Create.EaLength = 0;
IoSetCompletionRoutine(irp, IoCompletionRoutine, NULL, TRUE, TRUE, TRUE);
status = IoCallDriver(DeviceObject, irp);
if (status == STATUS_PENDING)
KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL);
status = ioStatus.Status;
if (!NT_SUCCESS(status))
{
ExFreePool(fileObject->FileName.Buffer);
fileObject->FileName.Length = 0;
fileObject->DeviceObject = NULL;
ObDereferenceObject(fileObject);
}
else
{
InterlockedIncrement(&fileObject->DeviceObject->ReferenceCount);
if (fileObject->Vpb)
{
InterlockedIncrement(&fileObject->Vpb->ReferenceCount);
}
*Object = fileObject;
DbgPrint("Open file success! object = %x\n", fileObject);
}
return status;
}
//IRP_MJ_CLEANUP
//NtClose
//用于关闭HANDLE的
NTSTATUS IrpClose(
IN PFILE_OBJECT FileObject)
{
NTSTATUS ntStatus;
IO_STATUS_BLOCK IoStatusBlock;
PIRP Irp;
KEVENT kEvent;
PIO_STACK_LOCATION IrpSp;
PDEVICE_OBJECT pBaseDeviceObject = FileObject->Vpb->DeviceObject;
if ( FileObject->Vpb == 0 || FileObject->Vpb->DeviceObject == NULL )
return STATUS_UNSUCCESSFUL;
Irp = IoAllocateIrp( FileObject->Vpb->DeviceObject->StackSize, FALSE );
if( Irp == NULL )
return STATUS_INSUFFICIENT_RESOURCES;
KeInitializeEvent( &kEvent, SynchronizationEvent, FALSE );
Irp->UserEvent = &kEvent;
Irp->UserIosb = &IoStatusBlock;
Irp->RequestorMode = KernelMode;
Irp->Flags = IRP_CLOSE_OPERATION | IRP_SYNCHRONOUS_API;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->Tail.Overlay.OriginalFileObject = FileObject; //输入的文件对象
IrpSp = IoGetNextIrpStackLocation(Irp);
IrpSp->MajorFunction = IRP_MJ_CLEANUP;
IrpSp->FileObject = FileObject;
ntStatus = IoCallDriver( pBaseDeviceObject, Irp );
if ( ntStatus == STATUS_PENDING )
KeWaitForSingleObject( &kEvent, Executive, KernelMode, FALSE, NULL );
ntStatus = IoStatusBlock.Status;
if(!NT_SUCCESS(ntStatus))
{
IoFreeIrp(Irp);
return ntStatus;
}
KeClearEvent(&kEvent);
IoReuseIrp( Irp , STATUS_SUCCESS );
Irp->UserEvent = &kEvent;
Irp->UserIosb = &IoStatusBlock;
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->AssociatedIrp.SystemBuffer = (PVOID)NULL;
Irp->Flags = IRP_CLOSE_OPERATION | IRP_SYNCHRONOUS_API;
IrpSp = IoGetNextIrpStackLocation(Irp);
IrpSp->MajorFunction = IRP_MJ_CLOSE;
IrpSp->FileObject = FileObject;
if ( FileObject->Vpb && !(FileObject->Flags & FO_DIRECT_DEVICE_OPEN) )
{
InterlockedDecrement( &FileObject->Vpb->ReferenceCount );
FileObject->Flags |= FO_FILE_OPEN_CANCELLED;
}
ntStatus = IoCallDriver( pBaseDeviceObject, Irp );
if ( ntStatus == STATUS_PENDING )
KeWaitForSingleObject( &kEvent, Executive, KernelMode, FALSE, NULL );
IoFreeIrp(Irp);
ntStatus = IoStatusBlock.Status;
return ntStatus;
}
NTSTATUS
IrpFileClose(
IN PDEVICE_OBJECT DeviceObject,
IN PFILE_OBJECT FileObject
)
{
NTSTATUS status;
KEVENT event;
PIRP irp;
PVPB vpb;
IO_STATUS_BLOCK ioStatusBlock;
PIO_STACK_LOCATION irpSp;
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (irp == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
irp->Tail.Overlay.OriginalFileObject = FileObject;
irp->Tail.Overlay.Thread = PsGetCurrentThread();
irp->RequestorMode = KernelMode;
irp->UserEvent = &event;
irp->UserIosb = &irp->IoStatus;
irp->Overlay.AsynchronousParameters.UserApcRoutine = (PIO_APC_ROUTINE)NULL;
irp->Flags = IRP_SYNCHRONOUS_API | IRP_CLOSE_OPERATION;
irpSp = IoGetNextIrpStackLocation(irp);
irpSp->MajorFunction = IRP_MJ_CLEANUP;
irpSp->FileObject = FileObject;
status = IoCallDriver(DeviceObject, irp);
if (status == STATUS_PENDING)
{
KeWaitForSingleObject( &event,
UserRequest,
KernelMode,
FALSE,
NULL);
}
IoReuseIrp(irp , STATUS_SUCCESS);
KeClearEvent(&event);
irpSp = IoGetNextIrpStackLocation(irp);
irpSp->MajorFunction = IRP_MJ_CLOSE;
irpSp->FileObject = FileObject;
irp->UserIosb = &ioStatusBlock;
irp->UserEvent = &event;
irp->Tail.Overlay.OriginalFileObject = FileObject;
irp->Tail.Overlay.Thread = PsGetCurrentThread();
irp->AssociatedIrp.SystemBuffer = (PVOID)NULL;
irp->Flags = IRP_CLOSE_OPERATION | IRP_SYNCHRONOUS_API;
vpb = FileObject->Vpb;
if (vpb && !(FileObject->Flags & FO_DIRECT_DEVICE_OPEN))
{
InterlockedDecrement(&vpb->ReferenceCount);
FileObject->Flags |= FO_FILE_OPEN_CANCELLED;
}
status = IoCallDriver(DeviceObject, irp);
if (status == STATUS_PENDING)
{
KeWaitForSingleObject( &event,
Executive,
KernelMode,
FALSE,
NULL);
}
IoFreeIrp(irp);
return status;
}
//IRP_MJ_DIRECTORY_CONTROL
//NtQueryDirectoryFile
//枚举目录,好多时候都被hook的
NTSTATUS
IrpQueryDirectoryFile(
IN PFILE_OBJECT FileObject,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass,
IN PUNICODE_STRING FileName OPTIONAL )
{
NTSTATUS ntStatus;
PIRP Irp;
KEVENT kEvent; //Handle for a caller-created event
PIO_STACK_LOCATION IrpSp;
if ( FileObject->Vpb == 0 || FileObject->Vpb->DeviceObject == NULL )
return STATUS_UNSUCCESSFUL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -