-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathloader.h
More file actions
426 lines (400 loc) · 13.4 KB
/
loader.h
File metadata and controls
426 lines (400 loc) · 13.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
#pragma once
#pragma pack(push, 8)
using PDLL_INIT_ROUTINE = bool(NTAPI*)(void* DllHandle, std::uint32_t Reason, void* Context);
using PPROCESS_STARTER_ROUTINE = bool(NTAPI*)(void* RealStartAddress);
_Q_NT_BIT_TEMPLATE struct LDR_SERVICE_TAG_RECORD
{
private:
_Q_NT_BIT_TYPE
public:
#if Q_NT_VERSION >= Q_NT_WIN8
BitnessType_t<LDR_SERVICE_TAG_RECORD*> Links; // 0x00
#else
LIST_ENTRY<nBitness> Links; // 0x00
#endif
std::uint32_t ServiceTag; // 0x04 / 0x08
#if Q_NT_VERSION < Q_NT_WIN8
std::uint32_t Count; // 0x0C / 0x14
#endif
};
_Q_NT_BIT_ASSERT(LDR_SERVICE_TAG_RECORD, 0x8, 0x10);
#if Q_NT_VERSION >= Q_NT_WIN8
_Q_NT_BIT_TEMPLATE struct LDRP_CSLIST
{
private:
_Q_NT_BIT_TYPE
public:
BitnessType_t<SINGLE_LIST_ENTRY<nBitness>*> Tail;
};
_Q_NT_BIT_ASSERT(LDRP_CSLIST, 0x4, 0x8);
using LDR_DDAG_STATE = enum _LDR_DDAG_STATE
{
LdrModulesMerged = -5,
LdrModulesInitError = -4,
LdrModulesSnapError = -3,
LdrModulesUnloaded = -2,
LdrModulesUnloading = -1,
LdrModulesPlaceHolder = 0,
LdrModulesMapping = 1,
LdrModulesMapped = 2,
LdrModulesWaitingForDependencies = 3,
LdrModulesSnapping = 4,
LdrModulesSnapped = 5,
LdrModulesCondensed = 6,
LdrModulesReadyToInit = 7,
LdrModulesInitializing = 8,
LdrModulesReadyToRun = 9
};
_Q_NT_BIT_TEMPLATE struct LDR_DDAG_NODE
{
private:
_Q_NT_BIT_TYPE
public:
LIST_ENTRY<nBitness> Modules; // 0x00
BitnessType_t<LDR_SERVICE_TAG_RECORD<nBitness>*> ServiceTagList; // 0x08 / 0x10
std::uint32_t LoadCount; // 0x0C / 0x18
#if Q_NT_VERSION >= Q_NT_WIN10
std::uint32_t LoadWhileUnloadingCount; // 0x10 / 0x1C
std::uint32_t LowestLink; // 0x14 / 0x20
#else
std::uint32_t ReferenceCount; // 0x10 / 0x1C
std::uint32_t DependencyCount; // 0x14 / 0x20
#endif
union
{
LDRP_CSLIST<nBitness> Dependencies;
#if Q_NT_VERSION < Q_NT_WIN10
SINGLE_LIST_ENTRY<nBitness> RemovalLink;
#endif
}; // 0x18 / 0x28
LDRP_CSLIST<nBitness> IncomingDependencies; // 0x1C / 0x30
LDR_DDAG_STATE State; // 0x20 / 0x38
SINGLE_LIST_ENTRY<nBitness> CondenseLink; // 0x24 / 0x40
std::uint32_t PreorderNumber; // 0x28 / 0x48
#if Q_NT_VERSION < Q_NT_WIN10
std::uint32_t LowestLink; // 0x2C / 0x4C
#endif
};
_Q_NT_BIT_ASSERT(LDR_DDAG_NODE, 0x2C, 0x50);
using LDR_DLL_LOAD_REASON = enum _LDR_DLL_LOAD_REASON : std::int32_t
{
LoadReasonUnknown = -1,
LoadReasonStaticDependency = 0,
LoadReasonStaticForwarderDependency = 1,
LoadReasonDynamicForwarderDependency = 2,
LoadReasonDelayloadDependency = 3,
LoadReasonDynamicLoad = 4,
LoadReasonAsImageLoad = 5,
LoadReasonAsDataLoad = 6,
#if Q_NT_VERSION >= Q_NT_WIN10_RS3
LoadReasonEnclavePrimary = 7,
LoadReasonEnclaveDependency = 8,
#endif
#if Q_NT_VERSION >= Q_NT_WIN11
LoadReasonPatchImage = 9
#endif
};
#endif
#if Q_NT_VERSION >= Q_NT_WIN11
using LDR_HOT_PATCH_STATE = enum _LDR_HOT_PATCH_STATE
{
LdrHotPatchBaseImage,
LdrHotPatchNotApplied,
LdrHotPatchAppliedReverse,
LdrHotPatchAppliedForward,
LdrHotPatchFailedToPatch,
LdrHotPatchStateMax
};
#endif
// private flags for loader data table entries
#define LDRP_PACKAGED_BINARY 0x00000001
#define LDRP_MARKED_FOR_REMOVAL 0x00000002
#define LDRP_IMAGE_DLL 0x00000004
#define LDRP_LOAD_NOTIFICATIONS_SENT 0x00000008
#define LDRP_TELEMETRY_ENTRY_PROCESSED 0x00000010
#define LDRP_PROCESS_STATIC_IMPORT 0x00000020
#define LDRP_IN_LEGACY_LISTS 0x00000040
#define LDRP_IN_INDEXES 0x00000080
#define LDRP_SHIM_DLL 0x00000100
#define LDRP_IN_EXCEPTION_TABLE 0x00000200
#define LDRP_LOAD_IN_PROGRESS 0x00001000
#define LDRP_LOAD_CONFIG_PROCESSED 0x00002000
#define LDRP_ENTRY_PROCESSED 0x00004000
#define LDRP_PROTECT_DELAY_LOAD 0x00008000
#define LDRP_DONT_CALL_FOR_THREADS 0x00040000
#define LDRP_PROCESS_ATTACH_CALLED 0x00080000
#define LDRP_PROCESS_ATTACH_FAILED 0x00100000
#define LDRP_COR_DEFERRED_VALIDATE 0x00200000
#define LDRP_COR_IMAGE 0x00400000
#define LDRP_DONT_RELOCATE 0x00800000
#define LDRP_COR_IL_ONLY 0x01000000
#define LDRP_CHPE_IMAGE 0x02000000
#define LDRP_CHPE_EMULATOR_IMAGE 0x04000000
#define LDRP_REDIRECTED 0x10000000
#define LDRP_COMPAT_DATABASE_PROCESSED 0x80000000
_Q_NT_BIT_TEMPLATE struct LDR_DATA_TABLE_ENTRY
{
private:
_Q_NT_BIT_TYPE
public:
LIST_ENTRY<nBitness> InLoadOrderLinks; // 0x0000
LIST_ENTRY<nBitness> InMemoryOrderLinks; // 0x0008 / 0x0010
union
{
LIST_ENTRY<nBitness> InInitializationOrderLinks;
#if Q_NT_VERSION >= Q_NT_WIN8 && Q_NT_VERSION < Q_NT_WIN10
LIST_ENTRY<nBitness> InProgressLinks;
#endif
}; // 0x0010 / 0x0020
BitnessType_t<void*> DllBase; // 0x0018 / 0x0030
BitnessType_t<void*> EntryPoint; // 0x001C / 0x0038
std::uint32_t SizeOfImage; // 0x0020 / 0x0040
UNICODE_STRING<nBitness> FullDllName; // 0x0024 / 0x0048
UNICODE_STRING<nBitness> BaseDllName; // 0x002C / 0x0058
#if Q_NT_VERSION >= Q_NT_WIN8
union
{
std::uint8_t FlagGroup[4];
std::uint32_t Flags; // LDRP_*
struct
{
std::uint32_t PackagedBinary : 1;
std::uint32_t MarkedForRemoval : 1;
std::uint32_t ImageDll : 1;
std::uint32_t LoadNotificationsSent : 1;
std::uint32_t TelemetryEntryProcessed : 1;
std::uint32_t ProcessStaticImport : 1;
std::uint32_t InLegacyLists : 1;
std::uint32_t InIndexes : 1;
std::uint32_t ShimDll : 1;
std::uint32_t InExceptionTable : 1;
std::uint32_t ReservedFlags1 : 2;
std::uint32_t LoadInProgress : 1;
#if Q_NT_VERSION >= Q_NT_WIN10
std::uint32_t LoadConfigProcessed : 1;
#else
std::uint32_t ReservedFlags2 : 1;
#endif
std::uint32_t EntryProcessed : 1;
#if Q_NT_VERSION >= Q_NT_WIN10
std::uint32_t ProtectDelayLoad : 1;
std::uint32_t ReservedFlags3 : 2;
#else
std::uint32_t ReservedFlags3 : 3;
#endif
std::uint32_t DontCallForThreads : 1;
std::uint32_t ProcessAttachCalled : 1;
std::uint32_t ProcessAttachFailed : 1;
std::uint32_t CorDeferredValidate : 1;
std::uint32_t CorImage : 1;
std::uint32_t DontRelocate : 1;
std::uint32_t CorILOnly : 1;
#if Q_NT_VERSION >= Q_NT_WIN10_RS4
std::uint32_t ChpeImage : 1;
std::uint32_t ReservedFlags5 : 2;
#else
std::uint32_t ReservedFlags5 : 3;
#endif
std::uint32_t Redirected : 1;
std::uint32_t ReservedFlags6 : 2;
std::uint32_t CompatDatabaseProcessed : 1;
};
}; // 0x0034 / 0x0068
#else
std::uint32_t Flags; // 0x0034 / 0x0068 // LDRP_*
#endif
#if Q_NT_VERSION >= Q_NT_WIN8
std::uint16_t ObsoleteLoadCount; // 0x0038 / 0x006C
#else
std::uint16_t LoadCount; // 0x0038 / 0x006C
#endif
std::uint16_t TlsIndex; // 0x003A / 0x006E
union
{
LIST_ENTRY<nBitness> HashLinks;
#if Q_NT_VERSION < Q_NT_WIN8
struct
{
BitnessType_t<void*> SectionPointer;
std::uint32_t CheckSum;
};
#endif
}; // 0x003C / 0x0070
union
{
std::uint32_t TimeDateStamp;
#if Q_NT_VERSION < Q_NT_WIN8
BitnessType_t<void*> LoadedImports;
#endif
}; // 0x0044 / 0x0080
BitnessType_t<struct ACTIVATION_CONTEXT*> EntryPointActivationContext; // 0x0048 / 0x0088
#if Q_NT_VERSION >= Q_NT_WIN10
BitnessType_t<void*> Lock; // 0x004C / 0x0090
#elif Q_NT_VERSION >= Q_NT_WINBLUE
BitnessType_t<void*> Spare; // 0x004C / 0x0090
#else
BitnessType_t<void*> PatchInformation; // 0x004C / 0x0090
#endif
#if Q_NT_VERSION >= Q_NT_WIN8
BitnessType_t<LDR_DDAG_NODE<nBitness>*> DdagNode; // 0x0050 / 0x0098
LIST_ENTRY<nBitness> NodeModuleLink; // 0x0054 / 0x00A0
#if Q_NT_VERSION >= Q_NT_WIN10
BitnessType_t<struct LDRP_LOAD_CONTEXT*> LoadContext; // 0x005C / 0x00B0
#endif
BitnessType_t<void*> ParentDllBase; // 0x0060 / 0x00B8
BitnessType_t<void*> SwitchBackContext; // 0x0064 /0x00C0
RTL_BALANCED_NODE<nBitness> BaseAddressIndexNode; // 0x0068 / 0x00C8
RTL_BALANCED_NODE<nBitness> MappingInfoIndexNode; // 0x0074 / 0x00E0
#else
LIST_ENTRY<nBitness> ForwarderLinks; // 0x0050 / 0x0098
LIST_ENTRY<nBitness> ServiceTagLinks; // 0x0058 / 0x00A8
LIST_ENTRY<nBitness> StaticLinks; // 0x0060 / 0x00B8
#endif
#if Q_NT_VERSION >= Q_NT_WIN7
#if Q_NT_VERSION == Q_NT_WIN7
BitnessType_t<void*> ContextInformation; // 0x0068 / 0x00C8
#endif
BitnessType_t<std::uintptr_t> OriginalBase; // 0x0080 / 0x00F8
LARGE_INTEGER LoadTime; // 0x0088 / 0x0100
#endif
#if Q_NT_VERSION >= Q_NT_WIN8
std::uint32_t BaseNameHashValue; // 0x0090 / 0x0108
LDR_DLL_LOAD_REASON LoadReason; // 0x0094 / 0x010C
#endif
#if Q_NT_VERSION >= Q_NT_WINBLUE
std::uint32_t ImplicitPathOptions; // 0x0098 / 0x0110
#endif
#if Q_NT_VERSION >= Q_NT_WIN10
std::uint32_t ReferenceCount; // 0x009C / 0x0114
#endif
#if Q_NT_VERSION >= Q_NT_WIN10_RS1
std::uint32_t DependentLoadFlags; // 0x00A0 / 0x0118
#endif
#if Q_NT_VERSION >= Q_NT_WIN10_RS2
std::uint8_t SigningLevel; // 0x00A4 / 0x011C
#endif
#if Q_NT_VERSION >= Q_NT_WIN11
std::uint32_t CheckSum; // 0x00A8 / 0x0120
BitnessType_t<void*> ActivePatchImageBase; // 0x00AC / 0x0128
LDR_HOT_PATCH_STATE HotPatchState; // 0x00B0 / 0x0130
#endif
};
_Q_NT_BIT_ASSERT(LDR_DATA_TABLE_ENTRY, 0xB8, 0x138);
#define LDR_IS_DATAFILE(DllHandle) (reinterpret_cast<std::uintptr_t>(DllHandle) & static_cast<std::uintptr_t>(1U))
#define LDR_IS_IMAGEMAPPING(DllHandle) (reinterpret_cast<std::uintptr_t>(DllHandle) & static_cast<std::uintptr_t>(2U))
#define LDR_IS_RESOURCE(DllHandle) (LDR_IS_IMAGEMAPPING(DllHandle) || LDR_IS_DATAFILE(DllHandle))
#define LDR_MAPPEDVIEW_TO_DATAFILE(BaseAddress) (reinterpret_cast<void*>(reinterpret_cast<std::uintptr_t>(BaseAddress) | static_cast<std::uintptr_t>(1U)))
#define LDR_MAPPEDVIEW_TO_IMAGEMAPPING(BaseAddress) (reinterpret_cast<void*>(reinterpret_cast<std::uintptr_t>(BaseAddress) | static_cast<std::uintptr_t>(2U)))
#define LDR_DATAFILE_TO_MAPPEDVIEW(DllHandle) (reinterpret_cast<void*>(reinterpret_cast<std::uintptr_t>(DllHandle) & ~static_cast<std::uintptr_t>(1U)))
#define LDR_IMAGEMAPPING_TO_MAPPEDVIEW(DllHandle) (reinterpret_cast<void*>(reinterpret_cast<std::uintptr_t>(DllHandle) & ~static_cast<std::uintptr_t>(2U)))
using PLDR_IMPORT_MODULE_CALLBACK = void(NTAPI*)(void* Parameter, char* ModuleName);
_Q_NT_BIT_TEMPLATE struct LDR_IMPORT_CALLBACK_INFO
{
private:
_Q_NT_BIT_TYPE
public:
BitnessType_t<PLDR_IMPORT_MODULE_CALLBACK> ImportCallbackRoutine; // 0x0
BitnessType_t<void*> ImportCallbackParameter; // 0x4 / 0x8
};
_Q_NT_BIT_ASSERT(LDR_IMPORT_CALLBACK_INFO, 0x8, 0x10);
_Q_NT_BIT_TEMPLATE struct LDR_SECTION_INFO
{
private:
_Q_NT_BIT_TYPE
public:
BitnessType_t<HANDLE> SectionHandle; // 0x00
ACCESS_MASK DesiredAccess; // 0x04 / 0x08
BitnessType_t<OBJECT_ATTRIBUTES<nBitness>*> ObjA; // 0x08 / 0x10
std::uint32_t SectionPageProtection; // 0x0C / 0x18
std::uint32_t AllocationAttributes; // 0x10 / 0x1C
};
_Q_NT_BIT_ASSERT(LDR_SECTION_INFO, 0x14, 0x20);
_Q_NT_BIT_TEMPLATE struct LDR_VERIFY_IMAGE_INFO
{
std::uint32_t Size; // 0x00
std::uint32_t Flags; // 0x04
LDR_IMPORT_CALLBACK_INFO<nBitness> CallbackInfo; // 0x08
LDR_SECTION_INFO<nBitness> SectionInfo; // 0x10 / 0x18
std::uint16_t ImageCharacteristics; // 0x24 / 0x38
};
_Q_NT_BIT_ASSERT(LDR_VERIFY_IMAGE_INFO, 0x28, 0x40);
_Q_NT_BIT_TEMPLATE struct LDR_DLL_LOADED_NOTIFICATION_DATA
{
private:
_Q_NT_BIT_TYPE
public:
std::uint32_t Flags; // 0x00
BitnessType_t<UNICODE_STRING<nBitness>*> FullDllName; // 0x04 / 0x08
BitnessType_t<UNICODE_STRING<nBitness>*> BaseDllName; // 0x08 / 0x10
BitnessType_t<void*> DllBase; // 0x0C / 0x18
std::uint32_t SizeOfImage; // 0x10 / 0x20
};
_Q_NT_BIT_ASSERT(LDR_DLL_LOADED_NOTIFICATION_DATA, 0x14, 0x28);
_Q_NT_BIT_TEMPLATE using LDR_DLL_UNLOADED_NOTIFICATION_DATA = LDR_DLL_LOADED_NOTIFICATION_DATA<nBitness>;
_Q_NT_BIT_TEMPLATE union LDR_DLL_NOTIFICATION_DATA
{
LDR_DLL_LOADED_NOTIFICATION_DATA<nBitness> Loaded;
LDR_DLL_UNLOADED_NOTIFICATION_DATA<nBitness> Unloaded;
};
_Q_NT_BIT_ASSERT(LDR_DLL_NOTIFICATION_DATA, 0x14, 0x28);
#define LDR_DLL_NOTIFICATION_REASON_LOADED (1)
#define LDR_DLL_NOTIFICATION_REASON_UNLOADED (2)
using PLDR_DLL_NOTIFICATION_FUNCTION = void(NTAPI*)(std::uint32_t NotificationReason, const LDR_DLL_NOTIFICATION_DATA<Q_ARCH_BIT>* NotificationData, void* Context);
#define LDR_GET_DLL_HANDLE_EX_UNCHANGED_REFCOUNT (0x00000001)
#define LDR_GET_DLL_HANDLE_EX_PIN (0x00000002)
#define LDR_FIND_RESOURCE_LANGUAGE_CAN_FALLBACK (0x00000000)
#define LDR_FIND_RESOURCE_LANGUAGE_EXACT (0x00000004)
#define LDR_FIND_RESOURCE_LANGUAGE_REDIRECT_VERSION (0x00000008)
#define LDR_MAXIMUM_RESOURCE_PATH_DEPTH (3)
_Q_NT_BIT_TEMPLATE struct LDR_ENUM_RESOURCE_ENTRY
{
private:
_Q_NT_BIT_TYPE
public:
union
{
BitnessType_t<std::uintptr_t> NameOrId;
BitnessType_t<IMAGE_RESOURCE_DIRECTORY_STRING*> Name;
struct
{
std::uint16_t Id;
std::uint16_t NameIsPresent;
};
} Path[LDR_MAXIMUM_RESOURCE_PATH_DEPTH]; // 0x00
BitnessType_t<void*> Data; // 0x0C / 0x18
std::uint32_t Size; // 0x10 / 0x20
std::uint32_t Reserved; // 0x14 / 0x24
};
_Q_NT_BIT_ASSERT(LDR_ENUM_RESOURCE_ENTRY, 0x18, 0x28);
#if Q_NT_VERSION >= Q_NT_WIN8
_Q_NT_BIT_TEMPLATE struct DELAYLOAD_PROC_DESCRIPTOR
{
private:
_Q_NT_BIT_TYPE
public:
std::uint32_t ImportDescribedByName; // 0x0
union
{
BitnessType_t<const char*> Name;
std::uint32_t Ordinal;
} Description; // 0x4 / 0x8
};
_Q_NT_BIT_ASSERT(DELAYLOAD_PROC_DESCRIPTOR, 0x8, 0x10);
_Q_NT_BIT_TEMPLATE struct DELAYLOAD_INFO
{
private:
_Q_NT_BIT_TYPE
public:
std::uint32_t Size; // 0x00
BitnessType_t<const IMAGE_DELAYLOAD_DESCRIPTOR*> DelayloadDescriptor; // 0x04 / 0x08
BitnessType_t<IMAGE_THUNK_DATA*> ThunkAddress; // 0x08 / 0x10
BitnessType_t<const char*> TargetDllName; // 0x0C / 0x18
DELAYLOAD_PROC_DESCRIPTOR<nBitness> TargetApiDescriptor; // 0x10 / 0x20
BitnessType_t<void*> TargetModuleBase; // 0x18 / 0x30
BitnessType_t<void*> Unused; // 0x1C / 0x38
std::uint32_t LastError; // 0x20 / 0x40
};
_Q_NT_BIT_ASSERT(DELAYLOAD_INFO, 0x24, 0x48);
using PDELAYLOAD_FAILURE_DLL_CALLBACK = void*(NTAPI*)(std::uint32_t NotificationReason, DELAYLOAD_INFO<Q_ARCH_BIT>* DelayloadInfo);
#endif
#pragma pack(pop)