Files
MalwareSourceCode/Win32/Proof of Concepts/CheckKernelEATHook/CheckKernelHookDrv/CheckKernelHook/FileSystem.c
T
vxunderground 900263ea6f updates and moves
n/a
2022-04-11 20:00:13 -05:00

307 lines
8.6 KiB
C

#include "FileSystem.h"
/*创建文件对象,相当于自己实现了IoCreateFile FileObject中的IrpList循环指向自身*/
NTSTATUS
IrpCreateFile(
IN PUNICODE_STRING FilePath,
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 PFILE_OBJECT *FileObject
)
{
NTSTATUS ntStatus;
HANDLE hFile;
PFILE_OBJECT _FileObject;
UNICODE_STRING UniDeviceNameString;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
WCHAR *FileNameBuffer=NULL;
WORD FileObjectSize;
PIRP Irp;
KEVENT kEvent;
PIO_STACK_LOCATION IrpSp;
ACCESS_STATE AccessState;
AUX_ACCESS_DATA AuxData;
IO_SECURITY_CONTEXT SecurityContext;
PLIST_ENTRY IrpList;
InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_CASE_INSENSITIVE, 0, NULL);
//in win7 x86
FileObjectSize=0x80;
//创建文件对象
ntStatus = ObCreateObject(KernelMode,
*IoFileObjectType,
&ObjectAttributes,
KernelMode,
NULL,
FileObjectSize,
0,
0,
&_FileObject);
if(!NT_SUCCESS(ntStatus))
{
return ntStatus;
}
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); //在Irp堆栈上申请内存空间 大小为之前查询的DeviceObject->Size
if(Irp == NULL)
{
ObDereferenceObject(_FileObject);
return STATUS_INSUFFICIENT_RESOURCES;
}
KeInitializeEvent(&kEvent, SynchronizationEvent, FALSE);
RtlZeroMemory(_FileObject, FileObjectSize);
_FileObject->Type = IO_TYPE_FILE; //文件对象类型
_FileObject->Size = FileObjectSize; //文件对象大小
_FileObject->DeviceObject = RealDevice; //查询到的卷设备
_FileObject->Flags = FO_SYNCHRONOUS_IO;
FileNameBuffer=ExAllocatePool(NonPagedPool,FilePath->MaximumLength);
if (FileNameBuffer==NULL)
{
ObDereferenceObject(_FileObject);
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlCopyMemory(FileNameBuffer,FilePath->Buffer,FilePath->Length);//文件对象中的文件路径
_FileObject->FileName.Buffer=FileNameBuffer; //
_FileObject->FileName.Length=FilePath->Length;
_FileObject->FileName.MaximumLength=FilePath->MaximumLength;
IrpList=(PLIST_ENTRY)((DWORD)FileObject+0x74); //IrpList 循环指向自身
IrpList->Flink=IrpList;
IrpList->Blink=IrpList;
KeInitializeEvent(&_FileObject->Lock, SynchronizationEvent, FALSE);
KeInitializeEvent(&_FileObject->Event, NotificationEvent, FALSE);
RtlZeroMemory(&AuxData, sizeof(AUX_ACCESS_DATA));
ntStatus = SeCreateAccessState( &AccessState, //访问权限
&AuxData,
DesiredAccess,
IoGetFileObjectGenericMapping());
if (!NT_SUCCESS(ntStatus))
{
IoFreeIrp(Irp);
ObDereferenceObject(_FileObject);
ExFreePool(FileNameBuffer);
return ntStatus;
}
SecurityContext.SecurityQos = NULL;
SecurityContext.AccessState = &AccessState;
SecurityContext.DesiredAccess = DesiredAccess;
SecurityContext.FullCreateOptions = 0;
Irp->MdlAddress = NULL;
Irp->AssociatedIrp.SystemBuffer = NULL;
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 = _FileObject;
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, 0, TRUE, TRUE, TRUE);
ntStatus = IoCallDriver(DeviceObject, Irp);
if(ntStatus == STATUS_PENDING)
KeWaitForSingleObject(&kEvent, Executive, KernelMode, TRUE, 0);
ntStatus = IoStatusBlock.Status;
if(!NT_SUCCESS(ntStatus))
{
_FileObject->DeviceObject = NULL;
ObDereferenceObject(_FileObject);
}
else
{//增加引用计数
InterlockedIncrement(&_FileObject->DeviceObject->ReferenceCount);
if (_FileObject->Vpb)
InterlockedIncrement(&_FileObject->Vpb->ReferenceCount);
*FileObject = _FileObject;
}
return ntStatus;
}
NTSTATUS
IoCompletionRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context)
{
*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堆栈信息,传入FileObject
NTSTATUS
IrpQueryInformationFile(
IN PFILE_OBJECT FileObject,
IN PDEVICE_OBJECT DeviceObject,
OUT PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass)
{
NTSTATUS ntStatus;
PIRP Irp;
KEVENT kEvent;
PIO_STACK_LOCATION IrpSp;
IO_STATUS_BLOCK IoStatusBlock;
// if (FileObject->Vpb == 0 || FileObject->Vpb->DeviceObject == NULL)
// return STATUS_UNSUCCESSFUL;
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if(Irp == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
KeInitializeEvent(&kEvent, SynchronizationEvent, FALSE);
RtlZeroMemory(FileInformation, Length);
Irp->AssociatedIrp.SystemBuffer = FileInformation;
Irp->UserEvent = &kEvent;
Irp->UserIosb = &IoStatusBlock;
Irp->RequestorMode = KernelMode;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->Tail.Overlay.OriginalFileObject = FileObject;
IrpSp = IoGetNextIrpStackLocation(Irp);
IrpSp->MajorFunction = IRP_MJ_QUERY_INFORMATION;
IrpSp->DeviceObject = DeviceObject;
IrpSp->FileObject = FileObject;
IrpSp->Parameters.QueryFile.Length = Length;
IrpSp->Parameters.QueryFile.FileInformationClass = FileInformationClass;
IoSetCompletionRoutine(Irp, IoCompletionRoutine, 0, TRUE, TRUE, TRUE);
ntStatus = IoCallDriver(DeviceObject, Irp);
if (ntStatus == STATUS_PENDING)
KeWaitForSingleObject(&kEvent, Executive, KernelMode, TRUE, 0);
return IoStatusBlock.Status;
}
//Irp请求,将文件读入缓冲区中
NTSTATUS
IrpReadFile(
IN PFILE_OBJECT FileObject,
IN PDEVICE_OBJECT DeviceObject,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL)
{
NTSTATUS ntStatus;
PIRP Irp;
KEVENT kEvent;
PIO_STACK_LOCATION IrpSp;
//
if(ByteOffset == NULL)
{
if(!(FileObject->Flags & FO_SYNCHRONOUS_IO))
return STATUS_INVALID_PARAMETER;
ByteOffset = &FileObject->CurrentByteOffset;
}
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if(Irp == NULL) return STATUS_INSUFFICIENT_RESOURCES;
RtlZeroMemory(Buffer, Length);
if(FileObject->DeviceObject->Flags & DO_BUFFERED_IO) //缓冲方式
{
Irp->AssociatedIrp.SystemBuffer = Buffer;
}
else if(FileObject->DeviceObject->Flags & DO_DIRECT_IO) //直接方式
{
Irp->MdlAddress = IoAllocateMdl(Buffer, Length, 0, 0, 0);
if (Irp->MdlAddress == NULL)
{
IoFreeIrp(Irp);
return STATUS_INSUFFICIENT_RESOURCES;
}
MmBuildMdlForNonPagedPool(Irp->MdlAddress);
}
else //其他方式
{
Irp->UserBuffer = Buffer;
}
KeInitializeEvent(&kEvent, SynchronizationEvent, FALSE);
Irp->UserEvent = &kEvent;
Irp->UserIosb = IoStatusBlock;
Irp->RequestorMode = KernelMode;
Irp->Flags = IRP_READ_OPERATION;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->Tail.Overlay.OriginalFileObject = FileObject;
IrpSp = IoGetNextIrpStackLocation(Irp);
IrpSp->MajorFunction = IRP_MJ_READ;
IrpSp->MinorFunction = IRP_MN_NORMAL;
IrpSp->DeviceObject = DeviceObject;
IrpSp->FileObject = FileObject;
IrpSp->Parameters.Read.Length = Length;
IrpSp->Parameters.Read.ByteOffset = *ByteOffset;
IoSetCompletionRoutine(Irp, IoCompletionRoutine, 0, TRUE, TRUE, TRUE);
ntStatus = IoCallDriver(DeviceObject, Irp);
if (ntStatus == STATUS_PENDING)
KeWaitForSingleObject(&kEvent, Executive, KernelMode, TRUE, 0);
return IoStatusBlock->Status;
}