[转载]VB防火墙的开发原理-VB编程

导读:


防火墙主要有日志,网络状态列表,网络状态控制(如拦截)组成的。
正在装载数据……
所以,我们要3个界面,一个是主界面——状态列表。一个是日志界面,一个是控制界面。
打开VB新建一个工程,添加一个窗体。一共要3个窗体,2个模块。太复杂了,我也在考虑怎么写才能让大家理解。文章写的不好,还请大家包含。说下原理:
一、监控TCP连接


黑客程序或木马程序的本质是实现数据传输。TCP和UDP(用户数据文报协议)是两个最常用的数据传输协议,它们都使用设置监听端口的方法来完成数据传输。


实时监控所有端口的连接情况、及时对异常连接发出警告并提示用户删除异常连接,就可以有效地达到防黑目的。
使用微软的IP助手库函数(iphlpapi.dll)是一个捷径。其中的GetTcpTable函数能返回当前系统中全部有效的TCP连接。其定义为:
DeclareFunctionGetTcpTableLib"iphlpapi.dll"(ByRefpTcpTableAsMIB_TCPTABLE,ByRefpdwSizeAsLong,ByValbOrderAsLong)AsLong
其中参数一是TCP连接表缓冲区的指针,参数二是缓冲区大小(当缓冲区不够大时,该参数返回实际需要的大小),参数三指示连接表是否需要按“LocalIP”、“Localport”、“RemoteIP”、“Remoteport”依次进行排序。
对于监控UDP连接表,可使用GetUdpTable函数完成。由于在使用上完全类似,这里略去讨论。
二、异常警告及删除连接
通过定时比较前后两个TCP连接表,我们可以立即发现异常并发出警告。收到警告信号后,我们应首先将可疑连接删除掉,然后再仔细查找系统中是否有安全漏洞或有可疑进程在工作。IP助手库函数中的SetTcpEntry函数可以帮助我们删除可疑连接。其定义为:
PublicDeclareFunctionSetTcpEntryLib"IPhlpAPI"(pTcpRowAsMIB_TCPROW)AsLong'Thisisusedtocloseanopenport.
在调用此函数之前,应将欲删连接的状态置为MIB_TCP_STATE_Delete_TCB(删除)。MIB_TCP_STATE_Delete_TCB也是目前唯一可在运行时设置的状态。
好了,有了这些,一个放火墙的基本原理以及方法已经知道了,哈哈,我们想将这些函数,API封装起来。建立一个类模块,名称为modNetstat,代码如下



'-------------------------------------------------modNetstat-------------------------------
OptionExplicit


'定义一些ICMP协议


PublicMIBICMPSTATSAsMIBICMPSTATS
PublicTypeMIBICMPSTATS
dwEchosAsLong
dwEchoRepsAsLong
EndType


PublicMIBICMPINFOAsMIBICMPINFO
PublicTypeMIBICMPINFO
icmpOutStatsAsMIBICMPSTATS
EndType


PublicMIB_ICMPAsMIB_ICMP
PublicTypeMIB_ICMP
statsAsMIBICMPINFO
EndType
'GetIcmpStatistics函数能够让你查看当前ICMP数据报的流量
PublicDeclareFunctionGetIcmpStatisticsLib"iphlpapi.dll"(pStatsAsMIBICMPINFO)AsLong
PublicLast_ICMP_CntAsInteger


'-------------------------------------------------------------------------------
'定义一些TCP协议


TypeMIB_TCPROW
dwStateAsLong
dwLocalAddrAsLong
dwLocalPortAsLong
dwRemoteAddrAsLong
dwRemotePortAsLong
EndType


