読者です 読者をやめる 読者になる 読者になる

Natural Software

KinectなどのDepthセンサーを中心に活動しています

DLL内の関数名を取得

プログラム C++ C言語 Win32

おもしろかったなりよ@東方算程譚
こいつをこの時間に1時間ほど見てしまった^^;


WinUnit は DLL から直接関数名を取得している、とのことで忘れないうちにやってみた。


WinUnit のソースをちょいと解析して発見。
コードはほぼ WinUnit のパクリ^^;
ただ、これ作ってる最中に調べものしてたら、CodeZineに同じようなのが載ってた(;´Д`)


それでも諦めずに、上記リンク先のDLLを食わすとこんなカンジ(sqlite3.dll もいれとかないと Test.dll が読めなかった)。


以下、テストコード(ご使用は自己責任で^^;)
サンプルプロジェクト

#include <windows.h>
#include <iostream>
#include <stdexcept>

#define MakePtr(cast, ptr, addValue) (cast)((DWORD_PTR)(ptr) + (DWORD_PTR)(addValue))

void main( int argc, char* argv[] )
{
    HMODULE hModule = 0;

    try {
        if ( argc != 2 ) {
            throw std::runtime_error( "argc != 2" );
        }

        std::cout << "File name is " << argv[1] << std::endl;

        hModule = ::LoadLibrary( argv[1] );
        if ( hModule == 0 ) {
            throw std::runtime_error( "LoadLibrary failed" );
        }

        PIMAGE_DOS_HEADER pDOSHeader = (PIMAGE_DOS_HEADER)hModule ;

        // Is this the MZ header?
        if ( IsBadReadPtr( pDOSHeader, sizeof(IMAGE_DOS_HEADER) ) || (IMAGE_DOS_SIGNATURE != pDOSHeader->e_magic) ) {
            throw std::runtime_error( "Invalid PE" );
        }

        // Get the PE header.
        PIMAGE_NT_HEADERS pNTHeader = MakePtr( PIMAGE_NT_HEADERS, pDOSHeader, pDOSHeader->e_lfanew);

        // Is this a real PE image?
        if (IsBadReadPtr(pNTHeader, sizeof(IMAGE_NT_HEADERS)) ||
            (IMAGE_NT_SIGNATURE != pNTHeader->Signature)) {
            throw std::runtime_error( "Invalid PE signature" );
        }

        // If there is no exports section, leave now.
        DWORD VirtualAddress = pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
        if ( VirtualAddress == 0 ) {
            throw std::runtime_error( "No exports found" );
        }

        // Get the pointer to the exports section.
        PIMAGE_EXPORT_DIRECTORY pImageExportDirectory = MakePtr( PIMAGE_EXPORT_DIRECTORY, pDOSHeader, VirtualAddress );

        DWORD* pszFuncNames = MakePtr( DWORD*, hModule, pImageExportDirectory->AddressOfNames );
        for ( int i = 0; i < pImageExportDirectory->NumberOfNames; ++i ) {
            const char* exportName = MakePtr( const char*, hModule, pszFuncNames[i] );
            std::cout << exportName << std::endl;
        }
    }
    catch ( std::exception& ex ) {
        std::cout << ex.what() << std::endl;
    }

    if ( hModule != 0 ) {
        ::FreeLibrary( hModule );
    }
}