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

307 lines
8.6 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
}