返回列表 发帖

[讨论]用VB编写防火墙的可行性!

LBHIDDEN[0]LBHIDDEN因为偶只会VB,呵呵。。。而且有很多东西不清楚,向达人讨教了。
在网上找到的,请各位评评:
liuyinfeng的回复:  
关于防火墙,如果您想完成包过滤的功能,我是指真正意义上的包过滤,那么和您用vb,tc,或vc是无关的,如果在window平台下,您用且只能用标准c,然后用NDIS,在数据包进入协议栈,系统还没有处理前截获它,进行您自己的处理。这就是为什么要选择NDIS的原因,理论上,NDIS属于驱动程序级的东西,它是在操作系统的下面,这样,我们才能抢先在操作系统之前进行我们的处理。  
NDIS的要求就是ANSI  C,没听说过VB做防火墙的,除非是界面,关键的东西绝对是C,计算机专业大三的学生不应该还是新手!两个月你不用想着什么都自己做,那样不切实际。NDIS是MS的网络设备接口规范的缩写,那是在windows下做防火墙必须知道的东西,而且关键是对DDK中NDIS部分的了解,语言除了C,你不用想别的了  
  NDIS  (网络驱动器接口规范)是Windows的通信协议程序(比如TCP/IP)和网络设备驱动器之间通信的规范。NDIS为下面几种规定了接口:1.通过从叫做帧的格式化单位(有时叫信息包或数据包)发送和接收提取数据的程序。这个程序通常叫做协议堆栈,通常它是开放式系统互连参考模型(OSI)的第三或者第四层(网络寻址和传输层)。例子是TCP/IP和Internet网络信息包交换。2.设备驱动程序,它直接和网络接口卡(NIC)或者其他硬件适配器交互,这些设备以电信号的形式在通信线路上接受和发送数据。驱动程序和NIC在数据链路控制(MAC地址)层的媒体访问子层交互。(把信号放在线路上的是1层或者OSI的物理层)。MAC驱动程序的例子是那些以太网,光纤分布式数据接口和令牌网的驱动程序。3.协议管理器程序,在系统启动或者添加了新设备的时候这个程序告诉每个辅助协议堆栈程序和MAC驱动程序其他计算机的位置。这是所谓的绑定。系统文件PROTOCOL.INI确定协议堆栈使用的MAC驱动程序和他们的位置。在一台计算机连接入多个网络的时候,一个协议堆栈可以用于多个MAC驱动程序。一个单独的MAC驱动程序也能绑定到一台计算机的多个协议堆栈里。NDIS是由微软和3Com开发的。使用NDIS,Windows软件开发者可以为任何硬件开发商的通信适配器开发针对MAC驱动程序的协议堆栈。通过同样的方法,任何一个适配器厂商都可以编写适用于任何协议堆栈程序的MAC驱动程序软件。一个类似的接口程序叫做开放数据连接接口(ODI),它用于Novell的NetWare局域网开放系统。最新的NDIS版本NDIS 5.0规定了Windows 98和Windows NT 5.0的接口。在它里面为新型的微型端口设备模型确立了即插即用设备的特征。

[讨论]用VB编写防火墙的可行性!

纵观国内外的个人防火墙的实现方案,概括起来有以下几种:
用户层拦截winsock函数:因为在Windows上,大部分网络应用程序都是利用winsock提供的网络API来实现网络通信的。只要对这些API进行了拦截,就可以实现对网络数据的控制。这是一种最为简单的方案,如果把网络数据的拦截方案分成一个层次的话,这种方案位于最上面的一层。
用户层的SPI过滤接口:在WS2_32.DLL的下面,系统拥有Windows Sockets 2 SPI层,也就是Winsock Service Provider Interfaces。SPI是Windows Sockets 2提供的一个接口,使开发人员能够在ws2_32.dll之下通过SPI接口插入一层进行过滤。ws2_32.dll在需要的时候会自动加载插入的SPI。这种方案也是用户层下的一种方案,对于一些通过内核驱动来实现通信的数据则无能为力。早期的费尔防火墙便采用了这种技术。他可以过滤所有IP数据包。他的拦截层次比前面所说的拦截winsock函数要低一些,但是仍同属于用户层的拦截。
内核层的NDIS过滤钩子:Windows提供了一个IP过滤驱动ipfltdrv.sys。NDIS过滤钩子允许用户向IP过滤驱动注册回调函数。这样所有的数据都会发送到回调函数中去,在回调函数中可以选择拦截还是通行。这种方案可以拦截所有的IP包,他所依赖的是系统提供的IP过滤驱动。同时也是内核层最上面一层的拦截方案。
内核层的NDIS协议层驱动:NDIS协议层驱动是位于微端口驱动之上。该方案可以拦截所有数据链路层的数据包。相对于NDIS过滤钩子,该方案更为底层一点。
内核层的NDIS中间层驱动:NDIS中间层驱动位于协议层和微端口之间,起一个“中间过滤”的作用。该方案可拦截所有数据链路层的数据包。
内核层的NDIS微端口驱动:NDIS微端口驱动位于最底层,直接操作物理网卡。该方案是所有方案中最底层的部分。其难度也最大,是NDIS中最为复杂的部分。他可以拦截所有通过物理层的数据。
目前,大部分商业软件防火墙多采用内核层的过滤技术。并且越来越趋向于更低的层次。同时也结合了部分用户层的过滤技术。因为涉及到通用性等原因,用户层的拦截在不久的将来并不会消失,相反会使程序更加地灵活和全面。

