web-dev-qa-db-ja.com

DLLによって公開されているすべての機能を見つける方法はありますか

私は、dllの関数名にマップするすべての文字列を取得する方法を探してきました。

これにより、GetProcAddressを呼び出すことができるすべての文字列を意味します。 dllの16進ダンプを行う場合、シンボル(文字列)はありますが、それらの名前を取得するためのシステムコールが必要だと考えています。

58
minty

少し手間がかかりますが、Microsoftの DbgHelp ライブラリを使用してプログラムでこれを行うことができます。

Microsoft .NetおよびMicrosoft Windows用のアプリケーションのデバッグ、John Robbinsによる は、使用の詳細と完全なソースを含む優れた(少し古い場合)本です。そして、あなたはアマゾンでそれを安く手に入れることができます!

7
Aaron

MS Visual Studioを使用している場合、DUMPBINと呼ばれるコマンドラインツールがあります。

dumpbin/exports <nameofdll>
71
Die in Sente

Windowsには3種類のDLLがあります。

  1. DLLのエクスポートテーブルで使用可能なすべての関数を公開するクラシックDLL。 Visual Studioのdumpbin.exeまたはdepend.exeを使用するか、無料の dependency walker を使用してこれらのタイプを調べることができます。 Matt Pietrekは、Win32 PEファイルを掘り下げるための多くの記事とユーティリティを書きました。彼の古典的な MSDN Magazineの記事 をご覧ください。エクスポートされたクラスを含むC++ DLLは、クラス内のすべてのメソッドをエクスポートします。残念ながら、マングルされた名前をエクスポートするため、dumpbinの出力は事実上読み取れません。出力をデマングルするには、vc ++ _ filt.exeなどのプログラムを使用する必要があります。

  2. COMオブジェクトを公開するCOM DLL。これらのDLLは、COMシステムがオブジェクトをインスタンス化できるようにする少数の通常のエクスポート関数(DllRegisterServerなど)を公開します。これらのDLLを見ることができるユーティリティは多数ありますが、タイプライブラリが埋め込まれていない限り、調べるのは非常に困難です。 4Developers 優れたCOM/ActiveXツールが多数あります

  3. .NETアセンブリを含む.NET DLL。通常、これらを調べるには 。NET Reflector のようなツールを使用します。

編集:4Developersリンクが機能しません。

33
Mike Thompson

また、 http://www.dependencywalker.com/ にDEPENDsプログラムがあります

24
Die in Sente

これを試してください(Linux)Cコード:

#include <fcntl.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

unsigned int vpe2offset(void * base, unsigned int vpe) {
    unsigned int * ptr = base;
    unsigned int pe_offset;
    unsigned short num_sections;

    pe_offset = ptr[0x3c/4];                             //PE header offset
    ptr = base + pe_offset;                              //PE header address
    num_sections = ((unsigned short*)ptr)[6/2];          //Section count
    ptr = ((void*)base) + 0x18 + 0x60 + 16*8 + pe_offset;//Address of first section

    while (num_sections--) {
        if (vpe >= ptr[0x0c/4] && vpe < ptr[0x0c/4] + ptr[0x10/4]) {
            return vpe - ptr[0x0c/4] + ptr[0x14/4];
        }
        ptr += 0x28/4;
    }

    return 0;
}

void iterate_exports(void * base, int(*iterator)(char*)) {
    unsigned int * ptr = base;
    unsigned int pe_offset,
                 exports_offset,
                 number_of_names,
                 address_of_names;

    pe_offset = ptr[0x3c/4];
    ptr = base + pe_offset;
    exports_offset = ptr[0x78/4];
    ptr = base + vpe2offset(base, exports_offset);
    number_of_names = ptr[0x18/4];
    address_of_names = ptr[0x20/4];
    ptr = base + vpe2offset(base, address_of_names);
    while (number_of_names-- && iterator((char*)(base + vpe2offset(base, ptr++[0])))) {
        /* Do nothing */
    }
}

int print_symbol_name(char * name) {
    printf("%s\n", name);
    return 1;
}

