Migrate many models to StructLayout

This commit is contained in:
Matt Nadareski
2024-04-23 13:30:43 -04:00
parent b19dbf2254
commit c636d3252b
112 changed files with 1044 additions and 646 deletions

View File

@@ -1,31 +1,35 @@
namespace SabreTools.Models.PortableExecutable
using System.Runtime.InteropServices;
namespace SabreTools.Models.PortableExecutable
{
/// <summary>
/// Describes the data in an individual accelerator table resource. The structure definition
/// provided here is for explanation only; it is not present in any standard header file.
/// </summary>
/// <see href="https://learn.microsoft.com/en-us/windows/win32/menurc/acceltableentry"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class AcceleratorTableEntry
{
/// <summary>
/// Describes keyboard accelerator characteristics.
/// </summary>
public AcceleratorTableFlags Flags { get; set; }
[MarshalAs(UnmanagedType.U2)]
public AcceleratorTableFlags Flags;
/// <summary>
/// An ANSI character value or a virtual-key code that identifies the accelerator key.
/// </summary>
public ushort Ansi { get; set; }
public ushort Ansi;
/// <summary>
/// An identifier for the keyboard accelerator. This is the value passed to the window
/// procedure when the user presses the specified key.
/// </summary>
public ushort Id { get; set; }
public ushort Id;
/// <summary>
/// The number of bytes inserted to ensure that the structure is aligned on a DWORD boundary.
/// </summary>
public ushort Padding { get; set; }
public ushort Padding;
}
}

View File

