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;
}
IrpQueueCompletePacket(report, report_size);
IrpQueueSchedulePacket(report, report_size);
}
end:
@ -942,7 +942,7 @@ EnumHandleCallback(_In_ PHANDLE_TABLE HandleTable,
goto end;
}
IrpQueueCompletePacket(report, report_size);
IrpQueueSchedulePacket(report, report_size);
end:
ExUnlockHandleTableEntry(HandleTable, Entry);

View file

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

View file

@ -892,7 +892,7 @@ ReportInvalidProcessModule(_In_ PPROCESS_MODULE_INFORMATION Module)
return;
}
IrpQueueCompletePacket(report, report_size);
IrpQueueSchedulePacket(report, report_size);
}
/*
@ -2238,7 +2238,7 @@ HeartbeatDpcRoutine(_In_ PKDPC Dpc,
goto end;
}
IrpQueueCompletePacket(packet, packet_size);
IrpQueueSchedulePacket(packet, packet_size);
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.
*/
STATIC
NTSTATUS
IrpQueueCompletePacket(_In_ PVOID Buffer, _In_ ULONG BufferSize)
{
@ -334,6 +335,49 @@ IrpQueueCompletePacket(_In_ PVOID Buffer, _In_ ULONG BufferSize)
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
VOID
IrpQueueFreeDeferredPackets()
@ -364,6 +408,10 @@ IrpQueueInitialise()
InitializeListHead(&queue->queue);
InitializeListHead(&queue->deferred_reports.head);
for (UINT32 index = 0; index < EVENT_COUNT; index++) {
KeInitializeDpc(&queue->dpc[index], IrpQueueSchedulePacketDpc, NULL);
}
status = IoCsqInitialize(&queue->csq,
IrpQueueInsert,
IrpQueueRemove,
@ -1164,9 +1212,9 @@ DeviceCreate(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
UNREFERENCED_PARAMETER(DeviceObject);
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);
IoCompleteRequest(Irp, IO_NO_INCREMENT);

View file

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

View file

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

View file

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

View file

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