int main(int argc, char const *argv[]) {
    int fd;
    struct stat st;
    void * base;

    if (argc == 1) {
        printf("Usage: %s <dll>\n", argv[0]);
    } else if (stat(argv[1], &st) == 0 && (fd = open(argv[1], O_RDONLY)) >= 0) {
        base = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
        if (base != MAP_FAILED) {
            iterate_exports(base, print_symbol_name);
            munmap(base, st.st_size);
        } else {
            fprintf(stderr, "Could not map \"%s\".\n", argv[1]);
        }
        close(fd);
    } else {
        fprintf(stderr, "Could not open \"%s\" for reading.\n", argv[1]);
    }
    return 0;
}

PEファイル内の参照に従い、最後にエクスポートされたシンボルごとにコールバック関数を呼び出します。 PEファイル形式の概要については、以下を参照してください。 http://www.openrce.org/reference_library/files/reference/PE%20Format.pdf

16
Robert Larsen

私はそれを行うためのWIn32 APIを知りません:その代わりに、あなた(または他の投稿で言及されたツールの1つ)はPEファイルのバイナリ形式を知り、ファイルを読むことによってそれを行います:see http ://msdn.Microsoft.com/en-us/magazine/cc301808.aspx (およびその記事では「PEDUMP」ユーティリティについて言及されていました)。

10
ChrisW

dumpbinGUI を使用します。これにより、Windowsエクスプローラーで右クリックしてエクスポート(およびその他の)のリストが表示されます。 dumpbindependsは両方ともリストを提供します。

6
ctacke

最終的にはWindowsがとにかく行うので、.dllのPEヘッダーを検査する必要があります。

.dllの_IMAGE_OPTIONAL_HEADER_へのポインタがあると仮定します(dbghelpのImageNtHeader関数をLoadLibrary経由でロードされた.dllへのハンドルと共に使用するか、 .dllのレイアウトを自分で知っている)、_optional_header->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]_を見て、そこにオフセットがあるオプションのヘッダーに関連するエクスポートテーブルを見つけて、エクスポートテーブルを歩いてください(_IMAGE_EXPORT_DIRECTORY_)。

ファンシーの場合、後方互換性のあるPEイメージは_IMAGE_DOS_HEADER_で始まります。 _IMAGE_NT_HEADER_へのオフセットは_IMAGE_DOS_HEADER::e_lfanew_であり、_IMAGE_OPTIONAL_HEADER_はNTヘッダーに埋め込まれています。

5
MSN

使用できるdll export viewerというプログラムがあります。 http://www.nirsoft.net/utils/dll_export_viewer.html

2
nick

私はいつもこれをしなければなりません。これらのサイトの1つに行くだけです。彼らは通常必要な情報をホストします。

Windows 7 DLLファイル情報

Windows XP DLLファイル情報

2
claws

Windowsで「objdump」Linuxツールを使用することもできますが、最初にcygwinをインストールする必要があります。

次のコマンドを使用します。

# feed the output to less
objdump -x nameOfThe.Dll| less
# or use egrep to filter
objdump -x /cygdrive/c/Windows/system32/user32.dll | \ 
    egrep "^\s*\[[ [:digit:]]{4}\] \w{1,}" | less
1
SchLx

ランタイムまたは非常に役に立たないsystem( "dumpbin")で不明なdllの関数名を見つけたい場合は、PEファイルを解析し、自分で解体することになると思います。魔法。

あなたが望むものについてより明確にする必要があります。

[〜#〜] bfd [〜#〜] ライブラリは、いくつかのGNU binutilsツールの主要コンポーネントである、あなたが望むもの(およびキッチンシンク)を実行します。それがあなたの問題に合うかどうかはわかりません。

0
artificialidiot

ツールは必要なく、PEを解析する必要もありません。標準のWin32 API(D)を使用するだけです

コード(C)は、Adv.Win32 APIで何度も公開されています(news://comp.os.ms-windows.programmer.win32)(1992年以降...)

0
ferod