我找到了:
发信人:zzzzzzzzzzzz(肥龟·Synchronize),信区
rogramming
标题:拦截你的NetSend(一)
发信站:逸仙时空Yat-senChannel(SunMay412:51:262003),站内信件
作者:ZSQ
大家应该会经常收到一些骚扰的NetSend消息,有没有想过怎么实现消息过滤呢?
有没有想过为netsend定制一个pp一点的界面呢,或者利用NetSend做一个聊天室
呢?
归结到最后,我们发现问题的关键在于,如何替换掉WindowsNetSend服务
如果大家注意一下nbtstat的输出,就会发现
NetBIOSRemoteMachineNameTable
NameTypeStatus
--------------------------------------------
ZSQ<00>UNIQUERegistered
CHINA<00>GROUPRegistered
ZSQ<20>UNIQUERegistered
ZSQ<03>UNIQUERegistered
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~这个就是NetSend用的Stub
CHINA<1E>GROUPRegistered
ZSQ<01>UNIQUERegistered
类似于Socket中端口,所有的NetSend消息,都是通过这个位置传到你的计算机的
所以我们的第一个任务就是要先把这个端口关闭,然后用我们自己的服务来替换掉它
命令行方式的netstopmsg可以把整个消息服务关闭
只要我们写的程序沿用消息服务的协议,就可以完全地替换掉它的功能了
(待续)
Windows的消息服务沿用的是SMB/CIFSOverNetbiosOverTCP/IP的架构
我们自然就从这方面着手,主要实现两个功能,1是接收,二是发送
以下是实现的源代码,具体的原理也容易理解
//QMessngr.h
#defineWM_QMESSNGR_NOTIFYWM_USER+1
#defineMAX_BUFFER_LENGTH500
#defineREPLY_LENGTH35
#defineSMB_HEADER_LENGTH35
#defineNAME_LENGTH16
classCQMessngr
{
public:
CQMessngr();
virtual~CQMessngr();
public:
//发送函数
BOOLSend(char*sTo,char*sMsg);
//启动/停止消息接收线程
//参数:HWND接收消息的窗口句柄,
//收到消息后会发送WM_MESSENGER_NOTIFY到该窗口
intStart(HWNDhwnd);
intStop();
//线程函数
staticUINTMsgMonitorProc(LPVOIDparam);
staticCQMessngr*pseudoThis;//
staticHWNDhWndNotify;
public:
charm_sLocalName[16];
charm_sMsg[400];
UCHARm_sBuffer[500];
CWinThread*m_pThread;
};
(待续)
//QMessngr.cpp
#pragmacomment(lib,"netapi32.lib")
#pragmacomment(lib,"ws2_32.lib")
CQMessngr*CQMessngr:
seudoThis=NULL;
HWNDCQMessngr::hWndNotify=NULL;
voidToNcbName(char*str1,char*str2)
{
charpattern[20];
sprintf(pattern,"%%%ds",NAME_LENGTH);
sprintf(str2,pattern,"/3");
memcpy(str2,str1,strlen(str1));
}
CQMessngr::CQMessngr()
{
//成员变量初始化
WSADATAwsadata;
charname[NAME_LENGTH];
WSAStartup(MAKEWORD(2,0),&wsadata);
gethostname(name,NAME_LENGTH);
_tcsupr(name);
strcpy(m_sLocalName,name);
strcpy(m_sRemoteName,"*");
strcpy(m_sMsg,"");
//NETBIOS初始化
NCBncb;
memset(&ncb,0,sizeof(ncb));
ncb.ncb_command=NCBRESET;
intb=Netbios(&ncb);
charncbname[NAME_LENGTH];
ToNcbName(m_sLocalName,ncbname);
ncb.ncb_command=NCBADDNAME;
memcpy((char*)ncb.ncb_name,ncbname,NAME_LENGTH);
b=Netbios(&ncb);
if(b==NRC_DUPNAME){
MessageBox(NULL,"Messngr端口发现重名,初始化失败","警告",MB_OK);
return;
}elseif(b!=0){
MessageBox(NULL,"Messngr未知错误,初始化失败","警告",MB_OK);
}
}
CQMessngr::~CQMessngr()
{
NCBncb;
charncbname[NAME_LENGTH];
memset(&ncb,0,sizeof(ncb));
ToNcbName(m_sLocalName,ncbname);
ncb.ncb_command=NCBDELNAME;
memcpy((char*)ncb.ncb_name,ncbname,NAME_LENGTH);
intb=Netbios(&ncb);
}
//发送函数
BOOLCQMessngr::Send(char*sTo,char*sMsg)
{
NCBncb;
charncbname[NAME_LENGTH];
intbRet;
memset(&ncb,0,sizeof(ncb));
ToNcbName(m_sLocalName,ncbname);
memcpy((char*)ncb.ncb_name,ncbname,16);
ToNcbName(sTo,ncbname);
memcpy((char*)ncb.ncb_callname,ncbname,16);
ncb.ncb_command=NCBCALL;
bRet=Netbios(&ncb);
//memset(buffer,0,sizeof(buffer));
memset(m_sBuffer,0,sizeof(m_sBuffer));
sprintf((char*)m_sBuffer,"%c%s%c",0xff,"SMB",0xD0);
unsignedchar*pos=m_sBuffer+0x21;
intLength=7+strlen(m_sLocalName)+strlen(sTo)+strlen(sMsg);
*((WORD*)pos)=Length;
pos+=2;
*(pos++)=4;//TYPE
strcpy((char*)pos,m_sLocalName);//MACHINENAME
pos+=strlen(m_sLocalName)+1;
*(pos++)=4;//TYPE
strcpy((char*)pos,sTo);//MACHINENAME
pos+=strlen(sTo)+1;
*(pos++)=1;
*((WORD*)pos)=strlen(sMsg);
pos+=2;
memcpy(pos,sMsg,strlen(sMsg));
ncb.ncb_buffer=m_sBuffer;
ncb.ncb_length=Length+0x23;
ncb.ncb_command=NCBSEND;
bRet=Netbios(&ncb);
ncb.ncb_command=NCBRECV;
ncb.ncb_buffer=m_sBuffer;
ncb.ncb_length=MAX_BUFFER_LENGTH;
bRet=Netbios(&ncb);
ncb.ncb_command=NCBHANGUP;
bRet=Netbios(&ncb);
returnTRUE;
}
//初始化NETBIOS功能,启动消息接收线程
//参数:HWND接收消息的窗口句柄,
//收到消息后会发送WM_MESSENGER_NOTIFY到该窗口
intCQMessngr::Start(HWNDhwnd)
{
pseudoThis=this;
hWndNotify=hwnd;
m_pThread=AfxBeginThread(MsgMonitorProc,NULL);
returnTRUE;
}
intCQMessngr::Stop()
{
TerminateThread(m_pThread->m_hThread,0);
return0;
}
//线程函数
UINTCQMessngr::MsgMonitorProc(LPVOIDparam)
{
NCBncb;
charncbname[NAME_LENGTH];
intbRet;
while(TRUE)
{
////////////LISTENONNAMESTUB//////////////
memset(&ncb,0,sizeof(ncb));
ToNcbName(pseudoThis->m_sLocalName,ncbname);
memcpy((char*)ncb.ncb_name,ncbname,NAME_LENGTH);
strcpy((char*)ncb.ncb_callname,"*");
ncb.ncb_command=NCBLISTEN;
bRet=Netbios(&ncb);
//RECEIVETHENETBIOSBLOCKWHICHCONTAININGSMBDATA//
ncb.ncb_command=NCBRECV;
ncb.ncb_buffer=pseudoThis->m_sBuffer;
ncb.ncb_length=MAX_BUFFER_LENGTH;
bRet=Netbios(&ncb);
////////////SENDNETBIOSACK/////////////////
pseudoThis->m_sBuffer[33]=0;
ncb.ncb_length=REPLY_LENGTH;
ncb.ncb_command=NCBSEND;
bRet=Netbios(&ncb);
///////////PARSETHESMBPACKET//////////////
//SMBStructure
//TYPE1byte04Name
//REMOTEMACHINENAMEstringterminatewith'/0'
//TYPE1byte04Name
//LOCALMACHINENAMEstringterminatewith'/0'
//TYPE1byte01Message
//LENGTH2byte
//DATAstringwiththeLengthindicateinLENGTH
unsignedchar*pos=pseudoThis->m_sBuffer+SMB_HEADER_LENGTH+1;
strcpy(pseudoThis->m_sRemoteName,(char*)pos);
pos+=strlen((char*)pos)+2;
pos+=strlen((char*)pos)+2;
WORDMsgLength=*((WORD*)pos);
pos+=2;
memset(pseudoThis->m_sMsg,0,sizeof(pseudoThis->m_sMsg));
memcpy(pseudoThis->m_sMsg,(char*)pos,MsgLength);
*(pseudoThis->m_sMsg+MsgLength)=0;
////////////POSTAMESSAGETOTHENOTIFYWINDOW//////////
PostMessage(hWndNotify,WM_QMESSNGR_NOTIFY,NULL,NULL);
}
return0;
}
(待续)