如何实时捕获Windows当前刷新了屏幕上的哪块矩形区域? 小弟想做一个像PCAnywhere一样的能显示远程屏幕一举一动的程序,但如果每次用全屏截取再数据传输,那肯定是不可取的.我想PCAnywhere一定是获取了哪个消息,然后截取其中的刷新区域来的.不知道应该如何做? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 建议你去看VNC开放源码,是VC的,都用DELPHI来实现,效率太差吧你如果用DELPHI重写了,欢迎共享出来,我先预定一份 如果你想抓到windows API InvalidateRect所發出的消息,我對你所要做的東西是沒用的!頻率太高了! 出处:http://expert.csdn.net/Expert/topic/2298/2298878.xml?temp=.1626093很多木马程序支持了屏幕回传的功能,其根本的原理是先捕获屏幕画面,然后回 传给客户机,由于画面的数据量很大所以,很多木马程序都是在画面改变的时候才回传改变 部分的画面,常用的手段是最小矩形法,下面以好友“古老传说”的一段算法举例: #define MAXXCount 10 //屏幕X方向最多分割块数 #define MAXYCount 5 //... Y................ #define DestNum 1000 //每块的偏移检测点最大个数 COLORREF Colors[MAXXCount][MAXYCount][DestNum]; COLORREF BakColors[MAXXCount]{MAXYCount][DestNum]; TPoint Dests[DestNum]; int Sw; int Sh; int xCount; int yCount; int ItemWidth; int ItemHeight; int Dnum; int Qlity; //得到消息后执行: //另外:接收到的数据包中分析出 Dnum ,Qlity //Dnum:偏移观测点数量 //Qlity:图象要求质量 __fastcall TForm1::CopyScreen(int DNum,int Qlity){ ItemWidth=Sw/xCount; ItemHeight=Sh/yCount; Sw=Screen->Width; Sh=Screen->Height; xCount=(Sw>1000)?8:6; yCount=(Sh>1000)?3:2; for (int num1=0;num1 Dests[num1].x=random(ItemWidth); Dests[num1].y=random(ItemHeight); } CatchScreen(DNum,Qlity); } //收到刷屏消息后只执行: CatchScreen(DNum,Qlity); __fastcall TForm1::CatchScreen(int DNum,int Qlity){ //函数功能:扫描改变的屏幕区域,并切经过优化处理,最后发送这些区域数据 //DNum: 偏移量 Qlity:图象质量 HDC dc=GetDC(GetDesktopWindow()); Graphics::TBitmap *bm=new Graphics::TBitmap; bm->Width=Sw; bm->Height=Sh; BitBlt(bm->Canvas->Handle,0,0,Sw-1,Sh-1,dc,0,0); int num1,num2,num3; int nowx,nowy; bool Change; bool ItemChange[MAXXCount][MAXYCount]; for (num1=0;num1 nowx=ItemWidth*num1; for (num2=0;num2 nowy=ItemHeight*num2; Change=false; for (num3=0;num3 Colors[num1][num2][num3]=bm->Canvas->Pixels[nowx+Dests[num3].x] [nowy+Dests[num3].y]; if (Colors[num1][num2][num3]!=BakColors[num1][num2][num3]){ BakColors[num1][num2][num3]=Colors[num1][num2][num3]; ItemChange[num1][num2]=true; } } } } int CNum,MaxCNum; int ChangedNum=0; TRect *Rect; int num4; int MinSize=10000; int m; TRect MinRect; Graphics::TBitmap *bt2=new Graphics::TBitmap; TJPEGImage *j=new TJPEGImage; //************************ j->Quality=Qlity; //************************ CopyScreenUint CopyScreen; CopyScreenItemUint CopyScreenItem; TMemoryStream *ms=new TMemoryStream; ms->Write(&TcpMsg,sizeof(TcpMsgUint)); ms->Write(&CopyScreen,sizeof(CopyScreenUint)); do{ for (num1=0;num1 for (num2=0;num2 for (num3=num1+1;num3<=xCount;num3++){ MaxCNum=0; for (num4=num2+1;num4<=yCount;num4++){ //遍历所有矩形 CNum=GetChangedNum(TRect(num1,num2,num3,num4)); if (CNum>MaxCNum) MaxCNum=CNum; m=(num3-num1)*(num4-num2); if (2*m-CNum MinSize=2*m-CNum; MinRect=TRect(num1,num2,num3,num4); } } } TMemoryStream *ms; BitBlt(bt2->Canvas->Handle,0,0,ItemWidth-1,ItemHeight-1,bt->Canvas->Handle,0,0); j->Assign(bt2); j->SaveToStream(ms2); CopyScreenItem.Rect=TRect(num1,num2,num3,num4); CopyScreenItem.FileType=JPEGFILE; //JPEGFILE 定义为:#define JPEGFILE 1 ms2->Position=0; CopyScreenItem.Length=ms2->Size; ms->Write(&CopyScreenItem,sizeof(ScreenItemUint)); ms->CopyFrom(ms2,ms2->Size); ChangedNum++; }while(MaxCNum>0); TcpMsg.Type=MsgCopyScreen; ms->Position=0; TcpMsg.Length=ms->Size-sizeof(TcpMsgUint); CopyScreen.Count=ChangedNum; ms->Write(&TcpMsg,sizeof(TcpMsgUint)); ms->Write(&CopyScreen,sizeof(CopyScreenUInt)); ms->Position=0; sock->SendStream(ms); } 这个程序把屏幕画面切分为了多个部分,并存储画面为JPG格式,这样压缩率就变的十分 的高了。通过这种方法压缩处理过的数据,变得十分小. 使用系统钩子, Hook 键盘和鼠标, 及 Windows 的消息即可, 若是屏幕改变可以钩 WM_PAINT 消息. 程序A如何监视程序B中的EDIT是否得到焦点和失去焦点 怎么建立一个让其它程序检测不到我的进程 急死了,快帮我看看! 如何将Longword转换成string? 如何开机后运行先运行你的程序,然后根据你的程序选择是否运行windows2000 用IdTCPClient和IdTCPServer控件如何开发出支持并发的通讯程序 三层中,如何在多线程中同时访问数据库 关于cxGrid控件 问题 运行错误问题? 如何在delphi中调入gif动画 难题:如何在A程序中获得B程序的MDI子窗的句柄? 有关菜单的快捷按扭的问题?
你如果用DELPHI重写了,欢迎共享出来,我先预定一份
頻率太高了!
传给客户机,由于画面的数据量很大所以,很多木马程序都是在画面改变的时候才回传改变
部分的画面,常用的手段是最小矩形法,下面以好友“古老传说”的一段算法举例:
#define MAXXCount 10 //屏幕X方向最多分割块数
#define MAXYCount 5 //... Y................
#define DestNum 1000 //每块的偏移检测点最大个数
COLORREF Colors[MAXXCount][MAXYCount][DestNum];
COLORREF BakColors[MAXXCount]{MAXYCount][DestNum];
TPoint Dests[DestNum];
int Sw;
int Sh;
int xCount;
int yCount;
int ItemWidth;
int ItemHeight;
int Dnum;
int Qlity;
//得到消息后执行:
//另外:接收到的数据包中分析出 Dnum ,Qlity
//Dnum:偏移观测点数量
//Qlity:图象要求质量
__fastcall TForm1::CopyScreen(int DNum,int Qlity){
ItemWidth=Sw/xCount;
ItemHeight=Sh/yCount;
Sw=Screen->Width;
Sh=Screen->Height;
xCount=(Sw>1000)?8:6;
yCount=(Sh>1000)?3:2;
for (int num1=0;num1 Dests[num1].x=random(ItemWidth);
Dests[num1].y=random(ItemHeight);
}
CatchScreen(DNum,Qlity);
}
//收到刷屏消息后只执行:
CatchScreen(DNum,Qlity);
__fastcall TForm1::CatchScreen(int DNum,int Qlity){
//函数功能:扫描改变的屏幕区域,并切经过优化处理,最后发送这些区域数据
//DNum: 偏移量 Qlity:图象质量
HDC dc=GetDC(GetDesktopWindow());
Graphics::TBitmap *bm=new Graphics::TBitmap;
bm->Width=Sw;
bm->Height=Sh;
BitBlt(bm->Canvas->Handle,0,0,Sw-1,Sh-1,dc,0,0);
int num1,num2,num3;
int nowx,nowy;
bool Change;
bool ItemChange[MAXXCount][MAXYCount];
for (num1=0;num1 nowx=ItemWidth*num1;
for (num2=0;num2 nowy=ItemHeight*num2;
Change=false;
for (num3=0;num3 Colors[num1][num2][num3]=bm->Canvas->Pixels[nowx+Dests[num3].x]
[nowy+Dests[num3].y];
if (Colors[num1][num2][num3]!=BakColors[num1][num2][num3]){
BakColors[num1][num2][num3]=Colors[num1][num2][num3];
ItemChange[num1][num2]=true;
}
}
}
} int CNum,MaxCNum;
int ChangedNum=0;
TRect *Rect;
int num4;
int MinSize=10000;
int m;
TRect MinRect;
Graphics::TBitmap *bt2=new Graphics::TBitmap;
TJPEGImage *j=new TJPEGImage;
//************************
j->Quality=Qlity;
//************************
CopyScreenUint CopyScreen;
CopyScreenItemUint CopyScreenItem;
TMemoryStream *ms=new TMemoryStream;
ms->Write(&TcpMsg,sizeof(TcpMsgUint));
ms->Write(&CopyScreen,sizeof(CopyScreenUint));
do{
for (num1=0;num1 for (num2=0;num2 for (num3=num1+1;num3<=xCount;num3++){
MaxCNum=0;
for (num4=num2+1;num4<=yCount;num4++){ //遍历所有矩形
CNum=GetChangedNum(TRect(num1,num2,num3,num4));
if (CNum>MaxCNum) MaxCNum=CNum;
m=(num3-num1)*(num4-num2);
if (2*m-CNum MinSize=2*m-CNum;
MinRect=TRect(num1,num2,num3,num4);
}
}
}
TMemoryStream *ms;
BitBlt(bt2->Canvas->Handle,0,0,ItemWidth-1,ItemHeight-1,bt->Canvas->Handle,0,0);
j->Assign(bt2);
j->SaveToStream(ms2);
CopyScreenItem.Rect=TRect(num1,num2,num3,num4);
CopyScreenItem.FileType=JPEGFILE; //JPEGFILE 定义为:#define JPEGFILE 1
ms2->Position=0;
CopyScreenItem.Length=ms2->Size;
ms->Write(&CopyScreenItem,sizeof(ScreenItemUint));
ms->CopyFrom(ms2,ms2->Size);
ChangedNum++;
}while(MaxCNum>0);
TcpMsg.Type=MsgCopyScreen;
ms->Position=0;
TcpMsg.Length=ms->Size-sizeof(TcpMsgUint);
CopyScreen.Count=ChangedNum;
ms->Write(&TcpMsg,sizeof(TcpMsgUint));
ms->Write(&CopyScreen,sizeof(CopyScreenUInt));
ms->Position=0;
sock->SendStream(ms);
} 这个程序把屏幕画面切分为了多个部分,并存储画面为JPG格式,这样压缩率就变的十分
的高了。通过这种方法压缩处理过的数据,变得十分小.