2

Microsoftの迂回ライブラリをダウンロードしてコンパイルしました。プロジェクト内にヘッダーファイルをインクルードし、依存関係として.libファイルを追加しました。すべてがエラーなしでコンパイルされます。今、私はDrawTextを迂回しようとしていますが、何らかの理由で迂回された関数がまったく呼び出されません。同様に、Sleep関数を迂回させてみましたが、それは意図したとおりに機能し、迂回した関数が呼び出されました。

私はAPIプログラミングのビジネスやその他の低レベルのアクティビティにあまり精通していません。DLL内で迂回を行うのではなく、コンソールアプリケーション内でこれを実行しようとしているという事実と関係があるのではないかと思います。その場合、Sleepを迂回できるのは不思議です。

私のアプローチに何か問題がありますか、それともコードに問題がありますか?

#include <windows.h>
#include <stdio.h>
#include "detours.h"

int ( WINAPI *Real_DrawText )(HDC a0, LPCSTR a1, int a2, LPRECT a3, UINT a4) = DrawTextA;

int Mine_DrawText(HDC hdc, LPCSTR text,  int nCount, LPRECT lpRect, UINT uOptions)
{
   printf("TEST");
   return Real_DrawText(hdc, text, nCount, lpRect, uOptions);
}

int main(int argc, char **argv)
{
    DetourTransactionBegin();
    DetourUpdateThread(GetCurrentThread());
    DetourAttach(&(PVOID&)Real_DrawText, Mine_DrawText);
    DetourTransactionCommit();
    printf("Calling Sleep\n");
    Sleep(1000);
    printf("Second callout");
    Sleep(5000);

    DetourTransactionBegin();
    DetourUpdateThread(GetCurrentThread());
    DetourDetach(&(PVOID&)Real_DrawText, Mine_DrawText);
    DetourTransactionCommit();
    return 0;
}
4

3 に答える 3

1

Only a side note: EasyHook - The reinvention of Windows API Hooking is an open source (LGPL) project developing a successor to Detours. It is quite mature already.

于 2009-11-02T08:30:52.397 に答える
1

printf()がDrawText()を呼び出すと想定しているようです。そうではありません。DrawText()はGDI関数です。printf()はWriteConsole()に移動します。これらは混ざりません。「コンソールウィンドウ」は、他のすべてのウィンドウとはまったく異なります。この区別は、基本的なアーキテクチャ上の違いです。それらは別々のカーネルコンポーネントによってさえ管理されます。

于 2009-09-10T10:55:52.263 に答える
1

コード例に基づいて、自分のプロセスを迂回しているだけのようです。したがって、DrawText を迂回しても何も出力されません。おそらく、目的のターゲットのプロセス メモリにコードを挿入し、そこから API 呼び出しを迂回する必要があります。たとえば、システム全体の CBT フックを作成できます。これは、迂回のニーズに対する出発点のようなものです。方向を示すために、次のようなものがあります。

LRESULT CALLBACK CBTProcedure(int nCode, WPARAM wParam, LPARAM lParam)
{
        もし (nCode < 0)
                return CallNextHookEx(g_hHook, nCode, wParam, lParam);
        そうでなければ (!g_pClient)
                0 を返します。

        HWND hWnd = (HWND)wParam;

        もし (!hWnd)
                0 を返します。

        スイッチ (nCode) {
                ケースHCBT_ACTIVATE:
                        /** ここで、ハンドルを確認して確認できます。
                          * ターゲット ウィンドウが探しているものである場合...
                          *
                          */
                        if (!g_pClient->IsRegisteredWindow(hWnd))
                                if (g_pClient->RegisterWindow(hWnd)) {
                                }

                壊す;

                ケース HCBT_DESTROYWND:
                        if (g_pClient->IsRegisteredWindow(hWnd))
                                g_pClient->UnregisterWindow(hWnd);

                壊す;
        }

        0 を返します。
}

bool __0XYOUROWN_API InstallHook()
{
        // メイン プロセスからこれを呼び出します。システム全体のフックを設定します。

        g_hHook = SetWindowsHookEx(WH_CBT, (HOOKPROC)CBTProcedure, g_hInstance, 0);

        /** #pragma data_seg("共有")
          * HHOOK g_hHook = NULL;
          * #pragma data_seg()
          */

        g_hHook を返します != NULL;
}

/** 実際の DLL...
  *
  *
  */
BOOL APIENTRY DllMain(HANDLE hModule、DWORD ul_reason_for_call、LPVOID lpReserved)
{
        スイッチ (ul_reason_for_call) {
                ケースDLL_PROCESS_ATTACH:
                        g_hInstance = (HINSTANCE)hModule;

                        if (::GetModuleHandle(_T("THEDESIREDMODULE.EXE")) != NULL) {
                                g_pClient = 新しいクライアント();

                                もし (g_pClient) {
                                        InitializeCriticalSection(&g_CriticalSection); // 批評家をセットアップできます。秒 後で同期するために...
                                        DetourTransactionBegin();
                                        DetourUpdateThread(GetCurrentThread());
                                        DetourAttach(&(PVOID&)Real_DrawTextW, Mine_DrawTextW);
                                        DetourTransactionCommit();
                                }
                        }

                壊す;

                ケース DLL_THREAD_ATTACH: ブレーク;

                ケース DLL_THREAD_DETACH: ブレーク;

                ケースDLL_PROCESS_DETACH:
                        if (::GetModuleHandle(_T("THEDESIREDMODULE.EXE")) != NULL) {
                                もし (g_pClient) {
                                        DetourTransactionBegin();
                                        DetourUpdateThread(GetCurrentThread());
                                        DetourDetach(&(PVOID&)Real_DrawTextW, Mine_DrawTextW);
                                        DetourTransactionCommit();

                                        g_pClient を削除します。

                                        g_pClient = NULL;
                                }
                        }

                壊す;
        }
}
于 2009-09-09T18:10:50.233 に答える