How Windows Handle to associate corresponding object type?

There are two files. One is LearnHanle.exe
(It is spelled incorrectly, should be LearnHandle.exe
), and the other is pop.exe
.
Source code of these files are here:
// LearnHanle.cpp
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
int main() {
STARTUPINFOW startup = { 0 };
startup.cb = sizeof startup;
PROCESS_INFORMATION pi = { 0 };
BOOL createProcResult = FALSE;
if (!CreateProcessW(L"C:\\pop.exe", NULL, NULL, NULL, TRUE, 0, NULL, NULL, &startup, &pi))
MessageBoxA(NULL, "Create Process Failed", "Alert", MB_OK);
char handle[80] = { 0 };
sprintf_s(handle, "Process Handle: %llu ProcessId: %llu", pi.hProcess, pi.dwProcessId);
MessageBoxA(NULL, handle, "Process", MB_OK);
sprintf_s(handle, "Thread Handle: %llu ThreadId: %llu", pi.hThread, pi.dwThreadId);
MessageBoxA(NULL, handle, "Thread", MB_OK);
system("pause");
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
// pop.cpp
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
int main() {
MessageBox(0, 0, 0, 0);
// Just sleep
Sleep(6000000);
}
LearnHanle.exe
just creates pop.exe
process then suspends itself. I viewed the details of LearnHanle.exe
process with Process Explorer
, and I found the HANDLE, which associates with pop.exe
process, and then I got the HANDLE address, as shown here:
Basic Information
Name: pop.exe(9092)
Type: Process
Description: Contains threads, an address space, and handles.
Address: 0xFFFFE786E04AF080
I debugged Windows 11 kernel with WinDbg, and I used !object
command to view the HANDLE address. The output is here:
0: kd> !object 0xffffe786e04af080
Object: ffffe786e04af080 Type: (ffffe786da2cfd20) Process
ObjectHeader: ffffe786e04af050 (new version)
HandleCount: 9 PointerCount: 293899
The ObjectHeader
pointer points at the Object Header of _EPROCESS
of pop.exe
process:
0: kd> dt _OBJECT_HEADER ffffe786e04af050
nt!_OBJECT_HEADER
+0x000 PointerCount : 0n293899
+0x008 HandleCount : 0n9
+0x008 NextToFree : 0x00000000`00000009 Void
+0x010 Lock : _EX_PUSH_LOCK
+0x018 TypeIndex : 0x47 'G'
+0x019 TraceFlags : 0 ''
+0x019 DbgRefTrace : 0y0
+0x019 DbgTracePermanent : 0y0
+0x01a InfoMask : 0x88 ''
+0x01b Flags : 0 ''
+0x01b NewObject : 0y0
+0x01b KernelObject : 0y0
+0x01b KernelOnlyAccess : 0y0
+0x01b ExclusiveObject : 0y0
+0x01b PermanentObject : 0y0
+0x01b DefaultSecurityQuota : 0y0
+0x01b SingleHandleEntry : 0y0
+0x01b DeletedInline : 0y0
+0x01c Reserved : 0
+0x020 ObjectCreateInfo : 0xffffe786`dca5ccc0 _OBJECT_CREATE_INFORMATION
+0x020 QuotaBlockCharged : 0xffffe786`dca5ccc0 Void
+0x028 SecurityDescriptor : 0xffffd705`63f2962f Void
+0x030 Body : _QUAD
However,
0: kd> dq 0xffffe786e04af080
ffffe786`e04af080 00000000`00000003 ffffe786`e04af088
ffffe786`e04af090 ffffe786`e04af088 ffffe786`e04af098
ffffe786`e04af0a0 ffffe786`e04af098 00000000`9e0b9000
ffffe786`e04af0b0 ffffe786`df8ec378 ffffe786`df8ec378
ffffe786`e04af0c0 00000000`00000000 00000000`00000000
ffffe786`e04af0d0 00000000`00200001 00000000`0000000f
ffffe786`e04af0e0 00000000`00000000 00000000`00000000
ffffe786`e04af0f0 00000000`00000000 00000000`00000000
I don't know what the address stores, and how !object
command gets pop.exe
process' information.
Then I used !process
command to view the host process LearnHanle.exe
.
0: kd> !process 0 0 LearnHanle.exe
PROCESS ffffe786e04020c0
SessionId: 1 Cid: 22a8 Peb: 0036b000 ParentCid: 1344
DirBase: 999c2000 ObjectTable: ffffd70567953400 HandleCount: 121.
Image: LearnHanle.exe
I looked at LearnHanle.exe
_HANDLE_TABLE.
0: kd> dt _HANDLE_TABLE ffffd70567953400
nt!_HANDLE_TABLE
+0x000 NextHandleNeedingPool : 0x400
+0x004 ExtraInfoPages : 0n0
+0x008 TableCode : 0xffffd705`6645a000
+0x010 QuotaProcess : 0xffffe786`e04020c0 _EPROCESS
+0x018 HandleTableList : _LIST_ENTRY [ 0xffffd705`67953bd8 - 0xffffd705`67133918 ]
+0x028 UniqueProcessId : 0x22a8
+0x02c Flags : 0
+0x02c StrictFIFO : 0y0
+0x02c EnableHandleExceptions : 0y0
+0x02c Rundown : 0y0
+0x02c Duplicated : 0y0
+0x02c RaiseUMExceptionOnInvalidHandleClose : 0y0
+0x030 HandleContentionEvent : _EX_PUSH_LOCK
+0x038 HandleTableLock : _EX_PUSH_LOCK
+0x040 FreeLists : [1] _HANDLE_TABLE_FREE_LIST
+0x040 ActualEntry : [32] ""
+0x060 DebugInfo : (null)
0: kd> dt _HANDLE_TABLE_ENTRY
nt!_HANDLE_TABLE_ENTRY
+0x000 VolatileLowValue : Int8B
+0x000 LowValue : Int8B
+0x000 InfoTable : Ptr64 _HANDLE_TABLE_ENTRY_INFO
+0x008 HighValue : Int8B
+0x008 NextFreeHandleEntry : Ptr64 _HANDLE_TABLE_ENTRY
+0x008 LeafHandleValue : _EXHANDLE
+0x000 RefCountField : Int8B
+0x000 Unlocked : Pos 0, 1 Bit
+0x000 RefCnt : Pos 1, 16 Bits
+0x000 Attributes : Pos 17, 3 Bits
+0x000 ObjectPointerBits : Pos 20, 44 Bits
+0x008 GrantedAccessBits : Pos 0, 25 Bits
+0x008 NoRightsUpgrade : Pos 25, 1 Bit
+0x008 Spare1 : Pos 26, 6 Bits
+0x00c Spare2 : Uint4B
I want to know how handle table entry in handle table of process to associates with corresponding object type.
And I would also like to know the purpose of these two members: struct _HANDLE_TABLE_ENTRY::ObjectPointerBits
, struct _OBJECT_HEADER::TypeIndex
and struct _KPROCESS::Header
(_DISPATCHER_HEADER).