首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >DetourDetach()引发ERROR_INVALID_BLOCK错误

DetourDetach()引发ERROR_INVALID_BLOCK错误
EN

Stack Overflow用户
提问于 2020-09-27 16:52:32
回答 1查看 467关注 0票数 0

我想把Bitblt函数和Detours连接起来。

https://github.com/microsoft/Detours/blob/master/samples/simple/simple.cpp

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

当dll与目标进程分离时,我希望恢复原始函数,但是DetourDetach函数会抛出一个ERROR_INVALID_BLOCK错误,并且会发生目标进程的访问冲突。

如何纠正此错误?

下面是我写的源代码。

代码语言:javascript
复制
#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);
}

代码语言:javascript
复制
#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;
}

代码语言:javascript
复制
#include "framework.h"
#include <stdio.h>
#include <stdarg.h>
#include <tchar.h>
#include <detours.h>

(本文已由谷歌翻译。)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-09-28 09:53:21

我知道问题出在哪里了!

代码语言:javascript
复制
#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)

(本文已由谷歌翻译。)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64091010

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档