gxmgf
驱动牛犊
驱动牛犊
  • 注册日期2003-10-17
  • 最后登录2007-03-08
  • 粉丝0
  • 关注0
  • 积分50分
  • 威望5点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
阅读:1786回复:10

一个汇编版的NDIS驱动程序模板

楼主#
更多 发布于:2007-03-08 09:35
;文章作者:mgf

;一个汇编版的NDIS驱动程序模板(by mgf @2007.02.23)
;   写驱动程序已经很久了,但我一直用汇编来写驱动程序,原因是我不喜欢DDK,因为DDK和汇编一样,不是象VC,C#那样的“可视化”的开发工具,
;DDK和汇编一样看不见结构或对象的成员,也看不到各种函数的原型,这些东西和各种常量定义还必须去查看相关的包含文件,不仅如此,DDK还会
;“自作聪明”地把很多垃圾代码加到我的驱动里,虽然没有影响驱动程序的功能,但是还是不爽,不如直接用汇编,生成的驱动程序是什么样的自己
;心里有数。其实这也怪不得MS,它不想大家了解它的操作系统核心技术,但是又不得不开放一些技术细节给大家写驱动,所以只有提高门槛,搞出这
;么一个变态的DDK来吓走很多人,它的目的也就达到了,就是让尽可能少的人了解它的核心技术。能够跨过DDK这道槛的,必定不是一般的高手。呵呵!

;   很多书都建议写驱动最好不用汇编,因为写出来的程序不可移植,但是我不这么认为,因为现在90%的人写出的驱动都是在PC上运行的,没有必要
;为了这10%而放弃这么好的汇编语言。而且计算机都是相通的,如果你会写PC下的驱动了,再写MAC下的驱动不就容易多了吗?

;   这是一个标准的legacy驱动程序,虽然编译时用WDM的方法编译,它有Unload,Read,Write例程,而且还用NDIS HOOK来部分实现了防火墙的功能。
;NDIS HOOK技术被广泛应用于瑞星、江民、天网等众多流行的防火墙里,它的原理是使用NdisRegisterProtocol()注册假协议来获取系统的协议链地址,
;再搜索这个单向协议链,找到TCPIP协议的NDIS_OPEN_BLOCK(NDIS_BINDING_HANDLE)结构,里面就有TCPIP协议的各种派发函数地址,比如SEND在结构
;偏移30H的地方,RECV在结构偏移40H的地方,还有其他很多重要的函数地址都在这个表里。把表里的地址替换成我们的函数地址,就可以拦截操作系统
;收发的所有数据包了。本驱动只是实现了嗅探数据包的功能,还没有实现拦截恶意数据包的功能,如果想实现这个功能,在_Write函数、_mySend函数、
;_myRecv函数里加些代码,使它们配合完成拦截数据包的功能。本驱动如果IoAttachDevice其他驱动,可以改成过滤器;做些修改,还可以实现更多功能,
;可以用来过滤缓冲区溢出攻击包,也可以用来定制自己的SQL INJECTION防护网。

;   本驱动嗅探数据包的流程是这样的:当系统收发数据包时,被_mySend或_myRecv拦截,这两个函数就用NdisSetEvent()置位一个RING3事件(这个事
;件在DriverEntry里建立,在RING3里打开),这样在RING3应用层的WaitForSingleObject()因为事件被置位而返回,于是RING3代码用ReadFile()读取数
;据包的内容,判断是放行还是拦截,再用WriteFile来通知驱动做相应的操作。当然为了提高效率,不是每个数据包都提示RING3应用程序该不该放行,
;有些可以直接在RING0驱动里判断的就不必传到RING3去判断了。处于RING3的代码大概是这样的:


;#include "stdafx.h"
;#include "windows.h"
;#include "stdlib.h"


