Secondly, we consult MSDN for its signature:
VOID KeInitializeQueue(
_Out_ PRKQUEUE Queue,
_In_ ULONG Count
);
The routine itself does not return anything.
We learn it takes two parameters and as the assembly contains the ret 8 instruction, the KeInitializeQueue function cleans up the stack and thus, it uses the stdcall convention.
The KQUEUE data structure is defined as follows:
typedef struct _KQUEUE {
DISPATCHER_HEADER Header;
LIST_ENTRY EntryListHead;
ULONG CurrentCount;
ULONG MaximumCount;
LIST_ENTRY ThreadListHead;
} KQUEUE, *PKQUEUE, *RESTRICTED_POINTER PRKQUEUE;
In order to obtain the offsets for the struct parts, we query the data structure in WinDbg:
0: kd> dt nt!_KQUEUE
+0x000 Header : _DISPATCHER_HEADER
+0x010 EntryListHead : _LIST_ENTRY
+0x018 CurrentCount : Uint4B
+0x01c MaximumCount : Uint4B
+0x020 ThreadListHead : _LIST_ENTRY
Analogously, we investigate the data structure DISPATCHER_HEADER:
0: kd> dt nt!_DISPATCHER_HEADER
+0x000 Type : UChar
+0x001 TimerControlFlags : UChar
+0x001 Absolute : Pos 0, 1 Bit
+0x001 Coalescable : Pos 1, 1 Bit
+0x001 KeepShifting : Pos 2, 1 Bit
+0x001 EncodedTolerableDelay : Pos 3, 5 Bits
+0x001 Abandoned : UChar
+0x001 Signalling : UChar
+0x002 ThreadControlFlags : UChar
+0x002 CpuThrottled : Pos 0, 1 Bit
+0x002 CycleProfiling : Pos 1, 1 Bit
+0x002 CounterProfiling : Pos 2, 1 Bit
+0x002 Reserved : Pos 3, 5 Bits
+0x002 Hand : UChar
+0x002 Size : UChar
+0x003 TimerMiscFlags : UChar
+0x003 Index : Pos 0, 1 Bit
+0x003 Processor : Pos 1, 5 Bits
+0x003 Inserted : Pos 6, 1 Bit
+0x003 Expired : Pos 7, 1 Bit
+0x003 DebugActive : UChar
+0x003 ActiveDR7 : Pos 0, 1 Bit
+0x003 Instrumented : Pos 1, 1 Bit
+0x003 Reserved2 : Pos 2, 4 Bits
+0x003 UmsScheduled : Pos 6, 1 Bit
+0x003 UmsPrimary : Pos 7, 1 Bit
+0x003 DpcActive : UChar
+0x000 Lock : Int4B
+0x004 SignalState : Int4B
+0x008 WaitListHead : _LIST_ENTRY
The following page provides a clearer overview of the structure, which facilitates the comprehension:
http://msdn.moonsols.com/win7rtm_x86/DISPATCHER_HEADER.html
http://msdn.moonsols.com/win7rtm_x86/DISPATCHER_HEADER.html
The _LIST_ENTRY structure, in contrast, has only a few members:
0: kd> dt nt!_LIST_ENTRY
+0x000 Flink : Ptr32 _LIST_ENTRY
+0x004 Blink : Ptr32 _LIST_ENTRY
We try to translate it by introducing some additional variables:
VOID KeInitializeQueue(
_Out_ PRKQUEUE Queue,
_In_ ULONG Count
)
{
Queue->Header.Type = 4;{
Queue->Header.Size = 0x0A;
Queue->Header.Abandoned = 0;
Queue->Header.SignalState = 0;
Queue->Header.WaitListHead->Blink = &(Queue->WaitListHead);
Queue->Header.WaitListHead->Flink = &(Queue->WaitListHead);
Queue->EntryListHead->Blink = &(Queue->EntryListHead)
Queue->EntryListHead->Flink = &(Queue->EntryListHead)
Queue->ThreadListHead->Blink = &(Queue->ThreadListHead)
Queue->ThreadListHead->Flink = &(Queue->ThreadListHead)
if (Queue->CurrentCount != Count) {
Queue->MaximumCount = KeNumberProcessors();
}
else {
Queue->MaximumCount = Count;
}
}
No comments:
Post a comment