我想把Bitblt函数和Detours连接起来。
https://github.com/microsoft/Detours/blob/master/samples/simple/simple.cpp
通过参考上面的示例源代码,我成功地创建了一个连接Bitblt函数的dll,但是取消挂钩不能正常工作。
当dll与目标进程分离时,我希望恢复原始函数,但是DetourDetach函数会抛出一个ERROR_INVALID_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>
(本文已由谷歌翻译。)
发布于 2020-09-28 09:53:21
我知道问题出在哪里了!
#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();