;int _tmain(int argc, _TCHAR* argv[])
;{
;   HANDLE hdrv=CreateFile("\\\\.\\NDISDRV",0xc0000000,0,0,3,0,0);
;   HANDLE hEvent=OpenEvent(0x100000,0,"Send3Event"); //注意Send3Event必须和驱动里的名字对应
;   //HANDLE hEvent=OpenEvent(0x100000,0,"Recv3Event"); //注意Recv3Event必须和驱动里的名字对应
;
;   int dwTempVar=1;char szTempBuffer[0x800];
;   while(dwTempVar)
;   {
;     WaitForSingleObject(hEvent,-1);  
;     ReadFile(hdrv,szTempBuffer,0x800,(LPDWORD)&dwTempVar,0);
;   }
;
;   return 0;
;}

;把下面的代码保存到ndisdrv.asm里,在MASM32 6.14及以上的编译器里编译:
;ml /c /coff /Cp ndisdrv.asm
;link /subsystem:native /driver:wdm /release /align:16 /base:0x10000 /out:ndisdrv.sys ndisdrv.obj
;由于驱动程序涉及的知识太广而深奥了,本文难免有错漏的地方,希望大家指出,以免一错再错,误导别人。
;下面是驱动的代码:



.586p
.model flat,stdcall
option casemap:none
assume fs:nothing,gs:nothing

includelib ntoskrnl.lib
includelib hal.lib
includelib ndis.lib
includelib tdi.lib
includelib wdm.lib
;以上LIB文件要从DDK里复制到MASM32的LIB目录里


NdisQueryBufferSafe proto :dword,:dword,:dword,:dword
NdisInitializeEvent proto :dword
NdisSetEvent proto :dword
NdisResetEvent proto :dword
NdisWaitEvent proto :dword,:dword
NdisRegisterProtocol proto :dword,:dword,:dword,:dword
NdisDeregisterProtocol proto :dword,:dword
IoCreateDevice proto :dword,:dword,:dword,:dword,:dword,:dword,:dword
IoDeleteDevice proto :dword
IoCreateSymbolicLink proto :dword,:dword
IoDeleteSymbolicLink proto :dword
IoCompleteRequest proto :dword,:dword
IoCreateNotificationEvent proto :dword,:dword
PsGetVersion proto :dword,:dword,:dword,:dword
RtlCompareUnicodeString proto :dword,:dword,:dword
ZwClose proto :dword
;由于MASM32没有相关的INC文件,所以要使用的API要自己定义原型


.data
lpProtocolHandle dd 0 ;协议句柄的指针
lpDeviceObject dd 0 ;设备对象的指针
lpOldSend dd 0 ;保存TCPIP协议驱动的OPEN_BLOCK(BINDING HANDLE)里的SEND派发函数地址
lpOldRecv dd 0 ;保存TCPIP协议驱动的OPEN_BLOCK(BINDING HANDLE)里的RECV派发函数地址

lpSend3Event dd 0 ;RING3发送事件在本驱动的指针
hSend3Event dd 0 ;RING3发送事件在本驱动的句柄
lpRecv3Event dd 0 ;RING3接收事件在本驱动的指针
hRecv3Event dd 0 ;RING3接收事件在本驱动的句柄
dwStatus dd 0
dwTempVar dd 0

obSendEvent db 16 dup(0) ;RING0 SEND对象
obRecvEvent db 16 dup(0) ;RING0 RECV对象

stProtocolChar db 70h dup(0) ;NdisRegisterProtocol()要使用的NDIS_PROTOCOL_CHARACTERISTIC结构

szSendBuffer db 800h dup(0) ;系统将要发送的数据包的副本
szRecvBuffer db 800h dup(0) ;系统将要接收的数据包的副本
dwSendSize dd 0 ;发送副本大小
dwRecvSize dd 0 ;接收副本大小



.const
stTcpip dw 5*2,6*2
dd offset szTcpip
szTcpip dw 'T','c','p','i','p',0
stProtName dw 7*2,8*2
dd offset szProtName
szProtName dw 'N','d','i','s','D','r','v',0
stDeviceName dw 15*2,16*2
dd offset szDeviceName
szDeviceName dw '\','D','e','v','i','c','e','\','N','d','i','s','D','r','v',0
stSymbolicLinkName dw 19*2,20*2
dd offset szSymbolicLinkName
szSymbolicLinkName dw '\','D','o','s','D','e','v','i','c','e','s','\','N','D','I','S','D','R','V',0
stSend3Event dw 28*2,29*2
dd offset szSend3Event
szSend3Event dw '\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s','\','S','e','n','d','3','E','v','e','n','t',0
stRecv3Event dw 28*2,29*2
dd offset szRecv3Event
szRecv3Event dw '\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s','\','R','e','c','v','3','E','v','e','n','t',0


