1

私のプロジェクトは.cファイルと.dllファイルを検査する必要があります。それらの情報を組み合わせて、何を呼び出すかを決定し、それを呼び出します。

dllを調べて、どのdllにどの機能があるかを確認する必要があります。dllを初期化せずにメモリにマップするところまで来ました。ここで、ヘッダーを何かにマップして、呼び出し可能な名前が含まれているセクションを読み取る必要があります。

どうやってやるの?これはこれまでのコードです:

    [DllImport("kernel32.dll")]
    static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hReservedNull, LoadLibraryFlags dwFlags);

    public static string[] GetFKTNames(string dll)
    {
        IntPtr lib = LoadLibraryEx(dll, IntPtr.Zero, LoadLibraryFlags.DONT_RESOLVE_DLL_REFERENCES);

        //INDICATES WHAT I WANT TO DO, BUT DOES NOT WORk
        //Header header = GetHeader(lib);
        //Unload(lib);
        //return header.Names;
}

編集#2:

私は少し進歩し、今日はそれをやめました...ここドイツでは4日間の無料の日が来ています...

そのマーシャリングが正しいかどうかは完全にはわかりません。テストする方法がありませんでした。私はそのトピックに関する本を読みたいので、そのヘッダーがどのように機能するか、そしてそこにどのような異なるヘッダーがあるかを説明する良い本を知っているならコメントしてください。

    private static List<string> ListDLLFunctions(string sADllName)
    {
        List<string> names = new List<string>();
        IntPtr LoadedImage = LoadLibraryEx(sADllName, IntPtr.Zero, LoadLibraryFlags.DONT_RESOLVE_DLL_REFERENCES);

        IMAGE_NT_HEADERS header = (IMAGE_NT_HEADERS) Marshal.PtrToStructure(libPtr, typeof(IMAGE_NT_HEADERS));

        //    ImageExportDirectory = (_IMAGE_EXPORT_DIRECTORY*)
        //        ImageDirectoryEntryToData(LoadedImage.MappedAddress,
        //        false, IMAGE_DIRECTORY_ENTRY_EXPORT, &cDirSize);
        //    if (ImageExportDirectory != NULL)
        //    {
        //        dNameRVAs = (DWORD *)ImageRvaToVa(LoadedImage.FileHeader, 
        //            LoadedImage.MappedAddress,
        //        ImageExportDirectory->AddressOfNames, NULL);
        //        for(size_t i = 0; i < ImageExportDirectory->NumberOfNames; i++)
        //        {
        //            sName = (char *)ImageRvaToVa(LoadedImage.FileHeader, 
        //                    LoadedImage.MappedAddress,
        //                   dNameRVAs[i], NULL);
        //         slListOfDllFunctions.push_back(sName);
        //        }
        //    }
        FreeLibrary(LoadedImage);
        return names;
    }

    static void Main(string[] args)
    {
        List<string> names = ListDLLFunctions("KERNEL32.DLL");
    }
4

3 に答える 3

1

あなたのためにそれを行うことができる「ワンコール」関数はありません。dllをロードし、エクスポートテーブルで名前を探す必要があります。

C ++でそれを行うためのいくつかのコードを含む投稿があります-多分あなたはそれをc#に移植しようとすることができます

于 2012-04-05T11:02:12.873 に答える
0

コードからではありませんが、私は通常コンソールから使用します

Dllのエクスポートを確認するためのDumpBinユーティリティ。

Process.Start(..)必要な情報を取得するために、そのツールを使用してその出力を解析できると思います。

お役に立てれば。

于 2012-04-05T10:30:02.777 に答える
0

私は自分のユースケースの問題を解決しました:

libをmomoryにロードし、それをbytearrayにコピーしてから、PE情報を使用して調査します。

このトピックには、私を大いに助けてくれた便利なリソースがいくつかあります。

レトロスペックでは、他のアプローチを使用して情報を取得する方法を理解しています。私が書いたクラスは、PEを学び、いくつかのdllを探索するのに最適です。PEがどのように機能するかを把握したい場合は、クラスを書き直すことをお勧めします。

クラスは次のとおりです。

public class DLLHelper
{
    private byte[] dllInMemory;
    private UInt32 PESizeOfImage;
    private UInt32 VA_PE;

