我正在尝试在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#中模仿这些?
答案 0 :(得分:3)
我的建议是为计划与LDR_MODULE一起使用的函数创建托管C ++包装器。用pinvoke做这种复杂的结构会非常痛苦。
答案 1 :(得分:3)
我来参加派对的时间已经很晚了,但我只是为了个人的“好奇心项目”而这么做 - 签名最终看起来像:
[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;
}