• ベストアンサー

DLL内に定義されている関数名の取得方法

GetProcAddressにて関数の有無を取得することはできますが、DLL内に定義されている関数名すべてを取得することは可能でしょうか?可能であれば、その方法をお教えください。よろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • xcrOSgS2wY
  • ベストアンサー率50% (1006/1985)
回答No.5

Debug Help (dbghelp)はVS6の頃にはまだ存在せず、VS.NETになって新たに登場したものですので、VS6ですと見つかりません。 Debug HelpはImage Help (imagehlp)の後継で、例示プログラム中で使用している定義の範囲ですとImage Helpのヘッダファイル(imagehlp.h)でも同様に使用できますので、dbghelp.hのかわりにimagehlp.hを参照してください。

shouichi5928
質問者

お礼

ありがとうございました。試してみてもまだうまく動作さられていない状態ですが、おおきなヒントになりました。もう少し調べてみます。

その他の回答 (4)

  • xcrOSgS2wY
  • ベストアンサー率50% (1006/1985)
回答No.4

調べたところ、dbghelp.dllを使用すると「めちゃめちゃ面倒」は「少々面倒」くらいで済むようです。 エラーチェックは適当ですが、ひとまず動作するCのプログラムを下記するので、適当にVBコードに変更してください。(すみません最初からVBのコードでなくて。) #include <windows.h> #include <winnt.h> #include <dbghelp.h> #include <stdio.h> #include <string.h> int main(int argc, char** argv) {   char* pszImageName = argv[argc - 1];   HANDLE hProcess = GetCurrentProcess();   SymInitialize(hProcess, "", FALSE);   DWORD dwBase = SymLoadModule(hProcess, NULL, pszImageName, NULL, 0, 0);   if (dwBase == 0) {     printf("SymLoadModule failed\n");     return 1;   }   DWORD dwSize;   PVOID pv = ImageDirectoryEntryToData((PVOID)(DWORD_PTR)dwBase, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &dwSize);   if (pv == NULL) {     printf("ImageDirectoryEntryToData failed\n");     return 2;   }   PIMAGE_EXPORT_DIRECTORY pImageExportDirectory = (PIMAGE_EXPORT_DIRECTORY)pv;   char** ppFunctionName = (char**)(DWORD_PTR)(pImageExportDirectory->AddressOfNames + dwBase);      DWORD dw;   for (dw = 0; dw < pImageExportDirectory->NumberOfNames; ++dw) {     printf("%3u: %s\n", dw, *ppFunctionName + dwBase);     ++ppFunctionName;   }   SymUnloadModule(hProcess, dwBase);   return 0; }

shouichi5928
質問者

お礼

どうもありがとうございます。このコードから拝見するに、指定されたファイル中のエクスポートされている関数をpImageExportDirectory変数から取り出してリストアップしているような感じですよね。そうすると命令群を取り出すのにはImageDirectoryEntryToData命令を使用する必要があるといった感じでしょうか?各命令の意味を調べてみます。

shouichi5928
質問者

補足

こんにちは。VCで試してみたのですが、dbghelp.hが見つからないようです。こちらではVS6で試したのですが、Program Files\VC98以下のフォルダにはないようです。Googleで検索すると、http://dotnet.di.unipi.it/Content/sscli/docs/doxygen/tools/sos/dbghelp_8h-source.html が引っかかったので、これをdbghelp.hファイルとして行番号を抜いてみて使用してみたのですが、うまくコンパイルできませんでした。dbghelp.hはどこかから入手することができるのでしょうか?手数をかけてすみません。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.3

#2>プログラムコードから調べる方法を探しています 最悪、プログラムからツールを実行し、ツールの出力をプログラムから取り込む(バカげてる?)こともできるかと思いますが。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.2

borlandのツールIMPDEFで関数名が取り出せますが、 そういうことでなかったらごめんなさい

shouichi5928
質問者

補足

お返事ありがとうございます。プログラムコードから調べる方法を探しています。こういったツールはどうやって命令を調べているのでしょうね。気になるところです。

  • xcrOSgS2wY
  • ベストアンサー率50% (1006/1985)
回答No.1

