Обходной текст - PullRequest
       9

Обходной текст

2 голосов
/ 09 сентября 2009

Я скачал и скомпилировал обходную библиотеку Microsoft. Внутри моего проекта я включил заголовочный файл и добавил файл .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;
}

Ответы [ 3 ]

1 голос
/ 10 сентября 2009

Кажется, вы предполагаете, что printf () вызовет DrawText (). Не будет DrawText () является функцией GDI. printf () переходит в WriteConsole (). Они не смешиваются. «Консольные окна» совсем не похожи на все остальные окна. Это различие является фундаментальным архитектурным; они даже управляются отдельными компонентами ядра.

1 голос
/ 02 ноября 2009

Только примечание: EasyHook - переосмысление Windows API Hooking - проект с открытым исходным кодом ( LGPL ), развивающий преемника Detours . Он уже достаточно зрелый.

1 голос
/ 09 сентября 2009

Судя по вашему примеру с кодом, кажется, что вы только отклоняете свой собственный процесс. Поэтому обходящий 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;
        }
}
...