Pdbex - pdbex is a utility for reconstructing structures and unions from the PDB into compilable C headers

Overview

Build status

pdbex

pdbex is a utility for reconstructing structures and unions from the PDB files into compilable C headers.

Why?

PDB files, among others, contain information about structures and unions. These information can be very useful - for instance structures and unions from ntdll.dll or ntoskrnl.exe can be useful for experimenting with Windows internals. But information in the PDB files are limited only to the symbol name, member name, its type and offset. Information about nested anonymous structures and unions are lost. However, with a bit of work, they can be formed back.

I am not aware of any utility which could make a compilable and offset-accurate C header representation of symbols in the PDB file. Although there do exist some public servers which list some of the structures, it is only limited subset of various symbols of files of various Windows versions. Not to say that many of them are not offset-accurate. The fact that we have ReactOS and Volatility does not help. They will not provide header file for any given PDB file.

Usage

> pdbex.exe _SID ntdll.pdb

/*
 * PDB file: ntdll.pdb
 * Image architecture: x86
 *
 * Dumped by pdbex tool v0.1, by wbenny
 */

typedef struct _SID_IDENTIFIER_AUTHORITY
{
  /* 0x0000 */ unsigned char Value[6];
} SID_IDENTIFIER_AUTHORITY, *PSID_IDENTIFIER_AUTHORITY;

typedef struct _SID
{
  /* 0x0000 */ unsigned char Revision;
  /* 0x0001 */ unsigned char SubAuthorityCount;
  /* 0x0002 */ struct _SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
  /* 0x0008 */ unsigned long SubAuthority[1];
} SID, *PSID;

This command will dump not only specified symbol, but also all symbols referenced by it - and in correct order. If you insist on dumping only the specified symbol, you can disable this feature by -j- option:

> pdbex.exe _SID ntdll.pdb -j- -k-

typedef struct _SID
{
  /* 0x0000 */ unsigned char Revision;
  /* 0x0001 */ unsigned char SubAuthorityCount;
  /* 0x0002 */ struct _SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
  /* 0x0008 */ unsigned long SubAuthority[1];
} SID, *PSID;

(-k- switch is responsible for ommiting the header.)