TOP

[讨论]用VB编写防火墙的可行性!

对vb不大懂.
希望这些可以帮你.

火墙主要有日志,网络状态列表,网络状态控制(如拦截)组成的。所以,我们要3个界面,一个是主界面——状态列表。一个是日志界面,一个是控制界面。
打开VB新建一个工程,添加一个窗体。一共要3个窗体,2个模块。太复杂了,我也在考虑怎么写才能让大家理解。文章写的不好,还请大家包含。说下原理:
一、监控 TCP连接
黑客程序或木马程序的本质是实现数据传输。TCP和UDP(用户数据文报协议)是两个最常用的数据传输协议,它们都使用设置监听端口的方法来完成数据传输。
实时监控所有端口的连接情况、及时对异常连接发出警告并提示用户删除异常连接,就可以有效地达到防黑目的。
使用微软的IP助手库函数(iphlpapi.dll)是一个捷径。其中的 GetTcpTable函数能返回当前系统中全部有效的 TCP连接。其定义为:
Declare Function GetTcpTable Lib "iphlpapi.dll" (ByRef pTcpTable As MIB_TCPTABLE, ByRef pdwSize As Long, ByVal bOrder As Long) As Long
其中参数一是 TCP连接表缓冲区的指针,参数二是缓冲区大小(当缓冲区不够大时,该参数返回实际需要的大小),参数三指示连接表是否需要按“Local IP”、“Localport”、“Remote IP”、“Remote port”依次进行排序。
对于监控 UDP连接表,可使用 GetUdpTable函数完成。由于在使用上完全类似,这里略去讨论。
二、异常警告及删除连接
通过定时比较前后两个 TCP连接表,我们可以立即发现异常并发出警告。收到警告信号后,我们应首先将可疑连接删除掉,然后再仔细查找系统中是否有安全漏洞或有可疑进程在工作。IP助手库函数中的 SetTcpEntry函数可以帮助我们删除可疑连接。其定义为:
Public Declare Function SetTcpEntry Lib "IPhlpAPI" (pTcpRow As MIB_TCPROW) As Long ';This is used to close an open port.
在调用此函数之前,应将欲删连接的状态置为 MIB_TCP_STATE_DELETE_TCB(删除)。MIB_TCP_STATE_DELETE_TCB也是目前唯一可在运行时设置的状态。
好了,有了这些,一个放火墙的基本原理以及方法已经知道了,哈哈,我们想将这些函数,API封装起来。建立一个类模块,名称为modNetstat,代码如下
‘-------------------------------------------------modNetstat-------------------------------
Option Explicit
';定义一些ICMP协议
Public MIBICMPSTATS As MIBICMPSTATS
Public Type MIBICMPSTATS
dwEchos As Long
dwEchoReps As Long
End Type
Public MIBICMPINFO As MIBICMPINFO
Public Type MIBICMPINFO
icmpOutStats As MIBICMPSTATS
End Type
Public MIB_ICMP As MIB_ICMP
Public Type MIB_ICMP
stats As MIBICMPINFO
End Type
';GetIcmpStatistics函数能够让你查看当前ICMP数据报的流量
Public Declare Function GetIcmpStatistics Lib "iphlpapi.dll" (pStats As MIBICMPINFO) As Long
Public Last_ICMP_Cnt As Integer
';-------------------------------------------------------------------------------
';定义一些TCP协议
Type MIB_TCPROW
dwState As Long
dwLocalAddr As Long
dwLocalPort As Long
dwRemoteAddr As Long
dwRemotePort As Long
End Type
Type MIB_TCPTABLE
dwNumEntries As Long
table(100) As MIB_TCPROW
End Type
Public MIB_TCPTABLE As MIB_TCPTABLE
';GetTcpTable函数能返回当前系统中全部有效的 TCP连接
Declare Function GetTcpTable Lib "iphlpapi.dll" (ByRef pTcpTable As MIB_TCPTABLE, ByRef pdwSize As Long, ByVal bOrder As Long) As Long
';SetTcpEntry函数可以帮助我们删除可疑连接
Public Declare Function SetTcpEntry Lib "IPhlpAPI" (pTcpRow As MIB_TCPROW) As Long ';This is used to close an open port.
';定义连接状态为13个
Public IP_States(13) As String
Private Last_Tcp_Cnt As Integer
';-------------------------------------------------------------------------------
';定义winsock相关内容
Private Const AF_INET = 2
Private Const IP_SUCCESS As Long = 0
Private Const MAX_WSADescription = 256
Private Const MAX_WSASYSStatus = 128
Private Const SOCKET_ERROR As Long = -1
Private Const WS_VERSION_REQD As Long = &H101
Type HOSTENT
h_name As Long '; official name of host
h_aliases As Long '; alias list
h_addrtype As Integer '; host address type
h_length As Integer '; length of address
h_addr_list As Long '; list of addresses
End Type
Type servent
s_name As Long '; (pointer to string) official service name
s_aliases As Long '; (pointer to string) alias list (might be null-seperated with 2null terminated)
s_port As Long '; port #
s_proto As Long '; (pointer to) protocol to use
End Type
Private Type WSADATA
wVersion As Integer
wHighVersion As Integer
szDescription(0 To MAX_WSADescription) As Byte
szSystemStatus(0 To MAX_WSASYSStatus) As Byte
wMaxSockets As Long
wMaxUDPDG As Long
dwVendorInfo As Long
End Type
Public Declare Function ntohs Lib "WSOCK32.DLL" (ByVal netshort As Long) As Long
';inet_addr将IP地址从 点数格式转换成无符号长整型
Private Declare Function inet_addr Lib "WSOCK32.DLL" (ByVal CP As String) As Long
';inet_ntoa将IP地址从 点数格式转换成ascii
Private Declare Function inet_ntoa Lib "WSOCK32.DLL" (ByVal inn As Long) As Long
Private Declare Function gethostbyaddr Lib "WSOCK32.DLL" (Addr As Long, ByVal addr_len As Long, ByVal addr_type As Long) As Long
Private Declare Function gethostbyname Lib "WSOCK32.DLL" (ByVal host_name As String) As Long
Private Declare Function WSAStartup Lib "WSOCK32.DLL" (ByVal wVersionRequired As Long, lpWSADATA As WSADATA) As Long
Private Declare Function WSACleanup Lib "WSOCK32.DLL" () As Long
';若该函数的返回值非0,则为存储器的地址。由于VB不能直接操作地址,所以还必须调用RtlMoveMemory函数将数据写入地址中
Private Declare Sub RtlMoveMemory Lib "kernel32" (hpvDest As Any, ByVal hpvSource As Long, ByVal cbCopy As Long)
';将数据转换为内存二进制形式字符串
Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Dest As Any, Src As Any, ByVal cb&)
Declare Function lstrlen Lib "kernel32" (ByVal lpString As Any) As Integer
Private Blocked As Boolean
';定义网络状态
Sub InitStates()
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连接"
End Sub
Public Function GetAscIP(ByVal inn As Long) As String
Dim nStr&
Dim lpStr As Long
Dim retString As String
retString = String(32, 0)
lpStr = inet_ntoa(inn)
If lpStr Then
nStr = lstrlen(lpStr)
If nStr > 32 Then nStr = 32
CopyMemory ByVal retString, ByVal lpStr, nStr
retString = Left(retString, nStr)
GetAscIP = retString
Else
GetAscIP = "无法取得IP"
End If
End Function
好了,日志是建立一个LOG文件,所以我们将所需要的函数封装一个类模块里。建立一个public模块。代码如下
';对日志的定义
Public Function Log(RemA As String, RemP As String, LocP As String, Txt As String)
Dim ff As Long
ff = FreeFile
‘打开log文件
Open App.Path & "\log.log" For Append As #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
End Function
好了,封装好了函数以及API数据库,下面是设计界面,以及功能结合了:)
先建立主窗体,这里将名称改为frmMain,我不想抹杀你们的创意,但是为了代码的最后测试成功,请你不要改变:)
点工程——部件,插入microsoft windows common controls 6.0 (sp4)如图1:
前面点上小钩,确定:)
回到桌面,双点击Toolbar,加入后,在上面右键属性。
依次插入按钮,如图2:
索引 标题 样式 图象
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
最后完成界面如图:
添加代码如下:
‘定义一些常量
Private lC As Integer
Public Blk As String
Private a_RemA(1000) As String
Private a_LocP(1000) As String
Private a_RemP(1000) As String
Private a_Count As Long
‘下面是刷新网络状态的函数
Public Function RefreshTable(Optional force As Boolean = False)
On Error Resume Next
Dim tcpt As MIB_TCPTABLE, l As Long
Dim x As Integer, i As Integer
Dim RemA As String, LocP As String, RemP As String
l = Len(MIB_TCPTABLE)
GetTcpTable tcpt, l, 0
x = tcpt.dwNumEntries
If x < lC Or x > lC Or force Then
lC = x
ListView1.ListItems.Clear
For i = 0 To x - 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)


