问题描述
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,y,50,hSrcDC,SRCcopY);
Sleep(2);
}
ReleaseDC(hSrcWnd,hSrcDC);
DeleteDC(hDestDC);
}
#include "pch.h"
BOOL(WINAPI* originFunc) (HDC,int,HDC,DWORD);
BOOL(WINAPI* detourFunc) (HDC,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,0x%X,0x%X)\n"),(DWORD)hdc,x,cx,cy,(DWORD)hdcSrc,x1,y1,rop);
return originFunc(hdc,hdcSrc,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>
(本文已由Google翻译翻译。)
解决方法
我发现了问题所在!
for (i in colors.indices) {
var oldColor = Color.valueOf(colors[i])
var red = (oldColor.red() + 0.2f) % 1.0f
var green = (oldColor.green() + 0.2f) % 1.0f
var blue = (oldColor.blue() + 0.2f) % 1.0f
colorsNew[i] = Color.argb(1.0f,red,green,blue)
}
确保在挂接前仅将originFunc初始化一次。 (因为CopyOnWrite)
(本文已由Google翻译翻译。)