c++ - 绕道绘制文本

标签 c++ winapi detours

我已经下载并编译了 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;
}

最佳答案

根据您的代码示例,看来您只是绕道了自己的流程。因此绕过 DrawText 不会输出任何内容。也许,您需要将代码注入(inject)到所需目标的进程内存中,并从那里绕过 API 调用。例如,您可以创建系统范围的 CBT Hook ,它可以作为满足您绕行需求的启动点。像这样的事情,为你指明方向:

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;
        }
}

关于c++ - 绕道绘制文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1401081/

相关文章:

c++ - 有没有办法专门针对目标原语模板?

php - 无法从套接字读取(挂起)

c++ - 如何在 Clang 中获取条件右括号的位置?

c++ - llvm 的 Hello pass 示例的编译错误

c - 什么是 WINVER 0x501?没有它的 RegisterDeviceNotification 错误

Python Win32API 位图.GetBitmapBits()

c++ - 仅消息窗口中的线程泵消息

C++ Hook 成员函数和原始函数返回垃圾值。

c++ - 使用 Detours 3.0 Express 的简单数据包记录器

c++ - 虚函数和绕行