    [DllImport("kernel32.dll")]
    static public extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hReservedNull, LoadLibraryFlags dwFlags);

    [DllImport("kernel32.dll")]
    static public extern bool FreeLibrary(IntPtr hModule);

    public enum LoadLibraryFlags : uint
    {
        DONT_RESOLVE_DLL_REFERENCES = 0x00000001,
        LOAD_IGNORE_CODE_AUTHZ_LEVEL = 0x00000010,
        LOAD_LIBRARY_AS_DATAFILE = 0x00000002,
        LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE = 0x00000040,
        LOAD_LIBRARY_AS_IMAGE_RESOURCE = 0x00000020,
        LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008
    }


    public DLLHelper(string dllpath)
    {
        PESizeOfImage = GetDllSizeInMemory(dllpath);
        dllInMemory = GetDLLCopy(dllpath, PESizeOfImage);
        UInt32 VA_p_PE = 0x3C;
        VA_PE = Get4ByteFromLocation(VA_p_PE, dllInMemory);
    }

    private byte[] GetDLLCopy(string dllpath, uint PESizeOfImage)
    {
        IntPtr libPtr = LoadLibraryEx(dllpath, IntPtr.Zero, LoadLibraryFlags.DONT_RESOLVE_DLL_REFERENCES);
        byte[] dllInMemory = new byte[PESizeOfImage];
        Marshal.Copy(libPtr, dllInMemory, 0, (int)PESizeOfImage);
        FreeLibrary(libPtr);
        return dllInMemory;
    }

    private UInt32 GetDllSizeInMemory(string dllpath)
    {
        byte[] dllpreload = File.ReadAllBytes(dllpath);
        UInt32 pp_PE = 0x3C;
        UInt32 p_PE = Get4ByteFromLocation(pp_PE, dllpreload);
        UInt32 p_PEOPTIONALHEADER = p_PE + 0x18;
        UInt32 p_PESizeOfImage = p_PEOPTIONALHEADER + 0x38;
        return Get4ByteFromLocation(p_PESizeOfImage, dllpreload);
    }

    public void DumpToFile(String filename)
    {
        File.WriteAllBytes(filename, dllInMemory);
    }

    public string GetDLLName()
    {
        UInt32 VAExport = GetVAExport(VA_PE, dllInMemory);
        UInt32 VAName = GetVAName(VAExport, dllInMemory);
        String Name = GetString(VAName, dllInMemory);
        return Name;
    }

    public List<String> GetFunctionNames()
    {
        List<String> fkts = new List<String>();
        UInt32 VAExport = GetVAExport(VA_PE, dllInMemory);
        UInt32 VA_p_firstFKT = GetVA_p_firstFKT(VAExport, dllInMemory);
        UInt32 VA_p_lastFKT = GetVA_p_lastFKT(VAExport, dllInMemory);
        for (UInt32 VA_p_fkt = VA_p_firstFKT; VA_p_fkt <= VA_p_lastFKT; VA_p_fkt += sizeof(UInt32))
        {
            UInt32 VA_fkt = Get4ByteFromLocation(VA_p_fkt, dllInMemory);
            fkts.Add(GetString(VA_fkt, dllInMemory));
        }
        return fkts;
    }

    private UInt32 GetVA_p_lastFKT(UInt32 VAExport, byte[] dllInMemory)
    {
        UInt32 first = GetVA_p_firstFKT(VAExport, dllInMemory);
        UInt32 count = GetfktCount(VAExport, dllInMemory);
        UInt32 last = first + (count - 1) * sizeof(UInt32);
        return last;
    }

    private UInt32 GetfktCount(UInt32 VAExport, byte[] dllInMemory)
    {
        UInt32 RVA_Count = 0x14;
        UInt32 VA_Count = VAExport + RVA_Count;
        return Get4ByteFromLocation(VA_Count, dllInMemory);
    }

    private UInt32 GetVA_p_firstFKT(UInt32 VAExport, byte[] dllInMemory)
    {
        UInt32 RVA_p_FIRST = 0x20;
        UInt32 VA_p_FIRST = VAExport + RVA_p_FIRST;
        return Get4ByteFromLocation(VA_p_FIRST, dllInMemory);
    }

    private UInt32 GetVAName(UInt32 VAExport, byte[] dllInMemory)
    {
        UInt32 RVA_p_NAME = 0x0C;
        UInt32 VA_p_NAME = VAExport + RVA_p_NAME;
        return Get4ByteFromLocation(VA_p_NAME, dllInMemory);
    }

    private UInt32 GetVAExport(UInt32 VAPE, byte[] dllInMemory)
    {
        UInt32 RVA_p_EXPORT = 0x78;
        UInt32 VA_p_EXPORT = VAPE + RVA_p_EXPORT;
        return Get4ByteFromLocation(VA_p_EXPORT, dllInMemory);
    }

   string GetString(UInt32 location, byte[] dll)
    {
        int length = 0;
        while (dll[location + length] != 0x00)
        {
            length++;
        }
        if (location > int.MaxValue) throw new Exception("uncastable");
        return Encoding.UTF8.GetString(dll, (int)location, length);
    }

   private UInt32 Get4ByteFromLocation(UInt32 location, byte[] dll)
   {
       if (!(BitConverter.IsLittleEndian))
       {
           byte[] partial = GetByteSubset(4, location, dll);
           Array.Reverse(partial);
           return BitConverter.ToUInt32(partial, 0);
       }
       return BitConverter.ToUInt32(dll, (int)location);
   }

   private byte[] GetByteSubset(int size, UInt32 location, byte[] dll)
   {
       byte[] val = new byte[size];
       for (int i = 0; i < size; i++)
       {
           val[i] = dll[location + i];
       }
       return val;
   }
}
于 2012-04-13T15:54:22.910 に答える