_xhp_
October 11th, 2005, 10:21
The goal:
Get the picture of a window that uses WS_EX_LAYERED and UpdateLayeredWindow to paint itself (and does not use WM_PAINT or handles WM_PRINT/WM_PRINTCLIENT).
PrintWindow API won't work at all (becouse it relies on WM_PAINT).
Any of the BitBlt's are not an option becouse I need to get a picture of a window even when it is partialy hidden.
So I tought this would solve my problems:
1) hook and redirect UpdateLayeredWindow
2) Get the contens of the srcHdc argument and copy it to my DC
Now, the only problem is it doesn't work. So the question is why?
This is more of a programming question than it is a reversing one but I tought I'll try my luck here.
BOOL __stdcall UpdateLayeredWindowInjected(HWND hwnd, HDC hdcDst, POINT *pptDst, SIZE *psize, HDC hdcSrc, POINT *pptSrc, COLORREF crKey, BLENDFUNCTION *pblend, DWORD dwFlags )
{
try
{
if (hdcSrc)
{
SIZE bmpSize;
if (psize)
{
bmpSize = *psize;
}
else
{
RECT r;
GetWindowRect(hwnd, &r);
bmpSize.cx = abs(r.right - r.left);
bmpSize.cy = abs(r.bottom - r.top);
}
HDC hCaptureDC = CreateCompatibleDC(hdcSrc);
if (hCaptureDC)
{
HBITMAP hCaptureBitmap = CreateCompatibleBitmap(hdcSrc,
bmpSize.cx, bmpSize.cy);
if(hCaptureBitmap )
{
HGDIOBJ oldObj = SelectObject(hCaptureDC,hCaptureBitmap);
BitBlt(hCaptureDC,0,0,bmpSize.cx, bmpSize.cy,hdcSrc,0,0,SRCCOPY);
//::OpenClipboard(hwnd);
::OpenClipboard(NULL);
::EmptyClipboard() ;
::SetClipboardData (CF_BITMAP, hCaptureBitmap) ;
::CloseClipboard () ;
}
DeleteDC(hCaptureDC);
}
}
}
catch(...)
{
}
BOOL ret = UpdateLayeredWindowOriginal(hwnd,hdcDst,pptDst,psize,hdcSrc,pptSrc,crKey,pblend,dwFlags );
return ret;
}
I use the upper code in a simple dll, I inject the dll using RemoteLib (http://www.codeproject.com/dll/RemoteLib.asp) and then hook the API with MS detours.
The problem is I get "Courrupted clipoard data" when I try to paste the bitmap. This could be becouse of the transparency.
Get the picture of a window that uses WS_EX_LAYERED and UpdateLayeredWindow to paint itself (and does not use WM_PAINT or handles WM_PRINT/WM_PRINTCLIENT).
PrintWindow API won't work at all (becouse it relies on WM_PAINT).
Any of the BitBlt's are not an option becouse I need to get a picture of a window even when it is partialy hidden.
So I tought this would solve my problems:
1) hook and redirect UpdateLayeredWindow
2) Get the contens of the srcHdc argument and copy it to my DC
Now, the only problem is it doesn't work. So the question is why?
This is more of a programming question than it is a reversing one but I tought I'll try my luck here.
BOOL __stdcall UpdateLayeredWindowInjected(HWND hwnd, HDC hdcDst, POINT *pptDst, SIZE *psize, HDC hdcSrc, POINT *pptSrc, COLORREF crKey, BLENDFUNCTION *pblend, DWORD dwFlags )
{
try
{
if (hdcSrc)
{
SIZE bmpSize;
if (psize)
{
bmpSize = *psize;
}
else
{
RECT r;
GetWindowRect(hwnd, &r);
bmpSize.cx = abs(r.right - r.left);
bmpSize.cy = abs(r.bottom - r.top);
}
HDC hCaptureDC = CreateCompatibleDC(hdcSrc);
if (hCaptureDC)
{
HBITMAP hCaptureBitmap = CreateCompatibleBitmap(hdcSrc,
bmpSize.cx, bmpSize.cy);
if(hCaptureBitmap )
{
HGDIOBJ oldObj = SelectObject(hCaptureDC,hCaptureBitmap);
BitBlt(hCaptureDC,0,0,bmpSize.cx, bmpSize.cy,hdcSrc,0,0,SRCCOPY);
//::OpenClipboard(hwnd);
::OpenClipboard(NULL);
::EmptyClipboard() ;
::SetClipboardData (CF_BITMAP, hCaptureBitmap) ;
::CloseClipboard () ;
}
DeleteDC(hCaptureDC);
}
}
}
catch(...)
{
}
BOOL ret = UpdateLayeredWindowOriginal(hwnd,hdcDst,pptDst,psize,hdcSrc,pptSrc,crKey,pblend,dwFlags );
return ret;
}
I use the upper code in a simple dll, I inject the dll using RemoteLib (http://www.codeproject.com/dll/RemoteLib.asp) and then hook the API with MS detours.
The problem is I get "Courrupted clipoard data" when I try to paste the bitmap. This could be becouse of the transparency.