C++ DetourDetach()抛出错误\u无效\u块错误

C++ DetourDetach()抛出错误\u无效\u块错误,c++,hook,detours,C++,Hook,Detours,我想用Detours库钩住Bitblt函数 通过参考上面的示例源代码,我成功地创建了一个钩住Bitblt函数的dll,但是取消钩住不能正常工作 我希望在dll从目标进程分离时还原原始函数,但DetourDetach函数抛出错误\u INVALID\u BLOCK错误,并且发生目标进程的访问冲突 如何修复此错误 下面是我写的源代码 #include <stdio.h> #include <Windows.h> void capture(HBITMAP* canvas)

我想用Detours库钩住Bitblt函数

通过参考上面的示例源代码,我成功地创建了一个钩住Bitblt函数的dll,但是取消钩住不能正常工作

我希望在dll从目标进程分离时还原原始函数,但DetourDetach函数抛出错误\u INVALID\u BLOCK错误,并且发生目标进程的访问冲突

如何修复此错误

下面是我写的源代码

#include <stdio.h>
#include <Windows.h>

void capture(HBITMAP* canvas);

int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd) {
    HMODULE hModule = LoadLibrary(TEXT("testdll.dll"));
    if (!hModule) return 1;

    int i = 0;
    while(1) {
        HBITMAP canvas;
        capture(&canvas);
        Sleep(2000);
        if (++i >= 1) 
            FreeLibrary(hModule);
    }

    //FreeLibrary(hModule);
    return 0;
}

void capture(HBITMAP* canvas) {
    RECT srcRect;
    HWND hSrcWnd;
    HDC hSrcDC, hDestDC;

    hSrcWnd = GetDesktopWindow();
    hSrcDC = GetDC(hSrcWnd);

    GetWindowRect(hSrcWnd, &srcRect);
    int SrceenWidth = srcRect.right - srcRect.left;
    int SrceenHeight = srcRect.bottom - srcRect.top;

    hDestDC = CreateCompatibleDC(hSrcDC);
    *canvas = CreateCompatibleBitmap(hSrcDC, SrceenWidth, SrceenHeight);
    SelectObject(hDestDC, *canvas);

    for (int y = 0; y < SrceenHeight; y += 50) {
        BitBlt(hDestDC, 0, y, SrceenWidth, 50, hSrcDC, 0, y, SRCCOPY);
        Sleep(2);
    }

    ReleaseDC(hSrcWnd, hSrcDC);
    DeleteDC(hDestDC);
}
#include "pch.h"

BOOL(WINAPI* originFunc) (HDC, int, int, int, int, HDC, int, int, DWORD);
BOOL(WINAPI* detourFunc) (HDC, int, int, int, int, HDC, int, int, DWORD);

DWORD WriteLog(LPCTSTR format, ...) {
    TCHAR szLog[500];
    DWORD dwBytesWriten;

    va_list args;
    va_start(args, format);
    _vstprintf_s(szLog, 500, format, args);
    va_end(args);

    WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), szLog, _tcslen(szLog), &dwBytesWriten, 0);

    return dwBytesWriten;
}

BOOL WINAPI MyBitBlt(HDC hdc, int x, int y, int cx, int cy, HDC hdcSrc, int x1, int y1, DWORD rop) {
    WriteLog(TEXT("Function called : Bitblt(0x%X, %d, %d, %d, %d, 0x%X, %d, %d, 0x%X)\n"), 
        (DWORD)hdc, x, y, cx, cy, (DWORD)hdcSrc, x1, y1, rop);

    return originFunc(hdc, x, y, cx, cy, hdcSrc, x1, y1, rop);
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
    if (DetourIsHelperProcess())
        return TRUE;

    originFunc = BitBlt;
    detourFunc = MyBitBlt;

    LONG error;
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:
        AllocConsole();

        DetourRestoreAfterWith();

        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        DetourAttach(&(PVOID&)originFunc, detourFunc);
        error = DetourTransactionCommit();

        WriteLog(TEXT("Detour result(Attach) : 0x%08X\n"), error);

        break;

    case DLL_PROCESS_DETACH:
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        DetourDetach(&(PVOID&)originFunc, detourFunc);
        error = DetourTransactionCommit();

        WriteLog(TEXT("Detour result(Detach) : 0x%08X\n"), error);
        Sleep(500);

        FreeConsole();

        break;
    }

    return TRUE;
}
#include "framework.h"
#include <stdio.h>
#include <stdarg.h>
#include <tchar.h>
#include <detours.h>

#include <stdio.h>
#include <Windows.h>

void capture(HBITMAP* canvas);

int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd) {
    HMODULE hModule = LoadLibrary(TEXT("testdll.dll"));
    if (!hModule) return 1;

    int i = 0;
    while(1) {
        HBITMAP canvas;
        capture(&canvas);
        Sleep(2000);
        if (++i >= 1) 
            FreeLibrary(hModule);
    }

    //FreeLibrary(hModule);
    return 0;
}

