-
Notifications
You must be signed in to change notification settings - Fork 175
/
ntwow64.h
782 lines (683 loc) · 22.7 KB
/
ntwow64.h
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
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
/*
* Windows on Windows support functions
*
* This file is part of System Informer.
*/
#ifndef _NTWOW64_H
#define _NTWOW64_H
#define WOW64_SYSTEM_DIRECTORY "SysWOW64"
#define WOW64_SYSTEM_DIRECTORY_U L"SysWOW64"
#define WOW64_X86_TAG " (x86)"
#define WOW64_X86_TAG_U L" (x86)"
// In USER_SHARED_DATA
typedef enum _WOW64_SHARED_INFORMATION
{
SharedNtdll32LdrInitializeThunk,
SharedNtdll32KiUserExceptionDispatcher,
SharedNtdll32KiUserApcDispatcher,
SharedNtdll32KiUserCallbackDispatcher,
SharedNtdll32ExpInterlockedPopEntrySListFault,
SharedNtdll32ExpInterlockedPopEntrySListResume,
SharedNtdll32ExpInterlockedPopEntrySListEnd,
SharedNtdll32RtlUserThreadStart,
SharedNtdll32pQueryProcessDebugInformationRemote,
SharedNtdll32BaseAddress,
SharedNtdll32LdrSystemDllInitBlock,
Wow64SharedPageEntriesCount
} WOW64_SHARED_INFORMATION;
// 32-bit definitions
#define WOW64_POINTER(Type) ULONG
typedef struct _RTL_BALANCED_NODE32
{
union
{
WOW64_POINTER(struct _RTL_BALANCED_NODE *) Children[2];
struct
{
WOW64_POINTER(struct _RTL_BALANCED_NODE *) Left;
WOW64_POINTER(struct _RTL_BALANCED_NODE *) Right;
};
};
union
{
WOW64_POINTER(UCHAR) Red : 1;
WOW64_POINTER(UCHAR) Balance : 2;
WOW64_POINTER(ULONG_PTR) ParentValue;
};
} RTL_BALANCED_NODE32, *PRTL_BALANCED_NODE32;
typedef struct _RTL_RB_TREE32
{
WOW64_POINTER(PRTL_BALANCED_NODE) Root;
WOW64_POINTER(PRTL_BALANCED_NODE) Min;
} RTL_RB_TREE32, *PRTL_RB_TREE32;
typedef struct _PEB_LDR_DATA32
{
ULONG Length;
BOOLEAN Initialized;
WOW64_POINTER(HANDLE) SsHandle;
LIST_ENTRY32 InLoadOrderModuleList;
LIST_ENTRY32 InMemoryOrderModuleList;
LIST_ENTRY32 InInitializationOrderModuleList;
WOW64_POINTER(PVOID) EntryInProgress;
BOOLEAN ShutdownInProgress;
WOW64_POINTER(HANDLE) ShutdownThreadId;
} PEB_LDR_DATA32, *PPEB_LDR_DATA32;
typedef struct _LDR_SERVICE_TAG_RECORD32
{
WOW64_POINTER(struct _LDR_SERVICE_TAG_RECORD *) Next;
ULONG ServiceTag;
} LDR_SERVICE_TAG_RECORD32, *PLDR_SERVICE_TAG_RECORD32;
typedef struct _LDRP_CSLIST32
{
WOW64_POINTER(PSINGLE_LIST_ENTRY) Tail;
} LDRP_CSLIST32, *PLDRP_CSLIST32;
typedef struct _LDR_DDAG_NODE32
{
LIST_ENTRY32 Modules;
WOW64_POINTER(PLDR_SERVICE_TAG_RECORD) ServiceTagList;
ULONG LoadCount;
ULONG LoadWhileUnloadingCount;
ULONG LowestLink;
union
{
LDRP_CSLIST32 Dependencies;
SINGLE_LIST_ENTRY32 RemovalLink;
};
LDRP_CSLIST32 IncomingDependencies;
LDR_DDAG_STATE State;
SINGLE_LIST_ENTRY32 CondenseLink;
ULONG PreorderNumber;
} LDR_DDAG_NODE32, *PLDR_DDAG_NODE32;
#define LDR_DATA_TABLE_ENTRY_SIZE_WINXP_32 FIELD_OFFSET(LDR_DATA_TABLE_ENTRY32, DdagNode)
#define LDR_DATA_TABLE_ENTRY_SIZE_WIN7_32 FIELD_OFFSET(LDR_DATA_TABLE_ENTRY32, BaseNameHashValue)
#define LDR_DATA_TABLE_ENTRY_SIZE_WIN8_32 FIELD_OFFSET(LDR_DATA_TABLE_ENTRY32, ImplicitPathOptions)
#define LDR_DATA_TABLE_ENTRY_SIZE_WIN10_32 FIELD_OFFSET(LDR_DATA_TABLE_ENTRY32, SigningLevel)
#define LDR_DATA_TABLE_ENTRY_SIZE_WIN11_32 sizeof(LDR_DATA_TABLE_ENTRY32)
typedef struct _LDR_DATA_TABLE_ENTRY32
{
LIST_ENTRY32 InLoadOrderLinks;
LIST_ENTRY32 InMemoryOrderLinks;
union
{
LIST_ENTRY32 InInitializationOrderLinks;
LIST_ENTRY32 InProgressLinks;
};
WOW64_POINTER(PVOID) DllBase;
WOW64_POINTER(PVOID) EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING32 FullDllName;
UNICODE_STRING32 BaseDllName;
union
{
UCHAR FlagGroup[4];
ULONG Flags;
struct
{
ULONG PackagedBinary : 1;
ULONG MarkedForRemoval : 1;
ULONG ImageDll : 1;
ULONG LoadNotificationsSent : 1;
ULONG TelemetryEntryProcessed : 1;
ULONG ProcessStaticImport : 1;
ULONG InLegacyLists : 1;
ULONG InIndexes : 1;
ULONG ShimDll : 1;
ULONG InExceptionTable : 1;
ULONG ReservedFlags1 : 2;
ULONG LoadInProgress : 1;
ULONG LoadConfigProcessed : 1;
ULONG EntryProcessed : 1;
ULONG ProtectDelayLoad : 1;
ULONG ReservedFlags3 : 2;
ULONG DontCallForThreads : 1;
ULONG ProcessAttachCalled : 1;
ULONG ProcessAttachFailed : 1;
ULONG CorDeferredValidate : 1;
ULONG CorImage : 1;
ULONG DontRelocate : 1;
ULONG CorILOnly : 1;
ULONG ChpeImage : 1;
ULONG ReservedFlags5 : 2;
ULONG Redirected : 1;
ULONG ReservedFlags6 : 2;
ULONG CompatDatabaseProcessed : 1;
};
};
USHORT ObsoleteLoadCount;
USHORT TlsIndex;
LIST_ENTRY32 HashLinks;
ULONG TimeDateStamp;
WOW64_POINTER(struct _ACTIVATION_CONTEXT *) EntryPointActivationContext;
WOW64_POINTER(PVOID) Lock;
WOW64_POINTER(PLDR_DDAG_NODE) DdagNode;
LIST_ENTRY32 NodeModuleLink;
WOW64_POINTER(struct _LDRP_LOAD_CONTEXT *) LoadContext;
WOW64_POINTER(PVOID) ParentDllBase;
WOW64_POINTER(PVOID) SwitchBackContext;
RTL_BALANCED_NODE32 BaseAddressIndexNode;
RTL_BALANCED_NODE32 MappingInfoIndexNode;
WOW64_POINTER(ULONG_PTR) OriginalBase;
LARGE_INTEGER LoadTime;
ULONG BaseNameHashValue;
LDR_DLL_LOAD_REASON LoadReason;
ULONG ImplicitPathOptions;
ULONG ReferenceCount;
ULONG DependentLoadFlags;
UCHAR SigningLevel; // since REDSTONE2
ULONG CheckSum; // since 22H1
WOW64_POINTER(PVOID) ActivePatchImageBase;
LDR_HOT_PATCH_STATE HotPatchState;
} LDR_DATA_TABLE_ENTRY32, *PLDR_DATA_TABLE_ENTRY32;
typedef struct _CURDIR32
{
UNICODE_STRING32 DosPath;
WOW64_POINTER(HANDLE) Handle;
} CURDIR32, *PCURDIR32;
typedef struct _RTL_DRIVE_LETTER_CURDIR32
{
USHORT Flags;
USHORT Length;
ULONG TimeStamp;
STRING32 DosPath;
} RTL_DRIVE_LETTER_CURDIR32, *PRTL_DRIVE_LETTER_CURDIR32;
typedef struct _RTL_USER_PROCESS_PARAMETERS32
{
ULONG MaximumLength;
ULONG Length;
ULONG Flags;
ULONG DebugFlags;
WOW64_POINTER(HANDLE) ConsoleHandle;
ULONG ConsoleFlags;
WOW64_POINTER(HANDLE) StandardInput;
WOW64_POINTER(HANDLE) StandardOutput;
WOW64_POINTER(HANDLE) StandardError;
CURDIR32 CurrentDirectory;
UNICODE_STRING32 DllPath;
UNICODE_STRING32 ImagePathName;
UNICODE_STRING32 CommandLine;
WOW64_POINTER(PVOID) Environment;
ULONG StartingX;
ULONG StartingY;
ULONG CountX;
ULONG CountY;
ULONG CountCharsX;
ULONG CountCharsY;
ULONG FillAttribute;
ULONG WindowFlags;
ULONG ShowWindowFlags;
UNICODE_STRING32 WindowTitle;
UNICODE_STRING32 DesktopInfo;
UNICODE_STRING32 ShellInfo;
UNICODE_STRING32 RuntimeData;
RTL_DRIVE_LETTER_CURDIR32 CurrentDirectories[RTL_MAX_DRIVE_LETTERS];
WOW64_POINTER(ULONG_PTR) EnvironmentSize;
WOW64_POINTER(ULONG_PTR) EnvironmentVersion;
WOW64_POINTER(PVOID) PackageDependencyData;
ULONG ProcessGroupId;
ULONG LoaderThreads;
UNICODE_STRING32 RedirectionDllName; // REDSTONE4
UNICODE_STRING32 HeapPartitionName; // 19H1
WOW64_POINTER(ULONGLONG) DefaultThreadpoolCpuSetMasks;
ULONG DefaultThreadpoolCpuSetMaskCount;
ULONG DefaultThreadpoolThreadMaximum;
} RTL_USER_PROCESS_PARAMETERS32, *PRTL_USER_PROCESS_PARAMETERS32;
typedef struct _LEAP_SECOND_DATA *PLEAP_SECOND_DATA;
typedef struct _PEB32
{
BOOLEAN InheritedAddressSpace;
BOOLEAN ReadImageFileExecOptions;
BOOLEAN BeingDebugged;
union
{
BOOLEAN BitField;
struct
{
BOOLEAN ImageUsesLargePages : 1;
BOOLEAN IsProtectedProcess : 1;
BOOLEAN IsImageDynamicallyRelocated : 1;
BOOLEAN SkipPatchingUser32Forwarders : 1;
BOOLEAN IsPackagedProcess : 1;
BOOLEAN IsAppContainer : 1;
BOOLEAN IsProtectedProcessLight : 1;
BOOLEAN IsLongPathAwareProcess : 1;
};
};
WOW64_POINTER(HANDLE) Mutant;
WOW64_POINTER(PVOID) ImageBaseAddress;
WOW64_POINTER(PPEB_LDR_DATA) Ldr;
WOW64_POINTER(PRTL_USER_PROCESS_PARAMETERS) ProcessParameters;
WOW64_POINTER(PVOID) SubSystemData;
WOW64_POINTER(PVOID) ProcessHeap;
WOW64_POINTER(PRTL_CRITICAL_SECTION) FastPebLock;
WOW64_POINTER(PVOID) AtlThunkSListPtr;
WOW64_POINTER(PVOID) IFEOKey;
union
{
ULONG CrossProcessFlags;
struct
{
ULONG ProcessInJob : 1;
ULONG ProcessInitializing : 1;
ULONG ProcessUsingVEH : 1;
ULONG ProcessUsingVCH : 1;
ULONG ProcessUsingFTH : 1;
ULONG ReservedBits0 : 27;
};
};
union
{
WOW64_POINTER(PVOID) KernelCallbackTable;
WOW64_POINTER(PVOID) UserSharedInfoPtr;
};
ULONG SystemReserved;
ULONG AtlThunkSListPtr32;
WOW64_POINTER(PVOID) ApiSetMap;
ULONG TlsExpansionCounter;
WOW64_POINTER(PVOID) TlsBitmap;
ULONG TlsBitmapBits[2];
WOW64_POINTER(PVOID) ReadOnlySharedMemoryBase;
WOW64_POINTER(PVOID) SharedData;
WOW64_POINTER(PVOID *) ReadOnlyStaticServerData;
WOW64_POINTER(PVOID) AnsiCodePageData;
WOW64_POINTER(PVOID) OemCodePageData;
WOW64_POINTER(PVOID) UnicodeCaseTableData;
ULONG NumberOfProcessors;
ULONG NtGlobalFlag;
LARGE_INTEGER CriticalSectionTimeout;
WOW64_POINTER(SIZE_T) HeapSegmentReserve;
WOW64_POINTER(SIZE_T) HeapSegmentCommit;
WOW64_POINTER(SIZE_T) HeapDeCommitTotalFreeThreshold;
WOW64_POINTER(SIZE_T) HeapDeCommitFreeBlockThreshold;
ULONG NumberOfHeaps;
ULONG MaximumNumberOfHeaps;
WOW64_POINTER(PVOID *) ProcessHeaps;
WOW64_POINTER(PVOID) GdiSharedHandleTable;
WOW64_POINTER(PVOID) ProcessStarterHelper;
ULONG GdiDCAttributeList;
WOW64_POINTER(PRTL_CRITICAL_SECTION) LoaderLock;
ULONG OSMajorVersion;
ULONG OSMinorVersion;
USHORT OSBuildNumber;
USHORT OSCSDVersion;
ULONG OSPlatformId;
ULONG ImageSubsystem;
ULONG ImageSubsystemMajorVersion;
ULONG ImageSubsystemMinorVersion;
WOW64_POINTER(ULONG_PTR) ActiveProcessAffinityMask;
GDI_HANDLE_BUFFER32 GdiHandleBuffer;
WOW64_POINTER(PVOID) PostProcessInitRoutine;
WOW64_POINTER(PVOID) TlsExpansionBitmap;
ULONG TlsExpansionBitmapBits[32];
ULONG SessionId;
ULARGE_INTEGER AppCompatFlags;
ULARGE_INTEGER AppCompatFlagsUser;
WOW64_POINTER(PVOID) pShimData;
WOW64_POINTER(PVOID) AppCompatInfo;
UNICODE_STRING32 CSDVersion;
WOW64_POINTER(PACTIVATION_CONTEXT_DATA) ActivationContextData;
WOW64_POINTER(PVOID) ProcessAssemblyStorageMap;
WOW64_POINTER(PACTIVATION_CONTEXT_DATA) SystemDefaultActivationContextData;
WOW64_POINTER(PVOID) SystemAssemblyStorageMap;
WOW64_POINTER(SIZE_T) MinimumStackCommit;
WOW64_POINTER(PVOID) SparePointers[2]; // 19H1 (previously FlsCallback to FlsHighIndex)
WOW64_POINTER(PVOID) PatchLoaderData;
WOW64_POINTER(PVOID) ChpeV2ProcessInfo; // _CHPEV2_PROCESS_INFO
ULONG AppModelFeatureState;
ULONG SpareUlongs[2];
USHORT ActiveCodePage;
USHORT OemCodePage;
USHORT UseCaseMapping;
USHORT UnusedNlsField;
WOW64_POINTER(PVOID) WerRegistrationData;
WOW64_POINTER(PVOID) WerShipAssertPtr;
union
{
WOW64_POINTER(PVOID) pContextData; // WIN7
WOW64_POINTER(PVOID) pUnused; // WIN10
WOW64_POINTER(PVOID) EcCodeBitMap; // WIN11
};
WOW64_POINTER(PVOID) pImageHeaderHash;
union
{
ULONG TracingFlags;
struct
{
ULONG HeapTracingEnabled : 1;
ULONG CritSecTracingEnabled : 1;
ULONG LibLoaderTracingEnabled : 1;
ULONG SpareTracingBits : 29;
};
};
ULONGLONG CsrServerReadOnlySharedMemoryBase;
WOW64_POINTER(PVOID) TppWorkerpListLock;
LIST_ENTRY32 TppWorkerpList;
WOW64_POINTER(PVOID) WaitOnAddressHashTable[128];
WOW64_POINTER(PVOID) TelemetryCoverageHeader; // REDSTONE3
ULONG CloudFileFlags;
ULONG CloudFileDiagFlags; // REDSTONE4
CHAR PlaceholderCompatibilityMode;
CHAR PlaceholderCompatibilityModeReserved[7];
WOW64_POINTER(PLEAP_SECOND_DATA) LeapSecondData; // REDSTONE5
union
{
ULONG LeapSecondFlags;
struct
{
ULONG SixtySecondEnabled : 1;
ULONG Reserved : 31;
};
};
ULONG NtGlobalFlag2;
ULONGLONG ExtendedFeatureDisableMask; // since WIN11
} PEB32, *PPEB32;
//C_ASSERT(sizeof(PEB32) == 0x460); // REDSTONE3
//C_ASSERT(sizeof(PEB32) == 0x470); // REDSTONE5
C_ASSERT(sizeof(PEB32) == 0x488); // WIN11
// Note: Use PhGetProcessPeb32 instead. (dmex)
//#define WOW64_GET_PEB32(peb64) ((PPEB32)PTR_ADD_OFFSET((peb64), ALIGN_UP_BY(sizeof(PEB), PAGE_SIZE)))
#define GDI_BATCH_BUFFER_SIZE 310
typedef struct _GDI_TEB_BATCH32
{
ULONG Offset;
WOW64_POINTER(ULONG_PTR) HDC;
ULONG Buffer[GDI_BATCH_BUFFER_SIZE];
} GDI_TEB_BATCH32, *PGDI_TEB_BATCH32;
typedef struct _TEB32
{
NT_TIB32 NtTib;
WOW64_POINTER(PVOID) EnvironmentPointer;
CLIENT_ID32 ClientId;
WOW64_POINTER(PVOID) ActiveRpcHandle;
WOW64_POINTER(PVOID) ThreadLocalStoragePointer;
WOW64_POINTER(PPEB) ProcessEnvironmentBlock;
ULONG LastErrorValue;
ULONG CountOfOwnedCriticalSections;
WOW64_POINTER(PVOID) CsrClientThread;
WOW64_POINTER(PVOID) Win32ThreadInfo;
ULONG User32Reserved[26];
ULONG UserReserved[5];
WOW64_POINTER(PVOID) WOW32Reserved;
LCID CurrentLocale;
ULONG FpSoftwareStatusRegister;
WOW64_POINTER(PVOID) ReservedForDebuggerInstrumentation[16];
WOW64_POINTER(PVOID) SystemReserved1[36];
UCHAR WorkingOnBehalfTicket[8];
NTSTATUS ExceptionCode;
WOW64_POINTER(PVOID) ActivationContextStackPointer;
WOW64_POINTER(ULONG_PTR) InstrumentationCallbackSp;
WOW64_POINTER(ULONG_PTR) InstrumentationCallbackPreviousPc;
WOW64_POINTER(ULONG_PTR) InstrumentationCallbackPreviousSp;
BOOLEAN InstrumentationCallbackDisabled;
UCHAR SpareBytes[23];
ULONG TxFsContext;
GDI_TEB_BATCH32 GdiTebBatch;
CLIENT_ID32 RealClientId;
WOW64_POINTER(HANDLE) GdiCachedProcessHandle;
ULONG GdiClientPID;
ULONG GdiClientTID;
WOW64_POINTER(PVOID) GdiThreadLocalInfo;
WOW64_POINTER(ULONG_PTR) Win32ClientInfo[62];
WOW64_POINTER(PVOID) glDispatchTable[233];
WOW64_POINTER(ULONG_PTR) glReserved1[29];
WOW64_POINTER(PVOID) glReserved2;
WOW64_POINTER(PVOID) glSectionInfo;
WOW64_POINTER(PVOID) glSection;
WOW64_POINTER(PVOID) glTable;
WOW64_POINTER(PVOID) glCurrentRC;
WOW64_POINTER(PVOID) glContext;
NTSTATUS LastStatusValue;
UNICODE_STRING32 StaticUnicodeString;
WCHAR StaticUnicodeBuffer[261];
WOW64_POINTER(PVOID) DeallocationStack;
WOW64_POINTER(PVOID) TlsSlots[64];
LIST_ENTRY32 TlsLinks;
WOW64_POINTER(PVOID) Vdm;
WOW64_POINTER(PVOID) ReservedForNtRpc;
WOW64_POINTER(PVOID) DbgSsReserved[2];
ULONG HardErrorMode;
WOW64_POINTER(PVOID) Instrumentation[9];
GUID ActivityId;
WOW64_POINTER(PVOID) SubProcessTag;
WOW64_POINTER(PVOID) PerflibData;
WOW64_POINTER(PVOID) EtwTraceData;
WOW64_POINTER(PVOID) WinSockData;
ULONG GdiBatchCount;
union
{
PROCESSOR_NUMBER CurrentIdealProcessor;
ULONG IdealProcessorValue;
struct
{
UCHAR ReservedPad0;
UCHAR ReservedPad1;
UCHAR ReservedPad2;
UCHAR IdealProcessor;
};
};
ULONG GuaranteedStackBytes;
WOW64_POINTER(PVOID) ReservedForPerf;
WOW64_POINTER(PVOID) ReservedForOle;
ULONG WaitingOnLoaderLock;
WOW64_POINTER(PVOID) SavedPriorityState;
WOW64_POINTER(ULONG_PTR) ReservedForCodeCoverage;
WOW64_POINTER(PVOID) ThreadPoolData;
WOW64_POINTER(PVOID *) TlsExpansionSlots;
ULONG MuiGeneration;
ULONG IsImpersonating;
WOW64_POINTER(PVOID) NlsCache;
WOW64_POINTER(PVOID) pShimData;
USHORT HeapVirtualAffinity;
USHORT LowFragHeapDataSlot;
WOW64_POINTER(HANDLE) CurrentTransactionHandle;
WOW64_POINTER(PTEB_ACTIVE_FRAME) ActiveFrame;
WOW64_POINTER(PVOID) FlsData;
WOW64_POINTER(PVOID) PreferredLanguages;
WOW64_POINTER(PVOID) UserPrefLanguages;
WOW64_POINTER(PVOID) MergedPrefLanguages;
ULONG MuiImpersonation;
union
{
USHORT CrossTebFlags;
USHORT SpareCrossTebBits : 16;
};
union
{
USHORT SameTebFlags;
struct
{
USHORT SafeThunkCall : 1;
USHORT InDebugPrint : 1;
USHORT HasFiberData : 1;
USHORT SkipThreadAttach : 1;
USHORT WerInShipAssertCode : 1;
USHORT RanProcessInit : 1;
USHORT ClonedThread : 1;
USHORT SuppressDebugMsg : 1;
USHORT DisableUserStackWalk : 1;
USHORT RtlExceptionAttached : 1;
USHORT InitialThread : 1;
USHORT SessionAware : 1;
USHORT LoadOwner : 1;
USHORT LoaderWorker : 1;
USHORT SpareSameTebBits : 2;
};
};
WOW64_POINTER(PVOID) TxnScopeEnterCallback;
WOW64_POINTER(PVOID) TxnScopeExitCallback;
WOW64_POINTER(PVOID) TxnScopeContext;
ULONG LockCount;
LONG WowTebOffset;
WOW64_POINTER(PVOID) ResourceRetValue;
WOW64_POINTER(PVOID) ReservedForWdf;
ULONGLONG ReservedForCrt;
GUID EffectiveContainerId;
} TEB32, *PTEB32;
C_ASSERT(FIELD_OFFSET(TEB32, ProcessEnvironmentBlock) == 0x030);
C_ASSERT(FIELD_OFFSET(TEB32, ExceptionCode) == 0x1a4);
C_ASSERT(FIELD_OFFSET(TEB32, TxFsContext) == 0x1d0);
C_ASSERT(FIELD_OFFSET(TEB32, glContext) == 0xbf0);
C_ASSERT(FIELD_OFFSET(TEB32, StaticUnicodeBuffer) == 0xc00);
C_ASSERT(FIELD_OFFSET(TEB32, TlsLinks) == 0xf10);
C_ASSERT(FIELD_OFFSET(TEB32, DbgSsReserved) == 0xf20);
C_ASSERT(FIELD_OFFSET(TEB32, ActivityId) == 0xf50);
C_ASSERT(FIELD_OFFSET(TEB32, GdiBatchCount) == 0xf70);
C_ASSERT(FIELD_OFFSET(TEB32, TlsExpansionSlots) == 0xf94);
C_ASSERT(FIELD_OFFSET(TEB32, FlsData) == 0xfb4);
C_ASSERT(FIELD_OFFSET(TEB32, MuiImpersonation) == 0xfc4);
C_ASSERT(FIELD_OFFSET(TEB32, ReservedForCrt) == 0xfe8);
C_ASSERT(FIELD_OFFSET(TEB32, EffectiveContainerId) == 0xff0);
C_ASSERT(sizeof(TEB32) == 0x1000);
// Conversion
FORCEINLINE VOID UStr32ToUStr(
_Out_ PUNICODE_STRING Destination,
_In_ PUNICODE_STRING32 Source
)
{
Destination->Length = Source->Length;
Destination->MaximumLength = Source->MaximumLength;
Destination->Buffer = (PWCH)UlongToPtr(Source->Buffer);
}
FORCEINLINE VOID UStrToUStr32(
_Out_ PUNICODE_STRING32 Destination,
_In_ PUNICODE_STRING Source
)
{
Destination->Length = Source->Length;
Destination->MaximumLength = Source->MaximumLength;
Destination->Buffer = PtrToUlong(Source->Buffer);
}
// The Wow64Info structure follows the PEB32/TEB32 structures and is shared between 32-bit and 64-bit modules inside a Wow64 process.
// from SDK/10.0.10240.0/um/minwin/wow64t.h (dmex)
//
// Page size on x86 NT
//
#define PAGE_SIZE_X86NT 0x1000
#define PAGE_SHIFT_X86NT 12L
#define WOW64_SPLITS_PER_PAGE (PAGE_SIZE_X86NT / PAGE_SIZE_X86NT)
//
// Convert the number of native pages to sub x86-pages
//
#define Wow64GetNumberOfX86Pages(NativePages) \
(NativePages * (PAGE_SIZE_X86NT >> PAGE_SHIFT_X86NT))
//
// Macro to round to the nearest page size
//
#define WOW64_ROUND_TO_PAGES(Size) \
(((ULONG_PTR)(Size) + PAGE_SIZE_X86NT - 1) & ~(PAGE_SIZE_X86NT - 1))
//
// Get number of native pages
//
#define WOW64_BYTES_TO_PAGES(Size) \
(((ULONG)(Size) >> WOW64_ROUND_TO_PAGES) + (((ULONG)(Size) & (PAGE_SIZE_X86NT - 1)) != 0))
//
// Get the 32-bit TEB without doing a memory reference.
//
#define WOW64_GET_TEB32(teb64) ((PTEB32)(PVOID)RtlOffsetToPointer((teb64), WOW64_ROUND_TO_PAGES(sizeof(TEB))))
#define WOW64_TEB32_POINTER_ADDRESS(teb64) (PVOID)&((teb64)->NtTib.ExceptionList)
typedef union _WOW64_EXECUTE_OPTIONS
{
ULONG Flags;
struct
{
ULONG StackReserveSize : 8;
ULONG StackCommitSize : 4;
ULONG Deprecated0 : 1;
ULONG DisableWowAssert : 1;
ULONG DisableTurboDispatch : 1;
ULONG Unused : 13;
ULONG Reserved0 : 1;
ULONG Reserved1 : 1;
ULONG Reserved2 : 1;
ULONG Reserved3 : 1;
};
} WOW64_EXECUTE_OPTIONS, *PWOW64_EXECUTE_OPTIONS;
#define WOW64_CPUFLAGS_MSFT64 0x00000001
#define WOW64_CPUFLAGS_SOFTWARE 0x00000002
#define WOW64_CPUFLAGS_IA64 0x00000004
typedef struct _WOW64INFO
{
ULONG NativeSystemPageSize;
ULONG CpuFlags;
WOW64_EXECUTE_OPTIONS Wow64ExecuteFlags;
ULONG InstrumentationCallback;
} WOW64INFO, *PWOW64INFO;
typedef struct _PEB32_WITH_WOW64INFO
{
PEB32 Peb32;
WOW64INFO Wow64Info;
} PEB32_WITH_WOW64INFO, *PPEB32_WITH_WOW64INFO;
#if (PHNT_MODE != PHNT_MODE_KERNEL)
#ifdef _M_X64
FORCEINLINE
TEB32*
POINTER_UNSIGNED
Wow64CurrentGuestTeb(
VOID
)
{
TEB* POINTER_UNSIGNED Teb;
TEB32* POINTER_UNSIGNED Teb32;
Teb = NtCurrentTeb();
if (Teb->WowTebOffset == 0)
{
//
// Not running under or over WoW, so there is no "guest teb"
//
return NULL;
}
if (Teb->WowTebOffset < 0)
{
//
// Was called while running under WoW. The current teb is the guest
// teb.
//
Teb32 = (PTEB32)Teb;
RTL_ASSERT(&Teb32->WowTebOffset == &Teb->WowTebOffset);
}
else
{
//
// Called by the WoW Host, so calculate the position of the guest teb
// relative to the current (host) teb.
//
Teb32 = (PTEB32)RtlOffsetToPointer(Teb, Teb->WowTebOffset);
}
RTL_ASSERT(Teb32->NtTib.Self == PtrToUlong(Teb32));
return Teb32;
}
FORCEINLINE
VOID*
POINTER_UNSIGNED
Wow64CurrentNativeTeb(
VOID
)
{
TEB* POINTER_UNSIGNED Teb;
VOID* POINTER_UNSIGNED HostTeb;
Teb = NtCurrentTeb();
if (Teb->WowTebOffset >= 0)
{
//
// Not running under WoW, so it it either not running on WoW at all, or
// it is the host. Return the current teb as native teb.
//
HostTeb = (PVOID)Teb;
}
else
{
//
// Called while runnign under WoW Host, so calculate the position of the
// host teb relative to the current (guest) teb.
//
HostTeb = (PVOID)RtlOffsetToPointer(Teb, Teb->WowTebOffset);
}
RTL_ASSERT((((PTEB32)HostTeb)->NtTib.Self == PtrToUlong(HostTeb)) || ((ULONG_PTR)((PTEB)HostTeb)->NtTib.Self == (ULONG_PTR)HostTeb));
return HostTeb;
}
#define NtCurrentTeb32() (Wow64CurrentGuestTeb())
#define NtCurrentPeb32() ((PPEB32)(UlongToPtr((NtCurrentTeb32()->ProcessEnvironmentBlock))))
#define Wow64GetNativeTebField(teb, field) (((ULONG)(teb) == ((PTEB32)(teb))->NtTib.Self) ? (((PTEB32)(teb))->##field) : (((PTEB)(teb))->##field) )
#define Wow64SetNativeTebField(teb, field, value) { if ((ULONG)(teb) == ((PTEB32)(teb))->NtTib.Self) {(((PTEB32)(teb))->##field) = (value);} else {(((PTEB)(teb))->##field) = (value);} }
#endif
#endif
#endif