Next i
End If
End Function
Private Sub Form_Load()
‘调用网络状态函数
modNetstat.InitStates
‘一开始就刷新网络状态列表
RefreshTable
End Sub
Private Sub ListView1_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
‘判断是否为鼠标右键按下
If Button = 2 And ListView1.ListItems.Count > 0 Then
‘调用控制按钮,在下面将说到
frmMain.PopupMenu frmMenu.mnuConn
End If
End Sub
Private Sub tmrRefresh_Timer()
‘定时刷新网络状态列表
RefreshTable
End Sub
Public Sub Toolbar1_ButtonClick(ByVal Button As MSComctlLib.Button)
Select Case Button.Index
Case 1
‘停止功能按钮
If Button.Caption = "停止" Then
Button.Caption = "继续"
Button.ToolTipText = "继续开始工作"
tmrRefresh.Enabled = False
‘停止刷新网络状态列表,先面反之
Else
Button.Caption = "停止"
Button.ToolTipText = "停止工作"
tmrRefresh.Enabled = True
End If
Case 2
‘刷新按钮功能
RefreshTable
Case 4
‘显示日志
Frmlog.Show
End Select
End Sub
好了,下面定义控制按钮:)也就是网络状态上右键显示的拦截连接
新建一个窗体,命名为frmMenu,只需要有一个菜单,如图:
修改菜单属性:
标题 名称
mnuConn mnuConn
拦截连接 mnuDis
如图:
好了,添加代码如下:
Private Sub mnuDis_Click()
Dim tcpt As MIB_TCPTABLE
Dim l As Long
Dim i As Long
Dim RemA As String, RemP As String, LocP As String
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)
GetTcpTable tcpt, l, 0
tcpt.table(i - 1).dwState = 12
‘断开TCP连接,还记得一开始说的函数吗?
SetTcpEntry tcpt.table(i - 1)
DoEvents
‘写入日志
Log RemA, RemP, LocP, "拦截连接"
End Sub
好了,最后是一个日志操作窗体,建立一个名称为Frmlog的窗体
一个用一个listview和command控件,调整位置如图
listview属性
名称 lstLog
列首索引 文本 大小自己调节
1 时间
2 IP
3 远程端口
4 本地端口
5 说明
添加代码如下
Private Sub Command1_Click()
Dim r As String
r = MsgBox("防火墙日志是有效检查黑客入侵的手段!" & vbCrLf & vbCrLf & "清楚日志?", vbQuestion & vbYesNo, "注意!")
‘如果按的是“是”那么
If r = vbYes Then
Dim ff As Long
ff = FreeFile
‘打开日志写入空数据,也就是清空日志
Open App.Path & "\log.log" For Output As &#35;ff
Close &#35;ff
‘清空列表
lstLog.ListItems.Clear
End If
End Sub

TOP

[讨论]用VB编写防火墙的可行性!

谢谢两位!
再次请教,VB是不是可以用API或控件实现中间层编程?

TOP

[讨论]用VB编写防火墙的可行性!

可以的.
这个我还是明白的.
但是具体方法不清楚.

TOP

[讨论]用VB编写防火墙的可行性!

汗。。。偶搜遍网上,找到两个防火墙源码。。。。自己琢磨一下。。
再次感谢!

TOP

[讨论]用VB编写防火墙的可行性!

dabubaobao在黑客防线好象写过一个防火墙编程的文章,好象是利用windows的某个驱动提供的回调函数实现的.
但是在内核层,还是得写驱动..

TOP

返回列表 回复 发帖