2

我已经下载并编译了微软绕行库。在我的项目中,我包含了头文件并将.lib文件添加为依赖项。一切都编译没有错误。现在我一直在尝试绕开 DrawText,但由于某种原因,绕开的函数根本没有被调用。类似地,我尝试绕过 Sleep 函数,它按预期工作,并且调用了我绕过的函数。

我不太精通 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;
}
4

3 回答 3

1

根据您的代码示例,您似乎只是在绕道自己的流程。因此绕道 DrawText 不会输出任何东西。也许,您需要将代码注入所需目标的进程内存并从那里绕过 API 调用。例如,您可以创建系统范围的 CBT 挂钩,它的工作原理有点像.. 启动点来满足您的绕行需求。像这样,为您指出方向:

LRESULT CALLBACK CBTProcedure(int nCode, WPARAM wParam, LPARAM lParam)
{
        如果 (nCode < 0)
                返回 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(句柄 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 回答
1

看来您假设 printf() 将调用 DrawText()。它不会。DrawText() 是一个 GDI 函数。printf() 转到 WriteConsole()。这些不混合。“控制台窗口”与所有其他窗口完全不同。这种区别是基本的架构区别。它们甚至由单独的内核组件管理。

于 2009-09-10T10:55:52.263 回答
1

仅附注:EasyHook - Windows API Hooking 的重新发明是一个开源 ( LGPL ) 项目,开发了Detours的继任者。已经相当成熟了。

于 2009-11-02T08:30:52.397 回答