ARP主机在线检测程序设计开发手记要点_第1页
ARP主机在线检测程序设计开发手记要点_第2页
ARP主机在线检测程序设计开发手记要点_第3页
ARP主机在线检测程序设计开发手记要点_第4页
ARP主机在线检测程序设计开发手记要点_第5页
已阅读5页,还剩3页未读 继续免费阅读

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

主机在线检测程序设计开发手记最近,校园网中出现了大量的ARP欺骗病毒,因此最近关注了一下ARP欺骗病毒的相关资料,自己编写了一个简易的电脑在线扫描器,虽然技术并深奥,但通过亲手编写发现不少有趣的问题,现记录如下。在互联网上搜索了一番,果然发现ARP病毒现在已经是“全面开花”,让很多网管朋友都束手无策。其实ARP欺骗病毒主要的技术就是利用了ARP协议中的信任漏洞造成的,同时Windows操作系统中也缺少相关的安全设置更加助长了ARP病毒的发作。首先,需要了解一下ARP协议,网上相关的讨论比较多,打大家可以Google一下,这里就不浪费大家的时间了。通过了解ARP协议的原理和功能,我们可以想到,如果需要查找出当前网络上的在线电脑情况,速度最快也最准确的应该就是发送ARP请求了。因为我们知道,当一台电脑需要向另外一台电脑通信的时候,首先必须知道的一个条件就是对方对MAC地址,为了能够正常的被其他电脑访问,网络上的每一台电脑都要能够及时正确的响应ARP请求,因此当每一台电脑接收到ARP请求后都会广播一个ARP响应,我们接收到这个回应就能知道那些电脑是处于在线状态的,和“Ping”电脑不同,每一台点都不会用“防火墙”阻隔ARP响应,而ICMP数据包可能会被防火墙阻挡。不过ARP请求不能跨越网段,这也大大限制了其在这方面的使用,不过对于一般用户更关心的就是自己所在网段的电脑情况,所以使用ARP请求还是比较可行的方法。在实际程序设计中,为了简化ARP请求发送的程序编写,我们主要使用了Windows系统中的IPHELP库函数来实现,在使用相关函数之前需要添加相关函数的头文件和库文件链接,例如我的代码中就是这样写的:#include<Winsock2.h>#include<iphlpapi.h>#pragmacomment(lib,"Ws2_32.lib")#pragmacomment(lib,"iphlpapi.lib")其中发送ARP请求包可以直接使用SendARP这个API函数,具体定义如下:DWORDSendARP(IPAddrDestIP,〃需要发送ARP请求的电脑的IP地址IPAddrSrcIP,〃你的IP地址,选填,可以为零PULONGpMacAddr,//指向查询的得到MAC地址的内存,即查询结果地址PULONGPhyAddrLen//前一项的内存大小);其实使用IPHelp中API的过程打家可以直接查询MSDN就可以得到详细的说明甚至是完整的范例代码,本程序在设计过程中就大量使用了范例提供的代码段。准备好以上的基本资料,就可以开始编写程序咯!!!至于GUI开发技术还是选择经典的MFC,虽然VC2005进入.net时代后好像逐渐减少了MFC的关心,不过MFC的经典代码资源是其他设计语言和设计方法都不能相比的。使用VC2005的向导创建一个对话框程序框架后,我们就可以来填充我们的程序代码了。首先考虑的是如何确定需要操作的网络适配器,最后决定还是使用一个下拉列表让用户自己手动选择需要操作的网卡算了,不然还要写很多判断代码,实在觉得“累”。按照以上的思路,在窗体上添加一个下拉列表控件,然后使用GetAdaptersAddresses获得网卡信息,这里就不再赘述了,相关资料。。。呵呵,…。MSDN。。…平时在编写一些小程序的时候都会避开一些比较麻烦的技术,比如多线程,这次也相同,按照一开始的计划,使用一个循环,向电脑所在网段200多台电脑发送ARP请求,然后通过检查是否有相应确定电脑在线的情况。可是使用很快编写好的程序进行测试,居然扫描一个网段使用了近十几分钟(夸张了,不过时间确实很长)。不会吧,比那些使用ICMP技术“Ping”电脑还要慢阿,怎么体现快速的特点阿。仔细思考,想到每次ARP请求如果在缓存中没有相关记录那么就需要等待网络中ARP响应包,200多个ARP响应得时间当然慢拉!看来逼着我用多线程开发了,5多线程下载工具使用的确实不少,可是编写多线程程序还真的很少,基本上是没有吧,呵呵,实在不好意思说,教过C++居然没有写过多线程的程序。既然这样,没有办法只能硬着头皮看MSDN了,可能读者会觉得为什么我总是会提到MSDN呢?呵呵主要是在家不能上网没有资料可查,哈哈,没想到吧!网管家中不上网。经过漫长的和E文的斗争,终于弄明白了其实如果只是简单的使用多线程进行计算,其实只要调用A仅BeginThread函数创建每个线程,其中有个参数指向需要进行计算的函数入口,(函数指针!C++你学过的想起来么?),另外一个参数可以传递函数运行所需要的参数。顺便提一下,MSDN中自从2003版以后,虽然很多知识都翻译成了中文,但是很多关键的描述反而使用中文描述后更难理解了,这主要是我们在学习过程中的很多计算机概念名词和微软翻译的不一致,还不如直接看E文。回到vs开发环境中继续敲代码,本来觉得就是简单的将原来可以运行的代码重新添加到多线程需要调用的那个函数中就可以了,可是实际调试的时候却发现程序非常的不稳定,有时候可以运行,有时候或者连续运行几次就会出现系统异常错误。其实写过程序的人应该都知道,宁愿程序在编译的时候不通过,也不希望去复查一个不稳定的程序,因为不能通过编译的程序是静态的等待你去解决问题,可是调试一个不稳定的程序需要动态的思考进程当前的操作,分析程序可能在执行代码中的问题。经过几次测试,主要是以下几点问题:.非法访问内存。.调用不存在的对象。.程序界面上结果异常。(通过程序界面响应可以判断程序运行进度)考虑到多线程在发送ARP请求后,其返回的响应的时间不能准确的确定,可是这时候程序已经进入了结果显示的代码片段,这时候界面显示不出正确内容,可是当显示内容代码后面就是一条delete命令删除前面使用的显示内容对象,这时候有些线程这时才返回结果,需要写入的内存已经被释放了,必然出现“非法访问内存”的错误。找到问题,就需要找到解决方法了,这时候想起来曾经用过的一个系统函数WaitForSingleObject函数,原形如下:DWORDWaitForSingleObject(HANDLEhHandle,DWORDdwMilliseconds);使用这个函数可以等待一个对象的执行,直到出现信号后继续,这个对象可以Changenotification>Consoleinput、Event、Job、Memoryresourcenotification、Mutex、Process、SemaphoreThread>Waitabletimer等。通过编码测试,调整相关编码后,最后终于解决了所有问题实现了原设计目的。通过这个小程序的设计可以发现使用VC++编写程序需要解决很多细小的问题,,例如.函数库的引入,头文件和库文件的添加。.字符串的处理,现在程序设计基本上都是使用Unicode,即宽字符编程,可是很多函数的返回值比如用来转换数值模式的IP地址到字符串形式的IP地址的函数返回的就是多字节符号串,也就是窄符号串,需要使用MultiByteToWideChar函数进行转换等。.多线程程序设计过程中函数体设计的健壮性非常重要,在本次设计开始没有使用相关函数对线程计算的结果进行管理,造成了数据的丢失,程序不稳定等问题。.可能会使用一些新的技术,例如本例中为了能够以后更好的扩展使用网络适配器下拉选择空间,采用了子类化技术,不过由于采用了新的技术浪费了不少脑细胞在MSDN上;还有大量使用了vc的模版技术,尝试了CMap等模版类的使用等。最后附上主窗口函数代码和已经编译的程序。//ARPtestDlg.cpp:实现文件//#include"stdafx.h"#include"ARPtest.h"#include"ARPtestDlg.h"#include<commctrl.h>#include"Adapters.h"#ifdef_DEBUG#definenewDEBUGNEW#endif#defineMAX_THREAD254//用于应用程序“关于”菜单项的CAboutDlg对话框classCAboutDlg:publicCDialog{public:CAboutDlg();//对话框数据enum{IDD=IDD_ABOUTBOX};protected:virtualvoidDoDataExchange(CDataExchange*pDX);//DDX/DDV支持//实现protected:DECLARE_MESSAGE_MAP()};CAboutDlg::CAboutDlg():CDialog(CAboutDlg::IDD){}voidCAboutDlg::DoDataExchange(CDataExchange*pDX){CDialog::DoDataExchange(pDX);}BEGIN_MESSAGE_MAP(CAboutDlg,CDialog)END_MESSAGE_MAP()//CARPtestDlg对话框CARPtestDlg::CARPtestDlg(CWnd*pParent/*=NULL*/):CDialog(CARPtestDlg::IDD,pParent)mhIcon=A仅GetApp()->LoadIcon(IDRMAINFRAME);}voidCARPtestDlg二DoDataExchange(CDataExchange*pDX){CDialog::DoDataExchange(pDX);DDXControl(pDX,IDCLIST1,mListCtrl);DDXControl(pDX,IDCIP,mIpCtrl);DDX_Control(pDX,IDC_PROGRESS1,m_ProcessCtrl);}BEGINMESSAGEMAP(CARPtestDlg,CDialog)ON_WM_SYSCOMMAND()ONWMPAINT()ON_WM_QUERYDRAGICON()//}}AFX_MSG_MAPONBNCLICKED(IDCBUTTON1,&CARPtestDlg::OnBnClickedButton1)ONBNCLICKED(IDSCAN,&CARPtestDlg::OnBnClickedScan)ENDMESSAGEMAP()//CARPtestDlg消息处理程序BOOLCARPtestDlg::OnInitDialog(){CDialog::OnInitDialog();//将“关于…”菜单项添加到系统菜单中。//IDMABOUTBOX必须在系统命令范围内。ASSERT((IDMABOUTBOX&0xFFF0)==IDM_ABOUTBOX);ASSERT(IDMABOUTBOX<0xF000);CMenu*pSysMenu=GetSystemMenu(FALSE);if(pSysMenu!=NULL)一{CStringstrAboutMenu;strAboutMenu.LoadString(IDS_ABOUTBOX);if(!strAboutMenu.IsEmpty()){pSysMenu->AppendMenu(MF_SEPARATOR);pSysMenu->AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu);}}//设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动//执行此操作SetIcon(m_hIcon,TRUE);//设置大图标SetIcon(m_hIcon,FALSE);//设置小图标//TODO:在此添加额外的初始化代码//subclasstheadapterinfomationwithcomboxm_NetAdapterCB.SubclassDlgItem(IDC_COMBO1,this);m_NetAdapterCB.FreshItems();//inistthelistInitList();//InitProcessCtrl|m_ProcessCtrl.SetRange(0,MAX_THREAD);mProcessCtrl.SetStep(1);returnTRUE;//除非将焦点设置到控件,否则返回TRUE}voidCARPtestDlg::OnSysCommand(UINTnID,LPARAMlParam){if((nID&0xFFF0)==IDM_ABOUTBOX){CAboutDlgdlgAbout;dlgAbout.DoModal();}elseCDialog::OnSysCommand(nID,lParam);}}//如果向对话框添加最小化按钮,则需要下面的代码//来绘制该图标。对于使用文档/视图模型的MFC应用程序,//这将由框架自动完成。voidCARPtestDlg::OnPaint(){if(IsIconic()){CPaintDCdc(this);//用于绘制的设备上下文SendMessage(WMICONERASEBKGND,reinterpret_cast<WPARAM>(dc.GetSafeHdc()),0);//使图标在工作矩形中居中intcxIcon=GetSystemMetrics(SM_CXICON);intcyIcon=GetSystemMetrics(SM_CYICON);CRectrect;GetClientRect(&rect);intx=(rect.Width()-cxIcon+1)/2;inty=(rect.Height()-cyIcon+1)/2;//绘制图标dc.DrawIcon(x,y,m_hIcon);}else(CDialog::OnPaint();)}〃当用户拖动最小化窗口时系统调用此函数取得光标显示。//HCURSORCARPtestDlg::OnQueryDragIcon()returnstatic_cast<HCURSOR>(m_hIcon);}]voidCARPtestDlg二OnBnClickedButton1()(DWORDIfCurSel=m_NetAdapterCB.GetSelIfIndex();if(!IfCurSel){AfxMessageBox(IDSERR1,MBICONWARNING);return;}if(NOERROR!=FlushIpNetTable(IfCurSel)){AfxMessageBox(IDS_ERR_2,MB_ICONWARNING);return;}if(!GetMacAddr(GetIpAddr()))m_strMac.LoadString(IDS_ERR_3);SetDlgItemText(IDCSTATICINFO,(LPCTSTR)mstrMac);}voidCARPtestDlg二InitList(void){COLORREFcrBkColor=::GetSysC010r(COLOR_3DFACE);mListCtrl.SetBkC010r(crBkColor);mListCtrl.SetTextBkC010r(crBkColor);mListCtrl.SetExtendedStyle(mListCtrl.GetExtendedStyle()|LVS_EX_HEADERDRAGDROP|LVSEXFULLROWSELECT);LVCOLUMNlvCol;ZeroMemory(&lvCol,sizeof(lvCol));//=//—InitColumns//TCHARszColumn[MAXPATH];lvCol.mask=LVCF_SUBITEM|LVCF_WIDTH|LVCF_TEXT;lvCol.cx=120;for(UINTiCol=0;iCol<=IDSCOLUMN_END-IDSCOLUMN_BEGIN;iCol++){lvCol.pszText=szColumn;lvCol.iSubItem=iCol;LoadString(NULL,IDS_COLUMN_BEGIN+iCol,szColumn,sizeof(szColumn)/sizeof(szColuif(m_ListCtrl.InsertColumn(iCol,&lvCol)==-1)return;)}IPAddrCARPtestDlg::GetIpAddr(void){IPAddripAddr;ZeroMemory(&ipAddr,sizeof(ipAddr));mIpCtrl.GetAddress(ipAddr);returnipAddr;)IPAddrCARPtestDlg::GetGateway(void){return(IPAddr)((GetIpAddr()&((〜0UL)<<8))+1);}boolCARPtestDlg::GetMacAddr(IPAddripAddr){ULONGpulMac[2];ULONGulLen=6;DWORDdwRetVal=0;ZeroMemory(pulMac,sizeof(pulMac));if((dwRetVal=SendARP(htonl(ipAddr),0,pulMac,&ulLen))!=NO_ERROR){returnfalse;)PBYTEpbHexMac=(PBYTE)pulMac;m_strMac.Format(IDS_MAC_FORMAT,pbHexMac[0],pbHexMac[1],pbHexMac[2],\pbHexMac[3],pbHexMac[4],pbHexMac[5]);returntrue;)voidCARPtestDlg::OnBnClickedScan(){this->BeginWaitCursor();DWORDIfCurSel=mNetAdapterCB.GetSelIfIndex();if(!IfCurSel){AfxMessageBox(IDSERR_1,MBICONWARNING);return;)if(NOERROR!=FlushIpNetTable(IfCurSel)){AfxMessageBox(IDS_ERR_2,MB_ICONWARNING);return;1if(m_IpCtrl.IsBlank()){AfxMessageBox(IDS_ERR_4,MB_ICONWARNING);return;)m_ListCtrl.DeleteAllItems();m_ProcessCtrl.SetPos(0);typedefCWinThread*PCWinThread;IPAddrStartIP;ThreadParams*pThreadParm=newThreadParams[MAX_THREAD];PCWinThreadTheadList[MAXTHREAD];StartIP=GetGateway();for(DWORDi=0;i<MAX_THREAD;i++){pThreadParm[i].blive=FALSE;pThreadParm[i].ip=StartIP+i;TheadList[i]=AfxBeginThread(GetArpResponse,&pThreadParm[i],THREADPRIORITYNORMAL,NULL,CREATESUSPENDED,NULL);TheadList[i]->m_bAutoDelete=FALSE;TheadList[i]->ResumeThread();)for(intj=0;j<MAX_THREAD;j++){mProcessCtrl.StepIt();if(TheadList[j]!=NULL){WaitForSingleObject(*(TheadList[j]),INFINITE);deleteTheadListjTheadList[j]=NULL;))DisplayList(pThreadParm,MAX_THREAD);delete口pThreadParm;this->EndWaitCursor();this->DrawCaption(this->GetDC(),

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论