何か手軽なライブラリがあるといいんですけどね・・・ 私は 「An In-Depth Look into the Win32 Portable Executable File Format」 http://msdn.microsoft.com/msdnmag/issues/02/02/PE/default.aspx の記述に沿って、DLLファイルの中身をバイナリデータとしていちいち調べて使っていますが、めちゃめちゃ面倒です。

shouichi5928
質問者

お礼

ありがとうございます。うーむ。英語ドキュメントですね。でも少し目を通して見る必要がありそうな感じですね。Dependency Walker等はこのような方法で情報を取得しているのかも知れませんね。

関連するQ&A

  • Perlで定義されている関数名を全て取得する方法

    Perlで定義されている関数名を全て取得する方法はあるのでしょうか? ソースを見ればわかりますが、取得する方法があれば教えてください。 001.pl sub aaa{ print "a"; } 002.pl sub bbb{ print "b"; }

    • ベストアンサー
    • Perl
  • AfxLoadLibrary関数で、DLLのハンドルが取得できない

    はじめまして。 タイトルの通りですが、AfxLoadLibraryを使用して、DLLのハンドルを取得しようとしています。(取得したハンドルでGetProcAddress関数を使用する為) ここで、AfxLoadLibraryの戻り値となる、ハンドルがNULL(0x0000)となってしまい、GetProcAddressによる関数ポインタの設定が行えない状況となっています。 FormatMessage関数とGetLastErrorを使用し、原因を調べたところ、「指定されたモジュールが見つかりません」というメッセージとなりました。 AfxLoadLibraryで指定しているDLLについては、Exeファイルと同じフォルダ内に存在し、かつ、名前についても間違っていません。 試しに、別DLLを、上記NGとなるDLLと同様の名前で作成してみたところ、ハンドルの取得に成功したので、EXE側のコーディングミスという所は考えづらいところです。 お手数ですが、他の原因に心あたりがありましたらご教唆願います。 <コーディング(一部抜粋)> ---------------------------------------------------------------- HINSTANCE m_handle_Aaa; typedef WORD (WINAPI *LPOpenAaa)(); LPOpenAaa lpOpenAaa; BOOL DllLoad(void) { // Load Dll m_handle_Aaa = AfxLoadLibrary("AaaDLL.dll"); if(m_handle_Aaa < (HINSTANCE)HINSTANCE_ERROR) { PutLastError(); // Error Message return FALSE; } // Get Function Pointer lpOpenAaa = (LPOpenAaa)GetProcAddress( m_handle_Aaa, "OpenAaa"); if(lpOpenAaa == NULL) return FALSE; ・ ・ ・ ----------------------------------------------------------------

  • C/C++言語で変数名から変数のアドレスを取得する

    C/C++言語で変数名から変数のアドレスを取得する方法があれば、ご教示願います。 例えばですが、関数GetProcAddress()は、関数の文字列からエクスポート済みの関数のアドレスを戻り値で返しています。 GetProcAddress()と同じようにアドレスを取得したい変数名の文字列を渡して、変数のアドレスを取得したいです。 よろしくお願いします。

  • C++DLLの明示的リンクに関して

    DLLを明示的リンク(LoadLibraryとGetProcAddressを使用して)で使うとき、C言語では、関数名がそのまま利用できますが、C++では、オーバーロード機能があるため、関数名が変化してしまいます。C++でDLLを明示的リンクで使用するにはどうしたら良いのですか?

  • VC++6.0からVBで作成したActiveX.DLL内の関数が呼出しできない

    VB6.0で作成したActiveX.DLLをVC++6.0(Win32SDK)側で 呼び出すプログラムを作成中です。 VB側(DLL)では問題なく作成できています。 Classに1つPublic関数を作成しただけです。 (Instancingは5MultiUseにしてあります) しかし、VC++側の呼出しでDLL内の関数が 呼び出せないのです。 LoadLibraryExでDLL自体のハンドルは取得できるのですが GetProcAddressで関数の取得時にNULLが返ってきてしまいます。 今まで試したことは ・VBからの呼出しはOK ・MFCだとOK ・SDKでもuser32.dll呼出しのサンプルは関数も実行できる です。 今からMFCへ以降するのは厳しいのでSDkでの方法を 知りたいです。 VB側が悪いのかもしれませんが、関数1つですし、 いじるところもほとんどないので多分VC++側だと 思っています。 なにか注意点とか確認するところをおしえていただければ 幸いです。 環境 Windows2000 SP3 VB6.0 SP5 VC++6.0 SP5 Win32SDK

  • API関数とDLL関数

    API関数とDLL関数って同じものですか? ネットで調べると・・・ API関数=Win API→ひとつひとつの関数(単独で機能するプログラムコード の塊)。     API関数はdllファイルの中にある関数をさす。 とのようなことが書いてあります。つまり、DLL関数(私の認識であると、.dllファイルの中にある関数)であり、この関数はAPI関数と同定義と認識しています。 まだまだ初心者で、この認識があっているか確信がもてません。 どうか教えていただけないでしょうか?? お願いいたします。

  • VC#からdll関数を使う

    c#(vs2003)から、c++で書かれたdllの中に含まれる関数を読み込む部分を書いています。この関数は以下のように定義 され、構造体のポインタを返り値として返します。 SENSOR* GetSensor(); SENSOR構造体はdllの中では以下のように定義されています。 typedef struct{   int type; unsigned short param; char name[64]; DWORD con_pos; } SENSOR; これをc#のコードの中で読み込むため、c#のクラスの中で、以下のように再定義しました。 [StructLayout(LayoutKind.Sequential)] public struct SENSOR {   public int type;   public ushort param;   public string name;   public uint con_pos; } 後にc#のコードの中に、dllの中の関数を呼び出す定義を以下のように書きました。 [DllImport("sensor.dll"); public static extern SENSOR* GetSensor(); ここで SENSOR* sensor = GetSensor(); といった感じでdllをの関数を使って値を取得するようにしたのですが、実行すると 「return value をマーシャル できません : ポインタはマーシャルされた構造体を参照できません。」 といったエラーが出ます。いろいろと調べたのですが解決方法がわかりません。アドバイスをいただけたら幸いです。

  • DLLのLPSTR 項目の戻り値の取得について

    VB.NET初心者です。 C言語で作られたDLLの戻り値の取得で困ったことが発生しました。 どなたかが解決方法を教えてください。 -----------HHL5d.DLL定義(C言語)-----------  int HLFRecv ( LPSTR fileName ); ----------------------VB側宣言部---------- Declare Function HHLFRecvLib "HHL5d.DLL" _ (ByVal fileName As String) As Integer ※ fileName で指定された場所にファイルを書き込みます。 ・ 関数終了時には書き込んだファイルの(ファイル名を含んだ)フルパスがfileNameに上書きされます。 -----------VB側本文---------- Dim strRecvFile As String Dim intCnt As Integer  intRtn = HHLFRecv(strRecvFile) ※処理終了後に、strRecvFileにファイル名を含めたフルパスを戻したい。 byval定義の場合は、HHLFRecv関数内で変数の変更ができないため値の取得ができません・・ これを取得できるようにVB側の構文を書き換えたいのですが、方法がわかりません。 どなたかアドバイスをお願いいたします。

  • 関数定義の関数名の前にある&(アンパサンド)他

    関数定義で function &関数名() と関数名の前にアンパサンドを付けて定義しているものは、付けない普通の定義と何が違ってくるのでしょうか? あと、クラス関係で使われている::(コロン2つ)の使われ方がよくわかりません。 いくつかPHPの本を読みましたが上記2つのことについて明確に記述してあるものが見当たりませんでした。 ご教授お願いいたします。

    • ベストアンサー
    • PHP
  • VC++6.0からVB.NETで作成した関数を呼ぶことができますか?

    VB.NET(Visual Basic 2005 Express Edition)でクラスライブラリ(AAA.dll)を作成し、BBBというModuleにCCCというFunctionをひとつ作成しました。 そのFunctionをVC++6.0で作成したプログラムから呼び出すことは可能でしょうか?また、可能な場合はどのような手順で呼び出すことができるのでしょうか? ■VB6.0でDLLを作成した場合 DLLのファイル名とFunction名さえ指定すればVC++6.0よりLoadLibrary、GetProcAddress関数を使用して呼び出せる。 ■VB.NETでDLLを作成した場合 DLLのファイル名+Module名+Function名という構成になってしまい、従来のLoadLibrary、GetProcAddress関数ではModule名が指定できないように思われるのですが・・・どうなんでしょう。 ご存知の方いらっしゃいましたらご教授お願いいたしますm(_ _)m

専門家に質問してみよう