TypeMIB_TCPTABLE
dwNumEntriesAsLong
table(100)AsMIB_TCPROW
EndType
PublicMIB_TCPTABLEAsMIB_TCPTABLE
'GetTcpTable函数能返回当前系统中全部有效的TCP连接
DeclareFunctionGetTcpTableLib"iphlpapi.dll"(ByRefpTcpTableAsMIB_TCPTABLE,ByRefpdwSizeAsLong,ByValbOrderAsLong)AsLong
'SetTcpEntry函数可以帮助我们删除可疑连接
PublicDeclareFunctionSetTcpEntryLib"IPhlpAPI"(pTcpRowAsMIB_TCPROW)AsLong'Thisisusedtocloseanopenport.
'定义连接状态为13个
PublicIP_States(13)AsString
PrivateLast_Tcp_CntAsInteger


'-------------------------------------------------------------------------------
'定义winsock相关内容


PrivateConstAF_INET=2
PrivateConstIP_SUCCESSAsLong=0
PrivateConstMAX_WSADescription=256
PrivateConstMAX_WSASYSStatus=128
PrivateConstSOCKET_ERRORAsLong=-1
PrivateConstWS_VERSION_REQDAsLong=&H101


TypeHOSTENT
h_nameAsLong'officialnameofhost
h_aliasesAsLong'aliaslist
h_addrtypeAsInteger'hostaddresstype
h_lengthAsInteger'lengthofaddress
h_addr_listAsLong'listofaddresses
EndType


Typeservent
s_nameAsLong'(pointertostring)officialservicename
s_aliasesAsLong'(pointertostring)aliaslist(mightbenull-seperatedwith2nullterminated)
s_portAsLong'port#
s_protoAsLong'(pointerto)protocoltouse
EndType


PrivateTypeWSADATA
wVersionAsInteger
wHighVersionAsInteger
szDescription(0ToMAX_WSADescription)AsByte
szSystemStatus(0ToMAX_WSASYSStatus)AsByte
wMaxSocketsAsLong
wMaxUDPDGAsLong
dwVendorInfoAsLong
EndType


PublicDeclareFunctionntohsLib"WSOCK32.DLL"(ByValnetshortAsLong)AsLong
'inet_addr将IP地址从点数格式转换成无符号长整型
PrivateDeclareFunctioninet_addrLib"WSOCK32.DLL"(ByValCPAsString)AsLong
'inet_ntoa将IP地址从点数格式转换成ascii
PrivateDeclareFunctioninet_ntoaLib"WSOCK32.DLL"(ByValinnAsLong)AsLong
PrivateDeclareFunctiongethostbyaddrLib"WSOCK32.DLL"(AddrAsLong,ByValaddr_lenAsLong,ByValaddr_typeAsLong)AsLong
PrivateDeclareFunctiongethostbynameLib"WSOCK32.DLL"(ByValhost_nameAsString)AsLong
PrivateDeclareFunctionWSAStartupLib"WSOCK32.DLL"(ByValwVersionRequiredAsLong,lpWSADATAAsWSADATA)AsLong
PrivateDeclareFunctionWSACleanupLib"WSOCK32.DLL"()AsLong
'若该函数的返回值非0,则为存储器的地址。由于VB不能直接操作地址,所以还必须调用RtlMoveMemory函数将数据写入地址中
PrivateDeclareSubRtlMoveMemoryLib"kernel32"(hpvDestAsAny,ByValhpvSourceAsLong,ByValcbCopyAsLong)
'将数据转换为内存二进制形式字符串
DeclareSubCopyMemoryLib"kernel32"Alias"RtlMoveMemory"(DestAsAny,SrcAsAny,ByValcb&)
DeclareFunctionlstrlenLib"kernel32"(ByVallpStringAsAny)AsInteger
PrivateBlockedAsBoolean
'定义网络状态
SubInitStates()
IP_States(0)="未知"
IP_States(1)="已经关闭"
IP_States(2)="监听"
IP_States(3)="发送同步空闲字符"
IP_States(4)="接收同步空闲字符"
IP_States(5)="数据交换中"
IP_States(6)="结束等待1"
IP_States(7)="结束等待2"
IP_States(8)="关闭等待"
IP_States(9)="关闭中"
IP_States(10)="命令正确应答"
IP_States(11)="连接等待"
IP_States(12)="删除TCP连接"
EndSub