@@ -1,9 +1,12 @@
namespace SabreTools.Models.PortableExecutable
using System.Runtime.InteropServices;
namespace SabreTools.Models.PortableExecutable
{
/// <summary>
/// Type or Offset field entry is a WORD (2 bytes).
/// </summary>
/// <see href="https://learn.microsoft.com/en-us/windows/win32/debug/pe-format"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class BaseRelocationTypeOffsetFieldEntry
{
/// <summary>

View File

@@ -1,4 +1,6 @@
namespace SabreTools.Models.PortableExecutable
using System.Runtime.InteropServices;
namespace SabreTools.Models.PortableExecutable
{
/// <summary>
/// At the beginning of an object file, or immediately after the signature
@@ -6,48 +8,51 @@
/// Note that the Windows loader limits the number of sections to 96.
/// </summary>
/// <see href="https://learn.microsoft.com/en-us/windows/win32/debug/pe-format"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class COFFFileHeader
{
/// <summary>
/// The number that identifies the type of target machine.
/// </summary>
public MachineType Machine { get; set; }
[MarshalAs(UnmanagedType.U2)]
public MachineType Machine;
/// <summary>
/// The number of sections. This indicates the size of the section table,
/// which immediately follows the headers.
/// </summary>
public ushort NumberOfSections { get; set; }
public ushort NumberOfSections;
/// <summary>
/// The low 32 bits of the number of seconds since 00:00 January 1, 1970
/// (a C run-time time_t value), which indicates when the file was created.
/// </summary>
public uint TimeDateStamp { get; set; }
public uint TimeDateStamp;
/// <summary>
/// The file offset of the COFF symbol table, or zero if no COFF symbol table
/// is present. This value should be zero for an image because COFF debugging
/// information is deprecated.
/// </summary>
public uint PointerToSymbolTable { get; set; }
public uint PointerToSymbolTable;
/// <summary>
/// The number of entries in the symbol table. This data can be used to locate
/// the string table, which immediately follows the symbol table. This value
/// should be zero for an image because COFF debugging information is deprecated.
/// </summary>
public uint NumberOfSymbols { get; set; }
public uint NumberOfSymbols;
/// <summary>
/// The size of the optional header, which is required for executable files but
/// not for object files. This value should be zero for an object file.
/// </summary>
public ushort SizeOfOptionalHeader { get; set; }
public ushort SizeOfOptionalHeader;
/// <summary>
/// The flags that indicate the attributes of the file.
/// </summary>
public Characteristics Characteristics { get; set; }
[MarshalAs(UnmanagedType.U2)]
public Characteristics Characteristics;
}
}

View File

@@ -1,4 +1,6 @@
namespace SabreTools.Models.PortableExecutable
using System.Runtime.InteropServices;
namespace SabreTools.Models.PortableExecutable
{
/// <summary>
/// Object files contain COFF relocations, which specify how the section data
@@ -15,6 +17,7 @@
/// specified in the section header.
/// </summary>
/// <see href="https://learn.microsoft.com/en-us/windows/win32/debug/pe-format"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class COFFRelocation
{
/// <summary>
@@ -24,7 +27,7 @@
/// For example, if the first byte of the section has an address of 0x10,
/// the third byte has an address of 0x12.
/// </summary>
public uint VirtualAddress { get; set; }
public uint VirtualAddress;
/// <summary>
/// A zero-based index into the symbol table. This symbol gives the address
@@ -32,12 +35,13 @@
/// storage class, then the symbol's address is the address with the first
/// section of the same name.
/// </summary>
public uint SymbolTableIndex { get; set; }
public uint SymbolTableIndex;
/// <summary>
/// A value that indicates the kind of relocation that should be performed.
/// Valid relocation types depend on machine type.
/// </summary>
public RelocationType TypeIndicator { get; set; }
[MarshalAs(UnmanagedType.U2)]
public RelocationType TypeIndicator;
}
}

View File

@@ -1,4 +1,6 @@
namespace SabreTools.Models.PortableExecutable
using System.Runtime.InteropServices;
namespace SabreTools.Models.PortableExecutable
{
/// <summary>
/// Each data directory gives the address and size of a table or string that Windows uses.
@@ -9,6 +11,7 @@
/// that the sections that contain specific tables have specific names.
/// </summary>
/// <see href="https://learn.microsoft.com/en-us/windows/win32/debug/pe-format"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class DataDirectory
{
/// <summary>
@@ -16,11 +19,11 @@
/// is the address of the table relative to the base address of the image when
/// the table is loaded.
/// </summary>
public uint VirtualAddress { get; set; }
public uint VirtualAddress;
/// <summary>
/// The second field gives the size in bytes.
/// </summary>
public uint Size { get; set; }
public uint Size;
}
}

View File

@@ -1,4 +1,6 @@
namespace SabreTools.Models.PortableExecutable
using System.Runtime.InteropServices;
namespace SabreTools.Models.PortableExecutable
{
/// <summary>
/// Image files contain an optional debug directory that indicates what form
@@ -17,47 +19,49 @@
/// RVA is its address.
/// </summary>
/// <see href="https://learn.microsoft.com/en-us/windows/win32/debug/pe-format"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class DebugDirectoryEntry
{
/// <summary>
/// Reserved, must be zero.
/// </summary>
public uint Characteristics { get; set; }
public uint Characteristics;
/// <summary>
/// The time and date that the debug data was created.
/// </summary>
public uint TimeDateStamp { get; set; }
public uint TimeDateStamp;
/// <summary>
/// The major version number of the debug data format.
/// </summary>
public ushort MajorVersion { get; set; }
public ushort MajorVersion;
/// <summary>
/// The minor version number of the debug data format.
/// </summary>
public ushort MinorVersion { get; set; }
public ushort MinorVersion;
/// <summary>
/// The format of debugging information. This field enables support
/// of multiple debuggers.
/// </summary>
public DebugType DebugType { get; set; }
[MarshalAs(UnmanagedType.U4)]
public DebugType DebugType;
/// <summary>
/// The size of the debug data (not including the debug directory itself).
/// </summary>
public uint SizeOfData { get; set; }
public uint SizeOfData;
/// <summary>
/// The address of the debug data when loaded, relative to the image base.
/// </summary>
public uint AddressOfRawData { get; set; }
public uint AddressOfRawData;
/// <summary>
/// The file pointer to the debug data.
/// </summary>
public uint PointerToRawData { get; set; }
public uint PointerToRawData;
}
}

View File

@@ -1,4 +1,6 @@
namespace SabreTools.Models.PortableExecutable
using System.Runtime.InteropServices;
namespace SabreTools.Models.PortableExecutable
{
/// <summary>
/// The delay-load directory table is the counterpart to the import directory
@@ -6,6 +8,7 @@
/// the optional header data directories list (offset 200).
/// </summary>
/// <see href="https://learn.microsoft.com/en-us/windows/win32/debug/pe-format"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class DelayLoadDirectoryTable
{
/// <summary>
@@ -17,7 +20,7 @@
/// indicating the presence of new fields, or it can be used to indicate
/// behaviors to the delay or unload helper functions.
/// </remarks>
public uint Attributes { get; set; }
public uint Attributes;
/// <summary>
/// The RVA of the name of the DLL to be loaded. The name resides in the
@@ -27,7 +30,7 @@
/// The name of the DLL to be delay-loaded resides in the read-only data
/// section of the image. It is referenced through the szName field.
/// </remarks>
public uint Name { get; set; }
public uint Name;
/// <summary>
/// The RVA of the module handle (in the data section of the image) of the DLL
@@ -39,7 +42,7 @@
/// The phmod field points to the handle. The supplied delay-load helper uses
/// this location to store the handle to the loaded DLL.
/// </remarks>
public uint ModuleHandle { get; set; }
public uint ModuleHandle;
/// <summary>
/// The RVA of the delay-load import address table.
@@ -51,7 +54,7 @@
/// the calling loop. The function pointers are accessed by using the expression
/// pINT->u1.Function.
/// </remarks>
public uint DelayImportAddressTable { get; set; }
public uint DelayImportAddressTable;
/// <summary>
/// The RVA of the delay-load name table, which contains the names of the imports
@@ -63,7 +66,7 @@
/// in the IAT. They consist of the same structures as the standard INT and are
/// accessed by using the expression pINT->u1.AddressOfData->Name[0].
/// </remarks>
public uint DelayImportNameTable { get; set; }
public uint DelayImportNameTable;
/// <summary>
/// The RVA of the bound delay-load address table, if it exists.
@@ -73,7 +76,7 @@
/// IMAGE_THUNK_DATA items that is used along with the timestamp field of the
/// delay-load directory table by a post-process binding phase.
/// </remarks>
public uint BoundDelayImportTable { get; set; }
public uint BoundDelayImportTable;
/// <summary>
/// The RVA of the unload delay-load address table, if it exists. This is an exact
@@ -89,7 +92,7 @@
/// On the unload request, the library can be freed, the *phmod cleared, and the
/// UIAT written over the IAT to restore everything to its preload state.
/// </remarks>
public uint UnloadDelayImportTable { get; set; }
public uint UnloadDelayImportTable;
/// <summary>
/// The timestamp of the DLL to which this image has been bound.
@@ -99,6 +102,6 @@
/// IMAGE_THUNK_DATA items that is used along with the timestamp field of the
/// delay-load directory table by a post-process binding phase.
/// </remarks>
public uint TimeStamp { get; set; }
public uint TimeStamp;
}
}

View File

@@ -42,7 +42,7 @@ namespace SabreTools.Models.PortableExecutable
LastEntry = 0x80,
}
public enum BaseRelocationTypes : uint
public enum BaseRelocationTypes : ushort
{
/// <summary>
/// The base relocation is skipped. This type can be used to pad a block.

View File

@@ -1,85 +1,92 @@
namespace SabreTools.Models.PortableExecutable
using System.Runtime.InteropServices;
namespace SabreTools.Models.PortableExecutable
{
/// <summary>
/// Contains version information for a file. This information is language and
/// code page independent.
/// </summary>
/// <see href="https://learn.microsoft.com/en-us/windows/win32/api/verrsrc/ns-verrsrc-vs_fixedfileinfo"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class FixedFileInfo
{
/// <summary>
/// Contains the value 0xFEEF04BD. This is used with the szKey member of the VS_VERSIONINFO
/// structure when searching a file for the FixedFileInfo structure.
/// </summary>
public uint Signature { get; set; }
public uint Signature;
/// <summary>
/// The binary version number of this structure. The high-order word of this member contains
/// the major version number, and the low-order word contains the minor version number.
/// </summary>
public uint StrucVersion { get; set; }
public uint StrucVersion;
/// <summary>
/// The most significant 32 bits of the file's binary version number. This member is used with
/// FileVersionLS to form a 64-bit value used for numeric comparisons.
/// </summary>
public uint FileVersionMS { get; set; }
public uint FileVersionMS;
/// <summary>
/// The least significant 32 bits of the file's binary version number. This member is used with
/// FileVersionMS to form a 64-bit value used for numeric comparisons.
/// </summary>
public uint FileVersionLS { get; set; }
public uint FileVersionLS;
/// <summary>
/// The most significant 32 bits of the binary version number of the product with which this file
/// was distributed. This member is used with ProductVersionLS to form a 64-bit value used for
/// numeric comparisons.
/// </summary>
public uint ProductVersionMS { get; set; }
public uint ProductVersionMS;
/// <summary>
/// The least significant 32 bits of the binary version number of the product with which this file
/// was distributed. This member is used with ProductVersionMS to form a 64-bit value used for
/// numeric comparisons.
/// </summary>
public uint ProductVersionLS { get; set; }
public uint ProductVersionLS;
/// <summary>
/// Contains a bitmask that specifies the valid bits in FileFlags. A bit is valid only if it was
/// defined when the file was created.
/// </summary>
public uint FileFlagsMask { get; set; }
public uint FileFlagsMask;
/// <summary>
/// Contains a bitmask that specifies the Boolean attributes of the file.
/// </summary>
public FixedFileInfoFlags FileFlags { get; set; }
[MarshalAs(UnmanagedType.U4)]
public FixedFileInfoFlags FileFlags;
/// <summary>
/// The operating system for which this file was designed.
/// </summary>
public FixedFileInfoOS FileOS { get; set; }
[MarshalAs(UnmanagedType.U4)]
public FixedFileInfoOS FileOS;
/// <summary>
/// The general type of file.
/// </summary>
public FixedFileInfoFileType FileType { get; set; }
[MarshalAs(UnmanagedType.U4)]
public FixedFileInfoFileType FileType;
/// <summary>
/// The function of the file. The possible values depend on the value of FileType. For all values
/// of FileType not described in the following list, FileSubtype is zero.
/// </summary>
public FixedFileInfoFileSubtype FileSubtype { get; set; }
[MarshalAs(UnmanagedType.U4)]
public FixedFileInfoFileSubtype FileSubtype;
/// <summary>
/// The most significant 32 bits of the file's 64-bit binary creation date and time stamp.
/// </summary>
public uint FileDateMS { get; set; }
public uint FileDateMS;
/// <summary>
/// The least significant 32 bits of the file's 64-bit binary creation date and time stamp.
/// </summary>
public uint FileDateLS { get; set; }
public uint FileDateLS;
}
}

View File

@@ -1,22 +1,25 @@
namespace SabreTools.Models.PortableExecutable
using System.Runtime.InteropServices;
namespace SabreTools.Models.PortableExecutable
{
/// <summary>
/// Contains version information for the menu resource. The structure definition provided
/// here is for explanation only; it is not present in any standard header file.
/// </summary>
/// <see href="https://learn.microsoft.com/en-us/windows/win32/menurc/menuheader"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class MenuHeader
{
/// <summary>
/// The version number of the menu template. This member must be equal to zero to indicate
/// that this is an RT_MENU created with a standard menu template.
/// </summary>
public ushort Version { get; set; }
public ushort Version;
/// <summary>
/// The size of the menu template header. This value is zero for menus you create with a
/// standard menu template.
/// </summary>
public ushort HeaderSize { get; set; }
public ushort HeaderSize;
}
}

View File

@@ -1,27 +1,30 @@
namespace SabreTools.Models.PortableExecutable
using System.Runtime.InteropServices;
namespace SabreTools.Models.PortableExecutable
{
/// <summary>
/// Defines the header for an extended menu template. This structure definition is for
/// explanation only; it is not present in any standard header file.
/// </summary>
/// <see href="https://learn.microsoft.com/en-us/windows/win32/menurc/menuex-template-header"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class MenuHeaderExtended
{
/// <summary>
/// The template version number. This member must be 1 for extended menu templates.
/// </summary>
public ushort Version { get; set; }
public ushort Version;
/// <summary>
/// The offset to the first MENUEX_TEMPLATE_ITEM structure, relative to the end of
/// this structure member. If the first item definition immediately follows the
/// dwHelpId member, this member should be 4.
/// </summary>
public ushort Offset { get; set; }
public ushort Offset;
/// <summary>
/// The help identifier of menu bar.
/// </summary>
public uint HelpID { get; set; }
public uint HelpID;
}
}

View File

@@ -1,27 +1,30 @@
namespace SabreTools.Models.PortableExecutable
using System.Runtime.InteropServices;
namespace SabreTools.Models.PortableExecutable
{
/// <summary>
/// Contains information about message strings with identifiers in the range indicated
/// by the LowId and HighId members.
/// </summary>
/// <see href="https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-message_resource_block"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class MessageResourceBlock
{
/// <summary>
/// The lowest message identifier contained within this structure.
/// </summary>
public uint LowId { get; set; }
public uint LowId;
/// <summary>
/// The highest message identifier contained within this structure.
/// </summary>
public uint HighId { get; set; }
public uint HighId;
/// <summary>
/// The offset, in bytes, from the beginning of the MESSAGE_RESOURCE_DATA structure to the
/// MESSAGE_RESOURCE_ENTRY structures in this MESSAGE_RESOURCE_BLOCK. The MESSAGE_RESOURCE_ENTRY
/// structures contain the message strings.
/// </summary>
public uint OffsetToEntries { get; set; }
public uint OffsetToEntries;
}
}

View File

@@ -1,4 +1,6 @@
namespace SabreTools.Models.PortableExecutable
using System.Runtime.InteropServices;
namespace SabreTools.Models.PortableExecutable
{
/// <summary>
/// Contains the number of icon or cursor components in a resource group. The
@@ -6,23 +8,24 @@
/// in any standard header file.
/// </summary>
/// <see href="https://learn.microsoft.com/en-us/windows/win32/menurc/newheader"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class NewHeader
{
/// <summary>
/// Reserved; must be zero.
/// </summary>
public ushort Reserved { get; set; }
public ushort Reserved;
/// <summary>
/// The resource type. This member must have one of the following values.
/// - RES_ICON (1): Icon resource type.
/// - RES_CURSOR (2): Cursor resource type.
/// </summary>
public ushort ResType { get; set; }
public ushort ResType;
/// <summary>
/// The number of icon or cursor components in the resource group.
/// </summary>
public ushort ResCount { get; set; }
public ushort ResCount;
}
}

View File

@@ -1,4 +1,6 @@
namespace SabreTools.Models.PortableExecutable
using System.Runtime.InteropServices;
namespace SabreTools.Models.PortableExecutable
{
/// <summary>
/// Contains information about the resource header itself and the data specific to
@@ -7,6 +9,7 @@
/// explanation only; it is not present in any standard header file.
/// </summary>
/// <see href="https://learn.microsoft.com/en-us/windows/win32/menurc/resourceheader"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class ResourceHeader
{
/// <summary>
@@ -14,12 +17,12 @@
/// particular resource. It does not include any file padding between this
/// resource and any resource that follows it in the resource file.
/// </summary>
public uint DataSize { get; set; }
public uint DataSize;
/// <summary>
/// The size, in bytes, of the resource header data that follows.
/// </summary>
public uint HeaderSize { get; set; }
public uint HeaderSize;
/// <summary>
/// The resource type. The TYPE member can either be a numeric value or a
@@ -32,7 +35,8 @@
///
/// Values less than 256 are reserved for system use.
/// </summary>
public ResourceType ResourceType { get; set; }
[MarshalAs(UnmanagedType.U4)]
public ResourceType ResourceType;
/// <summary>
/// A name that identifies the particular resource. The NAME member, like the TYPE
@@ -44,13 +48,13 @@
/// members because they contain WORD data. However, you may need to add a WORD of
/// padding after the NAME member to align the rest of the header on DWORD boundaries.
/// </summary>
public uint Name { get; set; }
public uint Name;
/// <summary>
/// A predefined resource data version. This will determine which version of the
/// resource data the application should use.
/// </summary>
public uint DataVersion { get; set; }
public uint DataVersion;
/// <summary>
/// A set of attribute flags that can describe the state of the resource. Modifiers
@@ -62,7 +66,8 @@
/// ignored. Resources are loaded when the corresponding module is loaded, and are
/// freed when the module is unloaded.
/// </summary>
public MemoryFlags MemoryFlags { get; set; }
[MarshalAs(UnmanagedType.U2)]
public MemoryFlags MemoryFlags;
/// <summary>
/// The language for the resource or set of resources. Set the value for this member
@@ -75,20 +80,20 @@
/// the strings within the resources, you will need to specify a LanguageId for each
/// one.
/// </summary>
public ushort LanguageId { get; set; }
public ushort LanguageId;
/// <summary>
/// A user-defined version number for the resource data that tools can use to read and
/// write resource files. Set this value with the optional VERSION resource definition
/// statement.
/// </summary>
public uint Version { get; set; }
public uint Version;
/// <summary>
/// Specifies user-defined information about the resource that tools can use to read and
/// write resource files. Set this value with the optional CHARACTERISTICS resource
/// definition statement.
/// </summary>
public uint Characteristics { get; set; }
public uint Characteristics;
}
}

View File

@@ -1,4 +1,6 @@
namespace SabreTools.Models.PortableExecutable
using System.Runtime.InteropServices;
namespace SabreTools.Models.PortableExecutable
{
/// <summary>
/// Overlay data associated with SecuROM executables
@@ -8,60 +10,62 @@
/// environment by using sample from legally obtained software that
/// is protected by SecuROM.
/// </remarks>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public sealed class SecuROMAddDEntry
{
/// <summary>
/// Physical offset of the embedded file
/// </summary>
public uint PhysicalOffset { get; set; }
public uint PhysicalOffset;
/// <summary>
/// Length of the embedded file
/// </summary>
/// <remarks>The last entry seems to be 4 bytes short in 4.47.00.0039</remarks>
public uint Length { get; set; }
public uint Length;
/// <summary>
/// Unknown (0x08)
/// </summary>
/// <remarks>3149224 [3496, 48] in the sample (all 3 entries) in 4.47.00.0039</remarks>
public uint Unknown08h { get; set; }
public uint Unknown08h;
/// <summary>
/// Unknown (0x0C)
/// </summary>
/// <remarks>3147176 [1448, 48] in the sample (all 3 entries) in 4.47.00.0039</remarks>
public uint Unknown0Ch { get; set; }
public uint Unknown0Ch;
/// <summary>
/// Unknown (0x10)
/// </summary>
/// <remarks>3149224 [3496, 48] in the sample (all 3 entries) in 4.47.00.0039</remarks>
public uint Unknown10h { get; set; }
public uint Unknown10h;
/// <summary>
/// Unknown (0x14)
/// </summary>
/// <remarks>1245044 [65396, 18] in the sample (all 3 entries) in 4.47.00.0039</remarks>
public uint Unknown14h { get; set; }
public uint Unknown14h;
/// <summary>
/// Unknown (0x18)
/// </summary>
/// <remarks>4214725 [20421, 64] in the sample (all 3 entries) in 4.47.00.0039</remarks>
public uint Unknown18h { get; set; }
public uint Unknown18h;
/// <summary>
/// Unknown (0x1C)
/// </summary>
/// <remarks>2 [2, 0] in the sample (all 3 entries) in 4.47.00.0039</remarks>
public uint Unknown1Ch { get; set; }
public uint Unknown1Ch;
/// <summary>
/// Entry file name (null-terminated)
/// </summary>
/// <remarks>12 bytes long in the sample (all 3 entries) in 4.47.00.0039</remarks>
public string? FileName { get; set; }
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 12)]
public string? FileName;
/// <summary>
/// Unknown (0x2C)
@@ -70,6 +74,6 @@
/// Offset based on consistent-sized filenames (12 bytes) in 4.47.00.0039
/// 132 [132, 0] in the sample (all 3 entries) in 4.47.00.0039
/// </remarks>
public uint Unknown2Ch { get; set; }
public uint Unknown2Ch;
}
}