From 590cbcae2b25030abf35a19b171345a502933b50 Mon Sep 17 00:00:00 2001 From: James Forshaw Date: Mon, 19 Aug 2024 13:02:37 -0700 Subject: [PATCH] Added structure alignment types. --- NtApiDotNet/Ndr/NdrSimpleTypes.cs | 4 +++ NtApiDotNet/Ndr/NdrStructureTypes.cs | 41 ++++++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/NtApiDotNet/Ndr/NdrSimpleTypes.cs b/NtApiDotNet/Ndr/NdrSimpleTypes.cs index a728c74a..e9df7de5 100644 --- a/NtApiDotNet/Ndr/NdrSimpleTypes.cs +++ b/NtApiDotNet/Ndr/NdrSimpleTypes.cs @@ -620,6 +620,10 @@ internal static NdrBaseTypeReference Read(NdrParseContext context, BinaryReader case NdrFormatCharacter.FC_STRUCTPAD6: case NdrFormatCharacter.FC_STRUCTPAD7: return new NdrStructurePaddingTypeReference(format); + case NdrFormatCharacter.FC_ALIGNM2: + case NdrFormatCharacter.FC_ALIGNM4: + case NdrFormatCharacter.FC_ALIGNM8: + return new NdrStructureAlignTypeReference(format); case NdrFormatCharacter.FC_IGNORE: return new NdrIgnoreTypeReference(); case NdrFormatCharacter.FC_SYSTEM_HANDLE: diff --git a/NtApiDotNet/Ndr/NdrStructureTypes.cs b/NtApiDotNet/Ndr/NdrStructureTypes.cs index 9d6f815c..4575e75f 100644 --- a/NtApiDotNet/Ndr/NdrStructureTypes.cs +++ b/NtApiDotNet/Ndr/NdrStructureTypes.cs @@ -81,11 +81,18 @@ protected virtual List PopulateMembers() int current_offset = 0; foreach (var type in _base_members) { - if (!(type is NdrStructurePaddingTypeReference)) + if (type is NdrStructureAlignTypeReference align) { - members.Add(new NdrStructureMember(type, current_offset, $"Member{current_offset:X}")); + current_offset = align.Align(current_offset); + } + else + { + if (!(type is NdrStructurePaddingTypeReference)) + { + members.Add(new NdrStructureMember(type, current_offset, $"Member{current_offset:X}")); + } + current_offset += type.GetSize(); } - current_offset += type.GetSize(); } return members; } @@ -311,6 +318,34 @@ public override int GetSize() } } + [Serializable] + public sealed class NdrStructureAlignTypeReference : NdrBaseTypeReference + { + internal NdrStructureAlignTypeReference(NdrFormatCharacter format) : base(format) + { + } + + internal int Align(int offset) + { + switch (Format) + { + case NdrFormatCharacter.FC_ALIGNM2: + return (offset + 1) & ~1; + case NdrFormatCharacter.FC_ALIGNM4: + return (offset + 3) & ~3; + case NdrFormatCharacter.FC_ALIGNM8: + return (offset + 7) & ~7; + default: + throw new InvalidOperationException("Format must be an alignment."); + } + } + + public override int GetSize() + { + return 0; + } + } + [Serializable] public sealed class NdrPointerInfoInstance {