2011-07-27 12 views
1

は、私は、これは構造体で、勝利のAPIで使用されるC#での構造体を再作成しようとしている: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; 

私はわからないんだけど2人のメンバーがLIST_ENTRYであり、 UNICODE_STRING、どのように私は、これらはC#で模倣するのでしょうか?

+0

。私はP /呼び出しがうんざりするだろうというサーシャに同意するが、それは、ハード定型のだけたくさんではありません。 –

答えて

2

私はパーティーへの道遅刻だけど、私は個人的な「好奇心」プロジェクトのためにこれをしなければならなかった - 署名は、ように見える終わる:

IntPtr.ReadMemoryだけである
[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>(); } } 
    } 

拡張メソッド:あなたはこれを渡している機能

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

あなたのための私のアドバイスは、あなたがLDR_MODULEで使用する計画をしている機能のマネージC++ラッパーを作成することです。 PInvokeので、このような複雑な構造をしていることは多くの苦痛にあります。