2011-07-27 55 views
1

我試圖重新在C#中,這將與Win API使用的結構,這是結構:LIST_ENTRY和UNICODE_STRING PInvoke的C#

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

你將這個函數傳遞給哪個函數。我同意Sasha P/invoke會令人厭煩,但並不難,只是很多樣板。 –

回答

2

我來的方式遲到了,但我必須爲個人的「好奇心工程」做到這一點 - 簽名結束看起來像:

[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; 
    } 
2

我的建議是爲您打算使用LDR_MODULE的函數創建託管C++包裝器。做這樣複雜的結構與pinvoke是非常痛苦。