.code
start proc DriverObject,RegisterPath
pushad

invoke PsGetVersion,offset dwTempVar,0,0,0 ;获取操作系统版本,如果不是5.0(2000,XP,2003)就退出,因为不能使用NDIS5.0
.if dwTempVar!=5
jmp _exit
.endif


mov byte ptr stProtocolChar,5
mov byte ptr stProtocolChar+1,0

mov eax,dword ptr stProtName
mov dword ptr stProtocolChar+30h,eax
mov eax,dword ptr stProtName+4
mov dword ptr stProtocolChar+34h,eax

mov dword ptr stProtocolChar+08h,offset PtOpenAdapterComplete
mov dword ptr stProtocolChar+0ch,offset PtCloseAdapterComplete
mov dword ptr stProtocolChar+10h,offset PtSendComplete
mov dword ptr stProtocolChar+14h,offset PtTransferDataComplete
mov dword ptr stProtocolChar+18h,offset PtResetComplete
mov dword ptr stProtocolChar+1ch,offset PtRequestComplete
mov dword ptr stProtocolChar+20h,offset PtReceive
mov dword ptr stProtocolChar+24h,offset PtReceiveComplete
mov dword ptr stProtocolChar+28h,offset PtStatus
mov dword ptr stProtocolChar+2ch,offset PtStatusComplete
mov dword ptr stProtocolChar+3ch,offset PtBindAdapter
mov dword ptr stProtocolChar+40h,offset PtUnbindAdapter
mov dword ptr stProtocolChar+38h,offset PtReceivePacket
mov dword ptr stProtocolChar+44h,offset PtPNPHandler
;以上是填充NDIS_PROTOCOL_CHARACTERISTIC结构

invoke NdisRegisterProtocol,offset dwStatus,offset lpProtocolHandle,offset stProtocolChar,6ch ;获取系统协议链表的地址,前面做了这么多工作都是为了这个地址
.if dwStatus
jmp _exit
.endif
mov ebx,lpProtocolHandle
mov ebx,[ebx+10h] ;跳过我的假协议,保存协议链里下一项的地址
invoke NdisDeregisterProtocol,offset dwStatus,lpProtocolHandle ;我注册的假协议已经没有用了,注销
mov lpProtocolHandle,ebx ;真正的系统协议链的地址

mov esi,offset stTcpip
.repeat
lea edi,[ebx+44h]
invoke RtlCompareUnicodeString,edi,esi,1
.break .if eax==0
mov ebx,[ebx+10h]
.until ebx==0 ;这个循环是搜索TCPIP协议的PROTOCOL_HANDLE
.if eax
jmp _exit
.endif
mov ebx,[ebx] ;取出PROTOCOL_HANDLE里的OPEN_BLOCK指针,每个版本的NDIS的PROTOCOL_HANDLE结构都可能不同,要注意
mov lpProtocolHandle,ebx ;保存TCPIP协议的OPEN_BLOCK(BINDING_HANDLE)

mov eax,[ebx+30h]
mov lpOldSend,eax ;保存TCPIP协议的OPEN_BLOCK(BINDING_HANDLE)里的SEND派发函数地址
mov eax,[ebx+40h]
mov lpOldRecv,eax ;保存TCPIP协议的OPEN_BLOCK(BINDING_HANDLE)里的RECV派发函数地址


invoke IoCreateDevice,DriverObject,18h,offset stDeviceName,21h,0,0,offset lpDeviceObject ;建立设备,DeviceExtension size=18h, type= device_transfer
invoke IoCreateSymbolicLink,offset stSymbolicLinkName,offset stDeviceName
mov eax,lpDeviceObject
or dword ptr [eax+1ch],10h ;把device.flag设置为DO_DIRECT_IO,使驱动程序的READ、WRITE例程直接映射用户缓冲区到本驱动