PublicFunctionGetAscIP(ByValinnAsLong)AsString
DimnStr&
DimlpStrAsLong
DimretStringAsString
retString=String(32,0)
lpStr=inet_ntoa(inn)
IflpStrThen
nStr=lstrlen(lpStr)
IfnStr>32ThennStr=32
CopyMemoryByValretString,ByVallpStr,nStr
retString=Left(retString,nStr)
GetAscIP=retString
Else
GetAscIP="无法取得IP"
EndIf
EndFunction



好了,日志是建立一个LOG文件,所以我们将所需要的函数封装一个类模块里。建立一个public模块。代码如下
'对日志的定义
PublicFunctionLog(RemAAsString,RemPAsString,LocPAsString,TxtAsString)


DimffAsLong
ff=FreeFile
'打开log文件
OpenApp.Path&"/log.log"ForAppendAs#ff
'向log文件写入数据
Write#ff,Time&"-"&Date,RemA,RemP,LocP,Txt
'将数据在日志窗口中显示出来
Frmlog.lstLog.ListItems.Add,,Time&"-"&Date
Frmlog.lstLog.ListItems(Frmlog.lstLog.ListItems.Count).SubItems(1)=RemA
Frmlog.lstLog.ListItems(Frmlog.lstLog.ListItems.Count).SubItems(2)=RemP
Frmlog.lstLog.ListItems(Frmlog.lstLog.ListItems.Count).SubItems(3)=LocP
Frmlog.lstLog.ListItems(Frmlog.lstLog.ListItems.Count).SubItems(4)=Txt
'结束日志操作
Close#ff


EndFunction


好了,封装好了函数以及API数据库,下面是设计界面,以及功能结合了:)
先建立主窗体,这里将名称改为frmMain,我不想抹杀你们的创意,但是为了代码的最后测试成功,请你不要改变:)
点工程——部件,插入microsoftwindowscommoncontrols6.0(sp4)前面点上小钩,确定:)
回到桌面,双点击Toolbar,加入后,在上面右键属性。
依次插入按钮,如下:


索引 标题 样式 图象
1 停止拦截1-tbrcheck 暂时不说
2 刷新 0-tbrdefault
3 (空)3-tbrseparator
4 查看日志0-tbrdefault
插入2个ImageList空间,命名为imgHot和imgCold
依次插入图片,其实就是“停止拦截”等按钮上面显示的图片
在Toolbar上面右键属性如图3:


修改图象列表为imgcold,热图象列表为imghot
好了,在图2,我们看到图象图象后面的数字,这就是imgcold图片列表的数字:)
加入ListView控件
右键——属性——列首
索引文本宽度
1远程IP自己调节吧:)
2远程端口
3本地端口
4状态
好了,在加入一个timer控件,名称为tmrRefresh,这个是用来刷新网络状态列表的。
将Interval设顶为250
最后完成界面如图:


添加代码如下:
'定义一些常量
PrivatelCAsInteger
PublicBlkAsString


Privatea_RemA(1000)AsString
Privatea_LocP(1000)AsString
Privatea_RemP(1000)AsString


Privatea_CountAsLong
'下面是刷新网络状态的函数
PublicFunctionRefreshTable(OptionalforceAsBoolean=False)


OnErrorResumeNext


DimtcptAsMIB_TCPTABLE,lAsLong
DimxAsInteger,iAsInteger
DimRemAAsString,LocPAsString,RemPAsString


l=Len(MIB_TCPTABLE)
GetTcpTabletcpt,l,0
x=tcpt.dwNumEntries


Ifx lCOrforceThen


lC=x


ListView1.ListItems.Clear


Fori=0Tox-1


