我正在尝试在C#中重新创建将与Win API一起使用的结构,这是该结构:

typedef struct _LDR_MODULE {
  LIST_ENTRY              InLoadOrderModuleList;
  LIST_ENTRY              InMemoryOrderModuleList;
  LIST_ENTRY              InInitializationOrderModuleList;
  PVOID                   BaseAddress;
  PVOID                   EntryPoint;
  ULONG                   SizeOfImage;
  UNICODE_STRING          FullDllName;
  UNICODE_STRING          BaseDllName;
  ULONG                   Flags;
  SHORT                   LoadCount;
  SHORT                   TlsIndex;
  LIST_ENTRY              HashTableEntry;
  ULONG                   TimeDateStamp;
} LDR_MODULE, *PLDR_MODULE;


我不确定的两个成员是LIST_ENTRY和UNICODE_STRING,我将如何在C#中模拟它们?

最佳答案

我来晚了,但是我只是要做一个个人的“好奇心项目”-签名最终看起来像:

    [StructLayout(LayoutKind.Sequential, Pack = 0)]
    public struct LIST_ENTRY
    {
        public IntPtr Flink;
        public IntPtr Blink;

        public ListEntryWrapper Fwd
        {
            get
            {
                var fwdAddr = Flink.ToInt32();
                return new ListEntryWrapper()
                {
                    Header = Flink.ReadMemory<LIST_ENTRY>(),
                        Body = new IntPtr(fwdAddr + Marshal.SizeOf(typeof(LIST_ENTRY))).ReadMemory<LDR_MODULE>()
                };
            }
        }
        public ListEntryWrapper Back
        {
            get
            {
                var fwdAddr = Blink.ToInt32();
                return new ListEntryWrapper()
                {
                    Header = Flink.ReadMemory<LIST_ENTRY>(),
                    Body = new IntPtr(fwdAddr + Marshal.SizeOf(typeof(LIST_ENTRY))).ReadMemory<LDR_MODULE>()
                };
            }
        }
    }

    [StructLayout(LayoutKind.Sequential, Pack = 0)]
    public struct ListEntryWrapper
    {
        public LIST_ENTRY Header;
        public LDR_MODULE Body;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct UNICODE_STRING : IDisposable
    {
        public ushort Length;
        public ushort MaximumLength;
        private IntPtr buffer;

        public UNICODE_STRING(string s)
        {
            Length = (ushort)(s.Length * 2);
            MaximumLength = (ushort)(Length + 2);
            buffer = Marshal.StringToHGlobalUni(s);
        }

        public void Dispose()
        {
            Marshal.FreeHGlobal(buffer);
            buffer = IntPtr.Zero;
        }

        public override string ToString()
        {
            return Marshal.PtrToStringUni(buffer);
        }
    }

    [StructLayout(LayoutKind.Sequential, Pack = 0)]
    public struct PEB_LDR_DATA
    {
        public int Length;
        public int Initialized;
        public int SsHandle;
        public IntPtr InLoadOrderModuleListPtr;
        public IntPtr InMemoryOrderModuleListPtr;
        public IntPtr InInitOrderModuleListPtr;
        public int EntryInProgress;
        public ListEntryWrapper InLoadOrderModuleList { get { return InLoadOrderModuleListPtr.ReadMemory<ListEntryWrapper>(); } }
        public ListEntryWrapper InMemoryOrderModuleList { get { return InLoadOrderModuleListPtr.ReadMemory<ListEntryWrapper>(); } }
        public ListEntryWrapper InInitOrderModuleList { get { return InLoadOrderModuleListPtr.ReadMemory<ListEntryWrapper>(); } }
    }


其中IntPtr.ReadMemory只是扩展方法:

    public static T ReadMemory<T>(this IntPtr atAddress)
    {
        var ret = (T)Marshal.PtrToStructure(atAddress, typeof (T));
        return ret;
    }

10-08 20:20