small io packet change

This commit is contained in:
donnaskiez 2024-05-12 01:27:18 +10:00
parent 2ada40ddbd
commit f106fa892a
8 changed files with 70 additions and 19 deletions

View file

@ -747,7 +747,7 @@ ObPreOpCallbackRoutine(_In_ PVOID RegistrationContext,
goto end; goto end;
} }
IrpQueueCompletePacket(report, report_size); IrpQueueSchedulePacket(report, report_size);
} }
end: end:
@ -942,7 +942,7 @@ EnumHandleCallback(_In_ PHANDLE_TABLE HandleTable,
goto end; goto end;
} }
IrpQueueCompletePacket(report, report_size); IrpQueueSchedulePacket(report, report_size);
end: end:
ExUnlockHandleTableEntry(HandleTable, Entry); ExUnlockHandleTableEntry(HandleTable, Entry);

View file

@ -191,6 +191,8 @@ typedef struct _DEFERRED_REPORTS_LIST {
} DEFERRED_REPORTS_LIST, *PDEFERRED_REPORTS_LIST; } DEFERRED_REPORTS_LIST, *PDEFERRED_REPORTS_LIST;
#define EVENT_COUNT 5
typedef struct _IRP_QUEUE_HEAD { typedef struct _IRP_QUEUE_HEAD {
LIST_ENTRY queue; LIST_ENTRY queue;
volatile UINT32 irp_count; volatile UINT32 irp_count;
@ -200,6 +202,7 @@ typedef struct _IRP_QUEUE_HEAD {
IO_CSQ csq; IO_CSQ csq;
KSPIN_LOCK lock; KSPIN_LOCK lock;
DEFERRED_REPORTS_LIST deferred_reports; DEFERRED_REPORTS_LIST deferred_reports;
KDPC dpc[EVENT_COUNT];
} IRP_QUEUE_HEAD, *PIRP_QUEUE_HEAD; } IRP_QUEUE_HEAD, *PIRP_QUEUE_HEAD;

View file

@ -892,7 +892,7 @@ ReportInvalidProcessModule(_In_ PPROCESS_MODULE_INFORMATION Module)
return; return;
} }
IrpQueueCompletePacket(report, report_size); IrpQueueSchedulePacket(report, report_size);
} }
/* /*
@ -2238,7 +2238,7 @@ HeartbeatDpcRoutine(_In_ PKDPC Dpc,
goto end; goto end;
} }
IrpQueueCompletePacket(packet, packet_size); IrpQueueSchedulePacket(packet, packet_size);
IncrementHeartbeatCounter(config); IncrementHeartbeatCounter(config);
} }

View file

@ -292,6 +292,7 @@ IrpQueueDeferPacket(_In_ PIRP_QUEUE_HEAD Queue,
* *
* IMPORTANT: All report buffers must be allocated in non paged memory. * IMPORTANT: All report buffers must be allocated in non paged memory.
*/ */
STATIC
NTSTATUS NTSTATUS
IrpQueueCompletePacket(_In_ PVOID Buffer, _In_ ULONG BufferSize) IrpQueueCompletePacket(_In_ PVOID Buffer, _In_ ULONG BufferSize)
{ {
@ -334,6 +335,49 @@ IrpQueueCompletePacket(_In_ PVOID Buffer, _In_ ULONG BufferSize)
return status; return status;
} }
STATIC
VOID
IrpQueueSchedulePacketDpc(_In_ struct _KDPC* Dpc,
_In_opt_ PVOID DeferredContext,
_In_opt_ PVOID SystemArgument1,
_In_opt_ PVOID SystemArgument2)
{
UNREFERENCED_PARAMETER(Dpc);
UNREFERENCED_PARAMETER(DeferredContext);
if (!ARGUMENT_PRESENT(SystemArgument1) ||
!ARGUMENT_PRESENT(SystemArgument2))
return;
PVOID buffer = SystemArgument1;
UINT32 buffer_length = (UINT32)SystemArgument2;
IrpQueueCompletePacket(buffer, buffer_length);
}
/*
* Not only does this allow reporting threads to continue execution once the
* report is scheduled (which in some cases such as handle reporting is very
* important for performance reasons), but it allows us to safely report from
* within a region guarded by a mutex as we use a spinlock here (for performance
* reasons, we dont need certain time critical threads being slept whilst we
* wait).
*/
VOID
IrpQueueSchedulePacket(_In_ PVOID Buffer, _In_ UINT32 BufferLength)
{
PIRP_QUEUE_HEAD queue = GetIrpQueueHead();
/* Maybe not the best implementation, but 99.9999% of the time there should
* be a dpc available.*/
while (TRUE) {
for (UINT32 index = 0; index < EVENT_COUNT; index++) {
if (KeInsertQueueDpc(&queue->dpc[index], Buffer, BufferLength))
return;
}
}
}
STATIC STATIC
VOID VOID
IrpQueueFreeDeferredPackets() IrpQueueFreeDeferredPackets()
@ -364,6 +408,10 @@ IrpQueueInitialise()
InitializeListHead(&queue->queue); InitializeListHead(&queue->queue);
InitializeListHead(&queue->deferred_reports.head); InitializeListHead(&queue->deferred_reports.head);
for (UINT32 index = 0; index < EVENT_COUNT; index++) {
KeInitializeDpc(&queue->dpc[index], IrpQueueSchedulePacketDpc, NULL);
}
status = IoCsqInitialize(&queue->csq, status = IoCsqInitialize(&queue->csq,
IrpQueueInsert, IrpQueueInsert,
IrpQueueRemove, IrpQueueRemove,
@ -1164,10 +1212,10 @@ DeviceCreate(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
UNREFERENCED_PARAMETER(DeviceObject); UNREFERENCED_PARAMETER(DeviceObject);
DEBUG_INFO("Handle to driver opened."); DEBUG_INFO("Handle to driver opened.");
//NTSTATUS status = ValidatePciDevices(); // NTSTATUS status = ValidatePciDevices();
//if (!NT_SUCCESS(status)) // if (!NT_SUCCESS(status))
// DEBUG_ERROR("ValidatePciDevices failed with status %x", status); // DEBUG_ERROR("ValidatePciDevices failed with status %x", status);
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Irp->IoStatus.Status; return Irp->IoStatus.Status;

View file

@ -62,7 +62,7 @@ ValidateIrpInputBuffer(_In_ PIRP Irp, _In_ ULONG RequiredSize);
NTSTATUS NTSTATUS
IrpQueueInitialise(); IrpQueueInitialise();
NTSTATUS VOID
IrpQueueCompletePacket(_In_ PVOID Buffer, _In_ ULONG BufferSize); IrpQueueSchedulePacket(_In_ PVOID Buffer, _In_ UINT32 BufferLength);
#endif #endif

View file

@ -372,7 +372,7 @@ ReportInvalidDriverObject(_In_ PDRIVER_OBJECT Driver, _In_ UINT32 ReportSubType)
return; return;
} }
IrpQueueCompletePacket(report, packet_size); IrpQueueSchedulePacket(report, packet_size);
} }
FORCEINLINE FORCEINLINE
@ -595,7 +595,7 @@ ReportNmiBlocking()
return; return;
} }
IrpQueueCompletePacket(report, packet_size); IrpQueueSchedulePacket(report, packet_size);
} }
STATIC STATIC
@ -632,7 +632,7 @@ ReportMissingCidTableEntry(_In_ PNMI_CONTEXT Context)
return; return;
} }
IrpQueueCompletePacket(report, packet_size); IrpQueueSchedulePacket(report, packet_size);
} }
STATIC STATIC
@ -663,7 +663,7 @@ ReportInvalidRipFoundDuringNmi(_In_ PNMI_CONTEXT Context)
return; return;
} }
IrpQueueCompletePacket(report, packet_size); IrpQueueSchedulePacket(report, packet_size);
} }
/* /*
@ -956,7 +956,7 @@ ReportApcStackwalkViolation(_In_ UINT64 Rip)
return; return;
} }
IrpQueueCompletePacket(report, packet_size); IrpQueueSchedulePacket(report, packet_size);
} }
/* /*
@ -1292,7 +1292,7 @@ ReportDpcStackwalkViolation(_In_ PDPC_CONTEXT Context, _In_ UINT64 Frame)
return; return;
} }
IrpQueueCompletePacket(report, packet_size); IrpQueueSchedulePacket(report, packet_size);
} }
STATIC STATIC
@ -1606,7 +1606,7 @@ ReportDataTableInvalidRoutine(_In_ TABLE_ID TableId, _In_ UINT64 Address)
return; return;
} }
IrpQueueCompletePacket(report, packet_size); IrpQueueSchedulePacket(report, packet_size);
} }
NTSTATUS NTSTATUS
@ -1945,7 +1945,7 @@ ReportWin32kBase_DxgInterfaceViolation(_In_ UINT32 TableIndex,
return; return;
} }
IrpQueueCompletePacket(report, packet_size); IrpQueueSchedulePacket(report, packet_size);
} }
STATIC STATIC

View file

@ -745,7 +745,7 @@ FindUnlinkedProcesses()
continue; continue;
} }
IrpQueueCompletePacket(report, packet_size); IrpQueueSchedulePacket(report, packet_size);
} }
end: end:

View file

@ -129,7 +129,7 @@ DetectAttachedThreadsProcessCallback(_In_ PTHREAD_LIST_ENTRY ThreadListEntry,
return; return;
} }
IrpQueueCompletePacket(report, packet_size); IrpQueueSchedulePacket(report, packet_size);
} }
VOID VOID