现象:BitBlt 在 LSASS.EXE 进程中执行失败,GetLastError 返回 6(错误的句柄)
描述:对截屏类进行了两个测试,首先,在 exe 中使用该类,截屏成功。
然后,在 DLL 中使用该类,并使用 rundll32 执行该 dll ,截屏操作成功。可是,
使用线程注入方式将 dll 注入到 lsass.exe 中运行时,截屏失败,报告说 bitblt
错误。请问到底是怎么回事?// TCapture.h#ifndef TCaptureH
#define TCaptureH
//----------------------------------------------------------------------------------class TScreenCapture
{
public:
TScreenCapture();
BOOL Capture();
LPSTR Buffer();
DWORD Length();
~TScreenCapture();
private:
LPSTR FBuffer;
DWORD FLength;
BOOL FSucceed; INT FWidth;
INT FHeight; HDC HdcDesktop;
HWND HwndDesktop; HDC HdcMemory;
HBITMAP HBmpMemory;
PVOID PDatBitmap; BITMAPINFO BmpInfo;
BITMAPFILEHEADER BmpHeader;
};//----------------------------------------------------------------------------------
#endif// TCapture.cpp
#include <stdio.h>
#include <windows.h>#include "TCapture.h"
//------------------------------------------------------------------------------------------------------------
TScreenCapture::TScreenCapture()
{
FBuffer = NULL;
FLength = 0;
}
//------------------------------------------------------------------------------------------------------------
BOOL TScreenCapture::Capture()
{
FWidth = GetSystemMetrics( SM_CXSCREEN );
FHeight = GetSystemMetrics( SM_CYSCREEN ); memset(&BmpInfo, 0, sizeof(BITMAPINFO));
BmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
BmpInfo.bmiHeader.biHeight = FHeight;
BmpInfo.bmiHeader.biWidth = FWidth;
BmpInfo.bmiHeader.biPlanes = 1;
BmpInfo.bmiHeader.biBitCount = 16;
BmpInfo.bmiHeader.biCompression = BI_RGB;
BmpInfo.bmiHeader.biSizeImage = 2*FWidth*FHeight; memset(&BmpHeader, 0, sizeof(BITMAPFILEHEADER));
BmpHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
BmpHeader.bfSize = BmpInfo.bmiHeader.biSizeImage + BmpHeader.bfOffBits;
BmpHeader.bfType = 0x424D; FLength = BmpHeader.bfSize;
FSucceed = FALSE; HwndDesktop = GetDesktopWindow();
HdcDesktop = GetDC( HwndDesktop ); if ( HdcDesktop != NULL )
{
HdcMemory = CreateCompatibleDC( HdcDesktop ); if ( HdcMemory != NULL )
{
HBmpMemory = CreateDIBSection(HdcDesktop, &BmpInfo, DIB_RGB_COLORS, &PDatBitmap, NULL, 0); if ( HBmpMemory != NULL )
{
SelectObject(HdcMemory, HBmpMemory); if ( BitBlt(HdcMemory, 0, 0, FWidth, FHeight, HdcDesktop, 0, 0, SRCCOPY) )
{
if ( FBuffer != NULL )
{
free( FBuffer );
} FBuffer = (LPSTR)malloc( FLength ); if ( FBuffer != NULL )
{
memcpy(FBuffer, &BmpHeader, sizeof(BITMAPFILEHEADER));
memcpy(FBuffer+sizeof(BITMAPFILEHEADER), &BmpInfo, sizeof(BITMAPINFOHEADER));
memcpy(FBuffer+BmpHeader.bfOffBits, PDatBitmap, BmpInfo.bmiHeader.biSizeImage); FSucceed = TRUE;
}
} DeleteObject( HBmpMemory );
} DeleteDC( HdcMemory );
} ReleaseDC(HwndDesktop, HdcDesktop);
} return FSucceed;
}//------------------------------------------------------------------------------------------------------------
LPSTR TScreenCapture::Buffer()
{
return FBuffer;
}//------------------------------------------------------------------------------------------------------------
DWORD TScreenCapture::Length()
{
return FLength;
}
//------------------------------------------------------------------------------------------------------------
TScreenCapture::~TScreenCapture()
{
if ( FBuffer != NULL )
{
free( FBuffer );
}
}
描述:对截屏类进行了两个测试,首先,在 exe 中使用该类,截屏成功。
然后,在 DLL 中使用该类,并使用 rundll32 执行该 dll ,截屏操作成功。可是,
使用线程注入方式将 dll 注入到 lsass.exe 中运行时,截屏失败,报告说 bitblt
错误。请问到底是怎么回事?// TCapture.h#ifndef TCaptureH
#define TCaptureH
//----------------------------------------------------------------------------------class TScreenCapture
{
public:
TScreenCapture();
BOOL Capture();
LPSTR Buffer();
DWORD Length();
~TScreenCapture();
private:
LPSTR FBuffer;
DWORD FLength;
BOOL FSucceed; INT FWidth;
INT FHeight; HDC HdcDesktop;
HWND HwndDesktop; HDC HdcMemory;
HBITMAP HBmpMemory;
PVOID PDatBitmap; BITMAPINFO BmpInfo;
BITMAPFILEHEADER BmpHeader;
};//----------------------------------------------------------------------------------
#endif// TCapture.cpp
#include <stdio.h>
#include <windows.h>#include "TCapture.h"
//------------------------------------------------------------------------------------------------------------
TScreenCapture::TScreenCapture()
{
FBuffer = NULL;
FLength = 0;
}
//------------------------------------------------------------------------------------------------------------
BOOL TScreenCapture::Capture()
{
FWidth = GetSystemMetrics( SM_CXSCREEN );
FHeight = GetSystemMetrics( SM_CYSCREEN ); memset(&BmpInfo, 0, sizeof(BITMAPINFO));
BmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
BmpInfo.bmiHeader.biHeight = FHeight;
BmpInfo.bmiHeader.biWidth = FWidth;
BmpInfo.bmiHeader.biPlanes = 1;
BmpInfo.bmiHeader.biBitCount = 16;
BmpInfo.bmiHeader.biCompression = BI_RGB;
BmpInfo.bmiHeader.biSizeImage = 2*FWidth*FHeight; memset(&BmpHeader, 0, sizeof(BITMAPFILEHEADER));
BmpHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
BmpHeader.bfSize = BmpInfo.bmiHeader.biSizeImage + BmpHeader.bfOffBits;
BmpHeader.bfType = 0x424D; FLength = BmpHeader.bfSize;
FSucceed = FALSE; HwndDesktop = GetDesktopWindow();
HdcDesktop = GetDC( HwndDesktop ); if ( HdcDesktop != NULL )
{
HdcMemory = CreateCompatibleDC( HdcDesktop ); if ( HdcMemory != NULL )
{
HBmpMemory = CreateDIBSection(HdcDesktop, &BmpInfo, DIB_RGB_COLORS, &PDatBitmap, NULL, 0); if ( HBmpMemory != NULL )
{
SelectObject(HdcMemory, HBmpMemory); if ( BitBlt(HdcMemory, 0, 0, FWidth, FHeight, HdcDesktop, 0, 0, SRCCOPY) )
{
if ( FBuffer != NULL )
{
free( FBuffer );
} FBuffer = (LPSTR)malloc( FLength ); if ( FBuffer != NULL )
{
memcpy(FBuffer, &BmpHeader, sizeof(BITMAPFILEHEADER));
memcpy(FBuffer+sizeof(BITMAPFILEHEADER), &BmpInfo, sizeof(BITMAPINFOHEADER));
memcpy(FBuffer+BmpHeader.bfOffBits, PDatBitmap, BmpInfo.bmiHeader.biSizeImage); FSucceed = TRUE;
}
} DeleteObject( HBmpMemory );
} DeleteDC( HdcMemory );
} ReleaseDC(HwndDesktop, HdcDesktop);
} return FSucceed;
}//------------------------------------------------------------------------------------------------------------
LPSTR TScreenCapture::Buffer()
{
return FBuffer;
}//------------------------------------------------------------------------------------------------------------
DWORD TScreenCapture::Length()
{
return FLength;
}
//------------------------------------------------------------------------------------------------------------
TScreenCapture::~TScreenCapture()
{
if ( FBuffer != NULL )
{
free( FBuffer );
}
}
解决方案 »
- 有关学生成绩管理系统
- 封装协议!
- BCG库中CBCGPTabView 怎样设置STYLE_3D_ONENOTE风格
- VC调用VB的ACTIVE dll控件。在线急等,高手帮忙!!!!!
- 关于字体获取的问题,简单但是困扰了我好久
- 就这么多分了了,基础问题,各位老师讲解下
- 我把LINUX下面一个程序移植到WINDOWS下遇到的问题,请指点
- GDI+中字体和GDI中的字体之间的关系问题?
- DOC的问题
- 如何修改程序的标题?
- 【问】GDI API Bitblt 在 lsass.exe 中执行失败??【200】
- 从“void (__thiscall CECSound::* )(void)”到“AFX_PMSG”的转换不明确的错误如何改啊
{
BOOL IsSucceed = FALSE; // 保存当前窗口属性
HWINSTA hwinstaLsass = GetProcessWindowStation(); if ( hwinstaLsass != NULL )
{
// 保存当前线程桌面
HDESK hdeskLsass = GetThreadDesktop( GetCurrentThreadId() ); if ( hdeskLsass != NULL )
{
// 获取目标窗口属性
HWINSTA hwinstaUser = OpenWindowStation(DefaultWindowStation, FALSE, MAXIMUM_ALLOWED); if ( hwinstaUser != NULL )
{
// 设置目标窗口属性
if ( SetProcessWindowStation(hwinstaUser) )
{
// 获取目标桌面
HDESK hdeskUser = OpenDesktop(DefaultDesktop, 0, FALSE, MAXIMUM_ALLOWED); if ( hdeskUser != NULL )
{
// 设置线程桌面
if ( SetThreadDesktop(hdeskUser) )
{
// to do something // 完成需要与桌面进行交互的功能
IsSucceed = ScreenCapture(); // 我在这里完成截屏操作 // 恢复线程原始桌面
SetThreadDesktop( hdeskLsass );
} // 关闭目标桌面
CloseDesktop( hdeskUser );
} // 恢复进程原始窗口属性
SetProcessWindowStation( hwinstaLsass );
} // 关闭目标窗口属性
CloseWindowStation( hwinstaUser );
}
}
} return IsSucceed;
}
此外,还需要更正一下上面的截屏类,其中 BOOL TScreenCapture::Capture() 中 BmpHeader.bfType = 0x424D; 应该为 BmpHeader.bfType = 0x4D42; 好了,再次感谢 wangk(倒之) ,没有你的帮助,我就不能这么快的解决问题。结帖了。