mov edi,DriverObject
add edi,38h
mov ecx,1ch
mov eax,offset _CommonIoControl
rep stosd ;填充共用例程,必须,否则CreateFile()不能打开本驱动

mov eax,DriverObject
mov dword ptr [eax+34h],offset _Unload
mov dword ptr [eax+44h],offset _Read
mov dword ptr [eax+48h],offset _Write ;注册驱动例程
mov byte ptr [eax+8],2 ;强行修改Driver.flag为legacy driver,否则DriverEntry返回时系统就会卸载本驱动(因为本驱动默认编译为WDM drvier)


invoke NdisInitializeEvent,offset obSendEvent
invoke NdisInitializeEvent,offset obRecvEvent
invoke NdisResetEvent,offset obSendEvent
invoke NdisResetEvent,offset obRecvEvent
;建立RING0事件

invoke IoCreateNotificationEvent,offset stSend3Event,offset hSend3Event
mov lpSend3Event,eax
invoke NdisResetEvent,eax
invoke IoCreateNotificationEvent,offset stRecv3Event,offset hRecv3Event
mov lpRecv3Event,eax
invoke NdisResetEvent,eax
;建立RING3事件,在RING3用OpenEvent()打开

mov ebx,lpProtocolHandle
mov dword ptr [ebx+30h],offset _mySend ;HOOK TCPIP协议的SEND
mov dword ptr [ebx+40h],offset _myRecv ;HOOK TCPIP协议的RECV


_exit:
popad
xor eax,eax
ret
start endp


_Unload proc DriverObject
mov edx,lpProtocolHandle
mov eax,lpOldSend
mov [edx+30h],eax
mov eax,lpOldRecv
mov [edx+40h],eax
;恢复TCPIP协议的OPEN_BLOCK里原来的SEND/RECV派发例程

invoke ZwClose,hSend3Event
invoke ZwClose,hRecv3Event
invoke NdisSetEvent,offset obSendEvent
invoke NdisSetEvent,offset obRecvEvent

invoke IoDeleteSymbolicLink,offset stSymbolicLinkName
invoke IoDeleteDevice,lpDeviceObject

xor eax,eax
ret
_Unload endp


_CommonIoControl proc DeviceObject,pIrp
mov eax,pIrp
mov dword ptr [eax+18h],0
mov dword ptr [eax+1ch],0
invoke IoCompleteRequest,pIrp,0
xor eax,eax
ret
_CommonIoControl endp


_Read proc DeviceObject,pIrp
pushad
mov ebx,pIrp
mov edi,[ebx+4]
mov ecx,[edi+18h]
mov edi,[edi+10h]
add edi,ecx ;EDI=用户缓冲区

mov ecx,lpSend3Event
mov edx,lpRecv3Event
.if dword ptr [ecx+4]
invoke NdisResetEvent,lpSend3Event ;RING3事件复位,防止再次放行
mov esi,offset szSendBuffer
mov ecx,dwSendSize
mov eax,[ebx+60h]
.if ecx>[eax+4]
mov ecx,[eax+4]
.endif
.else
invoke NdisResetEvent,lpRecv3Event
mov esi,offset szRecvBuffer
mov ecx,dwRecvSize
mov eax,[ebx+60h]
.if ecx>[eax+4]
mov ecx,[eax+4]
.endif
.endif

mov dword ptr [ebx+18h],0
mov dword ptr [ebx+1ch],ecx ;设置ReadFile()的读取字节数
rep movsb ;把数据包复制到ReadFile()提供的缓冲区

invoke IoCompleteRequest,pIrp,0
popad
xor eax,eax
ret
_Read endp


_Write proc DeviceObject,pIrp
mov eax,pIrp
mov dword ptr [eax+18h],0
mov dword ptr [eax+1ch],0

mov edx,[eax+4]
mov ecx,[eax+60h]
mov ecx,[ecx+4]
mov eax,[edx+18h]
mov edx,[edx+10h]
add edx,eax
;EDX=用户缓冲区

invoke IoCompleteRequest,pIrp,0
xor eax,eax
ret
_Write endp


_mySend proc _lpAdapt,_lpPacket
local @va
local @size
pushad
mov ebx,_lpPacket
mov ebx,[ebx+8]

