私は、dllの関数名にマップするすべての文字列を取得する方法を探してきました。
これにより、GetProcAddressを呼び出すことができるすべての文字列を意味します。 dllの16進ダンプを行う場合、シンボル(文字列)はありますが、それらの名前を取得するためのシステムコールが必要だと考えています。
少し手間がかかりますが、Microsoftの DbgHelp ライブラリを使用してプログラムでこれを行うことができます。
Microsoft .NetおよびMicrosoft Windows用のアプリケーションのデバッグ、John Robbinsによる は、使用の詳細と完全なソースを含む優れた(少し古い場合)本です。そして、あなたはアマゾンでそれを安く手に入れることができます!
MS Visual Studioを使用している場合、DUMPBINと呼ばれるコマンドラインツールがあります。
dumpbin/exports <nameofdll>
Windowsには3種類のDLLがあります。
DLLのエクスポートテーブルで使用可能なすべての関数を公開するクラシックDLL。 Visual Studioのdumpbin.exeまたはdepend.exeを使用するか、無料の dependency walker を使用してこれらのタイプを調べることができます。 Matt Pietrekは、Win32 PEファイルを掘り下げるための多くの記事とユーティリティを書きました。彼の古典的な MSDN Magazineの記事 をご覧ください。エクスポートされたクラスを含むC++ DLLは、クラス内のすべてのメソッドをエクスポートします。残念ながら、マングルされた名前をエクスポートするため、dumpbinの出力は事実上読み取れません。出力をデマングルするには、vc ++ _ filt.exeなどのプログラムを使用する必要があります。
COMオブジェクトを公開するCOM DLL。これらのDLLは、COMシステムがオブジェクトをインスタンス化できるようにする少数の通常のエクスポート関数(DllRegisterServerなど)を公開します。これらのDLLを見ることができるユーティリティは多数ありますが、タイプライブラリが埋め込まれていない限り、調べるのは非常に困難です。 4Developers 優れたCOM/ActiveXツールが多数あります
.NETアセンブリを含む.NET DLL。通常、これらを調べるには 。NET Reflector のようなツールを使用します。
編集:4Developersリンクが機能しません。
また、 http://www.dependencywalker.com/ にDEPENDsプログラムがあります
これを試してください(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
私はそれを行うためのWIn32 APIを知りません:その代わりに、あなた(または他の投稿で言及されたツールの1つ)はPEファイルのバイナリ形式を知り、ファイルを読むことによってそれを行います:see http ://msdn.Microsoft.com/en-us/magazine/cc301808.aspx (およびその記事では「PEDUMP」ユーティリティについて言及されていました)。
dumpbinGUI を使用します。これにより、Windowsエクスプローラーで右クリックしてエクスポート(およびその他の)のリストが表示されます。 dumpbin
とdepends
は両方ともリストを提供します。
最終的には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ヘッダーに埋め込まれています。
使用できるdll export viewerというプログラムがあります。 http://www.nirsoft.net/utils/dll_export_viewer.html
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
ランタイムまたは非常に役に立たないsystem( "dumpbin")で不明なdllの関数名を見つけたい場合は、PEファイルを解析し、自分で解体することになると思います。魔法。
あなたが望むものについてより明確にする必要があります。
[〜#〜] bfd [〜#〜] ライブラリは、いくつかのGNU binutilsツールの主要コンポーネントである、あなたが望むもの(およびキッチンシンク)を実行します。それがあなたの問題に合うかどうかはわかりません。
ツールは必要なく、PEを解析する必要もありません。標準のWin32 API(D)を使用するだけです
コード(C)は、Adv.Win32 APIで何度も公開されています(news://comp.os.ms-windows.programmer.win32)(1992年以降...)