RemA=GetAscIP(tcpt.table(i).dwRemoteAddr)
RemP=ntohs(tcpt.table(i).dwRemotePort)
LocP=ntohs(tcpt.table(i).dwLocalPort)
ListView1.ListItems.Add,"x"&i,RemA
ListView1.ListItems(ListView1.ListItems.Count).SubItems(1)=RemP
ListView1.ListItems(ListView1.ListItems.Count).SubItems(2)=LocP
ListView1.ListItems(ListView1.ListItems.Count).SubItems(3)=modNetstat.IP_States(state)



Nexti


EndIf


EndFunction


PrivateSubForm_Load()
'调用网络状态函数
modNetstat.InitStates
'一开始就刷新网络状态列表
RefreshTable
EndSub


PrivateSubListView1_MouseUp(ButtonAsInteger,ShiftAsInteger,xAsSingle,yAsSingle)
'判断是否为鼠标右键按下
IfButton=2AndListView1.ListItems.Count>0Then
'调用控制按钮,在下面将说到
frmMain.PopupMenufrmMenu.mnuConn
EndIf
EndSub


PrivateSubtmrRefresh_Timer()
'定时刷新网络状态列表
RefreshTable
EndSub


PublicSubToolbar1_ButtonClick(ByValButtonAsMSComctlLib.Button)
SelectCaseButton.Index


Case1
'停止功能按钮
IfButton.Caption="停止"Then


Button.Caption="继续"
Button.ToolTipText="继续开始工作"
tmrRefresh.Enabled=False
'停止刷新网络状态列表,先面反之
Else


Button.Caption="停止"
Button.ToolTipText="停止工作"
tmrRefresh.Enabled=True


EndIf


Case2
'刷新按钮功能
RefreshTable


Case4
'显示日志
Frmlog.Show


EndSelect


EndSub
好了,下面定义控制按钮:)也就是网络状态上右键显示的拦截连接
新建一个窗体,命名为frmMenu,只需要有一个菜单,如图:


修改菜单属性:
标题 名称
mnuConnmnuConn
拦截连接 mnuDis
如图:


好了,添加代码如下:


PrivateSubmnuDis_Click()


DimtcptAsMIB_TCPTABLE
DimlAsLong
DimiAsLong
DimRemAAsString,RemPAsString,LocPAsString


i=Right(frmMain.ListView1.SelectedItem.Key,Len(frmMain.ListView1.SelectedItem.Key)-1) 1


RemA=frmMain.ListView1.ListItems(i)
RemP=frmMain.ListView1.ListItems(i).SubItems(1)
LocP=frmMain.ListView1.ListItems(i).SubItems(2)


l=Len(MIB_TCPTABLE)
GetTcpTabletcpt,l,0


tcpt.table(i-1).dwState=12
'断开TCP连接,还记得一开始说的函数吗?
SetTcpEntrytcpt.table(i-1)
DoEvents
'写入日志
LogRemA,RemP,LocP,"拦截连接"
EndSub
好了,最后是一个日志操作窗体,建立一个名称为Frmlog的窗体
一个用一个listview和command控件,调整位置如图


listview属性
名称lstLog
列首索引文本大小自己调节
1时间
2IP
3远程端口
4本地端口
5说明
添加代码如下
PrivateSubCommand1_Click()
DimrAsString


r=MsgBox("防火墙日志是有效检查黑客入侵的手段!"&vbCrLf&vbCrLf&"清除日志?",vbQuestion&vbYesNo,"注意!")
'如果按的是“是”那么
Ifr=vbYesThen


DimffAsLong
ff=FreeFile
'打开日志写入空数据,也就是清空日志
OpenApp.Path&"/log.log"ForOutputAs#ff


Close#ff
'清空列表
lstLog.ListItems.Clear


EndIf
EndSub
程序运行后,成功拦截我以前开发的一个盗取拨号密码的木马,如图:
第一次获得密码是没拦截,拦截后提示无法连接


好了,我们完成了对防火墙的简单操作,文章还有很大改进余地,大家可以发挥自己的思维去改变,去完善。


 


文章转载自『幽月's Blog』地址: http://a1l.cn/article.asp?id=19182本文转自
http://a1l.cn/article.asp?id=19182

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值