mov edi,offset szSendBuffer
.repeat
invoke NdisQueryBufferSafe,ebx,addr @va,addr @size,20h
mov esi,@va
mov ecx,@size
rep movsb
mov ebx,[ebx]
.until ebx==0
sub edi,offset szSendBuffer
mov dwSendSize,edi
;以上循环复制将要发送的数据包到本驱动

invoke NdisSetEvent,lpSend3Event ;放行RING3的WaitForSingleObject(),通知RING3用ReadFile来读数据包内容(重要)

popad
leave
jmp lpOldSend ;转到系统原来的Send例程执行
ret
_mySend endp


_myRecv proc _lpAdapt,_lpPacket
local @va
local @size
pushad
mov ebx,_lpPacket
mov ebx,[ebx+8]

mov edi,offset szRecvBuffer
.repeat
invoke NdisQueryBufferSafe,ebx,addr @va,addr @size,20h
mov esi,@va
mov ecx,@size
rep movsb
mov ebx,[ebx]
.until ebx==0
sub edi,offset szRecvBuffer
mov dwRecvSize,edi
;以上循环复制将要接收的数据包到本驱动

invoke NdisSetEvent,lpRecv3Event ;放行RING3的WaitForSingleObject(),通知RING3用ReadFile来读数据包内容(重要)

popad
leave
jmp lpOldRecv ;转到系统原来的Recv例程执行
ret
_myRecv endp


;以下空函数是为了填充NDIS_PROTOCOL_CHARACTERISTIC结构而设置的,实际下基本不会被系统调用,没有又不行。
PtOpenAdapterComplete proc pAdapt,Status,OpenErrorStatus
xor eax,eax
ret
PtOpenAdapterComplete endp


PtCloseAdapterComplete proc pAdapt,Status
xor eax,eax
ret
PtCloseAdapterComplete endp


PtSendComplete proc pAdapt,Packet,Status
xor eax,eax
ret
PtSendComplete endp


PtTransferDataComplete proc pAdapt,Packet,Status,BytesTransferred
xor eax,eax
ret
PtTransferDataComplete endp


PtResetComplete proc pAdapt,Status
xor eax,eax
ret
PtResetComplete endp


PtRequestComplete proc pAdapt,_NdisRequest,Status
xor eax,eax
ret
PtRequestComplete endp


PtReceive proc pAdapt,MacReceiveContext,HeaderBuffer,HeaderBufferSize,LookAheadBuffer,LookAheadBufferSize,PacketSize
xor eax,eax
ret
PtReceive endp


PtReceiveComplete proc pAdapt
xor eax,eax
ret
PtReceiveComplete endp


PtStatus proc pAdapt,GeneralStatus,StatusBuffer,StatusBufferSize
xor eax,eax
ret
PtStatus endp


PtStatusComplete proc pAdapt
xor eax,eax
ret
PtStatusComplete endp


PtBindAdapter proc Status,BindContext,DeviceName,SystemSpecific1,SystemSpecific2
xor eax,eax
ret
PtBindAdapter endp


PtUnbindAdapter proc Status,pAdapt,UnbindContext
xor eax,eax
ret
PtUnbindAdapter endp


PtReceivePacket proc pAdapt,Packet
xor eax,eax
ret
PtReceivePacket endp


PtPNPHandler proc pAdapt,pNetPnPEvent
xor eax,eax
ret
PtPNPHandler endp


end start
附件名称/大小 下载次数 最后更新
ndisdrv.rar (7KB)  46 2007-03-08 09:39
znsoft
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2023-10-25
  • 粉丝300
  • 关注6
  • 积分910分
  • 威望14796点
  • 贡献值7点
  • 好评度2410点
  • 原创分5分
  • 专家分100分
  • 社区居民
  • 最爱沙发
  • 社区明星
沙发#
发布于:2007-03-08 10:05
pf,但不鼓励...

