'HandleTableListHead'에 해당되는 글 1건

  1. 2009.11.18 [Windows NT] Win2k ObpKernelHandleTable
Windows OS2009. 11. 18. 22:30
반응형

Win2k에서 커널 핸들 테이블을 사용해야 하는데 이게 XP와 달라서 삽질한 내용이다.
요즘 세상에 Win2k를 위한 정보가 쓸모 있을까 싶지만 다른 데는 없는 정보이니 그냥 적어둔다. ^^

[XP의 커널 핸들 테이블 주소]

XP에서는 커널 핸들 테이블은 시스템 프로세스의 핸들 테이블을 의미한다.
다음과 같이 확인 할수 있다.

kd> dd nt!ObpKernelHandleTable L1
80561e38  e1001d28

ObpKernelHandleTable 내부 변수에 저장된 e1001d28이 커널 핸들 테이블 주소다.

이제 시스템 프로세스의 핸들 테이블을 찾아 보자.

kd> !process 0 0 System
PROCESS 8133e7f8  SessionId: none  Cid: 0004    Peb: 00000000  ParentCid: 0000
    DirBase: 00039000  ObjectTable: e1001d28  HandleCount: 230.
    Image: System

kd> dt 8133e7f8 _EPROCESS
nt!_EPROCESS
   +0x000 Pcb              : _KPROCESS
   +0x06c ProcessLock      : _EX_PUSH_LOCK
   +0x070 CreateTime       : _LARGE_INTEGER 0x0
   +0x078 ExitTime         : _LARGE_INTEGER 0x0
   +0x080 RundownProtect   : _EX_RUNDOWN_REF
   +0x084 UniqueProcessId  : 0x00000004
   +0x088 ActiveProcessLinks : _LIST_ENTRY [ 0x81193b48 - 0x80562758 ]
   +0x090 QuotaUsage       : [3] 0
   +0x09c QuotaPeak        : [3] 0
   +0x0a8 CommitCharge     : 7
   +0x0ac PeakVirtualSize  : 0x371000
   +0x0b0 VirtualSize      : 0x1d2000
   +0x0b4 SessionProcessLinks : _LIST_ENTRY [ 0x0 - 0x0 ]
   +0x0bc DebugPort        : (null)
   +0x0c0 ExceptionPort    : (null)
   +0x0c4 ObjectTable      : 0xe1001d28 _HANDLE_TABLE
    ...

시스템 프로세스의 ObjectTable 필드에 같은 값이 들어 있는 것을 볼 수 있다.
따라서 코드를 작성할 때는 간단히 다음과 같은 형식으로 구해도 된다.

MyObpKernelHandleTable = PsInitialSystemProcess->ObjectTable;

[2K의 커널 핸들 테이블 주소]

2K에서는 커널 핸들 테이블은 시스템 프로세스의 핸들 테이블을 의미하지 않는다.
위과 같은 방법으로 확인 할 수 있다.

kd> dd nt!ObpKernelHandleTable L1
8046e438  820b7608

ObpKernelHandleTable 내부 변수에 저장된 820b7608이 커널 핸들 테이블 주소다.

이제 시스템 프로세스의 핸들 테이블을 찾아 보자.

kd> !process 0 0 System
PROCESS 82083be0  SessionId: 0  Cid: 0008    Peb: 00000000  ParentCid: 0000
    DirBase: 00030000  ObjectTable: 820b7688  TableSize: 132.
    Image: System
kd> dt 82083be0 _EPROCESS
nt!_EPROCESS
   +0x000 Pcb              : _KPROCESS
   +0x06c ExitStatus       : 0x103
   +0x070 LockEvent        : _KEVENT
   +0x080 LockCount        : 1
   +0x088 CreateTime       : _LARGE_INTEGER 0x0
   +0x090 ExitTime         : _LARGE_INTEGER 0x0
   +0x098 LockOwner        : (null)
   +0x09c UniqueProcessId  : 0x00000008
   +0x0a0 ActiveProcessLinks : _LIST_ENTRY [ 0x81f96780 - 0x8046e460 ]
   +0x0a8 QuotaPeakPoolUsage : [2] 0
   +0x0b0 QuotaPoolUsage   : [2] 0
   +0x0b8 PagefileUsage    : 6
   +0x0bc CommitCharge     : 6
   +0x0c0 PeakPagefileUsage : 0x27
   +0x0c4 PeakVirtualSize  : 0x1d3000
   +0x0c8 VirtualSize      : 0x1b0000
   +0x0d0 Vm               : _MMSUPPORT
   +0x118 SessionProcessLinks : _LIST_ENTRY [ 0x0 - 0x0 ]
   +0x120 DebugPort        : (null)
   +0x124 ExceptionPort    : (null)
   +0x128 ObjectTable      : 0x820b7688 _HANDLE_TABLE
    ...

시스템 프로세스의 ObjectTable 필드에 다른 값이 들어 있는 것을 볼 수 있다.
이것이 의미하는 바는...

2K에서는 시스템 프로세스의 핸들 테이블은 그냥 시스템 프로세스의 핸들 테이블이고,
커널 핸들 테이블은 시스템 프로세스와 직접 연결되어 있지 않다는 것이다.

[2K 에서 커널 핸들 테이블을 사용하려면 어떻게 해야 하나?]

몇 시간의 구글링 끝에 단서를 하나 찾을 수 있었다.
커널 내부 변수중 하나인 핸들 테이블 리스트였다.

