#pragma once
#include "head.h"
enum params_type {
    PARAMS_INT,
    PARAMS_CHAR,
    PARAMS_WCHAR,
    PARAMS_UINT,
};

// ApiSetschema v1 structs
// ---------------------------------------------------------------------------------------------

// Windows 6.x redirection descriptor, describes forward and backward
// redirections.
typedef struct _REDIRECTION {
    DWORD OffsetRedirection1;
    USHORT RedirectionLength1;
    USHORT _padding1;
    DWORD OffsetRedirection2;
    USHORT RedirectionLength2;
    USHORT _padding2;
} REDIRECTION, *PREDIRECTION;

// Windows 6.x library director structure, describes redirections.
typedef struct _DLLREDIRECTOR {
    DWORD NumberOfRedirections;  // Number of REDIRECTION structs.
    REDIRECTION Redirection[1];  // array of REDIRECTION structures
} DLLREDIRECTOR, *PDLLREDIRECTOR;

// Windows 6.x library descriptor structure. These are located as a contiguously
// allocated array from the start of the first structure.
typedef struct _DLLHOSTDESCRIPTOR {
    DWORD OffsetDllString;
    DWORD StringLength;
    DWORD OffsetDllRedirector;  // offset to DLLREDIRECTOR
} DLLHOSTDESCRIPTOR, *PDLLHOSTDESCRIPTOR;

// Windows 6.x ApiSetSchema base structure.
typedef struct _APISETMAP {
    DWORD Version;        // dummy name (this field is never used)
    DWORD NumberOfHosts;  // number of DLLHOSTDESCRIPTOR structures following.
    DLLHOSTDESCRIPTOR descriptors[1];  // array of DLLHOSTDESCRIPTOR structures.
} APISETMAP, *PAPISETMAP;

// ApiSetschema v2 structs for Windows 8.1.
// ---------------------------------------------------------------------------------------------

typedef struct _API_SET_VALUE_ENTRY_V2 {
    ULONG Flags;
    ULONG NameOffset;
    ULONG NameLength;
    ULONG ValueOffset;
    ULONG ValueLength;
} API_SET_VALUE_ENTRY_V2, *PAPI_SET_VALUE_ENTRY_V2;

typedef struct _API_SET_VALUE_ARRAY_V2 {
    ULONG Flags;
    ULONG Count;
    _API_SET_VALUE_ENTRY_V2 Array[ANYSIZE_ARRAY];
} API_SET_VALUE_ARRAY_V2, *PAPI_SET_VALUE_ARRAY_V2;

typedef struct _API_SET_NAMESPACE_ENTRY_V2 {
    ULONG Flags;
    ULONG NameOffset;
    ULONG NameLength;
    ULONG AliasOffset;
    ULONG AliasLength;
    ULONG DataOffset;  // API_SET_VALUE_ARRAY
} API_SET_NAMESPACE_ENTRY_V2, *PAPI_SET_NAMESPACE_ENTRY_V2;

typedef struct _API_SET_NAMESPACE_ARRAY_V2 {
    ULONG Version;
    ULONG Size;
    ULONG Flags;
    ULONG Count;
    _API_SET_NAMESPACE_ENTRY_V2 Array[ANYSIZE_ARRAY];
} API_SET_NAMESPACE_ARRAY_V2, *PAPI_SET_NAMESPACE_ARRAY_V2;

// ApiSetschema structs for Windows 10.
// ---------------------------------------------------------------------------------------------

typedef struct _API_SET_VALUE_ENTRY_10 {
    ULONG Flags;
    ULONG NameOffset;
    ULONG NameLength;
    ULONG ValueOffset;
    ULONG ValueLength;
} API_SET_VALUE_ENTRY_10, *PAPI_SET_VALUE_ENTRY_10;

typedef struct _API_SET_VALUE_ARRAY_10 {
    ULONG Flags;
    ULONG NameOffset;
    ULONG Unk;
    ULONG NameLength;
    ULONG DataOffset;
    ULONG Count;
} API_SET_VALUE_ARRAY_10, *PAPI_SET_VALUE_ARRAY_10;

typedef struct _API_SET_NAMESPACE_ENTRY_10 {
    uint32_t Flags;
    uint32_t NameOffset;
    uint32_t NameLength;
    uint32_t HashedLength;
    uint32_t ValueOffset;
    uint32_t ValueCount;
} API_SET_NAMESPACE_ENTRY_10, *PAPI_SET_NAMESPACE_ENTRY_10;

typedef struct _API_SET_NAMESPACE_ARRAY_10 {
    ULONG Version;
    ULONG Size;
    ULONG Flags;
    ULONG Count;
    ULONG Start;
    ULONG End;
    API_SET_NAMESPACE_ENTRY_10 Array[1];
} API_SET_NAMESPACE_ARRAY_10, *PAPI_SET_NAMESPACE_ARRAY_10;

typedef struct _UNICODE_STRING {
    USHORT Length;
    USHORT MaximumLength;
    PWSTR Buffer;
} UNICODE_STRING;
typedef UNICODE_STRING* PUNICODE_STRING;
typedef const UNICODE_STRING* PCUNICODE_STRING;
typedef PVOID(NTAPI* RtlImageDirectoryEntryToDataFn)(PVOID, BOOLEAN, USHORT,
                                                     PULONG);
enum class Msr : unsigned int {
    kIa32ApicBase = 0x01B,

    kIa32FeatureControl = 0x03A,

    kIa32SysenterCs = 0x174,
    kIa32SysenterEsp = 0x175,
    kIa32SysenterEip = 0x176,

    kIa32Debugctl = 0x1D9,

    kIa32MtrrCap = 0xFE,
    kIa32MtrrDefType = 0x2FF,
    kIa32MtrrPhysBaseN = 0x200,
    kIa32MtrrPhysMaskN = 0x201,
    kIa32MtrrFix64k00000 = 0x250,
    kIa32MtrrFix16k80000 = 0x258,
    kIa32MtrrFix16kA0000 = 0x259,
    kIa32MtrrFix4kC0000 = 0x268,
    kIa32MtrrFix4kC8000 = 0x269,
    kIa32MtrrFix4kD0000 = 0x26A,
    kIa32MtrrFix4kD8000 = 0x26B,
    kIa32MtrrFix4kE0000 = 0x26C,
    kIa32MtrrFix4kE8000 = 0x26D,
    kIa32MtrrFix4kF0000 = 0x26E,
    kIa32MtrrFix4kF8000 = 0x26F,

