5

c++dllファイルの関数をテストするプログラムを作成したいとします。ユーザーがdllを選択できるようにする必要があります(c ++ dllについて話していると想定しています)。彼は、dllによってエクスポートされたすべての関数のリストを取得できるはずです。次に、ユーザーはリストから関数名を選択し、引数のリストを手動で入力して(引数はすべて、int、double、bool、char配列(c型文字列など)などの基本型)、次のことを実行できる必要があります。指定された引数を使用して、選択された関数を実行します。彼は、関数が指定された引数で実行されるかどうか、または関数がクラッシュする原因になるかどうかを知りたいと考えています(たとえば、署名と一致しないため)。

主な問題は、強い型の言語であるC ++では、コンパイル時に関数呼び出しの引数の数と型を知っている必要があることです。私の場合、これらの引数が何であるかは、ユーザーは実行時にそれらを選択します。

私が思いついた唯一の解決策は、アセンブリを使用して手動で引数を呼び出しスタックにプッシュすることでした。

ただし、アセンブリをいじりたい場合は、どの呼び出し規約がdllで使用されている関数であるかを確認したほうがよいことを理解するようになりました。

それで(最後に:)ここに私の質問があります:プログラムで呼び出し規約を推測できますか?Dependency Walkerは役に立ちません。また、PE形式を手動で読み取る方法がわかりません。

4

5 に答える 5

3

答えは多分です。

関数名がC++で装飾されている場合は、名前の装飾から引数の数と型を判別できます。これが最良のシナリオであり、最初にMSVCを使用してコードを記述した場合はかなり可能性があります。

エクスポートされた関数がstdcall呼び出し規約(Windows APIのデフォルト)である場合、プッシュするバイト数は決定できますが、引数のタイプは決定できません。

悪いニュースは、Cの呼び出し規約では、シンボル名を見てもわからないということです。ソースコードまたはデバッグ情報にアクセスできる必要があります。

http://en.wikipedia.org/wiki/X86_calling_conventions

関数にエクスポートとして指定される名前は、リンカーが認識する名前と関係がある必要はありませんが、ほとんどの場合、エクスポートされた名前とリンカーが認識するシンボル名は同じです。

于 2010-02-17T03:14:53.670 に答える
3

ここでは、32ビットと64ビットのどちらを話しているのかを指定していません。あなたと他のポスターが概説した問題は、主に32ビットコードに当てはまります。64ビットWindowsでは、基本的に呼び出し規約は1つだけです(John Knoellerによってリンクされているウィキペディアの記事にもあります)。つまり、呼び出し規約を知っているということですもちろん、自分で作成する人を除いて)。

また、Microsoft x64の呼び出し規約では、呼び出される関数のパラメーターの数がわからなくても、関数の呼び出しが妨げられることはなく、ユーザーが望むだけのパラメーターを提供できます。これは、呼び出し元としてスタックスペースを確保し、後でクリーンアップするためです。--もちろん、正しい[number of]パラメータを提供しないと、無効な入力を提供しているため、呼び出された関数がばかげたことをする可能性がありますが、それは別の話です。

于 2010-02-17T15:56:49.417 に答える
2

コンパイルされたコードは、「ここではこの関数はfastcallであり、この関数はstdcallです」とだけ言っているわけではありません。

IDAのような最新の逆アセンブラでさえ、デフォルトで呼び出しタイプを推測しようとはしません(プラグインまたはオプションがidkのどこかにある可能性があります)。

基本的に、あなたが人間である場合、最初のいくつかの指示を見て、90%の確率で話します。それらがポップアンドプッシュの場合、そのstdcall、レジスタ(特にecx)を介してパラメータを渡す場合、そのcdecl。Fastcallもレジスターを使用しますが、何か特別なことをします。しかし、あなたのプログラムは明らかに人間ではないので、このすべての情報は役に立ちません。

テストをしている場合、少なくともヘッダーファイルはありませんか?これは猫の皮を剥ぐのに非常に難しい方法です。

于 2010-02-17T02:55:33.297 に答える
0

C ++関数が使用する呼び出し規約を知りたい場合は、勉強することをお勧めします。

  1. その関数を宣言するヘッダー、および
  2. 特定のDLLをコンパイルしたコンパイラのドキュメント。

しかし、正直なところ、この全体は少し混乱しているように聞こえます。なぜあなたの友人はこれができるようになりたいのですか、そしてなぜ彼は関連する関数を宣言するヘッダーを解析することによって彼が必要とする情報を得ることができないのですか?

于 2010-02-17T02:55:42.883 に答える
0

このページでは、VC ++ 6がパラメーターと呼び出し規約情報をシンボル名にエンコードする方法について説明します:http ://www.bottledlight.com/docs/mangle.html

それ以降のバージョンのVC++には互換性があると思いますが、これは確認していません。

コンパイラに付属するこれを自動化するツールもいくつかあります:http://msdn.microsoft.com/en-us/library/5x49w699.aspx

名前マングリングはC++関数にのみ適用されます。関数が'extern"C"'の場合、これは機能しません。

于 2010-02-20T08:26:46.103 に答える