代码之家  ›  专栏  ›  技术社区  ›  Kasper Holdum

迂回的绘图文本

  •  2
  • Kasper Holdum  · 技术社区  · 15 年前

    我已经下载并编译了微软迂回图书馆。在我的项目中,我包含了头文件并添加了 利比 文件作为依赖项。所有的编译都没有错误。现在我一直在尝试绕开drawtext,但出于某种原因,绕开的函数根本不会被调用。类似地,我试图绕开睡眠功能,它按预期工作,我绕道去的功能被调用。

    我不太熟悉API编程的业务,也不太熟悉其他低级的活动。我怀疑这可能与我试图在控制台应用程序中执行此操作而不是在DLL中执行迂回操作的事实有关。我只是觉得奇怪,在这种情况下它能绕道睡觉。

    我的方法有什么问题吗?还是代码有问题?

    #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;
    }
    
    3 回复  |  直到 15 年前
        1
  •  1
  •   nhaa123    15 年前

    基于您的代码示例,似乎您只是在绕开自己的过程。因此,迂回的drawtext不会输出任何内容。也许,您需要将代码注入到所需目标的进程内存中,并从中绕开API调用。例如,您可以创建系统范围的CBT钩子,其工作方式类似于。启动点,满足您的迂回需求。像这样,给你指出一个方向:

    LRESULT CALLBACK CBTProcedure(int nCode, WPARAM wParam, LPARAM lParam)
    {
            if (nCode < 0)
                    return CallNextHookEx(g_hHook, nCode, wParam, lParam);
            else if (!g_pClient)
                    return 0;
    
            HWND hWnd = (HWND)wParam;
    
            if (!hWnd)
                    return 0;
    
            switch (nCode) {
                    case HCBT_ACTIVATE:
                            /** Here, you can check up against the handle to see,
                              * if the target window is the one you're looking for...
                              *
                              */
                            if (!g_pClient->IsRegisteredWindow(hWnd))
                                    if (g_pClient->RegisterWindow(hWnd)) {
                                    }
    
                    break;
    
                    case HCBT_DESTROYWND:
                            if (g_pClient->IsRegisteredWindow(hWnd))
                                    g_pClient->UnregisterWindow(hWnd);
    
                    break;
            }
    
            return 0;
    }
    
    bool __0XYOUROWN_API InstallHook()
    {
            // Call this one from your main process; set's up the system-wide hook.
    
            g_hHook = SetWindowsHookEx(WH_CBT, (HOOKPROC)CBTProcedure, g_hInstance, 0);
    
            /** #pragma data_seg("Shared")
              *         HHOOK g_hHook = NULL;
              * #pragma data_seg()
              */
    
            return g_hHook != NULL;
    }
    
    /** The actual DLL...
      *
      *
      */
    BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
    {
            switch (ul_reason_for_call) {
                    case DLL_PROCESS_ATTACH:
                            g_hInstance = (HINSTANCE)hModule;
    
                            if (::GetModuleHandle(_T("THEDESIREDMODULE.EXE")) != NULL) {
                                    g_pClient = new Client();
    
                                    if (g_pClient) {
                                            InitializeCriticalSection(&g_CriticalSection); // You can setup a critic. sec. for later synchronization...
                                            DetourTransactionBegin();
                                            DetourUpdateThread(GetCurrentThread());
                                            DetourAttach(&(PVOID&)Real_DrawTextW, Mine_DrawTextW);
                                            DetourTransactionCommit();
                                    }
                            }
    
                    break;
    
                    case DLL_THREAD_ATTACH: break;
    
                    case DLL_THREAD_DETACH: break;
    
                    case DLL_PROCESS_DETACH:
                            if (::GetModuleHandle(_T("THEDESIREDMODULE.EXE")) != NULL) {
                                    if (g_pClient) {
                                            DetourTransactionBegin(); 
                                            DetourUpdateThread(GetCurrentThread());
                                            DetourDetach(&(PVOID&)Real_DrawTextW, Mine_DrawTextW);
                                            DetourTransactionCommit();
    
                                            delete g_pClient;
    
                                            g_pClient = NULL;
                                    }
                            }
    
                    break;
            }
    }
    
        2
  •  1
  •   MSalters    15 年前

    似乎您假定printf()将调用drawtext()。不会的。drawtext()是一个gdi函数。printf()转到writeconsole()。它们不会混合在一起。”控制台窗口”与其他窗口完全不同。这种区别是一种基本的体系结构区别;它们甚至由单独的内核组件管理。

        3
  •  1
  •   MaD70    15 年前

    只有旁注: EasyHook - The reinvention of Windows API Hooking 是开放源代码( LGPL )项目开发继承人 Detours .它已经相当成熟了。