我已经下载并编译了Microsoft绕行库。在我的项目中,我已经包含了头文件并添加了 .lib 文件作为依赖项。一切都编译没有错误。现在我一直试图绕开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;
}
答案 0 :(得分:1)
根据您的代码示例,您似乎只是在绕过自己的流程。因此绕道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; } }
答案 1 :(得分:1)
看来你假设printf()会调用DrawText()。它不会。 DrawText()是一个GDI函数。 printf()转到WriteConsole()。这些不混合。 “控制台Windows”与所有其他窗口完全不同。这种区别是一个基本的建筑;它们甚至由独立的内核组件管理。
答案 2 :(得分:1)
只有附注:EasyHook - The reinvention of Windows API Hooking是一个开源(LGPL)项目,正在开发Detours的后续项目。它已经相当成熟了。