2011-01-28 18 views
4

私はC++、C#とPHPの人にはあまり良くありません。私はGetTickCountを使用してアプリケーションにフックするプロジェクトが割り当てられています。私はいくつかの理由でそれが計画どおりに動作していないためにいくつかの助けが必要...ここではフックのコードは、私はそれが以前にプロジェクトでそれを使用しているので、私は知っている。私はそれについて確信していない唯一のものはGetTickCountの一部です。私はGetTickCount64(私はそれに注入していたものをクラッシュしなかった)私の問題への修正だと思ったが、代わりにそれがクラッシュしないように全く働いていないことを知った。ここでC++でGetTickCountをフックする

bool APIENTRY DllMain(HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved) 
{ 
switch(dwReason) 
{ 
case DLL_PROCESS_ATTACH: 

    DisableThreadLibraryCalls(hDll); 
    CreateThread(0,0, (LPTHREAD_START_ROUTINE)KeyHooks, 0, 0, 0); 
    GetTickCount_orig = (DWORD (__stdcall *)(void))DetourFunction((PBYTE)GetProcAddress(GetModuleHandle("kernel32.dll"), "GetTickCount"), (PBYTE)GetTickCount_hooked); 

case DLL_PROCESS_DETACH: 
    DetourRemove((PBYTE)GetProcAddress(GetModuleHandle("kernel32.dll"), "GetTickCount"), (PBYTE)GetTickCount_hooked); 

    break; 
} 
return true; 
} 

GetTickCount

DWORD oldtick=0; 
DWORD (WINAPI *GetTickCount_orig)(void); 
DWORD WINAPI GetTickCount_hooked(void) 
{ 
if(oldtick==0) 
{ 
    oldtick=(*GetTickCount_orig)(); 
    return oldtick; 
} 
DWORD factor; 
DWORD ret; 

ret = (*GetTickCount_orig)(); 
factor = 3.0; 
DWORD newret; 

newret = ret+((oldtick-ret)*(factor-1)); 

oldtick=ret; 
return newret; 
} 

のために使用されるコードの残りの部分である、あなたは間違っているか、それが変更されなければならないものを見ることができますか?どんな助けもありがとうございます。ありがとうございました!

+0

実際の問題は何ですか? – wj32

+0

アプリを挿入しようとするとクラッシュします。私のQueryPerformanceCounterは問題なく問題なく注入します。 – E3pO

+9

'DLL_PROCESS_DETACH'の前に' break; 'を置くのはどうですか?今すぐ書かれているように - あなたはすぐに初期化の後にあなたのフックを削除します – valdo

答えて

1

oldtickを変更しないでください!

あなたは一度だけ、それを保存する必要があり、その後、

// accelerating time by factor of "factor" 
return oldtick + (realtick - oldtick) * factor; 

EDIT:

別の可能性のある問題は(少なくとも私のコンピュータ上で、XP 32ビット)GetTickCountは、標準的な「hookableを持っていないということです「preamle:

8B FF  mov  edi, edi 
55  push ebp 
8B EC  mov  ebp, esp 

それがなければ、それはIATからだけフックすることができ、これはそれを呼び出す各モジュールのために行われる必要があります。私はDetourFunctionがプロセスごとに動作すると考えているので、プリアンブルを使ってAPIをフックします。

これを解決するには、各モジュールのIATをフックするか手動でパッチを当てることができますが、フックされている間は元のバージョンを呼び出すことはできません。

EDIT2:ジャンプを使用するのが最も一般的な方法ですが、これは関数の先頭に5バイトを上書きする必要があることを意味します。主な問題は関数のサイズではなく、コードの開始点です。もちろん、何かを上書きすることもできますが、フックがオンになっている間(この質問のように)古い関数を呼び出せるようにするには、何を上書きしているかを知る必要があります。
オペコードの半分を上書きしたくないので、上書きされた部分を実行する必要があります。つまり、一般的なケースでは、完全逆アセンブラが必要です。

簡素化するために、ほとんどの機能は2バイトのNOP:mov edi, ediで始まります。そのため、プリアンブルには標準的で再配置が容易な5バイトがあります。

+0

私はDetoursが恣意的な指示ではうまくいかないほど馬鹿だとは思わない。彼らは引っ掛けのための "トランポリン"アイデアを考え出した人ではありませんか? – wj32

+0

@ wj32:なぜ、ほとんどのWin32 APIがこの 'mov edi、edi'で始まるのですか? – ruslik

+0

これは、問題が 'oldtick =(* GetTickCount_orig)();)のようです。 return oldtick; ' – E3pO

3

「KeyHooks」スレッドとはなんですか? detoured APIを呼び出す予定の場合は、スレッドを作成する前に迂回する必要があります。

GetTickCount_origは設定されていますか?

GetTickCountは、非常に短いAPIで、Detoursの問題を引き起こす可能性があります(フックインするのに十分なバイト数ではありません)。

DetourRemoveはGetTickCount64ではなくGetTickCount64を削除しています。

Detoursが機能していない場合は、ライセンスがはるかに簡単なmhookライブラリがあります。

+0

Keyhooksがやっているのは、ユーザーがShiftキーを押しているかどうかを確認することです。 (GetAsyncKeyState(0x14)){makemetrue = true;} Sleep(50);}}また、GetTickCount_origが設定されているかどうかわかりません。私はGetTickCount64を持っていないとき、私は何を注入しようとしているのか、それはクラッシュします。 – E3pO

+0

デバッガを取得し、GetTickCount_origが設定されているかどうかを確認します。また、欠けているbreak文についての上記のvaldoのポイントを見てください(私はそれを見ていないとは信じられません:) –

関連する問題