nt!HandleTableListHead

프로세스마다 존재하는 핸들 테이블은 리스트로 연결되어 있다.
커널 핸들 테이블이 직접 시스템 프로세스에 존재하지는 않지만 이것도 핸들 테이블이므로 저 리스트에 연결되어 있을 것이라는 생각이 들었다.

핸들 테이블을 리스트를 쭉 살펴보면 다음과 같다.

kd> dl nt!HandleTableListHead
8046dda8  820b76dc 81f11b1c 00000000 00000000
820b76dc  820b765c 8046dda8 00040000 00000000
820b765c  81f96a5c 820b76dc 00040000 00000000
81f96a5c  81f66f1c 820b765c 00040000 00000000
81f66f1c  81f667fc 81f96a5c 00040000 00000000
...

이 리스트는 HANDLE_TABLE 구조체에서 HandleTableList 로 연결된 리스트이다.

kd> dt _HANDLE_TABLE
nt!_HANDLE_TABLE
   +0x000 Flags            : Uint4B
   +0x004 HandleCount      : Int4B
   +0x008 Table            : Ptr32 Ptr32 Ptr32 _HANDLE_TABLE_ENTRY
   +0x00c QuotaProcess     : Ptr32 _EPROCESS
   +0x010 UniqueProcessId  : Ptr32 Void
   +0x014 FirstFreeTableEntry : Int4B
   +0x018 NextIndexNeedingPool : Int4B
   +0x01c HandleTableLock  : _ERESOURCE
   +0x054 HandleTableList  : _LIST_ENTRY
   +0x05c HandleContentionEvent : _KEVENT

따라서 핸들 테이블의 주소는 (리스트주소 - 54) 이다.
그러면 핸들 테이블들을 하나씩 살펴보자.

첫번째 핸들 테이블의 주소는 820b76dc - 54 이다.
이것은 누구의 핸들 테이블인지 보자.

kd> dt 820b7688 _HANDLE_TABLE
nt!_HANDLE_TABLE
   +0x000 Flags            : 0
   +0x004 HandleCount      : 0x84
   +0x008 Table            : 0xe1002000  -> 0xe1002400  -> 0xe1002800 _HANDLE_TABLE_ENTRY
   +0x00c QuotaProcess     : (null)
   +0x010 UniqueProcessId  : 0x00000008
   +0x014 FirstFreeTableEntry : 0x85
   +0x018 NextIndexNeedingPool : 0x100
   +0x01c HandleTableLock  : _ERESOURCE
   +0x054 HandleTableList  : _LIST_ENTRY [ 0x820b765c - 0x8046dda8 ]
   +0x05c HandleContentionEvent : _KEVENT

ProcessId 가 8 인걸 보니 시스템 프로세스 같다.
그러고 보니 위에서 찾았던 시스템 프로세스의 핸들 테이블 주소와 일치한다.

두번째 핸들 테이블의 주소는 820b765c - 54 이다.

kd> dt 820b7608 _HANDLE_TABLE
nt!_HANDLE_TABLE
   +0x000 Flags            : 0
   +0x004 HandleCount      : 0x24
   +0x008 Table            : 0xe1003000  -> 0xe1003400  -> 0xe1003800 _HANDLE_TABLE_ENTRY
   +0x00c QuotaProcess     : (null)
   +0x010 UniqueProcessId  : (null)
   +0x014 FirstFreeTableEntry : 0x29
   +0x018 NextIndexNeedingPool : 0x100
   +0x01c HandleTableLock  : _ERESOURCE
   +0x054 HandleTableList  : _LIST_ENTRY [ 0x81f96a5c - 0x820b76dc ]
   +0x05c HandleContentionEvent : _KEVENT

오... 주소가 위에서 봤던 커널 핸들 테이블 주소와 일치한다.
ProcessId 가 0으로 설정되어 있는 핸들 테이블이 커널 핸들 테이블인 것이다.

세번째 핸들 테이블의 주소는 81f96a5c -54 이다.

kd> dt 81f96a08 _HANDLE_TABLE
nt!_HANDLE_TABLE
   +0x000 Flags            : 0
   +0x004 HandleCount      : 0x21
   +0x008 Table            : 0xe1364000  -> 0xe1364400  -> 0xe1364800 _HANDLE_TABLE_ENTRY
   +0x00c QuotaProcess     : 0x81f966e0 _EPROCESS
   +0x010 UniqueProcessId  : 0x0000008c
   +0x014 FirstFreeTableEntry : 0x23
   +0x018 NextIndexNeedingPool : 0x100
   +0x01c HandleTableLock  : _ERESOURCE
   +0x054 HandleTableList  : _LIST_ENTRY [ 0x81f66f1c - 0x820b765c ]
   +0x05c HandleContentionEvent : _KEVENT

이제 OuotaProcess와 UniqueProcessId가 나타난다.

kd> !process 0x81f966e0 0
PROCESS 81f966e0  SessionId: 0  Cid: 008c    Peb: 7ffdf000  ParentCid: 0008
    DirBase: 034a4000  ObjectTable: 81f96a08  TableSize:  33.
    Image: smss.exe

이것은 smss.exe 프로세스의 핸들 테이블이다.
이후로는 실행중인 프로세스들의 핸들 테이블이 이어진다.

다행히 핸들 테이블이 리스트로 엮여 있어서 프로세스와 연결되어 있지 않은 ObpKernelHandleTable을 찾을 수 있었다. ^^b

반응형
Posted by GreeMate