汇编写的没移植性.ms也不建议大家使用汇编代码写驱动
http://www.zndev.com 免费源码交换网 ----------------------------- 软件创造价值,驱动提供力量! 淡泊以明志,宁静以致远。 ---------------------------------- 勤用搜索,多查资料,先搜再问。
guardee
驱动巨牛
驱动巨牛
  • 注册日期2002-11-08
  • 最后登录2010-05-29
  • 粉丝2
  • 关注1
  • 积分2分
  • 威望34点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2007-03-14 13:35
感觉实用价值不大。
事实上,但从效率来讲,ddk2k3里带的cl,远比想象的要优秀,可以ida一下它优化编译的驱动代码,比手工汇编要合理的多。cl会充分考虑x86cpu的特性,使指令流程更合理,命中率更高,x86cpu对命不中的惩罚是很严厉的。
他也不会把没有调用的函数编译到module了,即使你的代码里有该函数的实现,这个好象是最近才有的功能。
cheng_5103
驱动牛犊
驱动牛犊
  • 注册日期2003-10-06
  • 最后登录2012-03-21
  • 粉丝0
  • 关注0
  • 积分23分
  • 威望228点
  • 贡献值0点
  • 好评度45点
  • 原创分0分
  • 专家分0分
地板#
发布于:2007-04-10 16:59
好像你说的就像真的样.....用汇编写..是最好学习用的了..最好了解它的工作的了...人家的开头写得很清楚..我觉得作者真是一位高人....老大我们是中国人呢?  不要什么就说MS怎么样..就要怎么样....没出息的家伙...如果没有汇编...好多深层的破解、内核修改等很难实现。。。注意不是不可以实现 。。是很难实现。。。。。。我不是有心和你争的。。相信你也是高手吧。。对于我们这些初学者来说。。。他用汇编写真的是很容易学习。。。因为高人们总是把高深的说的更高深。。我觉得也不是什么显示自己能力。。也许这就是高人的作风吧。。就好比文学家高人总爱说点儿我们难懂的字、词。。也许这样才能促进人们学习。。。。。。。。。。。。。。无聊哈。。发起耍的。。。。呵呵~!~·!
cheng
cheng_5103
驱动牛犊
驱动牛犊
  • 注册日期2003-10-06
  • 最后登录2012-03-21
  • 粉丝0
  • 关注0
  • 积分23分
  • 威望228点
  • 贡献值0点
  • 好评度45点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2007-04-11 01:00
兄台..你看下你的HOOK接收数据哪儿..应该是[ebx+50h]哟..加40h的接收我试过的..试不行的哟...我也不知道为什么会在50h的行的哈..我以前对这个ndis驱动调试了很长段时间...
cheng
cheng_5103
驱动牛犊
驱动牛犊
  • 注册日期2003-10-06
  • 最后登录2012-03-21
  • 粉丝0
  • 关注0
  • 积分23分
  • 威望228点
  • 贡献值0点
  • 好评度45点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2007-04-11 08:49
怎么不在的啊??
cheng
cheng_5103
驱动牛犊
驱动牛犊
  • 注册日期2003-10-06
  • 最后登录2012-03-21
  • 粉丝0
  • 关注0
  • 积分23分
  • 威望228点
  • 贡献值0点
  • 好评度45点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2007-04-11 08:50
怎么没在的啊??我请教下。。在这个hook里面能不能发送自己构造的包啊。。。能的话。。怎么发啊。。。。。??
cheng
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
7楼#
发布于:2007-04-12 10:55
不错,用汇编写程序不难,难的是一辈子只用汇编写程序,哈哈。。。。。。
顶MGF老兄
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
gxmgf
驱动牛犊
驱动牛犊
  • 注册日期2003-10-17
  • 最后登录2007-03-08
  • 粉丝0
  • 关注0
  • 积分50分
  • 威望5点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2007-04-12 13:48
wowocock老弟呀,我也好久没有跟你联系了,因为忙的关系,我的QQ一直隐身,不过你还是可以留言给我的,呵呵!

