日期: 2004-07-19 16:55
更新: 2004-08-17 16:23
链接: http://www.opencjk.org/~scz/windows/200408171624.txt
--------------------------------------------------------------------------
☆ NDIS Protocol Driver
☆ ntoskrnl.exe引出的一些运行时函数
☆ 一个完整的NDIS Protocol Driver框架
a) NDIS协议驱动
1) ndisprotocol.c
2) sources
3) makefile
4) ndisprotocol.inf
b) NDIS协议驱动的用户态测试程序
1) ndisprotocoltest.c
2) sources
3) makefile
c) NDIS组件配置程序
d) 源代码目录结构
e) 编译
f) 安装
g) 测试
h) 卸载
i) 一些遗留问题
☆ 参考资源
--------------------------------------------------------------------------
☆ NDIS Protocol Driver
[1]给了一张Windows网络架构图,有助于理解NDIS,推荐入门者先看看这张图。
[2]有一些关于Windows网络架构的讨论,这只是一种个人学术观点,仅供参考,不可
当成官方结论。
NDIS(Network Device Interface Specification)提供一个系统的、完整的Wrapper,
NDIS Miniport Driver、NDIS ProtocolDriver等等均属于"插入"这个Wrapper中的"
模块",这些驱动调用Wrapper提供的函数,同时也向Wrapper注册回调函数,整个运
作过程由Wrapper统一调度。Wrapper对应ndis.sys。
TDI Client Driver利用协议驱动上沿引出的TDI接口(Transport Data Interface)实
现命名管道、邮槽、Winsock等等。
下面这些注册表内容对应着Network Control Panel Applet (NCPA):
--------------------------------------------------------------------------
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Class/{4D36E972-E325-11CE-BFC1-08002bE10318}
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Class/{4D36E973-E325-11CE-BFC1-08002BE10318}
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Class/{4D36E974-E325-11CE-BFC1-08002BE10318}
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Class/{4D36E975-E325-11CE-BFC1-08002BE10318}
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Network/{4D36E972-E325-11CE-BFC1-08002BE10318}
对应GUID_DEVCLASS_NET、Miniport Driver、Net。收到包后NDIS首先调用
Miniport Driver进行处理。Miniport Driver负责控制网卡硬件特性,在协议驱
动与网卡之间传递报文。
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Network/{4D36E973-E325-11CE-BFC1-08002BE10318}
对应GUID_DEVCLASS_NETCLIENT、Client Driver、NetClient。"Client for
Microsoft Networks"即是此类型驱动。负责向用户态提供NetBIOS Client API。
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Network/{4D36E974-E325-11CE-BFC1-08002BE10318}
对应GUID_DEVCLASS_NETSERVICE、Service Driver、NetService。"File and
Printer Sharing for Microsoft Networks"即是此类型驱动。
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Network/{4D36E975-E325-11CE-BFC1-08002BE10318}
对应GUID_DEVCLASS_NETTRANS、Protocol Driver、NetTrans。负责实现各种网
络协议,比如tcpip.sys实现了TCP/IP协议。协议驱动接收Miniport Driver上传
的报文,也接收Client Driver、Service Driver、TDI Client Driver下传的报
文。
--------------------------------------------------------------------------
中间层驱动(Intermediate Driver)是一种混合型驱动,位于Miniport Driver与协议
驱动之间,对下看起来像协议驱动,对上看起来像Miniport Driver。
在这些不同类型的驱动之间有一种操作叫作"绑定",其本质在于向NDIS Wrapper指明
报文(Packet)的传递路线。
☆ ntoskrnl.exe引出的一些运行时函数
> dumpbin /exports %systemroot%/system32/ntoskrnl.exe | find /I "printf"
1397 574 00052BCB _snprintf
1398 575 00052C22 _snwprintf
1406 57D 00052D73 _vsnprintf
1407 57E 00052DC9 _vsnwprintf
1430 595 00053D4D sprintf
1443 5A2 000543E0 swprintf
1450 5A9 000544F4 vsprintf
> dumpbin /exports %systemroot%/system32/ntoskrnl.exe | find "_str"
1399 576 00052C92 _stricmp
1400 577 00052C97 _strlwr
1401 578 00052CBA _strnicmp
1402 579 00052CD0 _strnset
1403 57A 00052D00 _strrev
1404 57B 00052D30 _strset
1405 57C 00052D50 _strupr
> dumpbin /exports %systemroot%/system32/ntoskrnl.exe | find " str"
1432 597 00053DC0 strcat
1433 598 00053EB0 strchr
1434 599 00053F70 strcmp
1435 59A 00053DB0 strcpy
1436 59B 00054000 strlen
1437 59C 00054080 strncat
1438 59D 000541B0 strncmp
1439 59E 000541F0 strncpy
1440 59F 000542F0 strrchr
1441 5A0 00054320 strspn
1442 5A1 00054360 strstr
> dumpbin /exports %systemroot%/system32/ntoskrnl.exe | find "wcs"
1408 57F 00052E38 _wcsicmp
1409 580 00052E83 _wcslwr
1410 581 00052EAF _wcsnicmp
1411 582 00052F08 _wcsnset
1412 583 00052F31 _wcsrev
1413 584 00052F63 _wcsupr
1422 58D 000531DB mbstowcs
1451 5AA 0005454B wcscat
1452 5AB 00054591 wcschr
1453 5AC 000545B3 wcscmp
1454 5AD 00054575 wcscpy
1455 5AE 000545E5 wcscspn
1456 5AF 00054628 wcslen
1457 5B0 0005463E wcsncat
1458 5B1 0005467B wcsncmp
1459 5B2 000546B0 wcsncpy
1460 5B3 000546ED wcsrchr
1461 5B4 0005471D wcsspn
1462 5B5 00054763 wcsstr
1463 5B6 000547C1 wcstombs
> dumpbin /exports %systemroot%/system32/ntoskrnl.exe | find "mem"
1424 58F 00053290 memchr
1425 590 00053340 memcpy
1426 591 00053680 memmove
1427 592 000539C0 memset
> dumpbin /exports %systemroot%/system32/ntoskrnl.exe | find "_ito"
1393 570 00052B76 _itoa
1394 571 00052BA0 _itow
☆ 一个完整的NDIS Protocol Driver框架
a) NDIS协议驱动
XP SP1 DDK自带了一个名为ndisuio的例子(NDIS User mode I/O Protocol),但我没
有找到NT4 DDK中名为packet的例子。参[3]、[4]、[5],这些都是完整的协议驱动源
代码。
ndisuio演示了"connection-less NDIS 5.0/5.1 protocol driver",用户态程序可
简单地通过ReadFile/WriteFile直接操作链路层数据(物理帧)。对于sniffer一类的
需求,这已经足够了。ndisuio没有在其上沿提供TDI接口。ndisuio做了很多限制,
使得我们无法随心所欲地操作链路层数据。假设有如下结构:
struct etherheader
{
unsigned char eth_dst[6]; /* destination eth addr */
unsigned char eth_src[6]; /* source ether addr */
unsigned short int eth_type; /* packet type ID field */
};
ndisuio在DispatchWrite()例程中对eth_src、eth_type进行检查,发送报文时不能
伪造源MAC,必须匹配事先指定的eth_type。
ndisuio允许用户态程序通过DeviceIoControl()指定eth_type,但其在
DispatchDeviceControl()例程中做了限制,不能任意指定eth_type。
ndisuio在ProtocolReceive()、ProtocolReceivePacket()例程中对eth_type进行检
查,只接收与事先指定的eth_type相匹配的报文。
ndisuio允许用户态程序通过DeviceIoControl()向Miniport Driver设置OID,但其在
DispatchDeviceControl()例程中做了限制,只允许设置部分OID。
从ndisuio例子所附用户态测试程序的代码来看,曾经有一个版本的ndisuio未做前述
限制,至少发送报文时可以伪造源MAC。现在我们要做的就是简单地注释掉相应代码,
使得可以随心所欲地操作链路层数据。
XP事实上缺省安装了ndisuio,可用"net start ndisuio"加载这个隐藏的协议驱动。
据tk讲,2000也缺省安装ndisuio,我不确认是某个Service Pack带进来的,还是最
初就有。由于存在前述限制,ndisuio对我们来讲没有多少意义。
下面是XP SP1中与ndisuio相关的注册表内容,NDI是"Network Device Installer"的
缩写。
--------------------------------------------------------------------------
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Network/{4D36E975-E325-11CE-BFC1-08002BE10318}/{03130807-B5F2-47A1-81B0-B870D16F272B}]
"Characteristics"=dword:00000028
"InfPath"="ndisuio.inf"
"InfSection"="Install"
"Description"="NDIS Usermode I/O Protocol"
"ComponentId"="ms_ndisuio"
[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Network/{4D36E975-E325-11CE-BFC1-08002BE10318}/{03130807-B5F2-47A1-81B0-B870D16F272B}/Ndi]
"Service"="Ndisuio"
"HelpText"="A driver to support user-mode I/O on NDIS devices"
[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Network/{4D36E975-E325-11CE-BFC1-08002BE10318}/{03130807-B5F2-47A1-81B0-B870D16F272B}/Ndi/Interfaces]
"UpperRange"="noupper"
"LowerRange"="ndis5,ndis4,ndis5_uio"
--------------------------------------------------------------------------
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Enum/Root/LEGACY_NDISUIO]
"NextInstance"=dword:00000001
[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Enum/Root/LEGACY_NDISUIO/0000]
"Service"="Ndisuio"
"Legacy"=dword:00000001
"ConfigFlags"=dword:00000000
"Class"="LegacyDriver"
"ClassGUID"="{8ECC055D-047F-11D1-A537-0000F8753ED1}"
"DeviceDesc"="NDIS Usermode I/O Protocol"
"Capabilities"=dword:00000000
[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Enum/Root/LEGACY_NDISUIO/0000/LogConf]
[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Enum/Root/LEGACY_NDISUIO/0000/Control]
"ActiveService"="Ndisuio"
--------------------------------------------------------------------------
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Ndisuio]
"Type"=dword:00000001
"Start"=dword:00000003
"ErrorControl"=dword:00000001
"Tag"=dword:0000000c
"ImagePath"=hex(2):53,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,44,00,/
52,00,49,00,56,00,45,00,52,00,53,00,5c,00,6e,00,64,00,69,00,73,00,75,00,69,/
00,6f,00,
更新: 2004-08-17 16:23
链接: http://www.opencjk.org/~scz/windows/200408171624.txt
--------------------------------------------------------------------------
☆ NDIS Protocol Driver
☆ ntoskrnl.exe引出的一些运行时函数
☆ 一个完整的NDIS Protocol Driver框架
a) NDIS协议驱动
1) ndisprotocol.c
2) sources
3) makefile
4) ndisprotocol.inf
b) NDIS协议驱动的用户态测试程序
1) ndisprotocoltest.c
2) sources
3) makefile
c) NDIS组件配置程序
d) 源代码目录结构
e) 编译
f) 安装
g) 测试
h) 卸载
i) 一些遗留问题
☆ 参考资源
--------------------------------------------------------------------------
☆ NDIS Protocol Driver
[1]给了一张Windows网络架构图,有助于理解NDIS,推荐入门者先看看这张图。
[2]有一些关于Windows网络架构的讨论,这只是一种个人学术观点,仅供参考,不可
当成官方结论。
NDIS(Network Device Interface Specification)提供一个系统的、完整的Wrapper,
NDIS Miniport Driver、NDIS ProtocolDriver等等均属于"插入"这个Wrapper中的"
模块",这些驱动调用Wrapper提供的函数,同时也向Wrapper注册回调函数,整个运
作过程由Wrapper统一调度。Wrapper对应ndis.sys。
TDI Client Driver利用协议驱动上沿引出的TDI接口(Transport Data Interface)实
现命名管道、邮槽、Winsock等等。
下面这些注册表内容对应着Network Control Panel Applet (NCPA):
--------------------------------------------------------------------------
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Class/{4D36E972-E325-11CE-BFC1-08002bE10318}
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Class/{4D36E973-E325-11CE-BFC1-08002BE10318}
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Class/{4D36E974-E325-11CE-BFC1-08002BE10318}
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Class/{4D36E975-E325-11CE-BFC1-08002BE10318}
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Network/{4D36E972-E325-11CE-BFC1-08002BE10318}
对应GUID_DEVCLASS_NET、Miniport Driver、Net。收到包后NDIS首先调用
Miniport Driver进行处理。Miniport Driver负责控制网卡硬件特性,在协议驱
动与网卡之间传递报文。
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Network/{4D36E973-E325-11CE-BFC1-08002BE10318}
对应GUID_DEVCLASS_NETCLIENT、Client Driver、NetClient。"Client for
Microsoft Networks"即是此类型驱动。负责向用户态提供NetBIOS Client API。
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Network/{4D36E974-E325-11CE-BFC1-08002BE10318}
对应GUID_DEVCLASS_NETSERVICE、Service Driver、NetService。"File and
Printer Sharing for Microsoft Networks"即是此类型驱动。
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Network/{4D36E975-E325-11CE-BFC1-08002BE10318}
对应GUID_DEVCLASS_NETTRANS、Protocol Driver、NetTrans。负责实现各种网
络协议,比如tcpip.sys实现了TCP/IP协议。协议驱动接收Miniport Driver上传
的报文,也接收Client Driver、Service Driver、TDI Client Driver下传的报
文。
--------------------------------------------------------------------------
中间层驱动(Intermediate Driver)是一种混合型驱动,位于Miniport Driver与协议
驱动之间,对下看起来像协议驱动,对上看起来像Miniport Driver。
在这些不同类型的驱动之间有一种操作叫作"绑定",其本质在于向NDIS Wrapper指明
报文(Packet)的传递路线。
☆ ntoskrnl.exe引出的一些运行时函数
> dumpbin /exports %systemroot%/system32/ntoskrnl.exe | find /I "printf"
1397 574 00052BCB _snprintf
1398 575 00052C22 _snwprintf
1406 57D 00052D73 _vsnprintf
1407 57E 00052DC9 _vsnwprintf
1430 595 00053D4D sprintf
1443 5A2 000543E0 swprintf
1450 5A9 000544F4 vsprintf
> dumpbin /exports %systemroot%/system32/ntoskrnl.exe | find "_str"
1399 576 00052C92 _stricmp
1400 577 00052C97 _strlwr
1401 578 00052CBA _strnicmp
1402 579 00052CD0 _strnset
1403 57A 00052D00 _strrev
1404 57B 00052D30 _strset
1405 57C 00052D50 _strupr
> dumpbin /exports %systemroot%/system32/ntoskrnl.exe | find " str"
1432 597 00053DC0 strcat
1433 598 00053EB0 strchr
1434 599 00053F70 strcmp
1435 59A 00053DB0 strcpy
1436 59B 00054000 strlen
1437 59C 00054080 strncat
1438 59D 000541B0 strncmp
1439 59E 000541F0 strncpy
1440 59F 000542F0 strrchr
1441 5A0 00054320 strspn
1442 5A1 00054360 strstr
> dumpbin /exports %systemroot%/system32/ntoskrnl.exe | find "wcs"
1408 57F 00052E38 _wcsicmp
1409 580 00052E83 _wcslwr
1410 581 00052EAF _wcsnicmp
1411 582 00052F08 _wcsnset
1412 583 00052F31 _wcsrev
1413 584 00052F63 _wcsupr
1422 58D 000531DB mbstowcs
1451 5AA 0005454B wcscat
1452 5AB 00054591 wcschr
1453 5AC 000545B3 wcscmp
1454 5AD 00054575 wcscpy
1455 5AE 000545E5 wcscspn
1456 5AF 00054628 wcslen
1457 5B0 0005463E wcsncat
1458 5B1 0005467B wcsncmp
1459 5B2 000546B0 wcsncpy
1460 5B3 000546ED wcsrchr
1461 5B4 0005471D wcsspn
1462 5B5 00054763 wcsstr
1463 5B6 000547C1 wcstombs
> dumpbin /exports %systemroot%/system32/ntoskrnl.exe | find "mem"
1424 58F 00053290 memchr
1425 590 00053340 memcpy
1426 591 00053680 memmove
1427 592 000539C0 memset
> dumpbin /exports %systemroot%/system32/ntoskrnl.exe | find "_ito"
1393 570 00052B76 _itoa
1394 571 00052BA0 _itow
☆ 一个完整的NDIS Protocol Driver框架
a) NDIS协议驱动
XP SP1 DDK自带了一个名为ndisuio的例子(NDIS User mode I/O Protocol),但我没
有找到NT4 DDK中名为packet的例子。参[3]、[4]、[5],这些都是完整的协议驱动源
代码。
ndisuio演示了"connection-less NDIS 5.0/5.1 protocol driver",用户态程序可
简单地通过ReadFile/WriteFile直接操作链路层数据(物理帧)。对于sniffer一类的
需求,这已经足够了。ndisuio没有在其上沿提供TDI接口。ndisuio做了很多限制,
使得我们无法随心所欲地操作链路层数据。假设有如下结构:
struct etherheader
{
unsigned char eth_dst[6]; /* destination eth addr */
unsigned char eth_src[6]; /* source ether addr */
unsigned short int eth_type; /* packet type ID field */
};
ndisuio在DispatchWrite()例程中对eth_src、eth_type进行检查,发送报文时不能
伪造源MAC,必须匹配事先指定的eth_type。
ndisuio允许用户态程序通过DeviceIoControl()指定eth_type,但其在
DispatchDeviceControl()例程中做了限制,不能任意指定eth_type。
ndisuio在ProtocolReceive()、ProtocolReceivePacket()例程中对eth_type进行检
查,只接收与事先指定的eth_type相匹配的报文。
ndisuio允许用户态程序通过DeviceIoControl()向Miniport Driver设置OID,但其在
DispatchDeviceControl()例程中做了限制,只允许设置部分OID。
从ndisuio例子所附用户态测试程序的代码来看,曾经有一个版本的ndisuio未做前述
限制,至少发送报文时可以伪造源MAC。现在我们要做的就是简单地注释掉相应代码,
使得可以随心所欲地操作链路层数据。
XP事实上缺省安装了ndisuio,可用"net start ndisuio"加载这个隐藏的协议驱动。
据tk讲,2000也缺省安装ndisuio,我不确认是某个Service Pack带进来的,还是最
初就有。由于存在前述限制,ndisuio对我们来讲没有多少意义。
下面是XP SP1中与ndisuio相关的注册表内容,NDI是"Network Device Installer"的
缩写。
--------------------------------------------------------------------------
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Network/{4D36E975-E325-11CE-BFC1-08002BE10318}/{03130807-B5F2-47A1-81B0-B870D16F272B}]
"Characteristics"=dword:00000028
"InfPath"="ndisuio.inf"
"InfSection"="Install"
"Description"="NDIS Usermode I/O Protocol"
"ComponentId"="ms_ndisuio"
[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Network/{4D36E975-E325-11CE-BFC1-08002BE10318}/{03130807-B5F2-47A1-81B0-B870D16F272B}/Ndi]
"Service"="Ndisuio"
"HelpText"="A driver to support user-mode I/O on NDIS devices"
[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Network/{4D36E975-E325-11CE-BFC1-08002BE10318}/{03130807-B5F2-47A1-81B0-B870D16F272B}/Ndi/Interfaces]
"UpperRange"="noupper"
"LowerRange"="ndis5,ndis4,ndis5_uio"
--------------------------------------------------------------------------
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Enum/Root/LEGACY_NDISUIO]
"NextInstance"=dword:00000001
[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Enum/Root/LEGACY_NDISUIO/0000]
"Service"="Ndisuio"
"Legacy"=dword:00000001
"ConfigFlags"=dword:00000000
"Class"="LegacyDriver"
"ClassGUID"="{8ECC055D-047F-11D1-A537-0000F8753ED1}"
"DeviceDesc"="NDIS Usermode I/O Protocol"
"Capabilities"=dword:00000000
[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Enum/Root/LEGACY_NDISUIO/0000/LogConf]
[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Enum/Root/LEGACY_NDISUIO/0000/Control]
"ActiveService"="Ndisuio"
--------------------------------------------------------------------------
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Ndisuio]
"Type"=dword:00000001
"Start"=dword:00000003
"ErrorControl"=dword:00000001
"Tag"=dword:0000000c
"ImagePath"=hex(2):53,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,44,00,/
52,00,49,00,56,00,45,00,52,00,53,00,5c,00,6e,00,64,00,69,00,73,00,75,00,69,/
00,6f,00,