⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 irpfile.c

📁 Shadow SDT的应用
💻 C
📖 第 1 页 / 共 3 页
字号:
///////////////////////////////////////////////////////////////////////////////
//
//  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 + -