    kIa32VmxBasic = 0x480,
    kIa32VmxPinbasedCtls = 0x481,
    kIa32VmxProcBasedCtls = 0x482,
    kIa32VmxExitCtls = 0x483,
    kIa32VmxEntryCtls = 0x484,
    kIa32VmxMisc = 0x485,
    kIa32VmxCr0Fixed0 = 0x486,
    kIa32VmxCr0Fixed1 = 0x487,
    kIa32VmxCr4Fixed0 = 0x488,
    kIa32VmxCr4Fixed1 = 0x489,
    kIa32VmxVmcsEnum = 0x48A,
    kIa32VmxProcBasedCtls2 = 0x48B,
    kIa32VmxEptVpidCap = 0x48C,
    kIa32VmxTruePinbasedCtls = 0x48D,
    kIa32VmxTrueProcBasedCtls = 0x48E,
    kIa32VmxTrueExitCtls = 0x48F,
    kIa32VmxTrueEntryCtls = 0x490,
    kIa32VmxVmfunc = 0x491,

    kIa32Efer = 0xC0000080,
    kIa32Star = 0xC0000081,
    kIa32Lstar = 0xC0000082,

    kIa32Fmask = 0xC0000084,

    kIa32FsBase = 0xC0000100,
    kIa32GsBase = 0xC0000101,
    kIa32KernelGsBase = 0xC0000102,
    kIa32TscAux = 0xC0000103,
};
typedef struct _PEB_LDR_DATA {
    BYTE Reserved1[8];
    PVOID Reserved2[3];
    LIST_ENTRY InMemoryOrderModuleList;
} PEB_LDR_DATA, *PPEB_LDR_DATA;

