2016-04-09 9 views
2

私はそのアドレスを使用して関数をフックしようとしていますが、これまでは全体的にうまくいっています!coutとフックされた関数を使用するとアプリケーションがクラッシュする

唯一の問題は、std::coutをWinAPIのフック付きのMessageBoxAと組み合わせて使用​​すると、クラッシュします。関数アドレスでの命令が直接32を返すように奇妙なことがあり、それだけで、それがテストのためにprintfまたは単にint i = MessageBoxA(...);

との組み合わせで呼び出されたいない場合は、その特定の場合にクラッシュし、私が作りました。 私が知っているフックはあまりありませんが、これはテスト用です。そして、それだけでクラッシュ

int i = MessageBoxA(NULL, "Hello World", "Injector", MB_OK); 

printf("Works: %d\n", i); 
printf("Works: %d\n", MessageBoxA(NULL, "Hello World", "Injector", MB_OK)); 

std::cout << "Works: " << i << std::endl; 
std::cout << "Doesn't: " << MessageBoxA(NULL, "Hello World", "Injector", MB_OK) << std::endl; 

printf("Hello World\n"); 

:今、私は基本的にはちょうど

memcpy(MessageBoxA, instructions, instructionCount); 

を行い、その後、VirtualProtect()と地域に を保護を変更することに加えて

// mov eax, 32 
// ret 
const DWORD instructionCount = 6; 
BYTE instructions[instructionCount] = { 0xB8, 0x20, 0x00, 0x00, 0x00, 0xC3 }; 

は今、これを使用して、それをテスト std::cout << MessageBoxA(...)以降。その行を削除すると、すべて動作します!

32が正常に印刷されることに注意してください。次の文に達するとクラッシュします。

Application Crash

は再びそれので、これを使用して、唯一それが動作しない場合である。

そして上記のコードを再利用し、並びに( testFunctionから MessageBoxAを変更
__declspec(noinline) int testFunction(int i) 
{ 
    return i; 
} 

議論)、そして今すべての4つの声明が働く!


ボトムラインの理由は何ですか?その特定のケースでクラッシュを引き起こしている理由は何ですか?他のケースは完全に正常に動作します。

+1

これをデバッガで実行し、クラッシュするポイントにasm、レジスタ、およびスタックバックトレースを表示します。 MessageBoxAはどのような呼び出し規約を使用していますか?それはスタックからargsをポップすることになっていますか?その場合、呼び出しコードはargsをプッシュし、呼び出された関数がスタックをクリーンアップすることを期待しています(win64 ABIがregに最初の4つのargを入れるため、32ビットコードにのみ適用可能です)。 –

+0

'std :: cout <<"はしません: "<<(int)MessageBoxA(NULL、" Hello World "、" Injector "、MB_OK)<< std :: endl; –

+0

@AdamMartinは同じエラーになります。 – Vallentin

答えて

2

私は問題があなたがスタックポインタを破壊していると思います。次を使用してみてください:ピーター・コルドが述べたようにスタックから引数をポップします

const DWORD instructionCount = 8; BYTE instructions[instructionCount] = { 0xB8, 0x20, 0x00, 0x00, 0x00, 0xC2, 0x10, 0x0 };

。希望が役立ちます。

+0

私は@PeterCordesのコメントを理解していましたが、私はそれを修正する方法を視覚化できませんでした(私はアセンブリでは決して動作しません)。しかし、あなたはそのトリックに答えます!どうもありがとう! – Vallentin

関連する問題