void capture(HBITMAP* canvas) {
    RECT srcRect;
    HWND hSrcWnd;
    HDC hSrcDC, hDestDC;

    hSrcWnd = GetDesktopWindow();
    hSrcDC = GetDC(hSrcWnd);

    GetWindowRect(hSrcWnd, &srcRect);
    int SrceenWidth = srcRect.right - srcRect.left;
    int SrceenHeight = srcRect.bottom - srcRect.top;

    hDestDC = CreateCompatibleDC(hSrcDC);
    *canvas = CreateCompatibleBitmap(hSrcDC, SrceenWidth, SrceenHeight);
    SelectObject(hDestDC, *canvas);

    for (int y = 0; y < SrceenHeight; y += 50) {
        BitBlt(hDestDC, 0, y, SrceenWidth, 50, hSrcDC, 0, y, SRCCOPY);
        Sleep(2);
    }

    ReleaseDC(hSrcWnd, hSrcDC);
    DeleteDC(hDestDC);
}
#include "pch.h"

BOOL(WINAPI* originFunc) (HDC, int, int, int, int, HDC, int, int, DWORD);
BOOL(WINAPI* detourFunc) (HDC, int, int, int, int, HDC, int, int, DWORD);

DWORD WriteLog(LPCTSTR format, ...) {
    TCHAR szLog[500];
    DWORD dwBytesWriten;

    va_list args;
    va_start(args, format);
    _vstprintf_s(szLog, 500, format, args);
    va_end(args);

    WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), szLog, _tcslen(szLog), &dwBytesWriten, 0);

    return dwBytesWriten;
}

BOOL WINAPI MyBitBlt(HDC hdc, int x, int y, int cx, int cy, HDC hdcSrc, int x1, int y1, DWORD rop) {
    WriteLog(TEXT("Function called : Bitblt(0x%X, %d, %d, %d, %d, 0x%X, %d, %d, 0x%X)\n"), 
        (DWORD)hdc, x, y, cx, cy, (DWORD)hdcSrc, x1, y1, rop);

    return originFunc(hdc, x, y, cx, cy, hdcSrc, x1, y1, rop);
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
    if (DetourIsHelperProcess())
        return TRUE;

    originFunc = BitBlt;
    detourFunc = MyBitBlt;

    LONG error;
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:
        AllocConsole();

        DetourRestoreAfterWith();

        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        DetourAttach(&(PVOID&)originFunc, detourFunc);
        error = DetourTransactionCommit();

        WriteLog(TEXT("Detour result(Attach) : 0x%08X\n"), error);

        break;

    case DLL_PROCESS_DETACH:
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        DetourDetach(&(PVOID&)originFunc, detourFunc);
        error = DetourTransactionCommit();

        WriteLog(TEXT("Detour result(Detach) : 0x%08X\n"), error);
        Sleep(500);

        FreeConsole();

        break;
    }

    return TRUE;
}
#include "framework.h"
#include <stdio.h>
#include <stdarg.h>
#include <tchar.h>
#include <detours.h>
#包括“framework.h”
#包括
#包括
#包括
#包括


(这篇文章已经被谷歌翻译了。)

我发现了问题所在

#include "pch.h"

BOOL(WINAPI* originFunc) (HDC, int, int, int, int, HDC, int, int, DWORD) = Bitblt; //HERE
BOOL(WINAPI* detourFunc) (HDC, int, int, int, int, HDC, int, int, DWORD);

DWORD WriteLog(LPCTSTR format, ...) {
    TCHAR szLog[500];
    DWORD dwBytesWriten;

    va_list args;
    va_start(args, format);
    _vstprintf_s(szLog, 500, format, args);
    va_end(args);

    WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), szLog, _tcslen(szLog), &dwBytesWriten, 0);

    return dwBytesWriten;
}

BOOL WINAPI MyBitBlt(HDC hdc, int x, int y, int cx, int cy, HDC hdcSrc, int x1, int y1, DWORD rop) {
    WriteLog(TEXT("Function called : Bitblt(0x%X, %d, %d, %d, %d, 0x%X, %d, %d, 0x%X)\n"), 
        (DWORD)hdc, x, y, cx, cy, (DWORD)hdcSrc, x1, y1, rop);

    return originFunc(hdc, x, y, cx, cy, hdcSrc, x1, y1, rop);
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
    if (DetourIsHelperProcess())
        return TRUE;

    //NOT HERE
    //originFunc = BitBlt;
    detourFunc = MyBitBlt;

    LONG error;
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:
        AllocConsole();

        DetourRestoreAfterWith();

        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        DetourAttach(&(PVOID&)originFunc, detourFunc);
        error = DetourTransactionCommit();

        WriteLog(TEXT("Detour result(Attach) : 0x%08X\n"), error);

        break;

    case DLL_PROCESS_DETACH:
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        DetourDetach(&(PVOID&)originFunc, detourFunc);
        error = DetourTransactionCommit();

        WriteLog(TEXT("Detour result(Detach) : 0x%08X\n"), error);
        Sleep(500);

        FreeConsole();

        break;
    }

    return TRUE;
}
确保originFunc在挂钩之前只初始化一次。(因为CopyOnWrite)

(本文已由谷歌翻译公司翻译。)