typedef struct _LDR_DATA_TABLE_ENTRY {
    LIST_ENTRY InLoadOrderLinks;
    LIST_ENTRY InMemoryOrderLinks;
    LIST_ENTRY InInitializationOrderLinks;
    PVOID DllBase;
    PVOID EntryPoint;
    ULONG SizeOfImages;
    UNICODE_STRING FullDllName;
    UNICODE_STRING BaseDllName;
    ULONG Flags;
    USHORT LoadCount;
    USHORT TlsIndex;
    union {
        LIST_ENTRY HashLinks;
        struct {
            PVOID SectionPointer;
            ULONG CheckSum;
        };
    };
    union {
        struct {
            ULONG TimeDateStamp;
        };
        struct {
            PVOID LoadedImports;
        };
    };
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
typedef struct _RTL_USER_PROCESS_PARAMETERS {
    BYTE Reserved1[16];
    PVOID Reserved2[10];
    UNICODE_STRING ImagePathName;
    UNICODE_STRING CommandLine;
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;

typedef struct _BASE_RELOCATION_ENTRY {
    WORD Offset : 12;
    WORD Type : 4;
} BASE_RELOCATION_ENTRY;
typedef VOID(NTAPI* PPS_POST_PROCESS_INIT_ROUTINE)(VOID);
// 0x10 bytes (sizeof)
struct _STRING64 {
    USHORT Length;         // 0x0
    USHORT MaximumLength;  // 0x2
    ULONGLONG Buffer;      // 0x8
};

// 0x58 bytes (sizeof)
struct X64_PEB_LDR_DATA {
    ULONG Length;                                        // 0x0
    UCHAR Initialized;                                   // 0x4
    VOID* SsHandle;                                      // 0x8
    struct _LIST_ENTRY InLoadOrderModuleList;            // 0x10
    struct _LIST_ENTRY InMemoryOrderModuleList;          // 0x20
    struct _LIST_ENTRY InInitializationOrderModuleList;  // 0x30
    VOID* EntryInProgress;                               // 0x40
    UCHAR ShutdownInProgress;                            // 0x48
    VOID* ShutdownThreadId;                              // 0x50
};
static_assert(sizeof(X64_PEB_LDR_DATA) == 0x58, "X64_PEB_LDR_DATA Size check");

typedef struct X64PEB {
    UCHAR InheritedAddressSpace;     // 0x0
    UCHAR ReadImageFileExecOptions;  // 0x1
    UCHAR BeingDebugged;             // 0x2
    union {
        UCHAR BitField;  // 0x3
        struct {
            UCHAR ImageUsesLargePages : 1;           // 0x3
            UCHAR IsProtectedProcess : 1;            // 0x3
            UCHAR IsImageDynamicallyRelocated : 1;   // 0x3
            UCHAR SkipPatchingUser32Forwarders : 1;  // 0x3
            UCHAR IsPackagedProcess : 1;             // 0x3
            UCHAR IsAppContainer : 1;                // 0x3
            UCHAR IsProtectedProcessLight : 1;       // 0x3
            UCHAR IsLongPathAwareProcess : 1;        // 0x3
        };
    };
    UCHAR Padding0[4];            // 0x4
    ULONGLONG Mutant;             // 0x8
    ULONGLONG ImageBaseAddress;   // 0x10
    ULONGLONG Ldr;                // 0x18
    ULONGLONG ProcessParameters;  // 0x20
    ULONGLONG SubSystemData;      // 0x28
    ULONGLONG ProcessHeap;        // 0x30
    ULONGLONG FastPebLock;        // 0x38
    ULONGLONG AtlThunkSListPtr;   // 0x40
    ULONGLONG IFEOKey;            // 0x48
    union {
        ULONG CrossProcessFlags;  // 0x50
        struct {
            ULONG ProcessInJob : 1;                // 0x50
            ULONG ProcessInitializing : 1;         // 0x50
            ULONG ProcessUsingVEH : 1;             // 0x50
            ULONG ProcessUsingVCH : 1;             // 0x50
            ULONG ProcessUsingFTH : 1;             // 0x50
            ULONG ProcessPreviouslyThrottled : 1;  // 0x50
            ULONG ProcessCurrentlyThrottled : 1;   // 0x50
            ULONG ProcessImagesHotPatched : 1;     // 0x50
            ULONG ReservedBits0 : 24;              // 0x50
        };
    };
    UCHAR Padding1[4];  // 0x54
    union {
        ULONGLONG KernelCallbackTable;  // 0x58
        ULONGLONG UserSharedInfoPtr;    // 0x58
    };
    ULONG SystemReserved;                          // 0x60
    ULONG AtlThunkSListPtr32;                      // 0x64
    ULONGLONG ApiSetMap;                           // 0x68
    ULONG TlsExpansionCounter;                     // 0x70
    UCHAR Padding2[4];                             // 0x74
    ULONGLONG TlsBitmap;                           // 0x78
    ULONG TlsBitmapBits[2];                        // 0x80
    ULONGLONG ReadOnlySharedMemoryBase;            // 0x88
    ULONGLONG SharedData;                          // 0x90
    ULONGLONG ReadOnlyStaticServerData;            // 0x98
    ULONGLONG AnsiCodePageData;                    // 0xa0
    ULONGLONG OemCodePageData;                     // 0xa8
    ULONGLONG UnicodeCaseTableData;                // 0xb0
    ULONG NumberOfProcessors;                      // 0xb8
    ULONG NtGlobalFlag;                            // 0xbc
    union _LARGE_INTEGER CriticalSectionTimeout;   // 0xc0
    ULONGLONG HeapSegmentReserve;                  // 0xc8
    ULONGLONG HeapSegmentCommit;                   // 0xd0
    ULONGLONG HeapDeCommitTotalFreeThreshold;      // 0xd8
    ULONGLONG HeapDeCommitFreeBlockThreshold;      // 0xe0
    ULONG NumberOfHeaps;                           // 0xe8
    ULONG MaximumNumberOfHeaps;                    // 0xec
    ULONGLONG ProcessHeaps;                        // 0xf0
    ULONGLONG GdiSharedHandleTable;                // 0xf8
    ULONGLONG ProcessStarterHelper;                // 0x100
    ULONG GdiDCAttributeList;                      // 0x108
    UCHAR Padding3[4];                             // 0x10c
    ULONGLONG LoaderLock;                          // 0x110
    ULONG OSMajorVersion;                          // 0x118
    ULONG OSMinorVersion;                          // 0x11c
    USHORT OSBuildNumber;                          // 0x120
    USHORT OSCSDVersion;                           // 0x122
    ULONG OSPlatformId;                            // 0x124
    ULONG ImageSubsystem;                          // 0x128
    ULONG ImageSubsystemMajorVersion;              // 0x12c
    ULONG ImageSubsystemMinorVersion;              // 0x130
    UCHAR Padding4[4];                             // 0x134
    ULONGLONG ActiveProcessAffinityMask;           // 0x138
    ULONG GdiHandleBuffer[60];                     // 0x140
    ULONGLONG PostProcessInitRoutine;              // 0x230
    ULONGLONG TlsExpansionBitmap;                  // 0x238
    ULONG TlsExpansionBitmapBits[32];              // 0x240
    ULONG SessionId;                               // 0x2c0
    UCHAR Padding5[4];                             // 0x2c4
    union _ULARGE_INTEGER AppCompatFlags;          // 0x2c8
    union _ULARGE_INTEGER AppCompatFlagsUser;      // 0x2d0
    ULONGLONG pShimData;                           // 0x2d8
    ULONGLONG AppCompatInfo;                       // 0x2e0
    struct _STRING64 CSDVersion;                   // 0x2e8
    ULONGLONG ActivationContextData;               // 0x2f8
    ULONGLONG ProcessAssemblyStorageMap;           // 0x300
    ULONGLONG SystemDefaultActivationContextData;  // 0x308
    ULONGLONG SystemAssemblyStorageMap;            // 0x310
    ULONGLONG MinimumStackCommit;                  // 0x318
    ULONGLONG FlsCallback;                         // 0x320
    struct LIST_ENTRY64 FlsListHead;               // 0x328
    ULONGLONG FlsBitmap;                           // 0x338
    ULONG FlsBitmapBits[4];                        // 0x340
    ULONG FlsHighIndex;                            // 0x350
    ULONGLONG WerRegistrationData;                 // 0x358
    ULONGLONG WerShipAssertPtr;                    // 0x360
    ULONGLONG pUnused;                             // 0x368
    ULONGLONG pImageHeaderHash;                    // 0x370
    union {
        ULONG TracingFlags;  // 0x378
        struct {
            ULONG HeapTracingEnabled : 1;       // 0x378
            ULONG CritSecTracingEnabled : 1;    // 0x378
            ULONG LibLoaderTracingEnabled : 1;  // 0x378
            ULONG SpareTracingBits : 29;        // 0x378
        };
    };
    UCHAR Padding6[4];                             // 0x37c
    ULONGLONG CsrServerReadOnlySharedMemoryBase;   // 0x380
    ULONGLONG TppWorkerpListLock;                  // 0x388
    struct LIST_ENTRY64 TppWorkerpList;            // 0x390
    ULONGLONG WaitOnAddressHashTable[128];         // 0x3a0
    ULONGLONG TelemetryCoverageHeader;             // 0x7a0
    ULONG CloudFileFlags;                          // 0x7a8
    ULONG CloudFileDiagFlags;                      // 0x7ac
    CHAR PlaceholderCompatibilityMode;             // 0x7b0
    CHAR PlaceholderCompatibilityModeReserved[7];  // 0x7b1
    ULONGLONG LeapSecondData;                      // 0x7b8
    union {
        ULONG LeapSecondFlags;  // 0x7c0
        struct {
            ULONG SixtySecondEnabled : 1;  // 0x7c0
            ULONG Reserved : 31;           // 0x7c0
        };
    };
    ULONG NtGlobalFlag2;  // 0x7c4
};
static_assert(sizeof(X64PEB) == 0x7c8, "X64PEB Size check");
// 0x8 bytes (sizeof)
struct _STRING32 {
    USHORT Length;         // 0x0
    USHORT MaximumLength;  // 0x2
    ULONG Buffer;          // 0x4
};
// 0x480 bytes (sizeof)
struct X32PEB {
    UCHAR InheritedAddressSpace;     // 0x0
    UCHAR ReadImageFileExecOptions;  // 0x1
    UCHAR BeingDebugged;             // 0x2
    union {
        UCHAR BitField;  // 0x3
        struct {
            UCHAR ImageUsesLargePages : 1;           // 0x3
            UCHAR IsProtectedProcess : 1;            // 0x3
            UCHAR IsImageDynamicallyRelocated : 1;   // 0x3
            UCHAR SkipPatchingUser32Forwarders : 1;  // 0x3
            UCHAR IsPackagedProcess : 1;             // 0x3
            UCHAR IsAppContainer : 1;                // 0x3
            UCHAR IsProtectedProcessLight : 1;       // 0x3
            UCHAR IsLongPathAwareProcess : 1;        // 0x3
        };
    };
    ULONG Mutant;             // 0x4
    ULONG ImageBaseAddress;   // 0x8
    ULONG Ldr;                // 0xc
    ULONG ProcessParameters;  // 0x10
    ULONG SubSystemData;      // 0x14
    ULONG ProcessHeap;        // 0x18
    ULONG FastPebLock;        // 0x1c
    ULONG AtlThunkSListPtr;   // 0x20
    ULONG IFEOKey;            // 0x24
    union {
        ULONG CrossProcessFlags;  // 0x28
        struct {
            ULONG ProcessInJob : 1;                // 0x28
            ULONG ProcessInitializing : 1;         // 0x28
            ULONG ProcessUsingVEH : 1;             // 0x28
            ULONG ProcessUsingVCH : 1;             // 0x28
            ULONG ProcessUsingFTH : 1;             // 0x28
            ULONG ProcessPreviouslyThrottled : 1;  // 0x28
            ULONG ProcessCurrentlyThrottled : 1;   // 0x28
            ULONG ProcessImagesHotPatched : 1;     // 0x28
            ULONG ReservedBits0 : 24;              // 0x28
        };
    };
    union {
        ULONG KernelCallbackTable;  // 0x2c
        ULONG UserSharedInfoPtr;    // 0x2c
    };
    ULONG SystemReserved;                         // 0x30
    ULONG AtlThunkSListPtr32;                     // 0x34
    ULONG ApiSetMap;                              // 0x38
    ULONG TlsExpansionCounter;                    // 0x3c
    ULONG TlsBitmap;                              // 0x40
    ULONG TlsBitmapBits[2];                       // 0x44
    ULONG ReadOnlySharedMemoryBase;               // 0x4c
    ULONG SharedData;                             // 0x50
    ULONG ReadOnlyStaticServerData;               // 0x54
    ULONG AnsiCodePageData;                       // 0x58
    ULONG OemCodePageData;                        // 0x5c
    ULONG UnicodeCaseTableData;                   // 0x60
    ULONG NumberOfProcessors;                     // 0x64
    ULONG NtGlobalFlag;                           // 0x68
    union _LARGE_INTEGER CriticalSectionTimeout;  // 0x70
    ULONG HeapSegmentReserve;                     // 0x78
    ULONG HeapSegmentCommit;                      // 0x7c
    ULONG HeapDeCommitTotalFreeThreshold;         // 0x80
    ULONG HeapDeCommitFreeBlockThreshold;         // 0x84
    ULONG NumberOfHeaps;                          // 0x88
    ULONG MaximumNumberOfHeaps;                   // 0x8c
    ULONG ProcessHeaps;                           // 0x90
    ULONG GdiSharedHandleTable;                   // 0x94
    ULONG ProcessStarterHelper;                   // 0x98
    ULONG GdiDCAttributeList;                     // 0x9c
    ULONG LoaderLock;                             // 0xa0
    ULONG OSMajorVersion;                         // 0xa4
    ULONG OSMinorVersion;                         // 0xa8
    USHORT OSBuildNumber;                         // 0xac
    USHORT OSCSDVersion;                          // 0xae
    ULONG OSPlatformId;                           // 0xb0
    ULONG ImageSubsystem;                         // 0xb4
    ULONG ImageSubsystemMajorVersion;             // 0xb8
    ULONG ImageSubsystemMinorVersion;             // 0xbc
    ULONG ActiveProcessAffinityMask;              // 0xc0
    ULONG GdiHandleBuffer[34];                    // 0xc4
    ULONG PostProcessInitRoutine;                 // 0x14c
    ULONG TlsExpansionBitmap;                     // 0x150
    ULONG TlsExpansionBitmapBits[32];             // 0x154
    ULONG SessionId;                              // 0x1d4
    union _ULARGE_INTEGER AppCompatFlags;         // 0x1d8
    union _ULARGE_INTEGER AppCompatFlagsUser;     // 0x1e0
    ULONG pShimData;                              // 0x1e8
    ULONG AppCompatInfo;                          // 0x1ec
    struct _STRING32 CSDVersion;                  // 0x1f0
    ULONG ActivationContextData;                  // 0x1f8
    ULONG ProcessAssemblyStorageMap;              // 0x1fc
    ULONG SystemDefaultActivationContextData;     // 0x200
    ULONG SystemAssemblyStorageMap;               // 0x204
    ULONG MinimumStackCommit;                     // 0x208
    ULONG SparePointers[4];                       // 0x20c
    ULONG SpareUlongs[5];                         // 0x21c
    ULONG WerRegistrationData;                    // 0x230
    ULONG WerShipAssertPtr;                       // 0x234
    ULONG pUnused;                                // 0x238
    ULONG pImageHeaderHash;                       // 0x23c
    union {
        ULONG TracingFlags;  // 0x240
        struct {
            ULONG HeapTracingEnabled : 1;       // 0x240
            ULONG CritSecTracingEnabled : 1;    // 0x240
            ULONG LibLoaderTracingEnabled : 1;  // 0x240
            ULONG SpareTracingBits : 29;        // 0x240
        };
    };
    ULONGLONG CsrServerReadOnlySharedMemoryBase;   // 0x248
    ULONG TppWorkerpListLock;                      // 0x250
    struct LIST_ENTRY32 TppWorkerpList;            // 0x254
    ULONG WaitOnAddressHashTable[128];             // 0x25c
    ULONG TelemetryCoverageHeader;                 // 0x45c
    ULONG CloudFileFlags;                          // 0x460
    ULONG CloudFileDiagFlags;                      // 0x464
    CHAR PlaceholderCompatibilityMode;             // 0x468
    CHAR PlaceholderCompatibilityModeReserved[7];  // 0x469
    ULONG LeapSecondData;                          // 0x470
    union {
        ULONG LeapSecondFlags;  // 0x474
        struct {
            ULONG SixtySecondEnabled : 1;  // 0x474
            ULONG Reserved : 31;           // 0x474
        };
    };
    ULONG NtGlobalFlag2;  // 0x478
};
static_assert(sizeof(X32PEB) == 0x480, "X64PEB Size check");
// 0x4e0 bytes (sizeof)
struct _GDI_TEB_BATCH32 {
    ULONG Offset : 31;              // 0x0
    ULONG HasRenderingCommand : 1;  // 0x0
    ULONG HDC;                      // 0x4
    ULONG Buffer[310];              // 0x8
};
// 0x18 bytes (sizeof)
struct _ACTIVATION_CONTEXT_STACK32 {
    ULONG ActiveFrame;                   // 0x0
    struct LIST_ENTRY32 FrameListCache;  // 0x4
    ULONG Flags;                         // 0xc
    ULONG NextCookieSequenceNumber;      // 0x10
    ULONG StackId;                       // 0x14
};
// 0x8 bytes (sizeof)
struct _CLIENT_ID32 {
    ULONG UniqueProcess;  // 0x0
    ULONG UniqueThread;   // 0x4
};
// 0x1000 bytes (sizeof)
struct X32TEB {
    struct _NT_TIB32 NtTib;                               // 0x0
    ULONG EnvironmentPointer;                             // 0x1c
    struct _CLIENT_ID32 ClientId;                         // 0x20
    ULONG ActiveRpcHandle;                                // 0x28
    ULONG ThreadLocalStoragePointer;                      // 0x2c
    ULONG ProcessEnvironmentBlock;                        // 0x30
    ULONG LastErrorValue;                                 // 0x34
    ULONG CountOfOwnedCriticalSections;                   // 0x38
    ULONG CsrClientThread;                                // 0x3c
    ULONG Win32ThreadInfo;                                // 0x40
    ULONG User32Reserved[26];                             // 0x44
    ULONG UserReserved[5];                                // 0xac
    ULONG WOW32Reserved;                                  // 0xc0
    ULONG CurrentLocale;                                  // 0xc4
    ULONG FpSoftwareStatusRegister;                       // 0xc8
    ULONG ReservedForDebuggerInstrumentation[16];         // 0xcc
    ULONG SystemReserved1[26];                            // 0x10c
    CHAR PlaceholderCompatibilityMode;                    // 0x174
    UCHAR PlaceholderHydrationAlwaysExplicit;             // 0x175
    CHAR PlaceholderReserved[10];                         // 0x176
    ULONG ProxiedProcessId;                               // 0x180
    struct _ACTIVATION_CONTEXT_STACK32 _ActivationStack;  // 0x184
    UCHAR WorkingOnBehalfTicket[8];                       // 0x19c
    LONG ExceptionCode;                                   // 0x1a4
    ULONG ActivationContextStackPointer;                  // 0x1a8
    ULONG InstrumentationCallbackSp;                      // 0x1ac
    ULONG InstrumentationCallbackPreviousPc;              // 0x1b0
    ULONG InstrumentationCallbackPreviousSp;              // 0x1b4
    UCHAR InstrumentationCallbackDisabled;                // 0x1b8
    UCHAR SpareBytes[23];                                 // 0x1b9
    ULONG TxFsContext;                                    // 0x1d0
    struct _GDI_TEB_BATCH32 GdiTebBatch;                  // 0x1d4
    struct _CLIENT_ID32 RealClientId;                     // 0x6b4
    ULONG GdiCachedProcessHandle;                         // 0x6bc
    ULONG GdiClientPID;                                   // 0x6c0
    ULONG GdiClientTID;                                   // 0x6c4
    ULONG GdiThreadLocalInfo;                             // 0x6c8
    ULONG Win32ClientInfo[62];                            // 0x6cc
    ULONG glDispatchTable[233];                           // 0x7c4
    ULONG glReserved1[29];                                // 0xb68
    ULONG glReserved2;                                    // 0xbdc
    ULONG glSectionInfo;                                  // 0xbe0
    ULONG glSection;                                      // 0xbe4
    ULONG glTable;                                        // 0xbe8
    ULONG glCurrentRC;                                    // 0xbec
    ULONG glContext;                                      // 0xbf0
    ULONG LastStatusValue;                                // 0xbf4
    struct _STRING32 StaticUnicodeString;                 // 0xbf8
    WCHAR StaticUnicodeBuffer[261];                       // 0xc00
    ULONG DeallocationStack;                              // 0xe0c
    ULONG TlsSlots[64];                                   // 0xe10
    struct LIST_ENTRY32 TlsLinks;                         // 0xf10
    ULONG Vdm;                                            // 0xf18
    ULONG ReservedForNtRpc;                               // 0xf1c
    ULONG DbgSsReserved[2];                               // 0xf20
    ULONG HardErrorMode;                                  // 0xf28
    ULONG Instrumentation[9];                             // 0xf2c
    struct _GUID ActivityId;                              // 0xf50
    ULONG SubProcessTag;                                  // 0xf60
    ULONG PerflibData;                                    // 0xf64
    ULONG EtwTraceData;                                   // 0xf68
    ULONG WinSockData;                                    // 0xf6c
    ULONG GdiBatchCount;                                  // 0xf70
    union {
        struct _PROCESSOR_NUMBER CurrentIdealProcessor;  // 0xf74
        ULONG IdealProcessorValue;                       // 0xf74
        struct {
            UCHAR ReservedPad0;    // 0xf74
            UCHAR ReservedPad1;    // 0xf75
            UCHAR ReservedPad2;    // 0xf76
            UCHAR IdealProcessor;  // 0xf77
        };
    };
    ULONG GuaranteedStackBytes;      // 0xf78
    ULONG ReservedForPerf;           // 0xf7c
    ULONG ReservedForOle;            // 0xf80
    ULONG WaitingOnLoaderLock;       // 0xf84
    ULONG SavedPriorityState;        // 0xf88
    ULONG ReservedForCodeCoverage;   // 0xf8c
    ULONG ThreadPoolData;            // 0xf90
    ULONG TlsExpansionSlots;         // 0xf94
    ULONG MuiGeneration;             // 0xf98
    ULONG IsImpersonating;           // 0xf9c
    ULONG NlsCache;                  // 0xfa0
    ULONG pShimData;                 // 0xfa4
    ULONG HeapData;                  // 0xfa8
    ULONG CurrentTransactionHandle;  // 0xfac
    ULONG ActiveFrame;               // 0xfb0
    ULONG FlsData;                   // 0xfb4
    ULONG PreferredLanguages;        // 0xfb8
    ULONG UserPrefLanguages;         // 0xfbc
    ULONG MergedPrefLanguages;       // 0xfc0
    ULONG MuiImpersonation;          // 0xfc4
    union {
        volatile USHORT CrossTebFlags;  // 0xfc8
        USHORT SpareCrossTebBits : 16;  // 0xfc8
    };
    union {
        USHORT SameTebFlags;  // 0xfca
        struct {
            USHORT SafeThunkCall : 1;         // 0xfca
            USHORT InDebugPrint : 1;          // 0xfca
            USHORT HasFiberData : 1;          // 0xfca
            USHORT SkipThreadAttach : 1;      // 0xfca
            USHORT WerInShipAssertCode : 1;   // 0xfca
            USHORT RanProcessInit : 1;        // 0xfca
            USHORT ClonedThread : 1;          // 0xfca
            USHORT SuppressDebugMsg : 1;      // 0xfca
            USHORT DisableUserStackWalk : 1;  // 0xfca
            USHORT RtlExceptionAttached : 1;  // 0xfca
            USHORT InitialThread : 1;         // 0xfca
            USHORT SessionAware : 1;          // 0xfca
            USHORT LoadOwner : 1;             // 0xfca
            USHORT LoaderWorker : 1;          // 0xfca
            USHORT SkipLoaderInit : 1;        // 0xfca
            USHORT SpareSameTebBits : 1;      // 0xfca
        };
    };
    ULONG TxnScopeEnterCallback;        // 0xfcc
    ULONG TxnScopeExitCallback;         // 0xfd0
    ULONG TxnScopeContext;              // 0xfd4
    ULONG LockCount;                    // 0xfd8
    LONG WowTebOffset;                  // 0xfdc
    ULONG ResourceRetValue;             // 0xfe0
    ULONG ReservedForWdf;               // 0xfe4
    ULONGLONG ReservedForCrt;           // 0xfe8
    struct _GUID EffectiveContainerId;  // 0xff0
};
static_assert(sizeof(X32TEB) == 0x1000, "X32TEB Size check");

/*
    x64的teb_64 32位的没做
*/
struct _ACTIVATION_CONTEXT_STACK {
    struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME* ActiveFrame;  // 0x0
    struct _LIST_ENTRY FrameListCache;                        // 0x8
    ULONG Flags;                                              // 0x18
    ULONG NextCookieSequenceNumber;                           // 0x1c
    ULONG StackId;                                            // 0x20
};
struct _GDI_TEB_BATCH {
    ULONG Offset : 31;              // 0x0
    ULONG HasRenderingCommand : 1;  // 0x0
    ULONGLONG HDC;                  // 0x8
    ULONG Buffer[310];              // 0x10
};
struct _CLIENT_ID {
    DWORD64 UniqueProcess;  // 0x0
    DWORD64 UniqueThread;   // 0x8
};
static_assert(sizeof(_CLIENT_ID) == 0x10, "_CLIENT_ID Size check");

static_assert(sizeof(_NT_TIB) == 0x38, "_NT_TIB Size check");
typedef struct X64TEB {
    struct _NT_TIB64 NtTib;                                           // 0x0
    VOID* EnvironmentPointer;                                         // 0x38
    struct _CLIENT_ID ClientId;                                       // 0x40
    VOID* ActiveRpcHandle;                                            // 0x50
    VOID* ThreadLocalStoragePointer;                                  // 0x58
    struct X64PEB* ProcessEnvironmentBlock;                           // 0x60
    ULONG LastErrorValue;                                             // 0x68
    ULONG CountOfOwnedCriticalSections;                               // 0x6c
    VOID* CsrClientThread;                                            // 0x70
    VOID* Win32ThreadInfo;                                            // 0x78
    ULONG User32Reserved[26];                                         // 0x80
    ULONG UserReserved[5];                                            // 0xe8
    VOID* WOW32Reserved;                                              // 0x100
    ULONG CurrentLocale;                                              // 0x108
    ULONG FpSoftwareStatusRegister;                                   // 0x10c
    VOID* ReservedForDebuggerInstrumentation[16];                     // 0x110
    VOID* SystemReserved1[30];                                        // 0x190
    CHAR PlaceholderCompatibilityMode;                                // 0x280
    UCHAR PlaceholderHydrationAlwaysExplicit;                         // 0x281
    CHAR PlaceholderReserved[10];                                     // 0x282
    ULONG ProxiedProcessId;                                           // 0x28c
    struct _ACTIVATION_CONTEXT_STACK _ActivationStack;                // 0x290
    UCHAR WorkingOnBehalfTicket[8];                                   // 0x2b8
    LONG ExceptionCode;                                               // 0x2c0
    UCHAR Padding0[4];                                                // 0x2c4
    struct _ACTIVATION_CONTEXT_STACK* ActivationContextStackPointer;  // 0x2c8
    ULONGLONG InstrumentationCallbackSp;                              // 0x2d0
    ULONGLONG InstrumentationCallbackPreviousPc;                      // 0x2d8
    ULONGLONG InstrumentationCallbackPreviousSp;                      // 0x2e0
    ULONG TxFsContext;                                                // 0x2e8
    UCHAR InstrumentationCallbackDisabled;                            // 0x2ec
    UCHAR UnalignedLoadStoreExceptions;                               // 0x2ed
    UCHAR Padding1[2];                                                // 0x2ee
    struct _GDI_TEB_BATCH GdiTebBatch;                                // 0x2f0
    struct _CLIENT_ID RealClientId;                                   // 0x7d8
    VOID* GdiCachedProcessHandle;                                     // 0x7e8
    ULONG GdiClientPID;                                               // 0x7f0
    ULONG GdiClientTID;                                               // 0x7f4
    VOID* GdiThreadLocalInfo;                                         // 0x7f8
    ULONGLONG Win32ClientInfo[62];                                    // 0x800
    VOID* glDispatchTable[233];                                       // 0x9f0
    ULONGLONG glReserved1[29];                                        // 0x1138
    VOID* glReserved2;                                                // 0x1220
    VOID* glSectionInfo;                                              // 0x1228
    VOID* glSection;                                                  // 0x1230
    VOID* glTable;                                                    // 0x1238
    VOID* glCurrentRC;                                                // 0x1240
    VOID* glContext;                                                  // 0x1248
    ULONG LastStatusValue;                                            // 0x1250
    UCHAR Padding2[4];                                                // 0x1254
    struct _UNICODE_STRING StaticUnicodeString;                       // 0x1258
    WCHAR StaticUnicodeBuffer[261];                                   // 0x1268
    UCHAR Padding3[6];                                                // 0x1472
    VOID* DeallocationStack;                                          // 0x1478
    VOID* TlsSlots[64];                                               // 0x1480
    struct _LIST_ENTRY TlsLinks;                                      // 0x1680
    VOID* Vdm;                                                        // 0x1690
    VOID* ReservedForNtRpc;                                           // 0x1698
    VOID* DbgSsReserved[2];                                           // 0x16a0
    ULONG HardErrorMode;                                              // 0x16b0
    UCHAR Padding4[4];                                                // 0x16b4
    VOID* Instrumentation[11];                                        // 0x16b8
    struct _GUID ActivityId;                                          // 0x1710
    VOID* SubProcessTag;                                              // 0x1720
    VOID* PerflibData;                                                // 0x1728
    VOID* EtwTraceData;                                               // 0x1730
    VOID* WinSockData;                                                // 0x1738
    ULONG GdiBatchCount;                                              // 0x1740
    union {
        struct _PROCESSOR_NUMBER CurrentIdealProcessor;  // 0x1744
        ULONG IdealProcessorValue;                       // 0x1744
        struct {
            UCHAR ReservedPad0;    // 0x1744
            UCHAR ReservedPad1;    // 0x1745
            UCHAR ReservedPad2;    // 0x1746
            UCHAR IdealProcessor;  // 0x1747
        };
    };
    ULONG GuaranteedStackBytes;             // 0x1748
    UCHAR Padding5[4];                      // 0x174c
    VOID* ReservedForPerf;                  // 0x1750
    VOID* ReservedForOle;                   // 0x1758
    ULONG WaitingOnLoaderLock;              // 0x1760
    UCHAR Padding6[4];                      // 0x1764
    VOID* SavedPriorityState;               // 0x1768
    ULONGLONG ReservedForCodeCoverage;      // 0x1770
    VOID* ThreadPoolData;                   // 0x1778
    VOID** TlsExpansionSlots;               // 0x1780
    VOID* DeallocationBStore;               // 0x1788
    VOID* BStoreLimit;                      // 0x1790
    ULONG MuiGeneration;                    // 0x1798
    ULONG IsImpersonating;                  // 0x179c
    VOID* NlsCache;                         // 0x17a0
    VOID* pShimData;                        // 0x17a8
    ULONG HeapData;                         // 0x17b0
    UCHAR Padding7[4];                      // 0x17b4
    VOID* CurrentTransactionHandle;         // 0x17b8
    struct _TEB_ACTIVE_FRAME* ActiveFrame;  // 0x17c0
    VOID* FlsData;                          // 0x17c8
    VOID* PreferredLanguages;               // 0x17d0
    VOID* UserPrefLanguages;                // 0x17d8
    VOID* MergedPrefLanguages;              // 0x17e0
    ULONG MuiImpersonation;                 // 0x17e8
    union {
        volatile USHORT CrossTebFlags;  // 0x17ec
        USHORT SpareCrossTebBits : 16;  // 0x17ec
    };
    union {
        USHORT SameTebFlags;  // 0x17ee
        struct {
            USHORT SafeThunkCall : 1;         // 0x17ee
            USHORT InDebugPrint : 1;          // 0x17ee
            USHORT HasFiberData : 1;          // 0x17ee
            USHORT SkipThreadAttach : 1;      // 0x17ee
            USHORT WerInShipAssertCode : 1;   // 0x17ee
            USHORT RanProcessInit : 1;        // 0x17ee
            USHORT ClonedThread : 1;          // 0x17ee
            USHORT SuppressDebugMsg : 1;      // 0x17ee
            USHORT DisableUserStackWalk : 1;  // 0x17ee
            USHORT RtlExceptionAttached : 1;  // 0x17ee
            USHORT InitialThread : 1;         // 0x17ee
            USHORT SessionAware : 1;          // 0x17ee
            USHORT LoadOwner : 1;             // 0x17ee
            USHORT LoaderWorker : 1;          // 0x17ee
            USHORT SkipLoaderInit : 1;        // 0x17ee
            USHORT SpareSameTebBits : 1;      // 0x17ee
        };
    };
    VOID* TxnScopeEnterCallback;        // 0x17f0
    VOID* TxnScopeExitCallback;         // 0x17f8
    VOID* TxnScopeContext;              // 0x1800
    ULONG LockCount;                    // 0x1808
    LONG WowTebOffset;                  // 0x180c
    VOID* ResourceRetValue;             // 0x1810
    VOID* ReservedForWdf;               // 0x1818
    ULONGLONG ReservedForCrt;           // 0x1820
    struct _GUID EffectiveContainerId;  // 0x1828
};
static_assert(sizeof(X64TEB) == 0x1838, "TEB Size check");
struct struct_gs_base {
    char unk[0x30];   // 0x0
    uint64_t teb;     // 0x30
    char unk2[0x28];  // 0x38
    uint64_t peb;     // 0x60
};
/// See: Segment Descriptor
union SegmentDescriptor {
    ULONG64 all;
    struct {
        ULONG64 limit_low : 16;
        ULONG64 base_low : 16;
        ULONG64 base_mid : 8;
        ULONG64 type : 4;
        ULONG64 system : 1;
        ULONG64 dpl : 2;
        ULONG64 present : 1;
        ULONG64 limit_high : 4;
        ULONG64 avl : 1;
        ULONG64 l : 1;  //!< 64-bit code segment (IA-32e mode only)
        ULONG64 db : 1;
        ULONG64 gran : 1;
        ULONG64 base_high : 8;
    } fields;
};
/// @copydoc SegmentDescriptor
struct SegmentDesctiptorX64 {
    SegmentDescriptor descriptor;
    ULONG32 base_upper32;
    ULONG32 reserved;
};
// 每个系统的KPCR结构都不一样,懒了
typedef struct _KPCR {
    SegmentDesctiptorX64 gdt[8];
} KPCR;

#include <pshpack1.h>
struct Idtr {
    unsigned short limit;
    ULONG_PTR base;
};

struct Idtr32 {
    unsigned short limit;
    ULONG32 base;
};
static_assert(sizeof(Idtr32) == 6, "Size check");
using Gdtr = Idtr;
#if defined(_AMD64_)
static_assert(sizeof(Idtr) == 10, "Size check");
static_assert(sizeof(Gdtr) == 10, "Size check");
#else
static_assert(sizeof(Idtr) == 6, "Size check");
static_assert(sizeof(Gdtr) == 6, "Size check");
#endif

#include <pshpack1.h>
union SegmentSelector {
    unsigned short all;
    struct {
        unsigned short rpl : 2;  //!< Requested Privilege Level
        unsigned short ti : 1;   //!< Table Indicator
        unsigned short index : 13;
    } fields;
};
static_assert(sizeof(SegmentSelector) == 2, "Size check");
#include <poppack.h>

union FlagRegister {
    ULONG_PTR all;
    struct {
        ULONG_PTR cf : 1;          //!< [0] Carry flag
        ULONG_PTR reserved1 : 1;   //!< [1] Always 1
        ULONG_PTR pf : 1;          //!< [2] Parity flag
        ULONG_PTR reserved2 : 1;   //!< [3] Always 0
        ULONG_PTR af : 1;          //!< [4] Borrow flag
        ULONG_PTR reserved3 : 1;   //!< [5] Always 0
        ULONG_PTR zf : 1;          //!< [6] Zero flag
        ULONG_PTR sf : 1;          //!< [7] Sign flag
        ULONG_PTR tf : 1;          //!< [8] Trap flag
        ULONG_PTR intf : 1;        //!< [9] Interrupt flag
        ULONG_PTR df : 1;          //!< [10] Direction flag
        ULONG_PTR of : 1;          //!< [11] Overflow flag
        ULONG_PTR iopl : 2;        //!< [12:13] I/O privilege level
        ULONG_PTR nt : 1;          //!< [14] Nested task flag
        ULONG_PTR reserved4 : 1;   //!< [15] Always 0
        ULONG_PTR rf : 1;          //!< [16] Resume flag
        ULONG_PTR vm : 1;          //!< [17] Virtual 8086 mode
        ULONG_PTR ac : 1;          //!< [18] Alignment check
        ULONG_PTR vif : 1;         //!< [19] Virtual interrupt flag
        ULONG_PTR vip : 1;         //!< [20] Virtual interrupt pending
        ULONG_PTR id : 1;          //!< [21] Identification flag
        ULONG_PTR reserved5 : 10;  //!< [22:31] Always 0
    } fields;
};
struct moudle_export {
    char name[MAX_PATH];
    uint64_t function_address;
    void* function_callback;
    uint64_t ordinal;
};
struct moudle_import {
    char name[MAX_PATH];
    char dll_name[MAX_PATH];
    uint64_t function_address;
    void* function_callback;
    bool is_delayed_import;
};
struct moudle_section {
    char name[9];
    ULONG base;
    ULONG size;
    ULONG protect_flag;
};
struct struct_handle_table {
    uint64_t handle;         // 值
    uint64_t type;           // 对象类型
    uint64_t address;        // 地址
    uint64_t authorization;  // 权限
    uint64_t protect_flag;   // 是否被保护
    char name[MAX_PATH];     // 名称
};
struct struct_moudle {
    char name[MAX_PATH];
    uint64_t entry;
    uint64_t base;
    uint64_t size;
    uint64_t real_base;
    std::vector<std::shared_ptr<moudle_import>> import_function;
    std::vector<std::shared_ptr<moudle_export>> export_function;
    std::vector<std::shared_ptr<moudle_section>> sections;
};
struct struct_process {
    char ImageFileName[MAX_PATH];            // 名字
    struct_handle_table HandleTable;         // 句柄表
    uint64_t DebugPort;                      // 一直为0谢谢
    uint64_t UniqueProcessId;                // 进程id
    uint64_t InheritedFromUniqueProcessId;   // 父进程ID
    X64PEB PebBaseAddress;                   // PEB 里面有ldr
    uint64_t ExitStatus;                     // 终止状态
    uint64_t AffinityMask;                   // 关联掩码
    uint64_t BasePriority;                   // 优先级类
    uint64_t VadRoot;                        // VAD
    std::vector<struct_moudle> moudle_list;  // 模块列表
};

typedef struct AllocBlock_s {
    AllocBlock_s(ULONG64 b, ULONG s) : base(b), size(s) { free = false; }
    ULONG64 base;
    ULONG size;
    bool free;
} AllocBlock_t;

struct struct_params {
    int type;                // 类型
    char str[MAX_PATH];      // PARAMS_CHAR
    wchar_t wstr[MAX_PATH];  // PARAMS_WCHAR
    uint64_t uint;           // PARAMS_UINT
    int _int;                // PARAMS_INT
};
struct struct_process_trace_log {
    time_t time;                   // 时间
    char function_name[MAX_PATH];  // 名字
    char moudle_name[MAX_PATH];    // 模块名字
    uint64_t function_address;     // 地址
    uint64_t call_address;
    int params_num;                          // 参数数量
    std::vector<uint64_t> save_regs;         // 各个寄存器状态
    std::vector<struct_params> save_params;  // 各个参数值
};
