1// Copyright (c) 2009 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4#ifndef CHROME_FRAME_NT_LOADER_H_
5#define CHROME_FRAME_NT_LOADER_H_
6
7#include <windows.h>
8#include <winnt.h>
9#include <winternl.h>
10
11namespace nt_loader {
12
13// These structures are gleaned from public symbol information.
14struct _PEB;
15struct _PEB_LDR_DATA;
16struct _RTL_USER_PROCESS_PARAMETERS;
17struct _PEB_FREE_BLOCK;
18
19
20typedef struct _NT_TIB {
21  _EXCEPTION_REGISTRATION_RECORD* ExceptionList;  // 0x000
22  void *StackBase;  // 0x004
23  void* StackLimit;  // 0x008
24  void* SubSystemTib;  // 0x00c
25  union {
26    void *FiberData;  // 0x010
27    DWORD Version;  // 0x010
28  };
29  void* ArbitraryUserPointer;  // 0x014
30  _NT_TIB* Self;  // 0x018
31} _NT_TIB, NT_TIB;
32
33typedef struct _CLIENT_ID {
34  void* UniqueProcess;  // 0x000
35  void* UniqueThread;  // 0x004
36} _CLIENT_ID, CLIENT_ID;
37
38typedef struct _TEB {
39  _NT_TIB NtTib;  // 0x000
40  void* EnvironmentPointer;  // 0x01c
41  _CLIENT_ID ClientId;  // 0x020
42  void* ActiveRpcHandle;  // 0x028
43  void* ThreadLocalStoragePointer;  // 0x02c
44  _PEB* ProcessEnvironmentBlock;  // 0x030
45  // There is more in a TEB, but this is all we need.
46} _TEB, TEB;
47
48typedef struct _PEB {
49  BYTE InheritedAddressSpace;  // 0x000
50  BYTE ReadImageFileExecOptions;  // 0x001
51  BYTE BeingDebugged;  // 0x002
52  BYTE SpareBool;  // 0x003
53  void* Mutant;  // 0x004
54  void* ImageBaseAddress;  // 0x008
55  _PEB_LDR_DATA* Ldr;  // 0x00c
56  _RTL_USER_PROCESS_PARAMETERS* ProcessParameters;  // 0x010
57  void* SubSystemData;  // 0x014
58  void* ProcessHeap;  // 0x018
59  _RTL_CRITICAL_SECTION* FastPebLock;  // 0x01c
60  void* FastPebLockRoutine;  // 0x020
61  void* FastPebUnlockRoutine;  // 0x024
62  ULONG EnvironmentUpdateCount;  // 0x028
63  void* KernelCallbackTable;  // 0x02c
64  ULONG SystemReserved[1]; // 0x030
65  ULONG AtlThunkSListPtr32;  // 0x034
66  _PEB_FREE_BLOCK* FreeList;  // 0x038
67  ULONG TlsExpansionCounter;  // 0x03c
68  void* TlsBitmap;  // 0x040
69  ULONG TlsBitmapBits[2]; // 0x044
70  void* ReadOnlySharedMemoryBase;  // 0x04c
71  void* ReadOnlySharedMemoryHeap;  // 0x050
72  void** ReadOnlyStaticServerData;  // 0x054
73  void* AnsiCodePageData;  // 0x058
74  void* OemCodePageData;  // 0x05c
75  void* UnicodeCaseTableData;  // 0x060
76  ULONG NumberOfProcessors;  // 0x064
77  ULONG NtGlobalFlag;  // 0x068
78  _LARGE_INTEGER CriticalSectionTimeout;  // 0x070
79  ULONG HeapSegmentReserve;  // 0x078
80  ULONG HeapSegmentCommit;  // 0x07c
81  ULONG HeapDeCommitTotalFreeThreshold;  // 0x080
82  ULONG HeapDeCommitFreeBlockThreshold;  // 0x084
83  ULONG NumberOfHeaps;  // 0x088
84  ULONG MaximumNumberOfHeaps;  // 0x08c
85  void** ProcessHeaps;  // 0x090
86  void* GdiSharedHandleTable;  // 0x094
87  void* ProcessStarterHelper;  // 0x098
88  ULONG GdiDCAttributeList;  // 0x09c
89  RTL_CRITICAL_SECTION* LoaderLock;  // 0x0a0
90  // There is more in a PEB, but this is all we need.
91} _PEB, PEB;
92
93struct _PEB_LDR_DATA {
94  ULONG Length;  // 0x000
95  BYTE Initialized;  // 0x004
96  void* SsHandle;  // 0x008
97  LIST_ENTRY InLoadOrderModuleList;  // 0x00c
98  LIST_ENTRY InMemoryOrderModuleList;  // 0x014
99  LIST_ENTRY InInitializationOrderModuleList;  // 0x01c
100  // There is more data in this structure, but this is all we need.
101};
102
103// These flags are gleaned from the !dlls Windbg extension.
104#define LDRP_STATIC_LINK            0x00000002
105#define LDRP_IMAGE_DLL              0x00000004
106#define LDRP_LOAD_IN_PROGRESS       0x00001000
107#define LDRP_UNLOAD_IN_PROGRESS     0x00002000
108#define LDRP_ENTRY_PROCESSED        0x00004000
109#define LDRP_DONT_CALL_FOR_THREADS  0x00040000
110#define LDRP_PROCESS_ATTACH_CALLED  0x00080000
111#define LDRP_COR_IMAGE              0x00400000
112#define LDRP_COR_OWNS_UNMAP         0x00800000
113#define LDRP_COR_IL_ONLY            0x01000000
114#define LDRP_REDIRECTED             0x10000000
115
116typedef struct _LDR_DATA_TABLE_ENTRY {
117  LIST_ENTRY InLoadOrderLinks;  // 0x000
118  LIST_ENTRY InMemoryOrderLinks;  // 0x008
119  LIST_ENTRY InInitializationOrderLinks; //  0x010
120  void* DllBase;  // 0x018
121  void* EntryPoint;  // 0x01c
122  ULONG SizeOfImage;  // 0x020
123  UNICODE_STRING FullDllName;  // 0x024
124  UNICODE_STRING BaseDllName;  // 0x02c
125  ULONG Flags;  // 0x034
126  USHORT LoadCount;  // 0x038
127  USHORT TlsIndex;  // 0x03a
128  union {
129    LIST_ENTRY HashLinks;  // 0x03c
130    struct {
131      void* SectionPointer;  // 0x03c
132      ULONG CheckSum;  // 0x040
133    };
134  };
135  union {
136    ULONG TimeDateStamp;  // 0x044
137    void* LoadedImports;  // 0x044
138  };
139  void *EntryPointActivationContext;  // 0x048
140  void* PatchInformation;  // 0x04c
141} _LDR_DATA_TABLE_ENTRY, LDR_DATA_TABLE_ENTRY;
142
143// Retrieves the current thread's TEB.
144inline TEB* GetCurrentTeb() {
145  return reinterpret_cast<TEB*>(NtCurrentTeb());
146}
147
148// Retrieves the current process' PEB.
149inline PEB* GetCurrentPeb() {
150  return GetCurrentTeb()->ProcessEnvironmentBlock;
151}
152
153// Returns true iff the current thread owns critsec.
154inline bool OwnsCriticalSection(CRITICAL_SECTION* critsec) {
155  return reinterpret_cast<DWORD>(critsec->OwningThread) ==
156      GetCurrentThreadId();
157}
158
159// Finds a loader table entry for module.
160// Note: must hold the loader's lock on entry.
161LDR_DATA_TABLE_ENTRY* GetLoaderEntry(HMODULE module);
162
163// Returns the loader's lock.
164inline CRITICAL_SECTION* GetLoaderLock() {
165  return GetCurrentPeb()->LoaderLock;
166}
167
168// Returns true iff the current thread owns the loader's lock on call.
169inline bool OwnsLoaderLock() {
170  return OwnsCriticalSection(GetLoaderLock());
171}
172
173}  // namespace nt_loader
174
175#endif  // CHROME_FRAME_NT_LOADER_H_
176