2009-09-09 55 views
2

我已經下載並編譯了Microsoft繞道庫。在我的項目中,我已經包含了頭文件並添加了.lib文件作爲依賴項。一切編譯沒有錯誤。現在我一直試圖繞過DrawText,但由於某種原因,繞道函數根本不會被調用。我很熟悉地嘗試繞行睡眠功能,並且按照預期工作,並且我繞過的功能被調用。迂迴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

主要是你打電話睡眠,而不是DrawTextA,這只是一個複製/粘貼錯誤,或者這是你用過的一個真實例子? – 2009-09-09 18:21:10

+0

如果我自己調用DrawTextA而不是睡眠,那麼調用我的路由函數來代替函數。我感興趣的是至少在全球範圍或其他窗口發生這種情況。 我希望有另一種方式比注入我的庫到應用程序。 – 2009-09-09 18:36:01

回答

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

如果是這樣的話,我的繞路函數還會被調用來繪製控制檯窗口的文本嗎? 問題是,DllMain seemes將在我自己的項目中聲明,但也會在導致錯誤的'detour.lib'中聲明。 – 2009-09-09 18:20:47

+0

請看MSalters的答案。 – nhaa123 2009-09-18 06:53:57

+0

你完全正確。迂迴只發生在注射程序內,這意味着我必須注入幾乎所有東西,直到找到所選程序。 你的代碼看起來漂亮的複製粘貼的方式 – 2009-09-19 21:18:58

1

看來你假設printf()會調用DrawText()。它不會。 DrawText()是一個GDI函數。 printf()轉到WriteConsole()。這些不混合。 「控制檯Windows」與其他所有窗口完全不同。這個區別是一個基本的體系結構。它們甚至由獨立的內核組件管理。