You can even control if definition of referenced symbols should be inlined by -e [n|i|a] option.

  • n - will not inline anything (unnamed symbols are created separately and named as TAG_UNNAMED_###
  • i - will inline only unnamed structures and union (default behavior)
  • a - will inline everything

Example of inlining everything:

> pdbex.exe _SID ntdll.pdb -e a -k-

typedef struct _SID
{
  /* 0x0000 */ unsigned char Revision;
  /* 0x0001 */ unsigned char SubAuthorityCount;
  struct _SID_IDENTIFIER_AUTHORITY
  {
    /* 0x0002 */ unsigned char Value[6];
  } IdentifierAuthority;
  /* 0x0008 */ unsigned long SubAuthority[1];
} SID, *PSID;

Example of not inlining anything:

> pdbex.exe _LARGE_INTEGER ntdll.pdb -e n -k-

typedef struct _TAG_UNNAMED_1
{
  /* 0x0000 */ unsigned long LowPart;
  /* 0x0004 */ long HighPart;
} TAG_UNNAMED_1, *PTAG_UNNAMED_1;

typedef union _LARGE_INTEGER
{
  union
  {
    struct
    {
      /* 0x0000 */ unsigned long LowPart;
      /* 0x0004 */ long HighPart;
    };
    /* 0x0000 */ struct _TAG_UNNAMED_1 u;
    /* 0x0000 */ __int64 QuadPart;
  };
} LARGE_INTEGER, *PLARGE_INTEGER;

Default behavior:

> pdbex.exe _LARGE_INTEGER ntdll.pdb -e i -k-

typedef union _LARGE_INTEGER
{
  union
  {
    struct
    {
      /* 0x0000 */ unsigned long LowPart;
      /* 0x0004 */ long HighPart;
    };
    struct // _TAG_UNNAMED_1
    {
      /* 0x0000 */ unsigned long LowPart;
      /* 0x0004 */ long HighPart;
    } u;
    /* 0x0000 */ __int64 QuadPart;
  };
} LARGE_INTEGER, *PLARGE_INTEGER;

You can also dump all symbols using "*" as the symbol name to dump:

> pdbex.exe * ntdll.pdb -o ntdll.h

This command will dump all structures and unions to the file ntdll.h.

Remarks

  • Pointers to functions are represented only as void* with additional comment /* function */.
  • Produced structures expect packing alignment to be set at 1 byte.
  • Produced unions have one extra union nested inside of it (you could notice few lines above). This is a known cosmetic bug.
  • pdbex is designed to dump headers from C project only - C++ classes are not supported.

Compilation

Compile pdbex using Visual Studio 2017. Solution file is included. No other dependencies are required.

Testing

There are 2 files in the Scripts folder:

  • env.bat - sets environment variables for Microsoft Visual C++ 2015
  • test.py - testing script

test.py dumps all symbols from the provided PDB file. It also generates C file which tests if offsets of the members of structures and unions do match the original offsets in the PDB file. The C file is then compiled using msbuild and ran. If the resulting program prints a line starting with [!], it is considered as error. In that case, line also contains information about struct/union + member + offset that did not match. It prints nothing on success.

Because the test.py uses msbuild for creating tests, special environment variables must be set. It can be accomplished either by running test.py from the developer console or by calling env.bat. env.bat file exists only for convenience and does nothing else than running the VsDevCmd.bat from the default Visual Studio 2015 installation directory. The environment variables are set in the current console process, therefore this script can be called only once.

Documentation

pdbex -h should make it:

Version v0.18

pdbex <symbol> <path> [-o <filename>] [-t <filename>] [-e <type>]
                     [-u <prefix>] [-s prefix] [-r prefix] [-g suffix]
                     [-p] [-x] [-m] [-b] [-d] [-i] [-l]

<symbol>             Symbol name to extract
                     Use '*' if all symbols should be extracted.
                     Use '%' if all symbols should be extracted separately.
<path>               Path to the PDB file.
 -o filename         Specifies the output file.                       (stdout)
 -t filename         Specifies the output test file.                  (off)
 -e [n,i,a]          Specifies expansion of nested structures/unions. (i)
                       n = none            Only top-most type is printed.
                       i = inline unnamed  Unnamed types are nested.
                       a = inline all      All types are nested.
 -u prefix           Unnamed union prefix  (in combination with -d).
 -s prefix           Unnamed struct prefix (in combination with -d).
 -r prefix           Prefix for all symbols.
 -g suffix           Suffix for all symbols.

Following options can be explicitly turned off by adding trailing '-'.
Example: -p-
 -p                  Create padding members.                          (T)
 -x                  Show offsets.                                    (T)
 -m                  Create Microsoft typedefs.                       (T)
 -b                  Allow bitfields in union.                        (F)
 -d                  Allow unnamed data types.                        (T)
 -i                  Use types from stdint.h instead of native types. (F)
 -j                  Print definitions of referenced types.           (T)
 -k                  Print header.                                    (T)
 -n                  Print declarations.                              (T)
 -l                  Print definitions.                               (T)
 -f                  Print functions.                                 (F)
 -z                  Print #pragma pack directives.                   (T)
 -y                  Sort declarations and definitions.               (F)

License

All the code in this repository is open-source under the MIT license. See the LICENSE.txt file in this repository.

If you find this project interesting, you can buy me a coffee

  BTC 3GwZMNGvLCZMi7mjL8K6iyj6qGbhkVMNMF
  LTC MQn5YC7bZd4KSsaj8snSg4TetmdKDkeCYk
Issues
  • File not found, invalid file name conversion

    File not found, invalid file name conversion

    Actually it doesn't work for me at all. I know about #2 however even giving to pdbex compiled version these dlls (confirmed pdbex loaded that msdia140 dll not system msdia) does not solve this problem here. The root of this problem is a unicode conversion of file path in routine

    https://github.com/wbenny/pdbex/blob/3fe750269959d4de71582335a9a28e26b3f5fed1/Source/PDB.cpp#L127-L128

    this conversion produce trash on output thus "file not found" error will be printed as result always. Not quite sure what is wrong with this fancy C++ stuff, but I would instead use MultiByteToWideChar (and I fixed that for myself) as loadDataFromPdb expect LPCOLESTR which is WCHAR*.

    opened by hfiref0x 4
  • Fix crash with newer Windows PDBs, add char8_t support

    Fix crash with newer Windows PDBs, add char8_t support

    Some of the more recent Windows PDBs use char8_t, which a type that is in the current (VS 19.10) MS DIA SDK, but is not in the known type maps for pdbex. This causes a crash due to a nullptr dereference in UdtFieldDefinition::VisitBaseType (there was already an issue for this - see #12).

    This is an input command that caused pdbex to crash for me (most arguments probably unnecessary): pdbex * WinTypes.pdb -o WinTypes.h -d -e i -u _anon_union_ -s _anon_struct_ -m -b -p- where WinTypes.pdb is the PDB for WinTypes.dll 10.0.21390.1, found in C:\Symbols\WinTypes.pdb\383E6861B516E717207B5610F6C0D2F91.

    The first commit in this PR fixes the nullptr dereference, should a new type be added to the MS DIA SDK again in future. The non-compilable string <unknown_type> will be printed instead.

    The second commit adds the char8_t type to the known type maps so that pdbex knows about it. Example output from the same WinTypes.pdb, which looks correct to me:

    struct std::_Codecvt_guard<char16_t,char8_t>
    {
      /* 0x0000 */ const char16_t* const& _First1;
      /* 0x0008 */ const char16_t*& _Mid1;
      /* 0x0010 */ char8_t* const& _First2;
      /* 0x0018 */ char8_t*& _Mid2;
    }; /* size: 0x0020 */
    
    opened by Mattiwatti 1
  • Silent failure, incorrect LoadDiaViaLoadLibrary return value

    Silent failure, incorrect LoadDiaViaLoadLibrary return value

    On my computer, both LoadDiaViaCoCreateInstance and LoadDiaViaLoadLibrary fail. It took me a while to understand that, had to debug a bit. That's because LoadDiaViaLoadLibrary returns FALSE on an error, but the return type is HRESULT, so it essentially returns S_OK.

    opened by m417z 1
  • Write the corrected name for unnamed enums

    Write the corrected name for unnamed enums

    The produced header was invalid when i ran it against a windows 10 ntoskrnl pdb, the PDB contained an unnamed enum which did not have a base typedef typedef enum /_TAG_UNNAMED_1 WAS MISSING/ { KTMOH_CommitTransaction_Result = 1, KTMOH_RollbackTransaction_Result = 2, } TAG_UNNAMED_1, *PTAG_UNNAMED_1;

    Resulting in the following struct: typedef struct _KTRANSACTION_HISTORY { /* 0x0000 / enum _TAG_UNNAMED_1 RecordType; / 0x0004 */ uint32_t Payload; } KTRANSACTION_HISTORY, PKTRANSACTION_HISTORY; / size: 0x0008 */

    to fail the compilation.

    opened by arilou 1
  • fix incorrect result of SymbolModuleBase::LoadDiaViaLoadLibrary

    fix incorrect result of SymbolModuleBase::LoadDiaViaLoadLibrary

    This fixes pdbex crash - If dll not exist or has wrong architecture the LoadDiaViaLoadLibrary code will produce incorrect result and pass error checking, later this will crash pdbex as invalid memory (NULL) will be dereferenced.

    This should fix #7 #11 #17

    opened by hfiref0x 0
  • return 0 or nullptr from GetBasicTypeString danger and will produce crash

    return 0 or nullptr from GetBasicTypeString danger and will produce crash

    here from table https://github.com/wbenny/pdbex/blob/master/Source/PDB.cpp#L1151 or here as not find https://github.com/wbenny/pdbex/blob/master/Source/PDB.cpp#L1156

    as example from here https://github.com/wbenny/pdbex/blob/master/Source/UdtFieldDefinition.h#L40 m_TypePrefix += PDB::GetBasicTypeString(Symbol, m_Settings->UseStdInt);

    std::string str; str += 0; <-- will crash so replace all 0 and nullptr as result from GetBasicTypeString for empty string or find better solution

    opened by marakew 0
  • wrong

    wrong

    D:\git\personal\wbenny\pdbex\Bin\x64\Debug>pdbex _KPRCB C:\Windows\System32\ntoskrnl.exe /*

    • PDB file: C:\Windows\System32\ntoskrnl.exe
    • Image architecture: AMD64 (0x8664)
    • Dumped by pdbex tool v0.18, by wbenny */

    #include <pshpack1.h> typedef struct _KDESCRIPTOR { /* 0x0000 / unsigned short Pad[3]; / 0x0006 / unsigned short Limit; / 0x0008 / void Base; } KDESCRIPTOR, PKDESCRIPTOR; / size: 0x0010 */

    typedef struct _KSPECIAL_REGISTERS { /* 0x0000 / unsigned __int64 Cr0; / 0x0008 / unsigned __int64 Cr2; / 0x0010 / unsigned __int64 Cr3; / 0x0018 / unsigned __int64 Cr4; / 0x0020 / unsigned __int64 KernelDr0; / 0x0028 / unsigned __int64 KernelDr1; / 0x0030 / unsigned __int64 KernelDr2; / 0x0038 / unsigned __int64 KernelDr3; / 0x0040 / unsigned __int64 KernelDr6; / 0x0048 / unsigned __int64 KernelDr7; / 0x0050 / struct _KDESCRIPTOR Gdtr; / 0x0060 / struct _KDESCRIPTOR Idtr; / 0x0070 / unsigned short Tr; / 0x0072 / unsigned short Ldtr; / 0x0074 / unsigned long MxCsr; / 0x0078 / unsigned __int64 DebugControl; / 0x0080 / unsigned __int64 LastBranchToRip; / 0x0088 / unsigned __int64 LastBranchFromRip; / 0x0090 / unsigned __int64 LastExceptionToRip; / 0x0098 / unsigned __int64 LastExceptionFromRip; / 0x00a0 / unsigned __int64 Cr8; / 0x00a8 / unsigned __int64 MsrGsBase; / 0x00b0 / unsigned __int64 MsrGsSwap; / 0x00b8 / unsigned __int64 MsrStar; / 0x00c0 / unsigned __int64 MsrLStar; / 0x00c8 / unsigned __int64 MsrCStar; / 0x00d0 / unsigned __int64 MsrSyscallMask; / 0x00d8 / unsigned __int64 Xcr0; / 0x00e0 / unsigned __int64 MsrFsBase; / 0x00e8 */ unsigned __int64 SpecialPadding0; } KSPECIAL_REGISTERS, PKSPECIAL_REGISTERS; / size: 0x00f0 */

    typedef struct _M128A { /* 0x0000 / unsigned __int64 Low; / 0x0008 */ __int64 High; } M128A, PM128A; / size: 0x0010 */

    typedef struct _XSAVE_FORMAT { /* 0x0000 / unsigned short ControlWord; / 0x0002 / unsigned short StatusWord; / 0x0004 / unsigned char TagWord; / 0x0005 / unsigned char Reserved1; / 0x0006 / unsigned short ErrorOpcode; / 0x0008 / unsigned long ErrorOffset; / 0x000c / unsigned short ErrorSelector; / 0x000e / unsigned short Reserved2; / 0x0010 / unsigned long DataOffset; / 0x0014 / unsigned short DataSelector; / 0x0016 / unsigned short Reserved3; / 0x0018 / unsigned long MxCsr; / 0x001c / unsigned long MxCsr_Mask; / 0x0020 / struct _M128A FloatRegisters[8]; / 0x00a0 / struct _M128A XmmRegisters[16]; / 0x01a0 */ unsigned char Reserved4[96]; } XSAVE_FORMAT, PXSAVE_FORMAT; / size: 0x0200 */

    typedef struct _CONTEXT { /* 0x0000 / unsigned __int64 P1Home; / 0x0008 / unsigned __int64 P2Home; / 0x0010 / unsigned __int64 P3Home; / 0x0018 / unsigned __int64 P4Home; / 0x0020 / unsigned __int64 P5Home; / 0x0028 / unsigned __int64 P6Home; / 0x0030 / unsigned long ContextFlags; / 0x0034 / unsigned long MxCsr; / 0x0038 / unsigned short SegCs; / 0x003a / unsigned short SegDs; / 0x003c / unsigned short SegEs; / 0x003e / unsigned short SegFs; / 0x0040 / unsigned short SegGs; / 0x0042 / unsigned short SegSs; / 0x0044 / unsigned long EFlags; / 0x0048 / unsigned __int64 Dr0; / 0x0050 / unsigned __int64 Dr1; / 0x0058 / unsigned __int64 Dr2; / 0x0060 / unsigned __int64 Dr3; / 0x0068 / unsigned __int64 Dr6; / 0x0070 / unsigned __int64 Dr7; / 0x0078 / unsigned __int64 Rax; / 0x0080 / unsigned __int64 Rcx; / 0x0088 / unsigned __int64 Rdx; / 0x0090 / unsigned __int64 Rbx; / 0x0098 / unsigned __int64 Rsp; / 0x00a0 / unsigned __int64 Rbp; / 0x00a8 / unsigned __int64 Rsi; / 0x00b0 / unsigned __int64 Rdi; / 0x00b8 / unsigned __int64 R8; / 0x00c0 / unsigned __int64 R9; / 0x00c8 / unsigned __int64 R10; / 0x00d0 / unsigned __int64 R11; / 0x00d8 / unsigned __int64 R12; / 0x00e0 / unsigned __int64 R13; / 0x00e8 / unsigned __int64 R14; / 0x00f0 / unsigned __int64 R15; / 0x00f8 / unsigned __int64 Rip; union { / 0x0100 / struct _XSAVE_FORMAT FltSave; struct { / 0x0100 / struct _M128A Header[2]; / 0x0120 / struct _M128A Legacy[8]; / 0x01a0 / struct _M128A Xmm0; / 0x01b0 / struct _M128A Xmm1; / 0x01c0 / struct _M128A Xmm2; / 0x01d0 / struct _M128A Xmm3; / 0x01e0 / struct _M128A Xmm4; / 0x01f0 / struct _M128A Xmm5; / 0x0200 / struct _M128A Xmm6; / 0x0210 / struct _M128A Xmm7; / 0x0220 / struct _M128A Xmm8; / 0x0230 / struct _M128A Xmm9; / 0x0240 / struct _M128A Xmm10; / 0x0250 / struct _M128A Xmm11; / 0x0260 / struct _M128A Xmm12; / 0x0270 / struct _M128A Xmm13; / 0x0280 / struct _M128A Xmm14; / 0x0290 / struct _M128A Xmm15; }; / size: 0x01a0 / }; / size: 0x0200 / / 0x0300 / struct _M128A VectorRegister[26]; / 0x04a0 / unsigned __int64 VectorControl; / 0x04a8 / unsigned __int64 DebugControl; / 0x04b0 / unsigned __int64 LastBranchToRip; / 0x04b8 / unsigned __int64 LastBranchFromRip; / 0x04c0 / unsigned __int64 LastExceptionToRip; / 0x04c8 */ unsigned __int64 LastExceptionFromRip; } CONTEXT, PCONTEXT; / size: 0x04d0 */

    typedef struct _KPROCESSOR_STATE { /* 0x0000 / struct _KSPECIAL_REGISTERS SpecialRegisters; / 0x00f0 */ struct _CONTEXT ContextFrame; } KPROCESSOR_STATE, PKPROCESSOR_STATE; / size: 0x05c0 */

    typedef struct _KPRCB { /* 0x0000 / unsigned long MxCsr; / 0x0004 / unsigned char LegacyNumber; / 0x0005 / unsigned char ReservedMustBeZero; / 0x0006 / unsigned char InterruptRequest; / 0x0007 / unsigned char IdleHalt; / 0x0008 / struct _KTHREAD CurrentThread; /* 0x0010 / struct _KTHREAD NextThread; /* 0x0018 / struct _KTHREAD IdleThread; /* 0x0020 / unsigned char NestingLevel; / 0x0021 / unsigned char ClockOwner; union { / 0x0022 / unsigned char PendingTickFlags; struct / bitfield / { / 0x0022 / unsigned char PendingTick : 1; / bit position: 0 / / 0x0022 / unsigned char PendingBackupTick : 1; / bit position: 1 / }; / bitfield / }; / size: 0x0001 / / 0x0023 / unsigned char IdleState; / 0x0024 / unsigned long Number; / 0x0028 / unsigned __int64 RspBase; / 0x0030 / unsigned __int64 PrcbLock; / 0x0038 / char PriorityState; /* 0x0040 / char CpuType; / 0x0041 / char CpuID; union { / 0x0042 / unsigned short CpuStep; struct { / 0x0042 / unsigned char CpuStepping; / 0x0043 / unsigned char CpuModel; }; / size: 0x0002 / }; / size: 0x0002 / / 0x0044 / unsigned long MHz; / 0x0048 / unsigned __int64 HalReserved[8]; / 0x0088 / unsigned short MinorVersion; / 0x008a / unsigned short MajorVersion; / 0x008c / unsigned char BuildType; / 0x008d / unsigned char CpuVendor; / 0x008e / unsigned char CoresPerPhysicalProcessor; / 0x008f / unsigned char LogicalProcessorsPerCore; / 0x0090 / unsigned __int64 TscFrequency; / 0x0098 / unsigned __int64 PrcbPad04[5]; / 0x00c0 / struct _KNODE ParentNode; /* 0x00c8 / unsigned __int64 GroupSetMember; / 0x00d0 / unsigned char Group; / 0x00d1 / unsigned char GroupIndex; / 0x00d2 / unsigned char PrcbPad05[2]; / 0x00d4 / unsigned long InitialApicId; / 0x00d8 / unsigned long ScbOffset; / 0x00dc / unsigned long ApicMask; / 0x00e0 / void AcpiReserved; /* 0x00e8 / unsigned long CFlushSize; / 0x00ec / long Padding_0; / 0x00f0 / unsigned __int64 PrcbPad11[2]; / 0x0100 / struct _KPROCESSOR_STATE ProcessorState; / 0x06c0 / struct _XSAVE_AREA_HEADER ExtendedSupervisorState; /* 0x06c8 / unsigned long ProcessorSignature; / 0x06cc / unsigned long ProcessorFlags; / 0x06d0 / unsigned __int64 PrcbPad12a; / 0x06d8 / unsigned __int64 PrcbPad12[3]; / 0x06f0 */ long PADDING[4]; } KPRCB, PKPRCB; / size: 0x0700 */

    #include <poppack.h>

    but in windbg:

    0: kd> dt _KPRCB ntdll!_KPRCB +0x000 MxCsr : Uint4B +0x004 LegacyNumber : UChar +0x005 ReservedMustBeZero : UChar +0x006 InterruptRequest : UChar +0x007 IdleHalt : UChar +0x008 CurrentThread : Ptr64 _KTHREAD +0x010 NextThread : Ptr64 _KTHREAD +0x018 IdleThread : Ptr64 _KTHREAD +0x020 NestingLevel : UChar +0x021 ClockOwner : UChar +0x022 PendingTickFlags : UChar +0x022 PendingTick : Pos 0, 1 Bit +0x022 PendingBackupTick : Pos 1, 1 Bit +0x023 IdleState : UChar +0x024 Number : Uint4B +0x028 RspBase : Uint8B +0x030 PrcbLock : Uint8B +0x038 PriorityState : Ptr64 Char +0x040 CpuType : Char +0x041 CpuID : Char +0x042 CpuStep : Uint2B +0x042 CpuStepping : UChar +0x043 CpuModel : UChar +0x044 MHz : Uint4B +0x048 HalReserved : [8] Uint8B +0x088 MinorVersion : Uint2B +0x08a MajorVersion : Uint2B +0x08c BuildType : UChar +0x08d CpuVendor : UChar +0x08e CoresPerPhysicalProcessor : UChar +0x08f LogicalProcessorsPerCore : UChar +0x090 TscFrequency : Uint8B +0x098 PrcbPad04 : [5] Uint8B +0x0c0 ParentNode : Ptr64 _KNODE +0x0c8 GroupSetMember : Uint8B +0x0d0 Group : UChar +0x0d1 GroupIndex : UChar +0x0d2 PrcbPad05 : [2] UChar +0x0d4 InitialApicId : Uint4B +0x0d8 ScbOffset : Uint4B +0x0dc ApicMask : Uint4B +0x0e0 AcpiReserved : Ptr64 Void +0x0e8 CFlushSize : Uint4B +0x0ec PrcbFlags : _KPRCBFLAG +0x0f0 TrappedSecurityDomain : Uint8B +0x0f8 BpbState : UChar +0x0f8 BpbCpuIdle : Pos 0, 1 Bit +0x0f8 BpbFlushRsbOnTrap : Pos 1, 1 Bit +0x0f8 BpbIbpbOnReturn : Pos 2, 1 Bit +0x0f8 BpbIbpbOnTrap : Pos 3, 1 Bit +0x0f8 BpbIbpbOnRetpolineExit : Pos 4, 1 Bit +0x0f8 BpbStateReserved : Pos 5, 3 Bits +0x0f9 BpbFeatures : UChar +0x0f9 BpbClearOnIdle : Pos 0, 1 Bit +0x0f9 BpbEnabled : Pos 1, 1 Bit +0x0f9 BpbSmep : Pos 2, 1 Bit +0x0f9 BpbFeaturesReserved : Pos 3, 5 Bits +0x0fa BpbCurrentSpecCtrl : UChar +0x0fb BpbKernelSpecCtrl : UChar +0x0fc BpbNmiSpecCtrl : UChar +0x0fd BpbUserSpecCtrl : UChar +0x0fe PairRegister : Int2B +0x0f0 PrcbPad11 : [2] Uint8B +0x100 ProcessorState : _KPROCESSOR_STATE +0x6c0 ExtendedSupervisorState : Ptr64 _XSAVE_AREA_HEADER +0x6c8 ProcessorSignature : Uint4B +0x6cc ProcessorFlags : Uint4B +0x6d0 BpbRetpolineExitSpecCtrl : UChar +0x6d1 BpbTrappedRetpolineExitSpecCtrl : UChar +0x6d2 BpbTrappedBpbState : UChar +0x6d2 BpbTrappedCpuIdle : Pos 0, 1 Bit +0x6d2 BpbTrappedFlushRsbOnTrap : Pos 1, 1 Bit +0x6d2 BpbTrappedIbpbOnReturn : Pos 2, 1 Bit +0x6d2 BpbTrappedIbpbOnTrap : Pos 3, 1 Bit +0x6d2 BpbTrappedIbpbOnRetpolineExit : Pos 4, 1 Bit +0x6d2 BpbtrappedBpbStateReserved : Pos 5, 3 Bits +0x6d3 BpbRetpolineState : UChar +0x6d3 BpbRunningNonRetpolineCode : Pos 0, 1 Bit +0x6d3 BpbIndirectCallsSafe : Pos 1, 1 Bit +0x6d3 BpbRetpolineEnabled : Pos 2, 1 Bit +0x6d3 BpbRetpolineStateReserved : Pos 3, 5 Bits +0x6d4 PrcbPad12b : Uint4B +0x6d0 PrcbPad12a : Uint8B +0x6d8 PrcbPad12 : [3] Uint8B +0x6f0 LockQueue : [17] _KSPIN_LOCK_QUEUE +0x800 PPLookasideList : [16] _PP_LOOKASIDE_LIST +0x900 PPNxPagedLookasideList : [32] _GENERAL_LOOKASIDE_POOL +0x1500 PPNPagedLookasideList : [32] _GENERAL_LOOKASIDE_POOL +0x2100 PPPagedLookasideList : [32] _GENERAL_LOOKASIDE_POOL +0x2d00 PrcbPad20 : Uint8B +0x2d08 DeferredReadyListHead : _SINGLE_LIST_ENTRY +0x2d10 MmPageFaultCount : Int4B +0x2d14 MmCopyOnWriteCount : Int4B +0x2d18 MmTransitionCount : Int4B +0x2d1c MmDemandZeroCount : Int4B +0x2d20 MmPageReadCount : Int4B +0x2d24 MmPageReadIoCount : Int4B +0x2d28 MmDirtyPagesWriteCount : Int4B +0x2d2c MmDirtyWriteIoCount : Int4B +0x2d30 MmMappedPagesWriteCount : Int4B +0x2d34 MmMappedWriteIoCount : Int4B +0x2d38 KeSystemCalls : Uint4B +0x2d3c KeContextSwitches : Uint4B +0x2d40 PrcbPad40 : Uint4B +0x2d44 CcFastReadNoWait : Uint4B +0x2d48 CcFastReadWait : Uint4B +0x2d4c CcFastReadNotPossible : Uint4B +0x2d50 CcCopyReadNoWait : Uint4B +0x2d54 CcCopyReadWait : Uint4B +0x2d58 CcCopyReadNoWaitMiss : Uint4B +0x2d5c IoReadOperationCount : Int4B +0x2d60 IoWriteOperationCount : Int4B +0x2d64 IoOtherOperationCount : Int4B +0x2d68 IoReadTransferCount : _LARGE_INTEGER +0x2d70 IoWriteTransferCount : _LARGE_INTEGER +0x2d78 IoOtherTransferCount : _LARGE_INTEGER +0x2d80 PacketBarrier : Int4B +0x2d84 TargetCount : Int4B +0x2d88 IpiFrozen : Uint4B +0x2d8c PrcbPad30 : Uint4B +0x2d90 IsrDpcStats : Ptr64 Void +0x2d98 DeviceInterrupts : Uint4B +0x2d9c LookasideIrpFloat : Int4B +0x2da0 InterruptLastCount : Uint4B +0x2da4 InterruptRate : Uint4B +0x2da8 PrcbPad31 : Uint8B +0x2db0 PairPrcb : Ptr64 _KPRCB +0x2db8 StaticAffinity : _KSTATIC_AFFINITY_BLOCK +0x3058 PrcbPad35 : [5] Uint8B +0x3080 InterruptObjectPool : _SLIST_HEADER +0x3090 DpcRuntimeHistoryHashTable : Ptr64 _RTL_HASH_TABLE +0x3098 DpcRuntimeHistoryHashTableCleanupDpc : Ptr64 _KDPC +0x30a0 CurrentDpcRoutine : Ptr64 void +0x30a8 CurrentDpcRuntimeHistoryCached : Uint8B +0x30b0 CurrentDpcStartTime : Uint8B +0x30b8 PrcbPad41 : [1] Uint8B +0x30c0 DpcData : [2] _KDPC_DATA +0x3110 DpcStack : Ptr64 Void +0x3118 MaximumDpcQueueDepth : Int4B +0x311c DpcRequestRate : Uint4B +0x3120 MinimumDpcRate : Uint4B +0x3124 DpcLastCount : Uint4B +0x3128 ThreadDpcEnable : UChar +0x3129 QuantumEnd : UChar +0x312a DpcRoutineActive : UChar +0x312b IdleSchedule : UChar +0x312c DpcRequestSummary : Int4B +0x312c DpcRequestSlot : [2] Int2B +0x312c NormalDpcState : Int2B +0x312e ThreadDpcState : Int2B +0x312c DpcNormalProcessingActive : Pos 0, 1 Bit +0x312c DpcNormalProcessingRequested : Pos 1, 1 Bit +0x312c DpcNormalThreadSignal : Pos 2, 1 Bit +0x312c DpcNormalTimerExpiration : Pos 3, 1 Bit +0x312c DpcNormalDpcPresent : Pos 4, 1 Bit +0x312c DpcNormalLocalInterrupt : Pos 5, 1 Bit +0x312c DpcNormalSpare : Pos 6, 10 Bits +0x312c DpcThreadActive : Pos 16, 1 Bit +0x312c DpcThreadRequested : Pos 17, 1 Bit +0x312c DpcThreadSpare : Pos 18, 14 Bits +0x3130 PrcbPad93 : Uint4B +0x3134 LastTick : Uint4B +0x3138 ClockInterrupts : Uint4B +0x313c ReadyScanTick : Uint4B +0x3140 InterruptObject : [256] Ptr64 Void +0x3940 TimerTable : _KTIMER_TABLE +0x7b58 PrcbPad92 : [10] Uint4B +0x7b80 DpcGate : _KGATE +0x7b98 PrcbPad52 : Ptr64 Void +0x7ba0 CallDpc : _KDPC +0x7be0 ClockKeepAlive : Int4B +0x7be4 PrcbPad60 : [2] UChar +0x7be6 NmiActive : UChar +0x7be7 MceActive : UChar +0x7be6 CombinedNmiMceActive : Uint2B +0x7be8 DpcWatchdogPeriod : Int4B +0x7bec DpcWatchdogCount : Int4B +0x7bf0 KeSpinLockOrdering : Int4B +0x7bf4 DpcWatchdogProfileCumulativeDpcThreshold : Uint4B +0x7bf8 CachedPtes : Ptr64 Void +0x7c00 WaitListHead : _LIST_ENTRY +0x7c10 WaitLock : Uint8B +0x7c18 ReadySummary : Uint4B +0x7c1c AffinitizedSelectionMask : Int4B +0x7c20 QueueIndex : Uint4B +0x7c24 PrcbPad75 : [2] Uint4B +0x7c2c DpcWatchdogSequenceNumber : Uint4B +0x7c30 TimerExpirationDpc : _KDPC +0x7c70 ScbQueue : _RTL_RB_TREE +0x7c80 DispatcherReadyListHead : [32] _LIST_ENTRY +0x7e80 InterruptCount : Uint4B +0x7e84 KernelTime : Uint4B +0x7e88 UserTime : Uint4B +0x7e8c DpcTime : Uint4B +0x7e90 InterruptTime : Uint4B +0x7e94 AdjustDpcThreshold : Uint4B +0x7e98 DebuggerSavedIRQL : UChar +0x7e99 GroupSchedulingOverQuota : UChar +0x7e9a DeepSleep : UChar +0x7e9b PrcbPad80 : UChar +0x7e9c DpcTimeCount : Uint4B +0x7ea0 DpcTimeLimit : Uint4B +0x7ea4 PeriodicCount : Uint4B +0x7ea8 PeriodicBias : Uint4B +0x7eac AvailableTime : Uint4B +0x7eb0 KeExceptionDispatchCount : Uint4B +0x7eb4 ReadyThreadCount : Uint4B +0x7eb8 ReadyQueueExpectedRunTime : Uint8B +0x7ec0 StartCycles : Uint8B +0x7ec8 TaggedCyclesStart : Uint8B +0x7ed0 TaggedCycles : [3] Uint8B +0x7ee8 AffinitizedCycles : Uint8B +0x7ef0 ImportantCycles : Uint8B +0x7ef8 UnimportantCycles : Uint8B +0x7f00 DpcWatchdogProfileSingleDpcThreshold : Uint4B +0x7f04 MmSpinLockOrdering : Int4B +0x7f08 CachedStack : Ptr64 Void +0x7f10 PageColor : Uint4B +0x7f14 NodeColor : Uint4B +0x7f18 NodeShiftedColor : Uint4B +0x7f1c SecondaryColorMask : Uint4B +0x7f20 PrcbPad81 : [6] UChar +0x7f26 ExceptionStackActive : UChar +0x7f27 TbFlushListActive : UChar +0x7f28 ExceptionStack : Ptr64 Void +0x7f30 PrcbPad82 : [1] Uint8B +0x7f38 CycleTime : Uint8B +0x7f40 Cycles : [4] [2] Uint8B +0x7f80 CcFastMdlReadNoWait : Uint4B +0x7f84 CcFastMdlReadWait : Uint4B +0x7f88 CcFastMdlReadNotPossible : Uint4B +0x7f8c CcMapDataNoWait : Uint4B +0x7f90 CcMapDataWait : Uint4B +0x7f94 CcPinMappedDataCount : Uint4B +0x7f98 CcPinReadNoWait : Uint4B +0x7f9c CcPinReadWait : Uint4B +0x7fa0 CcMdlReadNoWait : Uint4B +0x7fa4 CcMdlReadWait : Uint4B +0x7fa8 CcLazyWriteHotSpots : Uint4B +0x7fac CcLazyWriteIos : Uint4B +0x7fb0 CcLazyWritePages : Uint4B +0x7fb4 CcDataFlushes : Uint4B +0x7fb8 CcDataPages : Uint4B +0x7fbc CcLostDelayedWrites : Uint4B +0x7fc0 CcFastReadResourceMiss : Uint4B +0x7fc4 CcCopyReadWaitMiss : Uint4B +0x7fc8 CcFastMdlReadResourceMiss : Uint4B +0x7fcc CcMapDataNoWaitMiss : Uint4B +0x7fd0 CcMapDataWaitMiss : Uint4B +0x7fd4 CcPinReadNoWaitMiss : Uint4B +0x7fd8 CcPinReadWaitMiss : Uint4B +0x7fdc CcMdlReadNoWaitMiss : Uint4B +0x7fe0 CcMdlReadWaitMiss : Uint4B +0x7fe4 CcReadAheadIos : Uint4B +0x7fe8 MmCacheTransitionCount : Int4B +0x7fec MmCacheReadCount : Int4B +0x7ff0 MmCacheIoCount : Int4B +0x7ff4 PrcbPad91 : Uint4B +0x7ff8 MmInternal : Ptr64 Void +0x8000 PowerState : _PROCESSOR_POWER_STATE +0x8200 HyperPte : Ptr64 Void +0x8208 ScbList : _LIST_ENTRY +0x8218 ForceIdleDpc : _KDPC +0x8258 DpcWatchdogDpc : _KDPC +0x8298 DpcWatchdogTimer : _KTIMER +0x82d8 Cache : [5] _CACHE_DESCRIPTOR +0x8314 CacheCount : Uint4B +0x8318 CachedCommit : Uint4B +0x831c CachedResidentAvailable : Uint4B +0x8320 WheaInfo : Ptr64 Void +0x8328 EtwSupport : Ptr64 Void +0x8330 ExSaPageArray : Ptr64 Void +0x8338 KeAlignmentFixupCount : Uint4B +0x833c PrcbPad95 : Uint4B +0x8340 HypercallPageList : _SLIST_HEADER +0x8350 StatisticsPage : Ptr64 Uint8B +0x8358 GenerationTarget : Uint8B +0x8360 PrcbPad85 : [4] Uint8B +0x8380 HypercallCachedPages : Ptr64 Void +0x8388 VirtualApicAssist : Ptr64 Void +0x8390 PackageProcessorSet : _KAFFINITY_EX +0x8438 PackageId : Uint4B +0x843c PrcbPad86 : Uint4B +0x8440 SharedReadyQueueMask : Uint8B +0x8448 SharedReadyQueue : Ptr64 _KSHARED_READY_QUEUE +0x8450 SharedQueueScanOwner : Uint4B +0x8454 ScanSiblingIndex : Uint4B +0x8458 CoreProcessorSet : Uint8B +0x8460 ScanSiblingMask : Uint8B +0x8468 LLCMask : Uint8B +0x8470 CacheProcessorMask : [5] Uint8B +0x8498 ProcessorProfileControlArea : Ptr64 _PROCESSOR_PROFILE_CONTROL_AREA +0x84a0 ProfileEventIndexAddress : Ptr64 Void +0x84a8 DpcWatchdogProfile : Ptr64 Ptr64 Void +0x84b0 DpcWatchdogProfileCurrentEmptyCapture : Ptr64 Ptr64 Void +0x84b8 SchedulerAssist : Ptr64 Void +0x84c0 SynchCounters : _SYNCH_COUNTERS +0x8578 PrcbPad94 : Uint8B +0x8580 FsCounters : _FILESYSTEM_DISK_COUNTERS +0x8590 VendorString : [13] UChar +0x859d PrcbPad100 : [3] UChar +0x85a0 FeatureBits : Uint8B +0x85a8 UpdateSignature : _LARGE_INTEGER +0x85b0 PteBitCache : Uint8B +0x85b8 PteBitOffset : Uint4B +0x85bc PrcbPad105 : Uint4B +0x85c0 Context : Ptr64 _CONTEXT +0x85c8 ContextFlagsInit : Uint4B +0x85cc PrcbPad115 : Uint4B +0x85d0 ExtendedState : Ptr64 _XSAVE_AREA +0x85d8 IsrStack : Ptr64 Void +0x85e0 EntropyTimingState : _KENTROPY_TIMING_STATE +0x8730 PrcbPad110 : Uint8B +0x8738 StibpPairingTrace : +0x8770 AbSelfIoBoostsList : _SINGLE_LIST_ENTRY +0x8778 AbPropagateBoostsList : _SINGLE_LIST_ENTRY +0x8780 AbDpc : _KDPC +0x87c0 IoIrpStackProfilerCurrent : _IOP_IRP_STACK_PROFILER +0x8814 IoIrpStackProfilerPrevious : _IOP_IRP_STACK_PROFILER +0x8868 SecureFault : _KSECURE_FAULT_INFORMATION +0x8878 PrcbPad120 : Uint8B +0x8880 LocalSharedReadyQueue : _KSHARED_READY_QUEUE +0x8af0 PrcbPad125 : [2] Uint8B +0x8b00 TimerExpirationTraceCount : Uint4B +0x8b04 PrcbPad127 : Uint4B +0x8b08 TimerExpirationTrace : [16] _KTIMER_EXPIRATION_TRACE +0x8c08 PrcbPad128 : [7] Uint8B +0x8c40 Mailbox : Ptr64 _REQUEST_MAILBOX +0x8c48 PrcbPad130 : [7] Uint8B +0x8c80 McheckContext : [2] _MACHINE_CHECK_CONTEXT +0x8d20 PrcbPad134 : [4] Uint8B +0x8d40 SelfmapLockHandle : [4] _KLOCK_QUEUE_HANDLE +0x8da0 PrcbPad134a : [4] Uint8B +0x8dc0 PrcbPad138 : [128] UChar +0x8e40 PrcbPad138a : [64] UChar +0x8e80 KernelDirectoryTableBase : Uint8B +0x8e88 RspBaseShadow : Uint8B +0x8e90 UserRspShadow : Uint8B +0x8e98 ShadowFlags : Uint4B +0x8e9c PrcbPad138b : Uint4B +0x8ea0 PrcbPad138c : Uint8B +0x8ea8 PrcbPad138d : Uint2B +0x8eaa PrcbPad138e : Uint2B +0x8eac DbgMceNestingLevel : Uint4B +0x8eb0 DbgMceFlags : Uint4B +0x8eb4 PrcbPad139b : Uint4B +0x8eb8 PrcbPad140 : [505] Uint8B +0x9e80 PrcbPad140a : [8] Uint8B +0x9ec0 PrcbPad141 : [504] Uint8B +0xae80 PrcbPad141a : [64] UChar +0xaec0 RequestMailbox : [1] _REQUEST_MAILBOX 0: kd> ?? sizeof(nt!_KPRCB) unsigned int64 0xaf00

    opened by kouzhudong 0
  • Wrong offsets for KPCR::Prcb and others

    Wrong offsets for KPCR::Prcb and others

    And possibly others.

    Take this example: https://github.com/ntdiff/headers/blob/master/Win10_1909_19H2/x64/System32/ntoskrnl.exe/Standalone/_KPCR.h#L1331

    For all major compilers , the calculated offset is 0x178, not 0x180: https://godbolt.org/z/ZJ-DfV

    Edit: And if I use #pragma pack, the size is 0x174.


    Apparently the reason is:

    Curiously, PcrAlign1 does not by itself align the Prcb that follows. That Prcb is meant to be cache-aligned
    is certain: cache  alignment is plainly a recurring concern within the KPRCB and is obviously simpler to
    arrange if the KPRCB is itself cache aligned (which it isn’t for 32-bit Windows).
    

    Source

    opened by VelocityRa 4
  • Download symbols from microsoft public symbol server or other servers

    Download symbols from microsoft public symbol server or other servers

    Not needed but would be a pretty useful feature. Download symbols for a dll file, e.g.

    pdbex.exe * C:/windows/system32/ntdll.dll -o ntdll.h

    Similar to how IDA Pro and a few other tools do it. Make some class PDBSymbolDownloader, that would require using some HTTP lib, libcurl or something

    opened by bugproof 1
  • DataKind error always

    DataKind error always

    result of get_dataKind got error https://github.com/wbenny/pdbex/blob/master/Source/PDB.cpp#L621 because it should call from another context as example to here https://github.com/wbenny/pdbex/blob/master/Source/PDB.cpp#L863 and call by DiaChildSymbol-> and move DataKind from SYMBOL to SYMBOL_UDT_FIELD

    opened by marakew 0
  • incorrect condition for check result produce crash

    incorrect condition for check result produce crash

    if we have error for load dll at here https://github.com/wbenny/pdbex/blob/master/Source/PDB.cpp#L77 we are skip this condition https://github.com/wbenny/pdbex/blob/master/Source/PDB.cpp#L115 FAILED check for < 0 then we return FALSE so we crash when continue to deref pointer m_DataSource here https://github.com/wbenny/pdbex/blob/master/Source/PDB.cpp#L152

    opened by marakew 0
Owner
Petr Beneš
Petr Beneš
Repository of problems and solutions of labsheets used for Data Structures and Algorithms (CS F211) in Semester 2, 2020-21 at BITS Pilani - Hyderabad Campus.

CS F211 Data Structures and Algorithms (BITS Pilani - Hyderabad Campus) This repository contains the problems, solution approaches & explanations and

Rohit Dwivedula 27 Apr 13, 2022
Algo-Tree is a collection of Algorithms and data structures which are fundamentals to efficient code and good software design

Algo-Tree is a collection of Algorithms and data structures which are fundamentals to efficient code and good software design. Creating and designing excellent algorithms is required for being an exemplary programmer. It contains solutions in various languages such as C++, Python and Java.

DSC-Banasthali 53 Jun 12, 2022
Templates, algorithms and data structures implemented and collected for programming contests.

Templates, algorithms and data structures implemented and collected for programming contests.

Shahjalal Shohag 1.8k Jun 27, 2022
Easy to use, header only, macro generated, generic and type-safe Data Structures in C

C Macro Collections Easy to use, header only, macro generated, generic and type-safe Data Structures in C. Table of Contents Installation Contributing

Leonardo Vencovsky 307 Jun 28, 2022
🔗 Common Data Structures and Algorithms

?? Data Structures and Algorithms This library provides common data structures. It will also provide some data structures which needed in render or ga

Recep Aslantas 40 Jan 28, 2022
A collecton of generic reference counted data structures, tools to create compatible C style classes, and demo applications

The Offbrand library is a collection of reference counted generic data structures written in C for C. The library includes bash scripts to assist in t

Tyler Heck 82 Mar 4, 2022
An assortment of commonly used algorithms and data structures implemented with C++.

Algorithms-And-Data-Structures This repo contains C++ implementations of common algorithms and data structures, grouped by topics. The list will be sp

Tony Sheng 23 Nov 9, 2021
Wonderful library with lots of useful functions, algorithms and data structures in C, link it with -l9wada

Lib9wada Wonderful library with lots of useful functions, algorithms and data structures in C, link it with -l9wada Usage Compile the library with mak

Lprogrammers Lm9awdine 47 May 29, 2022
Wonderful library with lots of useful functions, algorithms and data structures in C, link it with -l9wada

LibC+ Wonderful library with lots of useful functions, algorithms and data structures in C, link it with -lC+ Better than C, not as much as c++ Usage

BnademOverflow 47 May 29, 2022
A collection of basic data structures syntaxes, useful for competitive coding and placement exams

Data-Structures A collection of basic data structures syntaxes, useful for competitive coding and placement exams 1. Array 2. Matrix 3. Linked List Si

MAINAK CHAUDHURI 2 Aug 8, 2021
The aim of this repository is to make it a one final stop for revision for technical interviews involving data structures and algorithms .

Hey ??‍♂️ This repository is meant for data structures and algorithms . I will be updating this often and will include all the data structures importa

Prakhar Rai 48 Jun 7, 2022
This is a beginner-friendly project aiming to build a problem-set on different data structures and algorithms in different programming languages.

DSAready Overview This is a beginner-friendly project that aims to create a problem-set for various Data Structures and Algorithms. Being a programmer

Riddhi Jain 12 Jun 12, 2022
A reverse engineering tool to interactively reconstruct structures and generate header files

ReGenny ReGenny is a reverse engineering tool to interactively reconstruct structures and generate usable C++ header files. Header file generation is

null 65 Jun 22, 2022
Explore the world of Data Structures and Algorithm

Hey Everyone! ?? DSA- PlayYard is the first open source project of Lets Grow More Community. It is the perfect place to start with or to test your DSA

LetsGrowMore 14 Nov 24, 2021
Postmodern immutable and persistent data structures for C++ — value semantics at scale

immer is a library of persistent and immutable data structures written in C++. These enable whole new kinds of architectures for interactive and concu

Juanpe Bolívar 2k Jun 27, 2022
Implementation of various data structures and algorithms.

Data Structures and Algorithms A place where you can find and learn the copious number of algorithms in an efficient manner. This repository covers va

Google DSC, GVP Chapter 13 Apr 8, 2022
Data Structures and Algorithms implemented in C++

OpenOcto - Data Structures and Algorithms Data Structures and Algorithms implemented in C++ Code here directly using Gitpod! Everthing done in C++ All

null 3 Oct 19, 2021
Data structures and algorithms course, winter 2021/22

Data Structures and Algorithms 2021/22 Repository for the "Data structures and algorithms" course for the 2021/22 academic year. Structure lectures --

Atanas Semerdzhiev 20 May 13, 2022
A repository by [email protected] for data structures and algorithms

DSA Overview The main goal of this project is to promote open-source, allowing anyone who wants to contribute. This repository would be focused on var

null 18 Jun 7, 2022