;处理ARP包开始.只检测谁在伪装网关.把伪装ARP响应包改成ARP请求包并填写正确的网关MAC地址.
mov ebx,_lpPacket
mov ebx,[ebx+8]
invoke NdisQueryBufferSafe,ebx,addr PacketVa,addr PacketSize,20h
mov edi,PacketVa ;由于ARP包小,不用获取下一个MDL
.if word ptr [edi+0ch]==0608h ;收到的网络包是ARP包.
.if word ptr [edi+14h]==0200h ;是ARP响应包.
lea esi,GateWay
mov eax,[edi+1ch]
mov ebx,[esi+6]
add edi,16h
mov ecx,10
.if word ptr [edi+14h]==0AA55h ;自己的特殊向网关请求的ARP包标志.
xchg esi,edi
rep movsb ;保存正确的网关IP及MAC
.elseif ebx==eax ;是来自网关的响应包.
mov word ptr [edi-02h],0100h ;把他改成请求包.
rep movsb
.endif
.endif
.endif
;处理ARP包结束
;*************************************************************************************
popad
leave
jmp lpOldRecvP ;转到系统原来的Recv例程执行
_myRecvP endp
_myRecv proc _PBC,_MRC,_HeaderBuffer,_HBSize,_LAB,_LABSize,_PacketSize
pushad
mov esi,_HeaderBuffer
mov edi,offset szRecvBuffer
mov ecx,_PacketSize
mov dwRecvSize,ecx
rep movsb
invoke NdisSetEvent,lpRecv3Event ;放行RING3的WaitForSingleObject(),通知RING3用ReadFile来读数据包内容(重要)
;*************************************************************************************
;处理ARP包开始.只检测谁在伪装网关.把伪装ARP响应包改成ARP请求包并填写正确的网关MAC地址.
mov edi,_HeaderBuffer
.if word ptr [edi+0ch]==0608h ;收到的网络包是ARP包.
.if word ptr [edi+14h]==0200h ;是ARP响应包.
lea esi,GateWay
mov eax,[edi+1ch]
mov ebx,[esi+6]
add edi,16h
mov ecx,10
.if word ptr [edi+14h]==0AA55h ;自己的特殊向网关请求的ARP包标志.
xchg esi,edi
rep movsb ;保存正确的网关IP及MAC
.elseif ebx==eax ;是来自网关的响应包.
mov word ptr [edi-02h],0100h ;把他改成请求包.
rep movsb
.endif
.endif
.endif
;处理ARP包结束
;*************************************************************************************
popad
leave
jmp lpOldRecv ;转到系统原来的Recv例程执行
_myRecv endp
;这是我们HOOK tcpip协议的发送完成函数
_mySendComplete proc _PBC,_Packet,_Status
pushad .if szMyPacketLen ;我们自己的构造的包长度
invoke CopyPktTOLocBuf,_Packet,addr szTempBuffer
mov esi,offset szTempBuffer
mov edi,offset szMyPacketBuffer
mov ecx,szMyPacketLen
repz cmpsb ;比较包的内容
.if !ecx ;是我们的包
mov szMyPacketLen,0 ;设置包的长度
popad
leave
xor eax,eax
ret ;是我们的包直接返回
.endif
.endif
popad ;不是我们的包转到系统原来例程
leave
jmp lpOldSendComplete ;转到系统原来的SendComplete例程执行
_mySendComplete endp
;*********************************************************************************************
;*********************************************************************************************
;MySendPacket: 发送自已构造的数据帧(注意:包是直接交给网卡发送)
;入口: BindingHandle=NDIS_PROTOCOL_BLOCK->_NDIS_OPEN_BLOCK
; MyPacket=数据帧缓冲首址,PacketLen=数据帧长度
;出口: dwStatus=返回状态
MySendPacket proc BindingHandle:dword,MyPacket:dword,PacketLen:dword
local PacketPoolHandle:dword
local PacketHandle:dword
local BufferHandle:dword
invoke NdisAllocatePacketPool,addr dwStatus,addr PacketPoolHandle,0FFFh,10h
invoke NdisAllocateBuffer,addr dwStatus,addr BufferHandle,0,MyPacket,PacketLen
invoke NdisAllocatePacket,addr dwStatus,addr PacketHandle,PacketPoolHandle
invoke NdisChainBufferAtFront,PacketHandle,BufferHandle
invoke NdisSend,Addr dwStatus,BindingHandle,PacketHandle
.if eax!=103h ;NDIS_STATUS_PENDING=103h
invoke NdisFreePacketPool,PacketPoolHandle
invoke NdisFreePacket,PacketHandle
invoke NdisFreeBuffer,BufferHandle
.endif
ret ;发送完成返回dwStatus
MySendPacket endp
;*********************************************************************
;看NTDDK中的Ndis.h中有定义.
NdisChainBufferAtFront proc uses ecx Packet:dword,Buffer:dword
mov eax,Buffer
.while 1
mov ecx,[eax]
.break .if ecx==0
mov eax,ecx ;MDL.Next
.endw ;eax=Tail
mov ecx,Packet
.if dword ptr [ecx+08h]==0 ;Packet->Private.Head
mov [ecx+0ch],eax ;Packet->Private.Tail
.endif
mov ecx,[ecx+08h]
mov [eax],ecx ;MDL.Next
mov eax,Packet
mov ecx,Buffer
mov [eax+08h],ecx
and byte ptr [eax+1ch],0 ;Packet->Private.ValidCounts
ret
NdisChainBufferAtFront endp
;***************************************************************************************************
;***************************************************************************************************
;以下空函数是为了填充NDIS_PROTOCOL_CHARACTERISTIC结构而设置的,实际下基本不会被系统调用,没有又不行。
PtBindAdapter proc Status,BindContext,DeviceName,SystemSpecific1,SystemSpecific2
xor eax,eax
ret
PtBindAdapter endp
PtUnbindAdapter proc Status,pAdapt,UnbindContext
xor eax,eax
ret
PtUnbindAdapter endp
;我们HOOK协议的及相关要用的函数在这里结束
;******************************************************************************************************
end start
:make
set drv=ndisdrv
d:\masm32\ml /c /coff /Cp %drv%.bat
d:\masm32\link /subsystem:native /driver:wdm /release /align:16 /base:0x10000 /out:%drv%.sys %drv%.obj
;del %drv%.obj
pause
应用层源代码:
;goto make
.386
.model flat, stdcall
option casemap:none
include d:\masm32\include\windows.inc
include d:\masm32\include\iphlpapi.inc
include d:\masm32\include\ws2_32.inc
include d:\masm32\include\kernel32.inc
include D:\masm32\macros\Strings.mac
include D:\masm32\include\advapi32.inc
include d:\masm32\include\user32.inc
includelib d:\masm32\lib\advapi32.lib
includelib d:\masm32\lib\iphlpapi.lib
includelib d:\masm32\LIB\WS2_32.LIB
includelib d:\masm32\lib\kernel32.lib
includelib d:\masm32\lib\user32.lib
.data
buffer db 800h dup(0)
filename db " \\.\NdisDrv",0
sFileName db "ndisdrv.sys",0
SeviceMe db "Ndis ARP",0
Send3E db "Send3Event",0
Recv3E db "Recv3Event",0
hdrv dd ?
hEvent dd ?
dwTempVar dd 1
hSCManager dd ?
hService dd ?
lpMemory dd ?
dwStructSize dd ?
acDriverPath db 260 dup (?)
LocalMac db 6 dup (?)
szMacLen dd 6
ArpPacket db 0ffh,0ffh,0ffh,0ffh,0ffh,0ffh,000h,090h,027h,099h,012h,0bah,008h,006h,000h,001h
db 008h,000h,006h,004h,000h,001h,000h,090h,027h,099h,012h,0bah,0c0h,0a8h,001h,006h
db 000h,000h,000h,000h,000h,000h,0c0h,0a8h,001h,001h,055h,0aah,0ffh,0ffh,0ffh,0ffh
MsgCaption db "ARP防火墙",0
MsgBoxText db "作者:成松林 QQ:179641795 该版本为调试版本试用系统win2k/xp",0
.code
MyArpPacket proc
;********************************************************************
invoke GetAdaptersInfo,NULL,addr dwStructSize
invoke GlobalAlloc,GPTR,dwStructSize
mov lpMemory,eax
invoke GetAdaptersInfo,lpMemory,addr dwStructSize
mov esi,lpMemory
lea edi,ArpPacket
add esi,1b0h
invoke inet_addr,esi
mov [edi+1ch],eax
invoke SendARP,eax,0,addr LocalMac,addr szMacLen
add esi,28h
invoke inet_addr,esi
mov [edi+26h],eax
lea esi,LocalMac
add edi,6
mov ecx,6
rep movsb
lea edi,ArpPacket
lea esi,LocalMac
add edi,16h
mov ecx,6
rep movsb
ret
MyArpPacket endp
start:
invoke OpenSCManager, NULL, NULL, SC_MANAGER_CREATE_SERVICE
.if eax != NULL
mov hSCManager, eax
push eax
invoke GetFullPathName, addr sFileName,sizeof acDriverPath,addr acDriverPath,esp
pop eax
invoke CreateService, hSCManager, addr sFileName, addr SeviceMe, \
SERVICE_START + DELETE, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, \
SERVICE_ERROR_IGNORE, addr acDriverPath, NULL, NULL, NULL, NULL, NULL
.if eax != NULL
mov hService, eax
invoke StartService, hService, 0, NULL
invoke DeleteService, hService
invoke CloseServiceHandle, hService
.else
;invoke MessageBox, NULL, $CTA0("Can't register driver."), NULL, MB_ICONSTOP
.endif
invoke CloseServiceHandle, hSCManager
.else
;invoke MessageBox, NULL, $CTA0("Can't connect to Service Control Manager."),NULL, MB_ICONSTOP
.endif
;************************************************************************************************************
invoke CreateFile,addr filename,0c0000000h,0,0,3,0,0
mov hdrv,eax
;invoke OpenEvent,100000h,0,addr Send3E
invoke OpenEvent,100000h,0,addr Recv3E
mov hEvent,eax ;接收数据事件
invoke MyArpPacket ;自己构造的ARP请求包.
invoke WriteFile,hdrv,addr ArpPacket,64,addr dwTempVar,0 ;发送数据包
;.while 1
invoke WaitForSingleObject,hEvent,-1
;.endw
invoke MessageBoxA, 0,addr MsgBoxText, addr MsgCaption,0
invoke ExitProcess, 0
end start
:make
set drv=ndisring3
d:\masm32\ml /c /coff %drv%.bat
d:\masm32\link /subsystem:windows %drv%.obj
del %drv%.obj
pause
本程序在win2k上调试通过。。用的NetFuke ver1.01工具作arp双向欺骗作实验..
mov ebx,_lpPacket
mov ebx,[ebx+8]
invoke NdisQueryBufferSafe,ebx,addr PacketVa,addr PacketSize,20h
mov edi,PacketVa ;由于ARP包小,不用获取下一个MDL
.if word ptr [edi+0ch]==0608h ;收到的网络包是ARP包.
.if word ptr [edi+14h]==0200h ;是ARP响应包.
lea esi,GateWay
mov eax,[edi+1ch]
mov ebx,[esi+6]
add edi,16h
mov ecx,10
.if word ptr [edi+14h]==0AA55h ;自己的特殊向网关请求的ARP包标志.
xchg esi,edi
rep movsb ;保存正确的网关IP及MAC
.elseif ebx==eax ;是来自网关的响应包.
mov word ptr [edi-02h],0100h ;把他改成请求包.
rep movsb
.endif
.endif
.endif
;处理ARP包结束
;*************************************************************************************
popad
leave
jmp lpOldRecvP ;转到系统原来的Recv例程执行
_myRecvP endp
_myRecv proc _PBC,_MRC,_HeaderBuffer,_HBSize,_LAB,_LABSize,_PacketSize
pushad
mov esi,_HeaderBuffer
mov edi,offset szRecvBuffer
mov ecx,_PacketSize
mov dwRecvSize,ecx
rep movsb
invoke NdisSetEvent,lpRecv3Event ;放行RING3的WaitForSingleObject(),通知RING3用ReadFile来读数据包内容(重要)
;*************************************************************************************
;处理ARP包开始.只检测谁在伪装网关.把伪装ARP响应包改成ARP请求包并填写正确的网关MAC地址.
mov edi,_HeaderBuffer
.if word ptr [edi+0ch]==0608h ;收到的网络包是ARP包.
.if word ptr [edi+14h]==0200h ;是ARP响应包.
lea esi,GateWay
mov eax,[edi+1ch]
mov ebx,[esi+6]
add edi,16h
mov ecx,10
.if word ptr [edi+14h]==0AA55h ;自己的特殊向网关请求的ARP包标志.
xchg esi,edi
rep movsb ;保存正确的网关IP及MAC
.elseif ebx==eax ;是来自网关的响应包.
mov word ptr [edi-02h],0100h ;把他改成请求包.
rep movsb
.endif
.endif
.endif
;处理ARP包结束
;*************************************************************************************
popad
leave
jmp lpOldRecv ;转到系统原来的Recv例程执行
_myRecv endp
;这是我们HOOK tcpip协议的发送完成函数
_mySendComplete proc _PBC,_Packet,_Status
pushad .if szMyPacketLen ;我们自己的构造的包长度
invoke CopyPktTOLocBuf,_Packet,addr szTempBuffer
mov esi,offset szTempBuffer
mov edi,offset szMyPacketBuffer
mov ecx,szMyPacketLen
repz cmpsb ;比较包的内容
.if !ecx ;是我们的包
mov szMyPacketLen,0 ;设置包的长度
popad
leave
xor eax,eax
ret ;是我们的包直接返回
.endif
.endif
popad ;不是我们的包转到系统原来例程
leave
jmp lpOldSendComplete ;转到系统原来的SendComplete例程执行
_mySendComplete endp
;*********************************************************************************************
;*********************************************************************************************
;MySendPacket: 发送自已构造的数据帧(注意:包是直接交给网卡发送)
;入口: BindingHandle=NDIS_PROTOCOL_BLOCK->_NDIS_OPEN_BLOCK
; MyPacket=数据帧缓冲首址,PacketLen=数据帧长度
;出口: dwStatus=返回状态
MySendPacket proc BindingHandle:dword,MyPacket:dword,PacketLen:dword
local PacketPoolHandle:dword
local PacketHandle:dword
local BufferHandle:dword
invoke NdisAllocatePacketPool,addr dwStatus,addr PacketPoolHandle,0FFFh,10h
invoke NdisAllocateBuffer,addr dwStatus,addr BufferHandle,0,MyPacket,PacketLen
invoke NdisAllocatePacket,addr dwStatus,addr PacketHandle,PacketPoolHandle
invoke NdisChainBufferAtFront,PacketHandle,BufferHandle
invoke NdisSend,Addr dwStatus,BindingHandle,PacketHandle
.if eax!=103h ;NDIS_STATUS_PENDING=103h
invoke NdisFreePacketPool,PacketPoolHandle
invoke NdisFreePacket,PacketHandle
invoke NdisFreeBuffer,BufferHandle
.endif
ret ;发送完成返回dwStatus
MySendPacket endp
;*********************************************************************
;看NTDDK中的Ndis.h中有定义.
NdisChainBufferAtFront proc uses ecx Packet:dword,Buffer:dword
mov eax,Buffer
.while 1
mov ecx,[eax]
.break .if ecx==0
mov eax,ecx ;MDL.Next
.endw ;eax=Tail
mov ecx,Packet
.if dword ptr [ecx+08h]==0 ;Packet->Private.Head
mov [ecx+0ch],eax ;Packet->Private.Tail
.endif
mov ecx,[ecx+08h]
mov [eax],ecx ;MDL.Next
mov eax,Packet
mov ecx,Buffer
mov [eax+08h],ecx
and byte ptr [eax+1ch],0 ;Packet->Private.ValidCounts
ret
NdisChainBufferAtFront endp
;***************************************************************************************************
;***************************************************************************************************
;以下空函数是为了填充NDIS_PROTOCOL_CHARACTERISTIC结构而设置的,实际下基本不会被系统调用,没有又不行。
PtBindAdapter proc Status,BindContext,DeviceName,SystemSpecific1,SystemSpecific2
xor eax,eax
ret
PtBindAdapter endp
PtUnbindAdapter proc Status,pAdapt,UnbindContext
xor eax,eax
ret
PtUnbindAdapter endp
;我们HOOK协议的及相关要用的函数在这里结束
;******************************************************************************************************
end start
:make
set drv=ndisdrv
d:\masm32\ml /c /coff /Cp %drv%.bat
d:\masm32\link /subsystem:native /driver:wdm /release /align:16 /base:0x10000 /out:%drv%.sys %drv%.obj
;del %drv%.obj
pause
应用层源代码:
;goto make
.386
.model flat, stdcall
option casemap:none
include d:\masm32\include\windows.inc
include d:\masm32\include\iphlpapi.inc
include d:\masm32\include\ws2_32.inc
include d:\masm32\include\kernel32.inc
include D:\masm32\macros\Strings.mac
include D:\masm32\include\advapi32.inc
include d:\masm32\include\user32.inc
includelib d:\masm32\lib\advapi32.lib
includelib d:\masm32\lib\iphlpapi.lib
includelib d:\masm32\LIB\WS2_32.LIB
includelib d:\masm32\lib\kernel32.lib
includelib d:\masm32\lib\user32.lib
.data
buffer db 800h dup(0)
filename db " \\.\NdisDrv",0
sFileName db "ndisdrv.sys",0
SeviceMe db "Ndis ARP",0
Send3E db "Send3Event",0
Recv3E db "Recv3Event",0
hdrv dd ?
hEvent dd ?
dwTempVar dd 1
hSCManager dd ?
hService dd ?
lpMemory dd ?
dwStructSize dd ?
acDriverPath db 260 dup (?)
LocalMac db 6 dup (?)
szMacLen dd 6
ArpPacket db 0ffh,0ffh,0ffh,0ffh,0ffh,0ffh,000h,090h,027h,099h,012h,0bah,008h,006h,000h,001h
db 008h,000h,006h,004h,000h,001h,000h,090h,027h,099h,012h,0bah,0c0h,0a8h,001h,006h
db 000h,000h,000h,000h,000h,000h,0c0h,0a8h,001h,001h,055h,0aah,0ffh,0ffh,0ffh,0ffh
MsgCaption db "ARP防火墙",0
MsgBoxText db "作者:成松林 QQ:179641795 该版本为调试版本试用系统win2k/xp",0
.code
MyArpPacket proc
;********************************************************************
invoke GetAdaptersInfo,NULL,addr dwStructSize
invoke GlobalAlloc,GPTR,dwStructSize
mov lpMemory,eax
invoke GetAdaptersInfo,lpMemory,addr dwStructSize
mov esi,lpMemory
lea edi,ArpPacket
add esi,1b0h
invoke inet_addr,esi
mov [edi+1ch],eax
invoke SendARP,eax,0,addr LocalMac,addr szMacLen
add esi,28h
invoke inet_addr,esi
mov [edi+26h],eax
lea esi,LocalMac
add edi,6
mov ecx,6
rep movsb
lea edi,ArpPacket
lea esi,LocalMac
add edi,16h
mov ecx,6
rep movsb
ret
MyArpPacket endp
start:
invoke OpenSCManager, NULL, NULL, SC_MANAGER_CREATE_SERVICE
.if eax != NULL
mov hSCManager, eax
push eax
invoke GetFullPathName, addr sFileName,sizeof acDriverPath,addr acDriverPath,esp
pop eax
invoke CreateService, hSCManager, addr sFileName, addr SeviceMe, \
SERVICE_START + DELETE, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, \
SERVICE_ERROR_IGNORE, addr acDriverPath, NULL, NULL, NULL, NULL, NULL
.if eax != NULL
mov hService, eax
invoke StartService, hService, 0, NULL
invoke DeleteService, hService
invoke CloseServiceHandle, hService
.else
;invoke MessageBox, NULL, $CTA0("Can't register driver."), NULL, MB_ICONSTOP
.endif
invoke CloseServiceHandle, hSCManager
.else
;invoke MessageBox, NULL, $CTA0("Can't connect to Service Control Manager."),NULL, MB_ICONSTOP
.endif
;************************************************************************************************************
invoke CreateFile,addr filename,0c0000000h,0,0,3,0,0
mov hdrv,eax
;invoke OpenEvent,100000h,0,addr Send3E
invoke OpenEvent,100000h,0,addr Recv3E
mov hEvent,eax ;接收数据事件
invoke MyArpPacket ;自己构造的ARP请求包.
invoke WriteFile,hdrv,addr ArpPacket,64,addr dwTempVar,0 ;发送数据包
;.while 1
invoke WaitForSingleObject,hEvent,-1
;.endw
invoke MessageBoxA, 0,addr MsgBoxText, addr MsgCaption,0
invoke ExitProcess, 0
end start
:make
set drv=ndisring3
d:\masm32\ml /c /coff %drv%.bat
d:\masm32\link /subsystem:windows %drv%.obj
del %drv%.obj
pause
本程序在win2k上调试通过。。用的NetFuke ver1.01工具作arp双向欺骗作实验..