下面是NDIS_OPEN_BLOCK结构的定义(最左边是偏移):
typedef struct _NDIS_COMMON_OPEN_BLOCK / _NdisBindingHandle
{
00    PVOID                           MacHandle;              // for backward compatibility
04    NDIS_HANDLE                     BindingHandle;          // Miniport's open context
08    PNDIS_MINIPORT_BLOCK            MiniportHandle;         // pointer to the miniport
0C    PNDIS_PROTOCOL_BLOCK            ProtocolHandle;         // pointer to our protocol
10    NDIS_HANDLE                     ProtocolBindingContext; // context when calling ProtXX
14    PNDIS_OPEN_BLOCK                MiniportNextOpen;       // used by adapter's OpenQueue
18    PNDIS_OPEN_BLOCK                ProtocolNextOpen;      // used by protocol's OpenQueue
1C    NDIS_HANDLE                     MiniportAdapterContext; // context for miniport
20    BOOLEAN                         Reserved1;
21    BOOLEAN                        Reserved2;
22    BOOLEAN                         Reserved3;
23    BOOLEAN                        Reserved4;
24    PNDIS_STRING                   BindDeviceName;
28    KSPIN_LOCK                     Reserved5;
2C    PNDIS_STRING                   RootDeviceName;

30    SEND_HANDLER                   SendHandler / WanSendHandler;
34    TRANSFER_DATA_HANDLER            TransferDataHandler;
38    SEND_COMPLETE_HANDLER          SendCompleteHandler;
3C    TRANSFER_DATA_COMPLETE_HANDLER     TransferDataCompleteHandler;
40    RECEIVE_HANDLER                ReceiveHandler;
44    RECEIVE_COMPLETE_HANDLER       ReceiveCompleteHandler;
48    WAN_RECEIVE_HANDLER            WanReceiveHandler;
4C    REQUEST_COMPLETE_HANDLER      RequestCompleteHandler;
50    RECEIVE_PACKET_HANDLER          ReceivePacketHandler;
54    SEND_PACKETS_HANDLER            SendPacketsHandler;
58    RESET_HANDLER                   ResetHandler;
5C    REQUEST_HANDLER                 RequestHandler;
60    RESET_COMPLETE_HANDLER          ResetCompleteHandler;
64    STATUS_HANDLER                  StatusHandler;
68    STATUS_COMPLETE_HANDLER        StatusCompleteHandler;

6C    ULONG                           Flags;
70    LONG                            References;
74    KSPIN_LOCK                      SpinLock;
78    NDIS_HANDLE                     FilterHandle;
7C    ULONG                           ProtocolOptions;
80    USHORT                          CurrentLookahead;
82    USHORT                          ConnectDampTicks;
84    USHORT                          DisconnectDampTicks;
86    USHORT                  reserved;

88    W_SEND_HANDLER                  WSendHandler;
8C    W_TRANSFER_DATA_HANDLER         WTransferDataHandler;
90    W_SEND_PACKETS_HANDLER          WSendPacketsHandler;

94    W_CANCEL_SEND_PACKETS_HANDLER       CancelSendPacketsHandler;
98    ULONG                           WakeUpEnable;
9C    PKEVENT                         CloseCompleteEvent;

A0    QUEUED_CLOSE                    QC;
A4    LONG                            AfReferences;
A8    PNDIS_OPEN_BLOCK                NextGlobalOpen;
} NDIS_COMMON_OPEN_BLOCK;

注意偏移40和50都是RECEIVE,只不过偏移40一次只能收一个包,偏移50一次可以收多个包,
有些系统用偏移40收包,有些系统用偏移50收包。4楼的兄弟应该属于偏移50收包的情况。

还有如果想发包,需要用NdisOpenAdapter()绑定网卡,比较麻烦。
gxmgf
驱动牛犊
驱动牛犊
  • 注册日期2003-10-17
  • 最后登录2007-03-08
  • 粉丝0
  • 关注0
  • 积分50分
  • 威望5点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2007-04-12 14:10
如果用DDK来改写这个程序,绝对要比MS提供的passthru简单明了很多,呵呵
softbiao
驱动牛犊
驱动牛犊
  • 注册日期2007-04-09
  • 最后登录2008-08-26
  • 粉丝0
  • 关注0
  • 积分240分
  • 威望26点
  • 贡献值0点
  • 好评度25点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2007-04-17 15:43
呵呵,支持,我现在也都是用汇编写东西 ~
游客

返回顶部