mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-25 14:41:02 +00:00
Comprehensive WOW64 subsystem implementation
This commit is contained in:
@@ -73,8 +73,18 @@
|
||||
#define SL_NO_CURSOR_UPDATE 0x10
|
||||
|
||||
#ifndef SEC_IMAGE
|
||||
#define SEC_IMAGE 0x01000000
|
||||
#define SEC_RESERVE 0x04000000
|
||||
#define SEC_HUGE_PAGES 0x00020000
|
||||
#define SEC_PARTITION_OWNER_HANDLE 0x00040000
|
||||
#define SEC_64K_PAGES 0x00080000
|
||||
#define SEC_FILE 0x00800000
|
||||
#define SEC_IMAGE 0x01000000
|
||||
#define SEC_PROTECTED_IMAGE 0x02000000
|
||||
#define SEC_RESERVE 0x04000000
|
||||
#define SEC_COMMIT 0x08000000
|
||||
#define SEC_NOCACHE 0x10000000
|
||||
#define SEC_WRITECOMBINE 0x40000000
|
||||
#define SEC_LARGE_PAGES 0x80000000
|
||||
#define SEC_IMAGE_NO_EXECUTE (SEC_IMAGE | SEC_NOCACHE)
|
||||
#endif
|
||||
|
||||
#define CTL_CODE(DeviceType, Function, Method, Access) (((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
|
||||
|
||||
@@ -4,7 +4,12 @@
|
||||
|
||||
// NOLINTBEGIN(modernize-use-using,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
|
||||
|
||||
#ifndef NT_SUCCESS
|
||||
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
|
||||
#endif
|
||||
|
||||
#define PROCESSOR_FEATURE_MAX 64
|
||||
#define GDI_HANDLE_BUFFER_SIZE32 34
|
||||
#define GDI_HANDLE_BUFFER_SIZE64 60
|
||||
#define RTL_ACTIVATION_CONTEXT_STACK_FRAME_FLAG_RELEASE_ON_DEACTIVATION 0x00000001
|
||||
#define RTL_ACTIVATION_CONTEXT_STACK_FRAME_FLAG_NO_DEACTIVATE 0x00000002
|
||||
@@ -115,12 +120,21 @@ typedef struct _EMU_NT_TIB64
|
||||
std::uint64_t StackBase;
|
||||
std::uint64_t StackLimit;
|
||||
std::uint64_t SubSystemTib;
|
||||
std::uint64_t FibreData;
|
||||
std::uint64_t FiberData;
|
||||
std::uint64_t ArbitraryUserPointer;
|
||||
EMULATOR_CAST(std::uint64_t, struct _EMU_NT_TIB64*) Self;
|
||||
} EMU_NT_TIB64;
|
||||
} EMU_NT_TIB64, *PEMU_NT_TIB64;
|
||||
|
||||
typedef EMU_NT_TIB64* PEMU_NT_TIB64;
|
||||
typedef struct _EMU_NT_TIB32
|
||||
{
|
||||
EMULATOR_CAST(std::uint32_t, struct _EXCEPTION_REGISTRATION_RECORD*) ExceptionList;
|
||||
std::uint32_t StackBase;
|
||||
std::uint32_t StackLimit;
|
||||
std::uint32_t SubSystemTib;
|
||||
std::uint32_t FiberData;
|
||||
std::uint32_t ArbitraryUserPointer;
|
||||
EMULATOR_CAST(std::uint32_t, struct _EMU_NT_TIB32*) Self;
|
||||
} EMU_NT_TIB32, *PEMU_NT_TIB32;
|
||||
|
||||
union PEB_BITFIELD_UNION
|
||||
{
|
||||
@@ -147,6 +161,105 @@ typedef struct _LIST_ENTRY64
|
||||
ULONGLONG Blink;
|
||||
} LIST_ENTRY64, *PLIST_ENTRY64, *RESTRICTED_POINTER PRLIST_ENTRY64;
|
||||
|
||||
typedef struct _LIST_ENTRY32
|
||||
{
|
||||
ULONG Flink;
|
||||
ULONG Blink;
|
||||
} LIST_ENTRY32, *PLIST_ENTRY32, *RESTRICTED_POINTER PRLIST_ENTRY32;
|
||||
|
||||
typedef enum _PROCESS_MITIGATION_POLICY
|
||||
{
|
||||
ProcessDEPPolicy,
|
||||
ProcessASLRPolicy,
|
||||
ProcessDynamicCodePolicy,
|
||||
ProcessStrictHandleCheckPolicy,
|
||||
ProcessSystemCallDisablePolicy,
|
||||
ProcessMitigationOptionsMask,
|
||||
ProcessExtensionPointDisablePolicy,
|
||||
ProcessControlFlowGuardPolicy,
|
||||
ProcessSignaturePolicy,
|
||||
ProcessFontDisablePolicy,
|
||||
ProcessImageLoadPolicy,
|
||||
ProcessSystemCallFilterPolicy,
|
||||
ProcessPayloadRestrictionPolicy,
|
||||
ProcessChildProcessPolicy,
|
||||
ProcessSideChannelIsolationPolicy,
|
||||
ProcessUserShadowStackPolicy,
|
||||
ProcessRedirectionTrustPolicy,
|
||||
ProcessUserPointerAuthPolicy,
|
||||
ProcessSEHOPPolicy,
|
||||
ProcessActivationContextTrustPolicy,
|
||||
MaxProcessMitigationPolicy
|
||||
} PROCESS_MITIGATION_POLICY, *PPROCESS_MITIGATION_POLICY;
|
||||
|
||||
#define WOW64_SIZE_OF_80387_REGISTERS 80
|
||||
|
||||
#define WOW64_MAXIMUM_SUPPORTED_EXTENSION 512
|
||||
|
||||
typedef struct _WOW64_FLOATING_SAVE_AREA
|
||||
{
|
||||
DWORD ControlWord;
|
||||
DWORD StatusWord;
|
||||
DWORD TagWord;
|
||||
DWORD ErrorOffset;
|
||||
DWORD ErrorSelector;
|
||||
DWORD DataOffset;
|
||||
DWORD DataSelector;
|
||||
BYTE RegisterArea[WOW64_SIZE_OF_80387_REGISTERS];
|
||||
DWORD Cr0NpxState;
|
||||
} WOW64_FLOATING_SAVE_AREA;
|
||||
|
||||
typedef struct _WOW64_CONTEXT
|
||||
{
|
||||
DWORD ContextFlags;
|
||||
DWORD Dr0;
|
||||
DWORD Dr1;
|
||||
DWORD Dr2;
|
||||
DWORD Dr3;
|
||||
DWORD Dr6;
|
||||
DWORD Dr7;
|
||||
WOW64_FLOATING_SAVE_AREA FloatSave;
|
||||
DWORD SegGs;
|
||||
DWORD SegFs;
|
||||
DWORD SegEs;
|
||||
DWORD SegDs;
|
||||
DWORD Edi;
|
||||
DWORD Esi;
|
||||
DWORD Ebx;
|
||||
DWORD Edx;
|
||||
DWORD Ecx;
|
||||
DWORD Eax;
|
||||
DWORD Ebp;
|
||||
DWORD Eip;
|
||||
DWORD SegCs;
|
||||
DWORD EFlags;
|
||||
DWORD Esp;
|
||||
DWORD SegSs;
|
||||
BYTE ExtendedRegisters[WOW64_MAXIMUM_SUPPORTED_EXTENSION];
|
||||
|
||||
} WOW64_CONTEXT;
|
||||
|
||||
#define MEM_EXTENDED_PARAMETER_GRAPHICS 0x00000001
|
||||
#define MEM_EXTENDED_PARAMETER_NONPAGED 0x00000002
|
||||
#define MEM_EXTENDED_PARAMETER_ZERO_PAGES_OPTIONAL 0x00000004
|
||||
#define MEM_EXTENDED_PARAMETER_NONPAGED_LARGE 0x00000008
|
||||
#define MEM_EXTENDED_PARAMETER_NONPAGED_HUGE 0x00000010
|
||||
#define MEM_EXTENDED_PARAMETER_SOFT_FAULT_PAGES 0x00000020
|
||||
#define MEM_EXTENDED_PARAMETER_EC_CODE 0x00000040
|
||||
#define MEM_EXTENDED_PARAMETER_IMAGE_NO_HPAT 0x00000080
|
||||
|
||||
typedef enum MEM_EXTENDED_PARAMETER_TYPE
|
||||
{
|
||||
MemExtendedParameterInvalidType = 0,
|
||||
MemExtendedParameterAddressRequirements,
|
||||
MemExtendedParameterNumaNode,
|
||||
MemExtendedParameterPartitionHandle,
|
||||
MemExtendedParameterUserPhysicalHandle,
|
||||
MemExtendedParameterAttributeFlags,
|
||||
MemExtendedParameterImageMachine,
|
||||
MemExtendedParameterMax
|
||||
} MEM_EXTENDED_PARAMETER_TYPE, *PMEM_EXTENDED_PARAMETER_TYPE;
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct _PEB_LDR_DATA64
|
||||
@@ -162,6 +275,21 @@ typedef struct _PEB_LDR_DATA64
|
||||
EmulatorTraits<Emu64>::HANDLE ShutdownThreadId;
|
||||
} PEB_LDR_DATA64, *PPEB_LDR_DATA64;
|
||||
|
||||
typedef struct _PEB_LDR_DATA32
|
||||
{
|
||||
ULONG Length;
|
||||
BOOLEAN Initialized;
|
||||
EmulatorTraits<Emu32>::HANDLE SsHandle;
|
||||
LIST_ENTRY32 InLoadOrderModuleList;
|
||||
LIST_ENTRY32 InMemoryOrderModuleList;
|
||||
LIST_ENTRY32 InInitializationOrderModuleList;
|
||||
std::uint32_t EntryInProgress;
|
||||
BOOLEAN ShutdownInProgress;
|
||||
EmulatorTraits<Emu32>::HANDLE ShutdownThreadId;
|
||||
} PEB_LDR_DATA32, *PPEB_LDR_DATA32;
|
||||
|
||||
static_assert(sizeof(PEB_LDR_DATA32) == 48);
|
||||
|
||||
using STRING64 = UNICODE_STRING<EmulatorTraits<Emu64>>;
|
||||
using ANSI_STRING64 = STRING64;
|
||||
using OEM_STRING64 = STRING64;
|
||||
@@ -189,6 +317,19 @@ typedef struct _CURDIR64
|
||||
EmulatorTraits<Emu64>::HANDLE Handle;
|
||||
} CURDIR64, *PCURDIR64;
|
||||
|
||||
#define RTL_USER_PROCESS_PARAMETERS_NORMALIZED 0x01
|
||||
#define RTL_USER_PROCESS_PARAMETERS_PROFILE_USER 0x02
|
||||
#define RTL_USER_PROCESS_PARAMETERS_PROFILE_KERNEL 0x04
|
||||
#define RTL_USER_PROCESS_PARAMETERS_PROFILE_SERVER 0x08
|
||||
#define RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB 0x20
|
||||
#define RTL_USER_PROCESS_PARAMETERS_RESERVE_16MB 0x40
|
||||
#define RTL_USER_PROCESS_PARAMETERS_CASE_SENSITIVE 0x80
|
||||
#define RTL_USER_PROCESS_PARAMETERS_DISABLE_HEAP_DECOMMIT 0x100
|
||||
#define RTL_USER_PROCESS_PARAMETERS_DLL_REDIRECTION_LOCAL 0x1000
|
||||
#define RTL_USER_PROCESS_PARAMETERS_APP_MANIFEST_PRESENT 0x2000
|
||||
#define RTL_USER_PROCESS_PARAMETERS_IMAGE_KEY_MISSING 0x4000
|
||||
#define RTL_USER_PROCESS_PARAMETERS_NX_OPTIN 0x20000
|
||||
|
||||
typedef struct _RTL_USER_PROCESS_PARAMETERS64
|
||||
{
|
||||
ULONG MaximumLength;
|
||||
@@ -334,6 +475,77 @@ typedef struct _NLSTABLEINFO
|
||||
EMULATOR_CAST(uint64_t, USHORT*) LowerCaseTable;
|
||||
} NLSTABLEINFO, *PNLSTABLEINFO;
|
||||
|
||||
typedef struct _CURDIR32
|
||||
{
|
||||
UNICODE_STRING<EmulatorTraits<Emu32>> DosPath;
|
||||
EmulatorTraits<Emu32>::HANDLE Handle;
|
||||
} CURDIR32, *PCURDIR32;
|
||||
|
||||
static_assert(sizeof(CURDIR32) == 12);
|
||||
|
||||
typedef struct _RTL_DRIVE_LETTER_CURDIR32
|
||||
{
|
||||
USHORT Flags;
|
||||
USHORT Length;
|
||||
ULONG TimeStamp;
|
||||
UNICODE_STRING<EmulatorTraits<Emu32>> DosPath;
|
||||
} RTL_DRIVE_LETTER_CURDIR32, *PRTL_DRIVE_LETTER_CURDIR32;
|
||||
|
||||
static_assert(sizeof(RTL_DRIVE_LETTER_CURDIR32) == 16);
|
||||
|
||||
typedef struct _RTL_USER_PROCESS_PARAMETERS32
|
||||
{
|
||||
ULONG MaximumLength;
|
||||
ULONG Length;
|
||||
|
||||
ULONG Flags;
|
||||
ULONG DebugFlags;
|
||||
|
||||
EmulatorTraits<Emu32>::HANDLE ConsoleHandle;
|
||||
ULONG ConsoleFlags;
|
||||
EmulatorTraits<Emu32>::HANDLE StandardInput;
|
||||
EmulatorTraits<Emu32>::HANDLE StandardOutput;
|
||||
EmulatorTraits<Emu32>::HANDLE StandardError;
|
||||
|
||||
CURDIR32 CurrentDirectory;
|
||||
UNICODE_STRING<EmulatorTraits<Emu32>> DllPath;
|
||||
UNICODE_STRING<EmulatorTraits<Emu32>> ImagePathName;
|
||||
UNICODE_STRING<EmulatorTraits<Emu32>> CommandLine;
|
||||
std::uint32_t Environment;
|
||||
|
||||
ULONG StartingX;
|
||||
ULONG StartingY;
|
||||
ULONG CountX;
|
||||
ULONG CountY;
|
||||
ULONG CountCharsX;
|
||||
ULONG CountCharsY;
|
||||
ULONG FillAttribute;
|
||||
|
||||
ULONG WindowFlags;
|
||||
ULONG ShowWindowFlags;
|
||||
UNICODE_STRING<EmulatorTraits<Emu32>> WindowTitle;
|
||||
UNICODE_STRING<EmulatorTraits<Emu32>> DesktopInfo;
|
||||
UNICODE_STRING<EmulatorTraits<Emu32>> ShellInfo;
|
||||
UNICODE_STRING<EmulatorTraits<Emu32>> RuntimeData;
|
||||
RTL_DRIVE_LETTER_CURDIR32 CurrentDirectories[RTL_MAX_DRIVE_LETTERS];
|
||||
|
||||
std::uint32_t EnvironmentSize;
|
||||
std::uint32_t EnvironmentVersion;
|
||||
|
||||
std::uint32_t PackageDependencyData;
|
||||
ULONG ProcessGroupId;
|
||||
ULONG LoaderThreads;
|
||||
|
||||
UNICODE_STRING<EmulatorTraits<Emu32>> RedirectionDllName; // REDSTONE4
|
||||
UNICODE_STRING<EmulatorTraits<Emu32>> HeapPartitionName; // 19H1
|
||||
std::uint32_t DefaultThreadpoolCpuSetMasks;
|
||||
ULONG DefaultThreadpoolCpuSetMaskCount;
|
||||
ULONG DefaultThreadpoolThreadMaximum;
|
||||
ULONG HeapMemoryTypeMask; // WIN11
|
||||
} RTL_USER_PROCESS_PARAMETERS32, *PRTL_USER_PROCESS_PARAMETERS32;
|
||||
|
||||
static_assert(sizeof(RTL_USER_PROCESS_PARAMETERS32) == 708);
|
||||
|
||||
typedef struct _PEB64
|
||||
{
|
||||
BOOLEAN InheritedAddressSpace;
|
||||
@@ -457,6 +669,184 @@ typedef struct _PEB64
|
||||
|
||||
static_assert(sizeof(PEB64) == 0x7D0);
|
||||
|
||||
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;
|
||||
};
|
||||
};
|
||||
|
||||
EmulatorTraits<Emu32>::HANDLE Mutant;
|
||||
|
||||
std::uint32_t ImageBaseAddress;
|
||||
EMULATOR_CAST(std::uint32_t, PPEB_LDR_DATA32) Ldr;
|
||||
EMULATOR_CAST(std::uint32_t, struct _RTL_USER_PROCESS_PARAMETERS32*) ProcessParameters;
|
||||
EMULATOR_CAST(std::uint32_t, PVOID32) SubSystemData;
|
||||
EMULATOR_CAST(std::uint32_t, PVOID32) ProcessHeap;
|
||||
EMULATOR_CAST(std::uint32_t, struct _RTL_CRITICAL_SECTION32*) FastPebLock;
|
||||
EMULATOR_CAST(std::uint32_t, union _SLIST_HEADER*) AtlThunkSListPtr;
|
||||
EMULATOR_CAST(std::uint32_t, PVOID32) IFEOKey;
|
||||
|
||||
union
|
||||
{
|
||||
ULONG CrossProcessFlags;
|
||||
struct
|
||||
{
|
||||
ULONG ProcessInJob : 1;
|
||||
ULONG ProcessInitializing : 1;
|
||||
ULONG ProcessUsingVEH : 1;
|
||||
ULONG ProcessUsingVCH : 1;
|
||||
ULONG ProcessUsingFTH : 1;
|
||||
ULONG ProcessPreviouslyThrottled : 1;
|
||||
ULONG ProcessCurrentlyThrottled : 1;
|
||||
ULONG ProcessImagesHotPatched : 1; // REDSTONE5
|
||||
ULONG ReservedBits0 : 24;
|
||||
};
|
||||
};
|
||||
union
|
||||
{
|
||||
EMULATOR_CAST(std::uint32_t, PVOID32) KernelCallbackTable;
|
||||
EMULATOR_CAST(std::uint32_t, PVOID32) UserSharedInfoPtr;
|
||||
};
|
||||
ULONG SystemReserved;
|
||||
ULONG AtlThunkSListPtr32;
|
||||
EMULATOR_CAST(std::uint32_t, struct _API_SET_NAMESPACE*) ApiSetMap;
|
||||
ULONG TlsExpansionCounter;
|
||||
EMULATOR_CAST(std::uint32_t, struct _RTL_BITMAP*) TlsBitmap;
|
||||
ARRAY_CONTAINER<ULONG, 2> TlsBitmapBits;
|
||||
|
||||
EMULATOR_CAST(std::uint32_t, PVOID32) ReadOnlySharedMemoryBase;
|
||||
EMULATOR_CAST(std::uint32_t, struct _SILO_USER_SHARED_DATA*) SharedData; // HotpatchInformation
|
||||
EMULATOR_CAST(std::uint32_t, PVOID32*) ReadOnlyStaticServerData;
|
||||
|
||||
EMULATOR_CAST(std::uint32_t, PVOID32) AnsiCodePageData; // PCPTABLEINFO
|
||||
EMULATOR_CAST(std::uint32_t, PVOID32) OemCodePageData; // PCPTABLEINFO
|
||||
EMULATOR_CAST(std::uint32_t, PVOID32) UnicodeCaseTableData; // PNLSTABLEINFO
|
||||
|
||||
ULONG NumberOfProcessors;
|
||||
ULONG NtGlobalFlag;
|
||||
|
||||
ULARGE_INTEGER CriticalSectionTimeout;
|
||||
EMULATOR_CAST(std::uint32_t, SIZE_T32) HeapSegmentReserve;
|
||||
EMULATOR_CAST(std::uint32_t, SIZE_T32) HeapSegmentCommit;
|
||||
EMULATOR_CAST(std::uint32_t, SIZE_T32) HeapDeCommitTotalFreeThreshold;
|
||||
EMULATOR_CAST(std::uint32_t, SIZE_T32) HeapDeCommitFreeBlockThreshold;
|
||||
|
||||
ULONG NumberOfHeaps;
|
||||
ULONG MaximumNumberOfHeaps;
|
||||
EMULATOR_CAST(std::uint32_t, PVOID32*) ProcessHeaps; // PHEAP
|
||||
|
||||
EMULATOR_CAST(std::uint32_t, PVOID32) GdiSharedHandleTable; // PGDI_SHARED_MEMORY
|
||||
EMULATOR_CAST(std::uint32_t, PVOID32) ProcessStarterHelper;
|
||||
ULONG GdiDCAttributeList;
|
||||
|
||||
EMULATOR_CAST(std::uint32_t, struct _RTL_CRITICAL_SECTION32*) LoaderLock;
|
||||
|
||||
ULONG OSMajorVersion;
|
||||
ULONG OSMinorVersion;
|
||||
USHORT OSBuildNumber;
|
||||
USHORT OSCSDVersion;
|
||||
ULONG OSPlatformId;
|
||||
ULONG ImageSubsystem;
|
||||
ULONG ImageSubsystemMajorVersion;
|
||||
ULONG ImageSubsystemMinorVersion;
|
||||
EMULATOR_CAST(std::uint32_t, KAFFINITY32) ActiveProcessAffinityMask;
|
||||
ARRAY_CONTAINER<ULONG, GDI_HANDLE_BUFFER_SIZE32> GdiHandleBuffer;
|
||||
EMULATOR_CAST(std::uint32_t, PVOID32) PostProcessInitRoutine;
|
||||
|
||||
EMULATOR_CAST(std::uint32_t, PVOID32) TlsExpansionBitmap;
|
||||
ARRAY_CONTAINER<ULONG, 32> TlsExpansionBitmapBits;
|
||||
|
||||
ULONG SessionId;
|
||||
|
||||
ULARGE_INTEGER AppCompatFlags;
|
||||
ULARGE_INTEGER AppCompatFlagsUser;
|
||||
EMULATOR_CAST(std::uint32_t, PVOID32) pShimData;
|
||||
EMULATOR_CAST(std::uint32_t, PVOID32) AppCompatInfo; // APPCOMPAT_EXE_DATA
|
||||
|
||||
UNICODE_STRING<EmulatorTraits<Emu32>> CSDVersion;
|
||||
|
||||
EMULATOR_CAST(std::uint32_t, struct _ACTIVATION_CONTEXT_DATA*) ActivationContextData;
|
||||
EMULATOR_CAST(std::uint32_t, struct _ASSEMBLY_STORAGE_MAP32*) ProcessAssemblyStorageMap;
|
||||
EMULATOR_CAST(std::uint32_t, struct _ACTIVATION_CONTEXT_DATA*) SystemDefaultActivationContextData;
|
||||
EMULATOR_CAST(std::uint32_t, struct _ASSEMBLY_STORAGE_MAP32*) SystemAssemblyStorageMap;
|
||||
|
||||
EMULATOR_CAST(std::uint32_t, SIZE_T32) MinimumStackCommit;
|
||||
|
||||
ARRAY_CONTAINER<ULONG, 2> SparePointers; // 19H1 (previously FlsCallback to FlsHighIndex)
|
||||
EMULATOR_CAST(std::uint32_t, PVOID32) PatchLoaderData;
|
||||
EMULATOR_CAST(std::uint32_t, PVOID32) ChpeV2ProcessInfo; // _CHPEV2_PROCESS_INFO
|
||||
|
||||
ULONG AppModelFeatureState;
|
||||
ULONG SpareUlongs[2];
|
||||
|
||||
USHORT ActiveCodePage;
|
||||
USHORT OemCodePage;
|
||||
USHORT UseCaseMapping;
|
||||
USHORT UnusedNlsField;
|
||||
|
||||
EMULATOR_CAST(std::uint32_t, PVOID32) WerRegistrationData;
|
||||
EMULATOR_CAST(std::uint32_t, PVOID32) WerShipAssertPtr;
|
||||
|
||||
union
|
||||
{
|
||||
EMULATOR_CAST(std::uint32_t, PVOID32) pContextData; // WIN7
|
||||
EMULATOR_CAST(std::uint32_t, PVOID32) pUnused; // WIN10
|
||||
EMULATOR_CAST(std::uint32_t, PVOID32) EcCodeBitMap; // WIN11
|
||||
};
|
||||
|
||||
EMULATOR_CAST(std::uint32_t, PVOID32) pImageHeaderHash;
|
||||
union
|
||||
{
|
||||
ULONG TracingFlags;
|
||||
struct
|
||||
{
|
||||
ULONG HeapTracingEnabled : 1;
|
||||
ULONG CritSecTracingEnabled : 1;
|
||||
ULONG LibLoaderTracingEnabled : 1;
|
||||
ULONG SpareTracingBits : 29;
|
||||
};
|
||||
};
|
||||
ULONGLONG CsrServerReadOnlySharedMemoryBase;
|
||||
EMULATOR_CAST(std::uint32_t, struct _RTL_CRITICAL_SECTION32*) TppWorkerpListLock;
|
||||
LIST_ENTRY32 TppWorkerpList;
|
||||
ARRAY_CONTAINER<ULONG, 128> WaitOnAddressHashTable;
|
||||
EMULATOR_CAST(std::uint32_t, struct _PTELEMETRY_COVERAGE_HEADER*) TelemetryCoverageHeader; // REDSTONE3
|
||||
ULONG CloudFileFlags;
|
||||
ULONG CloudFileDiagFlags; // REDSTONE4
|
||||
CHAR PlaceholderCompatibilityMode;
|
||||
ARRAY_CONTAINER<CHAR, 7> PlaceholderCompatibilityModeReserved;
|
||||
EMULATOR_CAST(std::uint32_t, struct _LEAP_SECOND_DATA*) LeapSecondData; // REDSTONE5
|
||||
union
|
||||
{
|
||||
ULONG LeapSecondFlags;
|
||||
struct
|
||||
{
|
||||
ULONG SixtySecondEnabled : 1;
|
||||
ULONG Reserved : 31;
|
||||
};
|
||||
};
|
||||
ULONG NtGlobalFlag2;
|
||||
ULONGLONG ExtendedFeatureDisableMask; // since WIN11
|
||||
|
||||
} PEB32, *PPEB32;
|
||||
|
||||
static_assert(sizeof(PEB32) == 0x488, "sizeof(PEB32) is incorrect"); // WIN11
|
||||
|
||||
typedef struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME64
|
||||
{
|
||||
struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME* Previous;
|
||||
@@ -464,6 +854,59 @@ typedef struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME64
|
||||
ULONG Flags; // RTL_ACTIVATION_CONTEXT_STACK_FRAME_FLAG_*
|
||||
} RTL_ACTIVATION_CONTEXT_STACK_FRAME64, *PRTL_ACTIVATION_CONTEXT_STACK_FRAME64;
|
||||
|
||||
typedef struct _ASSEMBLY_STORAGE_MAP_ENTRY32
|
||||
{
|
||||
ULONG Flags;
|
||||
UNICODE_STRING<EmulatorTraits<Emu32>> DosPath;
|
||||
EMULATOR_CAST(std::uint32_t, HANDLE32) Handle;
|
||||
} ASSEMBLY_STORAGE_MAP_ENTRY32, *PASSEMBLY_STORAGE_MAP_ENTRY32;
|
||||
|
||||
static_assert(sizeof(ASSEMBLY_STORAGE_MAP_ENTRY32) == 16);
|
||||
|
||||
typedef struct _ASSEMBLY_STORAGE_MAP32
|
||||
{
|
||||
ULONG Flags;
|
||||
ULONG AssemblyCount;
|
||||
EMULATOR_CAST(std::uint32_t, PASSEMBLY_STORAGE_MAP_ENTRY32*) AssemblyArray;
|
||||
} ASSEMBLY_STORAGE_MAP32, *PASSEMBLY_STORAGE_MAP32;
|
||||
|
||||
static_assert(sizeof(ASSEMBLY_STORAGE_MAP32) == 12);
|
||||
|
||||
typedef struct _ACTIVATION_CONTEXT32
|
||||
{
|
||||
LONG RefCount;
|
||||
ULONG Flags;
|
||||
EMULATOR_CAST(std::uint32_t, struct _ACTIVATION_CONTEXT_DATA*) ActivationContextData;
|
||||
std::uint32_t /*PACTIVATION_CONTEXT_NOTIFY_ROUTINE*/ NotificationRoutine;
|
||||
std::uint32_t NotificationContext;
|
||||
ULONG SentNotifications[8];
|
||||
ULONG DisabledNotifications[8];
|
||||
ASSEMBLY_STORAGE_MAP32 StorageMap;
|
||||
EMULATOR_CAST(std::uint32_t, PASSEMBLY_STORAGE_MAP_ENTRY32) InlineStorageMapEntries[32];
|
||||
} ACTIVATION_CONTEXT32, *PACTIVATION_CONTEXT32;
|
||||
|
||||
static_assert(sizeof(ACTIVATION_CONTEXT32) == 224);
|
||||
|
||||
typedef struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME32
|
||||
{
|
||||
EMULATOR_CAST(std::uint32_t, struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME32*) Previous;
|
||||
EMULATOR_CAST(std::uint32_t, PACTIVATION_CONTEXT32) ActivationContext;
|
||||
ULONG Flags; // RTL_ACTIVATION_CONTEXT_STACK_FRAME_FLAG_*
|
||||
} RTL_ACTIVATION_CONTEXT_STACK_FRAME32, *PRTL_ACTIVATION_CONTEXT_STACK_FRAME32;
|
||||
|
||||
static_assert(sizeof(RTL_ACTIVATION_CONTEXT_STACK_FRAME32) == 12);
|
||||
|
||||
typedef struct _ACTIVATION_CONTEXT_STACK32
|
||||
{
|
||||
EMULATOR_CAST(std::uint32_t, PRTL_ACTIVATION_CONTEXT_STACK_FRAME32) ActiveFrame;
|
||||
LIST_ENTRY32 FrameListCache;
|
||||
ULONG Flags; // ACTIVATION_CONTEXT_STACK_FLAG_*
|
||||
ULONG NextCookieSequenceNumber;
|
||||
ULONG StackId;
|
||||
} ACTIVATION_CONTEXT_STACK32, *PACTIVATION_CONTEXT_STACK32;
|
||||
|
||||
static_assert(sizeof(ACTIVATION_CONTEXT_STACK32) == 24);
|
||||
|
||||
typedef struct _ACTIVATION_CONTEXT_STACK64
|
||||
{
|
||||
EMULATOR_CAST(std::uint64_t, PRTL_ACTIVATION_CONTEXT_STACK_FRAME64) ActiveFrame;
|
||||
@@ -480,6 +923,15 @@ typedef struct _GDI_TEB_BATCH64
|
||||
ULONG Buffer[GDI_BATCH_BUFFER_SIZE];
|
||||
} GDI_TEB_BATCH64, *PGDI_TEB_BATCH64;
|
||||
|
||||
typedef struct _GDI_TEB_BATCH32
|
||||
{
|
||||
ULONG Offset;
|
||||
EMULATOR_CAST(std::uint32_t, ULONG_PTR32) HDC;
|
||||
ULONG Buffer[GDI_BATCH_BUFFER_SIZE];
|
||||
} GDI_TEB_BATCH32, *PGDI_TEB_BATCH32;
|
||||
|
||||
static_assert(sizeof(GDI_TEB_BATCH32) == 1248, "sizeof(GDI_TEB_BATCH32) is incorrect");
|
||||
|
||||
#ifndef OS_WINDOWS
|
||||
typedef struct _GUID
|
||||
{
|
||||
@@ -686,6 +1138,164 @@ inline TEB64* NtCurrentTeb64()
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef struct _TEB32
|
||||
{
|
||||
EMU_NT_TIB32 NtTib;
|
||||
|
||||
std::uint32_t EnvironmentPointer;
|
||||
CLIENT_ID32 ClientId;
|
||||
std::uint32_t ActiveRpcHandle;
|
||||
std::uint32_t ThreadLocalStoragePointer;
|
||||
EMULATOR_CAST(std::uint32_t, PPEB32) ProcessEnvironmentBlock;
|
||||
|
||||
ULONG LastErrorValue;
|
||||
ULONG CountOfOwnedCriticalSections;
|
||||
std::uint32_t CsrClientThread;
|
||||
std::uint32_t Win32ThreadInfo;
|
||||
ULONG User32Reserved[26];
|
||||
ULONG UserReserved[5];
|
||||
std::uint32_t WOW32Reserved;
|
||||
LCID CurrentLocale;
|
||||
ULONG FpSoftwareStatusRegister;
|
||||
std::uint32_t ReservedForDebuggerInstrumentation[16];
|
||||
std::uint32_t SystemReserved1[26];
|
||||
|
||||
CHAR PlaceholderCompatibilityMode;
|
||||
BOOLEAN PlaceholderHydrationAlwaysExplicit;
|
||||
CHAR PlaceholderReserved[10];
|
||||
|
||||
ULONG ProxiedProcessId;
|
||||
ACTIVATION_CONTEXT_STACK32 ActivationStack;
|
||||
|
||||
UCHAR WorkingOnBehalfTicket[8];
|
||||
NTSTATUS ExceptionCode;
|
||||
|
||||
EMULATOR_CAST(std::uint32_t, PACTIVATION_CONTEXT_STACK32) ActivationContextStackPointer;
|
||||
EMULATOR_CAST(std::uint32_t, ULONG_PTR32) InstrumentationCallbackSp;
|
||||
EMULATOR_CAST(std::uint32_t, ULONG_PTR32) InstrumentationCallbackPreviousPc;
|
||||
EMULATOR_CAST(std::uint32_t, ULONG_PTR32) InstrumentationCallbackPreviousSp;
|
||||
|
||||
BOOLEAN InstrumentationCallbackDisabled;
|
||||
UCHAR SpareBytes[23];
|
||||
ULONG TxFsContext;
|
||||
GDI_TEB_BATCH32 GdiTebBatch;
|
||||
CLIENT_ID32 RealClientId;
|
||||
EmulatorTraits<Emu32>::HANDLE GdiCachedProcessHandle;
|
||||
ULONG GdiClientPID;
|
||||
ULONG GdiClientTID;
|
||||
std::uint32_t GdiThreadLocalInfo;
|
||||
EMULATOR_CAST(std::uint32_t, ULONG_PTR32) Win32ClientInfo[WIN32_CLIENT_INFO_LENGTH];
|
||||
std::uint32_t glDispatchTable[233];
|
||||
EMULATOR_CAST(std::uint32_t, ULONG_PTR32) glReserved1[29];
|
||||
std::uint32_t glReserved2;
|
||||
std::uint32_t glSectionInfo;
|
||||
std::uint32_t glSection;
|
||||
std::uint32_t glTable;
|
||||
std::uint32_t glCurrentRC;
|
||||
std::uint32_t glContext;
|
||||
|
||||
NTSTATUS LastStatusValue;
|
||||
UNICODE_STRING<EmulatorTraits<Emu32>> StaticUnicodeString;
|
||||
WCHAR StaticUnicodeBuffer[STATIC_UNICODE_BUFFER_LENGTH];
|
||||
|
||||
std::uint32_t DeallocationStack;
|
||||
ARRAY_CONTAINER<std::uint32_t, TLS_MINIMUM_AVAILABLE> TlsSlots;
|
||||
LIST_ENTRY32 TlsLinks;
|
||||
|
||||
std::uint32_t Vdm;
|
||||
std::uint32_t ReservedForNtRpc;
|
||||
std::uint32_t DbgSsReserved[2];
|
||||
|
||||
ULONG HardErrorMode;
|
||||
std::uint32_t Instrumentation[9];
|
||||
GUID ActivityId;
|
||||
|
||||
std::uint32_t SubProcessTag;
|
||||
std::uint32_t PerflibData;
|
||||
std::uint32_t EtwTraceData;
|
||||
std::uint32_t WinSockData;
|
||||
ULONG GdiBatchCount;
|
||||
|
||||
union
|
||||
{
|
||||
EMULATOR_CAST(std::uint32_t, PROCESSOR_NUMBER) CurrentIdealProcessor;
|
||||
ULONG IdealProcessorValue;
|
||||
struct
|
||||
{
|
||||
UCHAR ReservedPad0;
|
||||
UCHAR ReservedPad1;
|
||||
UCHAR ReservedPad2;
|
||||
UCHAR IdealProcessor;
|
||||
};
|
||||
};
|
||||
|
||||
ULONG GuaranteedStackBytes;
|
||||
EMULATOR_CAST(std::uint32_t, PVOID32) ReservedForPerf;
|
||||
EMULATOR_CAST(std::uint32_t, PVOID32) ReservedForOle; // tagSOleTlsData32
|
||||
ULONG WaitingOnLoaderLock;
|
||||
EMULATOR_CAST(std::uint32_t, PVOID32) SavedPriorityState;
|
||||
EMULATOR_CAST(std::uint32_t, ULONG_PTR32) ReservedForCodeCoverage;
|
||||
std::uint32_t ThreadPoolData;
|
||||
EMULATOR_CAST(std::uint32_t, PVOID32*) TlsExpansionSlots;
|
||||
ULONG MuiGeneration;
|
||||
ULONG IsImpersonating;
|
||||
std::uint32_t NlsCache;
|
||||
std::uint32_t pShimData;
|
||||
ULONG HeapData;
|
||||
EMULATOR_CAST(std::uint32_t, HANDLE32) CurrentTransactionHandle;
|
||||
EMULATOR_CAST(std::uint32_t, PTEB_ACTIVE_FRAME32) ActiveFrame;
|
||||
std::uint32_t FlsData;
|
||||
|
||||
std::uint32_t PreferredLanguages;
|
||||
std::uint32_t UserPrefLanguages;
|
||||
std::uint32_t 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 SkipLoaderInit : 1;
|
||||
USHORT SkipFileAPIBrokering : 1;
|
||||
};
|
||||
};
|
||||
|
||||
std::uint32_t TxnScopeEnterCallback;
|
||||
std::uint32_t TxnScopeExitCallback;
|
||||
std::uint32_t TxnScopeContext;
|
||||
ULONG LockCount;
|
||||
LONG WowTebOffset;
|
||||
std::uint32_t ResourceRetValue;
|
||||
std::uint32_t ReservedForWdf;
|
||||
ULONGLONG ReservedForCrt;
|
||||
GUID EffectiveContainerId;
|
||||
ULONGLONG LastSleepCounter; // Win11
|
||||
ULONG SpinCallCount;
|
||||
ULONGLONG ExtendedFeatureDisableMask;
|
||||
} TEB32, *PTEB32;
|
||||
|
||||
static_assert(sizeof(TEB32) == 4120, "sizeof(TEB32) is incorrect");
|
||||
|
||||
#pragma pack(push, 4)
|
||||
typedef struct _KSYSTEM_TIME
|
||||
{
|
||||
@@ -993,6 +1603,33 @@ typedef struct _SYSTEM_DYNAMIC_TIMEZONE_INFORMATION
|
||||
BOOLEAN DynamicDaylightTimeDisabled;
|
||||
} SYSTEM_DYNAMIC_TIMEZONE_INFORMATION, *PSYSTEM_DYNAMIC_TIMEZONE_INFORMATION;
|
||||
|
||||
// Memory address requirements structure
|
||||
typedef struct _MEM_ADDRESS_REQUIREMENTS64
|
||||
{
|
||||
EMULATOR_CAST(std::uint64_t, PVOID) LowestStartingAddress;
|
||||
EMULATOR_CAST(std::uint64_t, PVOID) HighestEndingAddress;
|
||||
EMULATOR_CAST(std::uint64_t, SIZE_T) Alignment;
|
||||
} MEM_ADDRESS_REQUIREMENTS64, *PMEM_ADDRESS_REQUIREMENTS64;
|
||||
|
||||
// Extended memory parameter structure
|
||||
typedef struct _MEM_EXTENDED_PARAMETER64
|
||||
{
|
||||
struct
|
||||
{
|
||||
ULONG64 Type : 8; // MEM_EXTENDED_PARAMETER_TYPE
|
||||
ULONG64 Reserved : 56;
|
||||
};
|
||||
|
||||
union
|
||||
{
|
||||
ULONG64 ULong64;
|
||||
EMULATOR_CAST(std::uint64_t, PVOID) Pointer;
|
||||
EMULATOR_CAST(std::uint64_t, SIZE_T) Size;
|
||||
EMULATOR_CAST(std::uint64_t, HANDLE) Handle;
|
||||
ULONG ULong;
|
||||
};
|
||||
} MEM_EXTENDED_PARAMETER64, *PMEM_EXTENDED_PARAMETER64;
|
||||
|
||||
typedef struct _PROCESS_BASIC_INFORMATION64
|
||||
{
|
||||
NTSTATUS ExitStatus;
|
||||
@@ -1091,4 +1728,242 @@ struct OBJECT_TYPE_INFORMATION
|
||||
ULONG DefaultNonPagedPoolCharge;
|
||||
};
|
||||
|
||||
// WIN8 to REDSTONE
|
||||
typedef struct _PS_MITIGATION_OPTIONS_MAP_V1
|
||||
{
|
||||
ULONG64 Map[1];
|
||||
} PS_MITIGATION_OPTIONS_MAP_V1, *PPS_MITIGATION_OPTIONS_MAP_V1;
|
||||
|
||||
// private // REDSTONE2 to 19H2
|
||||
typedef struct _PS_MITIGATION_OPTIONS_MAP_V2
|
||||
{
|
||||
ULONG64 Map[2];
|
||||
} PS_MITIGATION_OPTIONS_MAP_V2, *PPS_MITIGATION_OPTIONS_MAP_V2;
|
||||
|
||||
// private // since 20H1
|
||||
typedef struct _PS_MITIGATION_OPTIONS_MAP_V3
|
||||
{
|
||||
ULONG64 Map[3];
|
||||
} PS_MITIGATION_OPTIONS_MAP_V3, *PPS_MITIGATION_OPTIONS_MAP_V3;
|
||||
|
||||
typedef PS_MITIGATION_OPTIONS_MAP_V3 PS_MITIGATION_OPTIONS_MAP, *PPS_MITIGATION_OPTIONS_MAP;
|
||||
|
||||
// private // REDSTONE3 to 19H2
|
||||
typedef struct _PS_MITIGATION_AUDIT_OPTIONS_MAP_V2
|
||||
{
|
||||
ULONG64 Map[2];
|
||||
} PS_MITIGATION_AUDIT_OPTIONS_MAP_V2, *PPS_MITIGATION_AUDIT_OPTIONS_MAP_V2;
|
||||
|
||||
// private // since 20H1
|
||||
typedef struct _PS_MITIGATION_AUDIT_OPTIONS_MAP_V3
|
||||
{
|
||||
ULONG64 Map[3];
|
||||
} PS_MITIGATION_AUDIT_OPTIONS_MAP_V3, *PPS_MITIGATION_AUDIT_OPTIONS_MAP_V3, PS_MITIGATION_AUDIT_OPTIONS_MAP,
|
||||
*PPS_MITIGATION_AUDIT_OPTIONS_MAP;
|
||||
|
||||
// private // VISTA to WIN7 SP1
|
||||
typedef enum class _WOW64_SHARED_INFORMATION_V1
|
||||
{
|
||||
SharedNtdll32LdrInitializeThunk = 0,
|
||||
SharedNtdll32KiUserExceptionDispatcher = 1,
|
||||
SharedNtdll32KiUserApcDispatcher = 2,
|
||||
SharedNtdll32KiUserCallbackDispatcher = 3,
|
||||
SharedNtdll32LdrHotPatchRoutine = 4,
|
||||
SharedNtdll32ExpInterlockedPopEntrySListFault = 5,
|
||||
SharedNtdll32ExpInterlockedPopEntrySListResume = 6,
|
||||
SharedNtdll32ExpInterlockedPopEntrySListEnd = 7,
|
||||
SharedNtdll32RtlUserThreadStart = 8,
|
||||
SharedNtdll32pQueryProcessDebugInformationRemote = 9,
|
||||
SharedNtdll32EtwpNotificationThread = 10,
|
||||
SharedNtdll32BaseAddress = 11,
|
||||
Wow64SharedPageEntriesCount = 12
|
||||
} WOW64_SHARED_INFORMATION_V1;
|
||||
|
||||
// private // WIN8
|
||||
typedef enum class _WOW64_SHARED_INFORMATION_V2
|
||||
{
|
||||
SharedNtdll32LdrInitializeThunk = 0,
|
||||
SharedNtdll32KiUserExceptionDispatcher = 1,
|
||||
SharedNtdll32KiUserApcDispatcher = 2,
|
||||
SharedNtdll32KiUserCallbackDispatcher = 3,
|
||||
SharedNtdll32LdrHotPatchRoutine = 4,
|
||||
SharedNtdll32ExpInterlockedPopEntrySListFault = 5,
|
||||
SharedNtdll32ExpInterlockedPopEntrySListResume = 6,
|
||||
SharedNtdll32ExpInterlockedPopEntrySListEnd = 7,
|
||||
SharedNtdll32RtlUserThreadStart = 8,
|
||||
SharedNtdll32pQueryProcessDebugInformationRemote = 9,
|
||||
SharedNtdll32EtwpNotificationThread = 10,
|
||||
SharedNtdll32BaseAddress = 11,
|
||||
SharedNtdll32RtlpWnfNotificationThread = 12,
|
||||
SharedNtdll32LdrSystemDllInitBlock = 13,
|
||||
Wow64SharedPageEntriesCount = 14
|
||||
} WOW64_SHARED_INFORMATION_V2;
|
||||
|
||||
// private // WIN8.1 to THRESHOLD 1
|
||||
typedef enum class _WOW64_SHARED_INFORMATION_V3
|
||||
{
|
||||
SharedNtdll32LdrInitializeThunk = 0,
|
||||
SharedNtdll32KiUserExceptionDispatcher = 1,
|
||||
SharedNtdll32KiUserApcDispatcher = 2,
|
||||
SharedNtdll32KiUserCallbackDispatcher = 3,
|
||||
SharedNtdll32ExpInterlockedPopEntrySListFault = 4,
|
||||
SharedNtdll32ExpInterlockedPopEntrySListResume = 5,
|
||||
SharedNtdll32ExpInterlockedPopEntrySListEnd = 6,
|
||||
SharedNtdll32RtlUserThreadStart = 7,
|
||||
SharedNtdll32pQueryProcessDebugInformationRemote = 8,
|
||||
SharedNtdll32BaseAddress = 9,
|
||||
SharedNtdll32LdrSystemDllInitBlock = 10,
|
||||
Wow64SharedPageEntriesCount = 11
|
||||
} WOW64_SHARED_INFORMATION_V3;
|
||||
|
||||
// private // THRESHOLD 2 to REDSTONE 2
|
||||
typedef enum class _WOW64_SHARED_INFORMATION_V4
|
||||
{
|
||||
SharedNtdll32LdrInitializeThunk = 0,
|
||||
SharedNtdll32KiUserExceptionDispatcher = 1,
|
||||
SharedNtdll32KiUserApcDispatcher = 2,
|
||||
SharedNtdll32KiUserCallbackDispatcher = 3,
|
||||
SharedNtdll32RtlUserThreadStart = 4,
|
||||
SharedNtdll32pQueryProcessDebugInformationRemote = 5,
|
||||
SharedNtdll32BaseAddress = 6,
|
||||
SharedNtdll32LdrSystemDllInitBlock = 7,
|
||||
Wow64SharedPageEntriesCount = 8
|
||||
} WOW64_SHARED_INFORMATION_V4;
|
||||
|
||||
// private // REDSTONE 3 to 24H2
|
||||
typedef enum class _WOW64_SHARED_INFORMATION_V5
|
||||
{
|
||||
SharedNtdll32LdrInitializeThunk = 0,
|
||||
SharedNtdll32KiUserExceptionDispatcher = 1,
|
||||
SharedNtdll32KiUserApcDispatcher = 2,
|
||||
SharedNtdll32KiUserCallbackDispatcher = 3,
|
||||
SharedNtdll32RtlUserThreadStart = 4,
|
||||
SharedNtdll32pQueryProcessDebugInformationRemote = 5,
|
||||
SharedNtdll32BaseAddress = 6,
|
||||
SharedNtdll32LdrSystemDllInitBlock = 7,
|
||||
SharedNtdll32RtlpFreezeTimeBias = 8,
|
||||
Wow64SharedPageEntriesCount = 9
|
||||
} WOW64_SHARED_INFORMATION_V5;
|
||||
|
||||
// private // WIN8 to REDSTONE
|
||||
typedef struct _PS_SYSTEM_DLL_INIT_BLOCK_V1
|
||||
{
|
||||
ULONG Size;
|
||||
ULONG SystemDllWowRelocation;
|
||||
ULONG64 SystemDllNativeRelocation;
|
||||
ULONG Wow64SharedInformation[16]; // use WOW64_SHARED_INFORMATION as index
|
||||
ULONG RngData;
|
||||
union
|
||||
{
|
||||
ULONG Flags;
|
||||
struct
|
||||
{
|
||||
ULONG CfgOverride : 1; // since REDSTONE
|
||||
ULONG Reserved : 31;
|
||||
};
|
||||
};
|
||||
ULONG64 MitigationOptions;
|
||||
ULONG64 CfgBitMap; // since WINBLUE
|
||||
ULONG64 CfgBitMapSize;
|
||||
ULONG64 Wow64CfgBitMap; // since THRESHOLD
|
||||
ULONG64 Wow64CfgBitMapSize;
|
||||
} PS_SYSTEM_DLL_INIT_BLOCK_V1, *PPS_SYSTEM_DLL_INIT_BLOCK_V1;
|
||||
|
||||
// RS2 - 19H2
|
||||
typedef struct _PS_SYSTEM_DLL_INIT_BLOCK_V2
|
||||
{
|
||||
ULONG Size;
|
||||
ULONG64 SystemDllWowRelocation;
|
||||
ULONG64 SystemDllNativeRelocation;
|
||||
ULONG64 Wow64SharedInformation[16]; // use WOW64_SHARED_INFORMATION as index
|
||||
ULONG RngData;
|
||||
union
|
||||
{
|
||||
ULONG Flags;
|
||||
struct
|
||||
{
|
||||
ULONG CfgOverride : 1;
|
||||
ULONG Reserved : 31;
|
||||
};
|
||||
};
|
||||
PS_MITIGATION_OPTIONS_MAP_V2 MitigationOptionsMap;
|
||||
ULONG64 CfgBitMap;
|
||||
ULONG64 CfgBitMapSize;
|
||||
ULONG64 Wow64CfgBitMap;
|
||||
ULONG64 Wow64CfgBitMapSize;
|
||||
PS_MITIGATION_AUDIT_OPTIONS_MAP_V2 MitigationAuditOptionsMap; // since REDSTONE3
|
||||
} PS_SYSTEM_DLL_INIT_BLOCK_V2, *PPS_SYSTEM_DLL_INIT_BLOCK_V2;
|
||||
|
||||
// private // since 20H1
|
||||
typedef struct _PS_SYSTEM_DLL_INIT_BLOCK_V3
|
||||
{
|
||||
ULONG Size;
|
||||
ULONG64 SystemDllWowRelocation; // effectively since WIN8
|
||||
ULONG64 SystemDllNativeRelocation;
|
||||
ULONG64 Wow64SharedInformation[16]; // use WOW64_SHARED_INFORMATION_V5 as index
|
||||
ULONG RngData;
|
||||
union
|
||||
{
|
||||
ULONG Flags;
|
||||
struct
|
||||
{
|
||||
ULONG CfgOverride : 1; // effectively since REDSTONE
|
||||
ULONG Reserved : 31;
|
||||
};
|
||||
};
|
||||
PS_MITIGATION_OPTIONS_MAP_V3 MitigationOptionsMap;
|
||||
ULONG64 CfgBitMap; // effectively since WINBLUE
|
||||
ULONG64 CfgBitMapSize;
|
||||
ULONG64 Wow64CfgBitMap; // effectively since THRESHOLD
|
||||
ULONG64 Wow64CfgBitMapSize;
|
||||
PS_MITIGATION_AUDIT_OPTIONS_MAP_V3 MitigationAuditOptionsMap; // effectively since REDSTONE3
|
||||
ULONG64 ScpCfgCheckFunction; // since 24H2
|
||||
ULONG64 ScpCfgCheckESFunction;
|
||||
ULONG64 ScpCfgDispatchFunction;
|
||||
ULONG64 ScpCfgDispatchESFunction;
|
||||
ULONG64 ScpArm64EcCallCheck;
|
||||
ULONG64 ScpArm64EcCfgCheckFunction;
|
||||
ULONG64 ScpArm64EcCfgCheckESFunction;
|
||||
} PS_SYSTEM_DLL_INIT_BLOCK_V3, *PPS_SYSTEM_DLL_INIT_BLOCK_V3, PS_SYSTEM_DLL_INIT_BLOCK, *PPS_SYSTEM_DLL_INIT_BLOCK;
|
||||
|
||||
static_assert(sizeof(PS_SYSTEM_DLL_INIT_BLOCK_V3) == 0x128);
|
||||
|
||||
//
|
||||
// Process mitigation policy information
|
||||
// NtSetInformationProcess using ProcessMitigationPolicy
|
||||
//
|
||||
|
||||
typedef struct _PROCESS_MITIGATION_POLICY_RAW_DATA
|
||||
{
|
||||
PROCESS_MITIGATION_POLICY Policy;
|
||||
ULONG Value;
|
||||
} PROCESS_MITIGATION_POLICY_RAW_DATA, *PPROCESS_MITIGATION_POLICY_RAW_DATA;
|
||||
|
||||
static_assert(sizeof(PROCESS_MITIGATION_POLICY_RAW_DATA) == 0x8);
|
||||
|
||||
typedef struct _WOW64_CPURESERVED
|
||||
{
|
||||
USHORT Flags; // Initialised to 0x02 by ntdll.dll and periodically bitwise OR'd with WOW64_CPURESERVED_FLAG_RESET_STATE
|
||||
USHORT MachineType; // IMAGE_FILE_MACHINE_I386 (0x014C) for x86 architecture
|
||||
|
||||
// Under IMAGE_FILE_MACHINE_I386 machine type, this is the WOW64_CONTEXT structure containing x86 architecture context
|
||||
WOW64_CONTEXT Context;
|
||||
|
||||
// Padding to align WOW64 stack
|
||||
BYTE AlignmentPad[0x10];
|
||||
} WOW64_CPURESERVED, *PWOW64_CPURESERVED;
|
||||
|
||||
static_assert(sizeof(WOW64_CPURESERVED) == 0x2E0);
|
||||
|
||||
#define WOW64_CPURESERVED_FLAG_RESET_STATE 1
|
||||
|
||||
typedef enum class _SECTION_INFORMATION_CLASS
|
||||
{
|
||||
SectionBasicInformation = 0,
|
||||
SectionImageInformation = 1,
|
||||
SectionRelocationInformation = 2,
|
||||
SectionOriginalBaseInformation = 3,
|
||||
SectionInternalImageInformation = 4
|
||||
} SECTION_INFORMATION_CLASS, *PSECTION_INFORMATION_CLASS;
|
||||
|
||||
// NOLINTEND(modernize-use-using,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
using LONG = std::int32_t;
|
||||
using ULONG = DWORD;
|
||||
using DWORD64 = std::uint64_t;
|
||||
using ULONG64 = std::uint64_t;
|
||||
using ULONGLONG = DWORD64;
|
||||
using LONGLONG = std::int64_t;
|
||||
using UINT = std::uint32_t;
|
||||
@@ -52,6 +53,7 @@ using BYTE = std::uint8_t;
|
||||
#endif
|
||||
|
||||
using WORD = std::uint16_t;
|
||||
#define WCHAR WORD
|
||||
|
||||
#define UCHAR uint8_t
|
||||
#define BOOLEAN UCHAR
|
||||
|
||||
@@ -6,24 +6,29 @@
|
||||
#define CREATE_SUSPENDED 0x00000004
|
||||
#endif
|
||||
|
||||
#define CONTEXT_X86_MAIN 0x00010000
|
||||
#define CONTEXT_AMD64_MAIN 0x100000
|
||||
#define CONTEXT_CONTROL_32 (CONTEXT_X86_MAIN | 0x1L)
|
||||
#define CONTEXT_CONTROL_64 (CONTEXT_AMD64_MAIN | 0x1L)
|
||||
#define CONTEXT_INTEGER_32 (CONTEXT_X86_MAIN | 0x2L)
|
||||
#define CONTEXT_INTEGER_64 (CONTEXT_AMD64_MAIN | 0x2L)
|
||||
#define CONTEXT_SEGMENTS_32 (CONTEXT_X86_MAIN | 0x4L)
|
||||
#define CONTEXT_SEGMENTS_64 (CONTEXT_AMD64_MAIN | 0x4L)
|
||||
#define CONTEXT_FLOATING_POINT_32 (CONTEXT_X86_MAIN | 0x8L)
|
||||
#define CONTEXT_FLOATING_POINT_64 (CONTEXT_AMD64_MAIN | 0x8L)
|
||||
#define CONTEXT_DEBUG_REGISTERS_32 (CONTEXT_X86_MAIN | 0x10L)
|
||||
#define CONTEXT_DEBUG_REGISTERS_64 (CONTEXT_AMD64_MAIN | 0x10L)
|
||||
#define CONTEXT_XSTATE_32 (CONTEXT_X86_MAIN | 0x20L)
|
||||
#define CONTEXT_XSTATE_64 (CONTEXT_AMD64_MAIN | 0x20L)
|
||||
#define CONTEXT_X86_MAIN 0x00010000
|
||||
#define CONTEXT_AMD64_MAIN 0x100000
|
||||
#define CONTEXT_CONTROL_32 (CONTEXT_X86_MAIN | 0x1L)
|
||||
#define CONTEXT_CONTROL_64 (CONTEXT_AMD64_MAIN | 0x1L)
|
||||
#define CONTEXT_INTEGER_32 (CONTEXT_X86_MAIN | 0x2L)
|
||||
#define CONTEXT_INTEGER_64 (CONTEXT_AMD64_MAIN | 0x2L)
|
||||
#define CONTEXT_SEGMENTS_32 (CONTEXT_X86_MAIN | 0x4L)
|
||||
#define CONTEXT_SEGMENTS_64 (CONTEXT_AMD64_MAIN | 0x4L)
|
||||
#define CONTEXT_FLOATING_POINT_32 (CONTEXT_X86_MAIN | 0x8L)
|
||||
#define CONTEXT_FLOATING_POINT_64 (CONTEXT_AMD64_MAIN | 0x8L)
|
||||
#define CONTEXT_DEBUG_REGISTERS_32 (CONTEXT_X86_MAIN | 0x10L)
|
||||
#define CONTEXT_DEBUG_REGISTERS_64 (CONTEXT_AMD64_MAIN | 0x10L)
|
||||
#define CONTEXT_EXTENDED_REGISTERS_32 (CONTEXT_X86_MAIN | 0x20L)
|
||||
#define CONTEXT_XSTATE_32 (CONTEXT_X86_MAIN | 0x40L)
|
||||
#define CONTEXT_XSTATE_64 (CONTEXT_AMD64_MAIN | 0x40L)
|
||||
|
||||
#define CONTEXT64_ALL \
|
||||
(CONTEXT_CONTROL_64 | CONTEXT_INTEGER_64 | CONTEXT_SEGMENTS_64 | CONTEXT_FLOATING_POINT_64 | CONTEXT_DEBUG_REGISTERS_64)
|
||||
|
||||
#define CONTEXT32_ALL \
|
||||
(CONTEXT_CONTROL_32 | CONTEXT_INTEGER_32 | CONTEXT_SEGMENTS_32 | CONTEXT_FLOATING_POINT_32 | CONTEXT_DEBUG_REGISTERS_32 | \
|
||||
CONTEXT_EXTENDED_REGISTERS_32)
|
||||
|
||||
using SYSTEM_INFORMATION_CLASS = enum _SYSTEM_INFORMATION_CLASS
|
||||
{
|
||||
SystemBasicInformation, // q: SYSTEM_BASIC_INFORMATION
|
||||
@@ -977,6 +982,12 @@ struct GDI_SHARED_MEMORY64
|
||||
|
||||
static_assert(offsetof(GDI_SHARED_MEMORY64, Objects) == 0x1800B0);
|
||||
|
||||
struct CLIENT_ID32
|
||||
{
|
||||
ULONG UniqueProcess;
|
||||
ULONG UniqueThread;
|
||||
};
|
||||
|
||||
struct CLIENT_ID64
|
||||
{
|
||||
DWORD64 UniqueProcess;
|
||||
|
||||
@@ -39,11 +39,14 @@ using NTSTATUS = std::uint32_t;
|
||||
#define STATUS_INVALID_PAGE_PROTECTION ((NTSTATUS)0xC0000045L)
|
||||
#define STATUS_MUTANT_NOT_OWNED ((NTSTATUS)0xC0000046L)
|
||||
#define STATUS_SEMAPHORE_LIMIT_EXCEEDED ((NTSTATUS)0xC0000047L)
|
||||
#define STATUS_SECTION_NOT_IMAGE ((NTSTATUS)0xC0000049L)
|
||||
#define STATUS_NO_TOKEN ((NTSTATUS)0xC000007CL)
|
||||
#define STATUS_FILE_INVALID ((NTSTATUS)0xC0000098L)
|
||||
#define STATUS_MEMORY_NOT_ALLOCATED ((NTSTATUS)0xC00000A0L)
|
||||
#define STATUS_FILE_IS_A_DIRECTORY ((NTSTATUS)0xC00000BAL)
|
||||
#define STATUS_NOT_SUPPORTED ((NTSTATUS)0xC00000BBL)
|
||||
#define STATUS_INTERNAL_ERROR ((NTSTATUS)0xC00000E5L)
|
||||
#define STATUS_PROCEDURE_NOT_FOUND ((NTSTATUS)0xC000007AL)
|
||||
#define STATUS_INVALID_ADDRESS ((NTSTATUS)0xC0000141L)
|
||||
#define STATUS_CONNECTION_RESET ((NTSTATUS)0xC000020DL)
|
||||
#define STATUS_NOT_FOUND ((NTSTATUS)0xC0000225L)
|
||||
|
||||
@@ -8,7 +8,6 @@ struct UNICODE_STRING
|
||||
{
|
||||
USHORT Length;
|
||||
USHORT MaximumLength;
|
||||
uint32_t _Padding;
|
||||
EMULATOR_CAST(typename Traits::PVOID, char16_t*) Buffer;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstring>
|
||||
#include <cstdint>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <system_error>
|
||||
#include <variant>
|
||||
|
||||
// NOLINTBEGIN(modernize-use-using,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
|
||||
|
||||
@@ -54,10 +59,42 @@
|
||||
#define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE 0x0040
|
||||
#define IMAGE_FILE_DLL 0x2000
|
||||
|
||||
#define IMAGE_FILE_MACHINE_I386 0x014c
|
||||
#define IMAGE_FILE_MACHINE_AMD64 0x8664
|
||||
#ifndef OS_WINDOWS
|
||||
#define IMAGE_FILE_MACHINE_UNKNOWN 0
|
||||
#define IMAGE_FILE_MACHINE_TARGET_HOST 0x0001 // Useful for indicating we want to interact with the host and not a WoW guest.
|
||||
#define IMAGE_FILE_MACHINE_I386 0x014c // Intel 386.
|
||||
#define IMAGE_FILE_MACHINE_R3000 0x0162 // MIPS little-endian, 0x160 big-endian
|
||||
#define IMAGE_FILE_MACHINE_R4000 0x0166 // MIPS little-endian
|
||||
#define IMAGE_FILE_MACHINE_R10000 0x0168 // MIPS little-endian
|
||||
#define IMAGE_FILE_MACHINE_WCEMIPSV2 0x0169 // MIPS little-endian WCE v2
|
||||
#define IMAGE_FILE_MACHINE_ALPHA 0x0184 // Alpha_AXP
|
||||
#define IMAGE_FILE_MACHINE_SH3 0x01a2 // SH3 little-endian
|
||||
#define IMAGE_FILE_MACHINE_SH3DSP 0x01a3
|
||||
#define IMAGE_FILE_MACHINE_SH3E 0x01a4 // SH3E little-endian
|
||||
#define IMAGE_FILE_MACHINE_SH4 0x01a6 // SH4 little-endian
|
||||
#define IMAGE_FILE_MACHINE_SH5 0x01a8 // SH5
|
||||
#define IMAGE_FILE_MACHINE_ARM 0x01c0 // ARM Little-Endian
|
||||
#define IMAGE_FILE_MACHINE_THUMB 0x01c2 // ARM Thumb/Thumb-2 Little-Endian
|
||||
#define IMAGE_FILE_MACHINE_ARMNT 0x01c4 // ARM Thumb-2 Little-Endian
|
||||
#define IMAGE_FILE_MACHINE_AM33 0x01d3
|
||||
#define IMAGE_FILE_MACHINE_POWERPC 0x01F0 // IBM PowerPC Little-Endian
|
||||
#define IMAGE_FILE_MACHINE_POWERPCFP 0x01f1
|
||||
#define IMAGE_FILE_MACHINE_IA64 0x0200 // Intel 64
|
||||
#define IMAGE_FILE_MACHINE_MIPS16 0x0266 // MIPS
|
||||
#define IMAGE_FILE_MACHINE_ALPHA64 0x0284 // ALPHA64
|
||||
#define IMAGE_FILE_MACHINE_MIPSFPU 0x0366 // MIPS
|
||||
#define IMAGE_FILE_MACHINE_MIPSFPU16 0x0466 // MIPS
|
||||
#define IMAGE_FILE_MACHINE_AXP64 IMAGE_FILE_MACHINE_ALPHA64
|
||||
#define IMAGE_FILE_MACHINE_TRICORE 0x0520 // Infineon
|
||||
#define IMAGE_FILE_MACHINE_CEF 0x0CEF
|
||||
#define IMAGE_FILE_MACHINE_EBC 0x0EBC // EFI Byte Code
|
||||
#define IMAGE_FILE_MACHINE_AMD64 0x8664 // AMD64 (K8)
|
||||
#define IMAGE_FILE_MACHINE_M32R 0x9041 // M32R little-endian
|
||||
#define IMAGE_FILE_MACHINE_ARM64 0xAA64 // ARM64 Little-Endian
|
||||
#define IMAGE_FILE_MACHINE_CEE 0xC0EE
|
||||
#endif
|
||||
|
||||
#define PROCESSOR_ARCHITECTURE_AMD64 9
|
||||
#define PROCESSOR_ARCHITECTURE_AMD64 9
|
||||
|
||||
enum class PEMachineType : std::uint16_t
|
||||
{
|
||||
@@ -311,7 +348,7 @@ typedef struct _IMAGE_IMPORT_DESCRIPTOR
|
||||
DWORD ForwarderChain; // -1 if no forwarders
|
||||
DWORD Name;
|
||||
DWORD FirstThunk; // RVA to IAT (if bound this IAT has actual addresses)
|
||||
} IMAGE_IMPORT_DESCRIPTOR;
|
||||
} IMAGE_IMPORT_DESCRIPTOR, *PIMAGE_IMPORT_DESCRIPTOR;
|
||||
|
||||
typedef struct _IMAGE_THUNK_DATA64
|
||||
{
|
||||
@@ -322,10 +359,65 @@ typedef struct _IMAGE_THUNK_DATA64
|
||||
ULONGLONG Ordinal;
|
||||
ULONGLONG AddressOfData; // PIMAGE_IMPORT_BY_NAME
|
||||
} u1;
|
||||
} IMAGE_THUNK_DATA64;
|
||||
} IMAGE_THUNK_DATA64, *PIMAGE_THUNK_DATA64;
|
||||
|
||||
typedef struct _IMAGE_THUNK_DATA32
|
||||
{
|
||||
union
|
||||
{
|
||||
DWORD ForwarderString; // PBYTE
|
||||
DWORD Function; // PDWORD
|
||||
DWORD Ordinal;
|
||||
DWORD AddressOfData; // PIMAGE_IMPORT_BY_NAME
|
||||
} u1;
|
||||
} IMAGE_THUNK_DATA32, *PIMAGE_THUNK_DATA32;
|
||||
|
||||
#endif
|
||||
|
||||
// Template type definitions for architecture-specific thunk data
|
||||
template <typename T>
|
||||
struct thunk_data_traits;
|
||||
|
||||
template <>
|
||||
struct thunk_data_traits<std::uint32_t>
|
||||
{
|
||||
using type = IMAGE_THUNK_DATA32;
|
||||
static constexpr DWORD ordinal_flag = IMAGE_ORDINAL_FLAG32;
|
||||
|
||||
static constexpr WORD ordinal_mask(DWORD ordinal)
|
||||
{
|
||||
return IMAGE_ORDINAL32(ordinal);
|
||||
}
|
||||
static constexpr bool snap_by_ordinal(DWORD ordinal)
|
||||
{
|
||||
return IMAGE_SNAP_BY_ORDINAL32(ordinal);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct thunk_data_traits<std::uint64_t>
|
||||
{
|
||||
using type = IMAGE_THUNK_DATA64;
|
||||
static constexpr ULONGLONG ordinal_flag = IMAGE_ORDINAL_FLAG64;
|
||||
|
||||
static constexpr WORD ordinal_mask(ULONGLONG ordinal)
|
||||
{
|
||||
return IMAGE_ORDINAL64(ordinal);
|
||||
}
|
||||
static constexpr bool snap_by_ordinal(ULONGLONG ordinal)
|
||||
{
|
||||
return IMAGE_SNAP_BY_ORDINAL64(ordinal);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Traits>
|
||||
struct SECTION_BASIC_INFORMATION
|
||||
{
|
||||
typename Traits::PVOID BaseAddress;
|
||||
ULONG Attributes;
|
||||
LARGE_INTEGER Size;
|
||||
};
|
||||
|
||||
template <typename Traits>
|
||||
struct SECTION_IMAGE_INFORMATION
|
||||
{
|
||||
@@ -383,4 +475,121 @@ struct SECTION_IMAGE_INFORMATION
|
||||
ULONG CheckSum;
|
||||
};
|
||||
|
||||
namespace winpe
|
||||
{
|
||||
|
||||
enum class pe_arch
|
||||
{
|
||||
pe32,
|
||||
pe64
|
||||
};
|
||||
|
||||
inline std::variant<pe_arch, std::error_code> get_pe_arch(const std::filesystem::path& file)
|
||||
{
|
||||
std::ifstream f(file, std::ios::binary);
|
||||
if (!f)
|
||||
{
|
||||
return std::make_error_code(std::errc::no_such_file_or_directory);
|
||||
}
|
||||
|
||||
PEDosHeader_t dos{};
|
||||
f.read(reinterpret_cast<char*>(&dos), sizeof(dos));
|
||||
if (!f || dos.e_magic != PEDosHeader_t::k_Magic)
|
||||
{
|
||||
return std::make_error_code(std::errc::executable_format_error);
|
||||
}
|
||||
|
||||
f.seekg(dos.e_lfanew, std::ios::beg);
|
||||
uint32_t nt_signature = 0;
|
||||
f.read(reinterpret_cast<char*>(&nt_signature), sizeof(nt_signature));
|
||||
if (!f || nt_signature != PENTHeaders_t<std::uint32_t>::k_Signature)
|
||||
{
|
||||
return std::make_error_code(std::errc::executable_format_error);
|
||||
}
|
||||
|
||||
PEFileHeader_t file_header{};
|
||||
f.read(reinterpret_cast<char*>(&file_header), sizeof(file_header));
|
||||
if (!f)
|
||||
{
|
||||
return std::make_error_code(std::errc::executable_format_error);
|
||||
}
|
||||
|
||||
uint16_t magic = 0;
|
||||
f.read(reinterpret_cast<char*>(&magic), sizeof(magic));
|
||||
if (!f)
|
||||
{
|
||||
return std::make_error_code(std::errc::executable_format_error);
|
||||
}
|
||||
|
||||
if (magic == PEOptionalHeader_t<std::uint32_t>::k_Magic)
|
||||
{
|
||||
return pe_arch::pe32;
|
||||
}
|
||||
if (magic == PEOptionalHeader_t<std::uint64_t>::k_Magic)
|
||||
{
|
||||
return pe_arch::pe64;
|
||||
}
|
||||
|
||||
return std::make_error_code(std::errc::executable_format_error);
|
||||
}
|
||||
|
||||
inline std::variant<pe_arch, std::error_code> get_pe_arch(uint64_t base_address, uint64_t image_size)
|
||||
{
|
||||
const auto* base = reinterpret_cast<const std::byte*>(reinterpret_cast<const void*>(static_cast<uintptr_t>(base_address)));
|
||||
const uint64_t size = image_size;
|
||||
|
||||
auto read = [&](uint64_t off, void* dst, size_t n) -> bool {
|
||||
if (off > size)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (n > size - off)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
memcpy(dst, base + off, n);
|
||||
return true;
|
||||
};
|
||||
|
||||
PEDosHeader_t dos{};
|
||||
if (!read(0, &dos, sizeof(dos)) || dos.e_magic != PEDosHeader_t::k_Magic)
|
||||
{
|
||||
return std::make_error_code(std::errc::executable_format_error);
|
||||
}
|
||||
|
||||
const auto nt_off = static_cast<uint64_t>(dos.e_lfanew);
|
||||
uint32_t nt_signature = 0;
|
||||
if (!read(nt_off, &nt_signature, sizeof(nt_signature)) || nt_signature != PENTHeaders_t<std::uint32_t>::k_Signature)
|
||||
{
|
||||
return std::make_error_code(std::errc::executable_format_error);
|
||||
}
|
||||
|
||||
PEFileHeader_t file_header{};
|
||||
const uint64_t fh_off = nt_off + sizeof(nt_signature);
|
||||
if (!read(fh_off, &file_header, sizeof(file_header)))
|
||||
{
|
||||
return std::make_error_code(std::errc::executable_format_error);
|
||||
}
|
||||
|
||||
uint16_t magic = 0;
|
||||
const uint64_t opt_magic_off = fh_off + sizeof(file_header);
|
||||
if (!read(opt_magic_off, &magic, sizeof(magic)))
|
||||
{
|
||||
return std::make_error_code(std::errc::executable_format_error);
|
||||
}
|
||||
|
||||
if (magic == PEOptionalHeader_t<std::uint32_t>::k_Magic)
|
||||
{
|
||||
return pe_arch::pe32;
|
||||
}
|
||||
if (magic == PEOptionalHeader_t<std::uint64_t>::k_Magic)
|
||||
{
|
||||
return pe_arch::pe64;
|
||||
}
|
||||
|
||||
return std::make_error_code(std::errc::executable_format_error);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// NOLINTEND(modernize-use-using,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
|
||||
|
||||
Reference in New Issue
Block a user