4

exitたとえば、次のコードに示すように、呼び出し関数をインターセプトするためにヒッポモックが何をするのか疑問に思っています。

   MockRepository mocks;
   mocks.ExpectCallFunc(exit).With(2).Throw(std::exception());
4

2 に答える 2

6

渡された関数 (この場合は単純な関数ポインター) を char * にキャストし、OS に書き込みを許可するように適切に要求し (Unices では mprotect を使用し、Windows では VirtualProtect を使用)、最初の 5 から 14 バイトを変更します。無条件ジャンプ命令になります。生成された (テンプレートを使用して) 同一の署名を持つ関数のアドレスを配置し、関数を効果的にオーバーライドします。

必要に応じて、HippoMocks のコードを直接再利用できます。これには、適切な引数を使用してスタック上にクラス Replace のオブジェクトを作成します。コードをコピーすることもできます (GitHub の最新の hippomocks.h では、32/64 ビット x86、ARM、および親指の両方がサポートされています)。200号線あたりなので比較的高い位置にあります。さらに、dororable_cast クラスと Unprotect クラスもコピーする必要があります。1 つ目はメンバー関数ポインターを他の型にキャストできるようにし (reinterpret_cast では不可能)、2 つ目は OS 固有の保護解除 (および再保護) 呼び出しをラップします。

C++11 のコードをクリーンアップする際に、このサブセットを正確に抽出したので、detail/replace.h ファイルを使用して、これを行うコードだけを取得できます。直接リンクについては、https://github.com/dascandy/hippomocks/blob/cpp11/HippoMocks/detail/replace.hを参照してください。

于 2014-08-28T14:11:28.773 に答える
5

インターセプトを行うコードは にありhippomocks.hます。メモリ保護フラグを変更して、提供された関数ポインタのアドレスへの書き込みを許可し、関数の最初のバイトの代わりにジャンプ命令を書き込みます。フックが不要になると、元のバイトが復元されます。これは、 Microsoft Detoursライブラリなどで使用されているのと同じアプローチです。

于 2014-08-01T12:12:03.760 に答える