论文部分内容阅读
摘要:WinPcap系统是一个功能强大的用于网络数据获取开发包,它直接和网卡打交道,获取数据链路层的数据,能捕获数据链路层的所有数据包。基于WinPcap的网络数据获取系统具有结构简单、捕获数据快、协议识别率高等特点,它的三个模块的相互套用,实现了网络数据获取的基本功能。
关键字:网络数据获取;网络安全;数据包;WinPcap
中图分类号:TP393文献标识码:A文章编号:1009-3044(2007)04-11094-02
1 引言
随着计算机技术的发展,网络已日益成为生活中不可或缺的工具,但伴之而来的非法入侵也一直威胁着计算机网络系统的安全。由于局域网中采用广播方式,因此,在某个广播域中可以监听到所有的数据包。而黑客通过对数据包进行分析,就能获取局域网上传输的一些重要信息。事实上,很多黑客入侵时都把局域网扫描和窃听作为其最基本的步骤和手段,原因是想用这种方法获取其想要的密码等信息。但另一方面,我们对黑客入侵活动和其它网络犯罪进行调查、取证时,也可以使用网络监听技术来获取必要的信息。因此,了解以太网监听技术的原理、实现方法和防范措施就显得尤为重要。
网络数据获取可以通过两种方式实现[1]:一种是利用以太网的广播特性,另一种是通过设置网络设备的监听端口来实现.以太网的数据传输具有广播特性,局域网中的所有网络端口都有访问物理媒体上传输的所有数据的能力。但一般情况下,网卡从网络上收到一个数据帧后,先要进行地址匹配检查,只把与网卡MAC地址相匹配的或者为广播地址或特定组播地址的数据帧递交给操作系统内核,而丢弃其他一切数据帧,所以应用程序只接收到到达本机的数据。要捕获到流经网卡但不属于本机的数据,必须将网卡的工作模式设置为“混杂模式(promiscuous)”,当网卡工作在这种模式下,就具备了接收所有到达网卡数据的能力,它对所有接收到的数据帧都产生中断,不进行地址匹配,而直接把所有数据帧递交给系统处理,这样操作系统通过直接访问数据链路层,就可以捕获流经网卡的所有数据报文。把网卡设成混杂模式需要网卡驱动程序的支持,驱动程序通过系统I/O调用把网卡设成混杂模式,从而跳过地址的匹配检查。
2 网络数据获取机理
在Windows操作系统中,NDIS起着十分重要的作用,它是网络层协议与网络接口适配器(NIC)之间的桥梁纽带,所有的网络功能调用都通过NDIS接口函数访问网卡来实现,NDIS处于Miniport驱动程序的上面[2]。Miniport相当于IEEE 802标准的数据链路层的介质访问控制(MAC)子层,而NDIS相当于逻辑连接控制(LLC)子层。当数据包达到网络适配器时,网卡驱动程序将数据通过NDIS发送给Miniport驱动程序,然后Miniport驱动程序通过NDIS发送给传输驱动程序,最后达到上层应用程序。同样,当要发送数据时,应用程序将数据发送给传输驱动程序,传输驱动程序通过NDIS发送给Miniport驱动程序,然后Miniport驱动程序通过NDIS发送给网卡驱动程序,最后发送到物理链路上。OSI通信模型与NDIS的关系如图1所示。
图1 OSI通信模型与NDIS的关系
应用程序对网卡的访问必须经过NDIS接口实现,NDIS向上层提供一个协议接口,向下提供一个miniport接口。NDIS驱动程序通常需要向NDIS接口注册一组进程,NDIS接口在适当的时候能调用注册进程,驱动程序就可以通过这些进程进行相应的数据处理。Windows允许多个传输驱动程序处于NDIS的最高层,典型的TCP/IP实现模块tcpip.sys就位于这一层,传输驱动程序可以注册为传输提供者,从而为上层的TDI客户提供服务,TDI客户与传输驱动之间采用特定的机制进行通信。
对于获取网络上的传输数据,并对数据进行处理,一般可将应用系统结构划分为三个处理层次:数据捕获和还原层、数据预处理层、应用处理层。
数据捕获和还原层(底层处理模块):由数据获取模块和底层打包模块组成。数据获取负责控制网卡,接收网络上的所有报文,其输入为网卡接收的数据流,输出为打包模块;打包模块负责将接收到的报文根据不同的应用,按源IP地址、目的IP地址、源端口号、目的端口号进行数据还原。对于大流量的数据处理,可对接收到的数据进行分类打包,存入数据缓冲区或数据库,方便多线程的处理。
数据预处理层(中层处理模块):由分布控制模块和线程处理模块组成。分布控制模块负责与线程队列通信,以及从经底层处理模块处理后的存在缓冲区或数据库中的数据进行提取,并根据不同的应用需求进行预处理,同时按照一定的分布式计算方法将其放入本机检索队列或后援检索队列或解压队列中,待进一步基于应用的处理。
应用处理层(上层处理模块):负责实现和用户之间的交互。根据不同的应用进行数据的内容分析和数据展示,将数据包去掉包头,读取内容并进行分析。
3 WinPcap的总体结构
WinPcap是由意大利人Fulvio Risso和Loris Degioanni等人提出并实现的[3]。WinPcap是一个在Win32环境下用于实现高效数据包捕获的开发包,它的主要思想来自于UNIX系统中著名的BSD包捕获结构,具有良好的结构和性能。
WinPcap能实现以下四项功能[4]:捕获原始数据包,包括共享网络上各主机发送/接收的以及相互之间交换的数据包;在数据包发往应用程序之前,按照自定义的规则将某些特殊的数据包过滤掉;在网络上发送原始的数据包;收集网络通信过程中的统计信息。
WinPcap开发包分为三个相对独立的部分:网络组包过滤器(Netgroup Packet Filter,NPF)、低级动态连接库(Packet.dll)、高级系统无关库(Wpcap.dll),其总体结构如图2所示。
图2 WinPcap的总体结构
网络组包过滤器。它是运行于操作系统内核中的驱动程序,它直接与网卡驱动程序进行交互,获取在网络上传输的原始数据包。NPF的结构来源于BPF(Berkley Packet Filter),BPF是用于UNIX系统中的一种网络监控工具,它使用由UNIX操作系统提供的内核级别的可访问未处理的原始网络数据的功能。BPF有两个部分,网络开关(network tap)和包过滤机(packet filter),network tap从网络设备驱动程序中收集数据拷贝并转发到监听程序,network filter决定是否接收该数据包以及该数据包方式。实际上NPF是BPF的一个虚拟机,但NPF不是由操作系统提供而是WinPcap的一部分,其主要任务是从网络系统中获取数据链路层的数据帧,并将它转发给上层模块。NPF与操作系统有关,WinPcap开发组针对不同的Windows操作系统提供了不同版本的NPF。在Win95/98/ME系统中,它以VxD文件形式存在,在WindowsNT和Windows 2000系统中,它以SYS文件形式存在。该模块提供了捕获数据包以及发送数据包的基本功能,此外还提供了一些高级功能,如数据包过滤系统和检测引擎。NPF通过NDIS和NIC进行数据交换,WinPcap允许同时运行多个NPF。
当有新的数据到达网卡,NIC就会通知BPF的network tap,BPF开始接收数据,并送到不同的network filter,由network filter判断是否保留此数据还是将其丢弃。符合过滤条件的数据包,将被送到内核缓冲区(Kernel buffer),等待着向用户级缓冲区(User buffer)传递。NPF中的内核缓冲使用的是动态循环缓冲区(Hold buffer和Store buffer),内核缓存在包捕获时开始被分配,在结束时被释放。当Hold buffer存满时,Store buffer中的数据被送到用户级缓存,Store buffer中的数据包被送到Hold buffer,如此循环不止。
WinPcap的过滤机制。由于网络中传输的数据有很多是用户不关心的,称为垃圾数据,大量的垃圾数据会影响系统的工作效率,所以在数据获取的过程中,必须对到达网卡的数据进行过滤,丢弃垃圾数据,提高工作效率。用户可以根据本地主机和网络状况设置特定的源(或目的)IP地址、端口号、主机名等等,NPF根据用户设置的过滤条件对数据进行过滤,只把用户需要的数据传送到内核缓存,从而提高了系统的工作效率。WinPcap中的过滤是在NPF中的过滤机实现的,它使用tcpdump表达式来指定过滤规则。
Packet.dll和WinPcap.dll。动态连接库Packet.dll运行在用户层,把应用程序和NPF功能独立开,使应用程序可以不加修改地在不同的Windows系统上运行。通过Packet.dll提供的API(Application Programming Interface)能够直接访问NPF的包驱动API。动态链接库Wpcap.dll和应用程序编译在一起,它使用由Packet.dll提供的服务,向应用程序提供完善的接口函数(在UNIX系统中通过Libpcap.dll提供的相同接口,而Wpcap.dll实际上是Libpcap.dll的一个超集,Wpcap.dll提供的一些编程接口是Windows平台特有的函数)。
4 基于WinPcap的网络数据获取流程
利用WinPcap实现网络数据获取既可以通过调用Packet.dll中的API实现,也可以通过调用Wpcap.dll中的API实现。此处考虑到与操作系统的无关性,介绍基于Windows的Wpcap.dll的网络数据获取。过程可分为四步:获取NIC的有关信息、建立网络侦听、设置过滤条件、进行循环捕获,基本流程如图3所示。
图3 数据捕获的流程图
Wpcap.dll中定义了多个函数和数据类型,在C程序中使用Wpcap.dll时必须在程序的预处理部分包含“Pcap.h”头文件,在C ++中必须包含“Pcap c ++.h”头文件[5]。
获取NIC的有关信息。有两种获取NIC信息的方法:一种是由用户自己指定;一种是调用Pcap接口函数自动搜索本地主机可用的网络接口,常使用第二种方法。获取NIC相关信息的函数为Pcap_lookupdev和pcap_lookupnet。Pcap_lookupdev用来寻找本地主机可用的网络接口,返回类型为字符型指针,用来表示本地接口网络接口。pcap_lookupnet用来获取本地主机的IP地址和子网掩码,并用32位整数表示。pcap_lookupnet的返回值为int型,当函数调用失败则返回-1。
启动网络侦听。启用上一步骤中获得的网络接口,所使用的函数为Pcap_open_live,它负责按照用户指定的参数和系统默认的初始化WinPcap。Pcap_open_live的返回值类型为Pcap_t型指针,作为侦听句柄。Pcap_t是Wpcap.dll定义的数据类型。
设置过滤条件。设置过滤条件有两个步骤:一是将用户输入的字符型的过滤条件转换成系统认可的bpf_program型,bpf_program是WinPcap定义的数据结构;另一步骤是将转换后的过滤条件传递给侦听句柄。
进行循环捕获。前面所有的步骤都是对NPF的初始化,完成初始化之后,最后一个步骤就是进行数据的循环捕获。Pcap库提供了两个函数实现这个功能:Pcap_dispath和Pcap_loop,它们实现的功能基本相同,调用成功时返回读取到的字节数,否则返回0。它们的区别在于Pcap_loop在读取超时(在Pcap_open_live中设置)的时候不会返回,而Pcap_dispath遇到读取超时就返回0。用户对数据包的所有操作都是在回调函数中完成的,回调函数被定义成一个全局的函数,对每一个循环中读取的数据包按用户的定义进行操作。
5 结论
WinPcap系统是一个功能强大的用于网络数据获取开发包,它直接和网卡打交道,获取数据链层的数据,能捕获数据链路层的所有数据包。WinPcap的分层思想为Windows平台提供了一个完整的、简单的、系统无关的编程接口,为在Windows平台下开发高性能的网络数据获取软件提供了方便。WinPcap的两级缓存的设计,极大地提高了数据包的捕获率,使丢包率降到了很低的程度,尤其是它内核级缓存的动态循环存储的思想,是它在数据捕获的速度方面优于UNIX中的Libpcap。总之,基于WinPcap的网络数据获取系统实验方案具有结构简单、捕获数据快、协议识别率高等特点,它的三个模块的相互套用,实现了网络数据获取的基本功能。
参考文献:
[1]王威伟,郑雪峰.局域网中网络监听与防范技术[J].计算机工程与设计,2005,26(11):3056-3058.
[2]吴玉,娄智.基于操作系统内核的包过滤防火墙系统[J].湖南工程学院学报,2006,16(2):39-41.
[3]胡晓元,史涪山.WinPcap包截获系统的分析及其应用[J].计算机工程,2005,31(2):96-98.
[4]赵新辉,李祥.捕获网络数据包的方法[J].计算机应用研究,2004,8:242-243,255.
[5]DAVID J.KRUGLINSHKI.著.潘爱民.译.Visual C++技术内幕[M].北京:希望电子出版社,2002.
本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文。
关键字:网络数据获取;网络安全;数据包;WinPcap
中图分类号:TP393文献标识码:A文章编号:1009-3044(2007)04-11094-02
1 引言
随着计算机技术的发展,网络已日益成为生活中不可或缺的工具,但伴之而来的非法入侵也一直威胁着计算机网络系统的安全。由于局域网中采用广播方式,因此,在某个广播域中可以监听到所有的数据包。而黑客通过对数据包进行分析,就能获取局域网上传输的一些重要信息。事实上,很多黑客入侵时都把局域网扫描和窃听作为其最基本的步骤和手段,原因是想用这种方法获取其想要的密码等信息。但另一方面,我们对黑客入侵活动和其它网络犯罪进行调查、取证时,也可以使用网络监听技术来获取必要的信息。因此,了解以太网监听技术的原理、实现方法和防范措施就显得尤为重要。
网络数据获取可以通过两种方式实现[1]:一种是利用以太网的广播特性,另一种是通过设置网络设备的监听端口来实现.以太网的数据传输具有广播特性,局域网中的所有网络端口都有访问物理媒体上传输的所有数据的能力。但一般情况下,网卡从网络上收到一个数据帧后,先要进行地址匹配检查,只把与网卡MAC地址相匹配的或者为广播地址或特定组播地址的数据帧递交给操作系统内核,而丢弃其他一切数据帧,所以应用程序只接收到到达本机的数据。要捕获到流经网卡但不属于本机的数据,必须将网卡的工作模式设置为“混杂模式(promiscuous)”,当网卡工作在这种模式下,就具备了接收所有到达网卡数据的能力,它对所有接收到的数据帧都产生中断,不进行地址匹配,而直接把所有数据帧递交给系统处理,这样操作系统通过直接访问数据链路层,就可以捕获流经网卡的所有数据报文。把网卡设成混杂模式需要网卡驱动程序的支持,驱动程序通过系统I/O调用把网卡设成混杂模式,从而跳过地址的匹配检查。
2 网络数据获取机理
在Windows操作系统中,NDIS起着十分重要的作用,它是网络层协议与网络接口适配器(NIC)之间的桥梁纽带,所有的网络功能调用都通过NDIS接口函数访问网卡来实现,NDIS处于Miniport驱动程序的上面[2]。Miniport相当于IEEE 802标准的数据链路层的介质访问控制(MAC)子层,而NDIS相当于逻辑连接控制(LLC)子层。当数据包达到网络适配器时,网卡驱动程序将数据通过NDIS发送给Miniport驱动程序,然后Miniport驱动程序通过NDIS发送给传输驱动程序,最后达到上层应用程序。同样,当要发送数据时,应用程序将数据发送给传输驱动程序,传输驱动程序通过NDIS发送给Miniport驱动程序,然后Miniport驱动程序通过NDIS发送给网卡驱动程序,最后发送到物理链路上。OSI通信模型与NDIS的关系如图1所示。
图1 OSI通信模型与NDIS的关系
应用程序对网卡的访问必须经过NDIS接口实现,NDIS向上层提供一个协议接口,向下提供一个miniport接口。NDIS驱动程序通常需要向NDIS接口注册一组进程,NDIS接口在适当的时候能调用注册进程,驱动程序就可以通过这些进程进行相应的数据处理。Windows允许多个传输驱动程序处于NDIS的最高层,典型的TCP/IP实现模块tcpip.sys就位于这一层,传输驱动程序可以注册为传输提供者,从而为上层的TDI客户提供服务,TDI客户与传输驱动之间采用特定的机制进行通信。
对于获取网络上的传输数据,并对数据进行处理,一般可将应用系统结构划分为三个处理层次:数据捕获和还原层、数据预处理层、应用处理层。
数据捕获和还原层(底层处理模块):由数据获取模块和底层打包模块组成。数据获取负责控制网卡,接收网络上的所有报文,其输入为网卡接收的数据流,输出为打包模块;打包模块负责将接收到的报文根据不同的应用,按源IP地址、目的IP地址、源端口号、目的端口号进行数据还原。对于大流量的数据处理,可对接收到的数据进行分类打包,存入数据缓冲区或数据库,方便多线程的处理。
数据预处理层(中层处理模块):由分布控制模块和线程处理模块组成。分布控制模块负责与线程队列通信,以及从经底层处理模块处理后的存在缓冲区或数据库中的数据进行提取,并根据不同的应用需求进行预处理,同时按照一定的分布式计算方法将其放入本机检索队列或后援检索队列或解压队列中,待进一步基于应用的处理。
应用处理层(上层处理模块):负责实现和用户之间的交互。根据不同的应用进行数据的内容分析和数据展示,将数据包去掉包头,读取内容并进行分析。
3 WinPcap的总体结构
WinPcap是由意大利人Fulvio Risso和Loris Degioanni等人提出并实现的[3]。WinPcap是一个在Win32环境下用于实现高效数据包捕获的开发包,它的主要思想来自于UNIX系统中著名的BSD包捕获结构,具有良好的结构和性能。
WinPcap能实现以下四项功能[4]:捕获原始数据包,包括共享网络上各主机发送/接收的以及相互之间交换的数据包;在数据包发往应用程序之前,按照自定义的规则将某些特殊的数据包过滤掉;在网络上发送原始的数据包;收集网络通信过程中的统计信息。
WinPcap开发包分为三个相对独立的部分:网络组包过滤器(Netgroup Packet Filter,NPF)、低级动态连接库(Packet.dll)、高级系统无关库(Wpcap.dll),其总体结构如图2所示。
图2 WinPcap的总体结构
网络组包过滤器。它是运行于操作系统内核中的驱动程序,它直接与网卡驱动程序进行交互,获取在网络上传输的原始数据包。NPF的结构来源于BPF(Berkley Packet Filter),BPF是用于UNIX系统中的一种网络监控工具,它使用由UNIX操作系统提供的内核级别的可访问未处理的原始网络数据的功能。BPF有两个部分,网络开关(network tap)和包过滤机(packet filter),network tap从网络设备驱动程序中收集数据拷贝并转发到监听程序,network filter决定是否接收该数据包以及该数据包方式。实际上NPF是BPF的一个虚拟机,但NPF不是由操作系统提供而是WinPcap的一部分,其主要任务是从网络系统中获取数据链路层的数据帧,并将它转发给上层模块。NPF与操作系统有关,WinPcap开发组针对不同的Windows操作系统提供了不同版本的NPF。在Win95/98/ME系统中,它以VxD文件形式存在,在WindowsNT和Windows 2000系统中,它以SYS文件形式存在。该模块提供了捕获数据包以及发送数据包的基本功能,此外还提供了一些高级功能,如数据包过滤系统和检测引擎。NPF通过NDIS和NIC进行数据交换,WinPcap允许同时运行多个NPF。
当有新的数据到达网卡,NIC就会通知BPF的network tap,BPF开始接收数据,并送到不同的network filter,由network filter判断是否保留此数据还是将其丢弃。符合过滤条件的数据包,将被送到内核缓冲区(Kernel buffer),等待着向用户级缓冲区(User buffer)传递。NPF中的内核缓冲使用的是动态循环缓冲区(Hold buffer和Store buffer),内核缓存在包捕获时开始被分配,在结束时被释放。当Hold buffer存满时,Store buffer中的数据被送到用户级缓存,Store buffer中的数据包被送到Hold buffer,如此循环不止。
WinPcap的过滤机制。由于网络中传输的数据有很多是用户不关心的,称为垃圾数据,大量的垃圾数据会影响系统的工作效率,所以在数据获取的过程中,必须对到达网卡的数据进行过滤,丢弃垃圾数据,提高工作效率。用户可以根据本地主机和网络状况设置特定的源(或目的)IP地址、端口号、主机名等等,NPF根据用户设置的过滤条件对数据进行过滤,只把用户需要的数据传送到内核缓存,从而提高了系统的工作效率。WinPcap中的过滤是在NPF中的过滤机实现的,它使用tcpdump表达式来指定过滤规则。
Packet.dll和WinPcap.dll。动态连接库Packet.dll运行在用户层,把应用程序和NPF功能独立开,使应用程序可以不加修改地在不同的Windows系统上运行。通过Packet.dll提供的API(Application Programming Interface)能够直接访问NPF的包驱动API。动态链接库Wpcap.dll和应用程序编译在一起,它使用由Packet.dll提供的服务,向应用程序提供完善的接口函数(在UNIX系统中通过Libpcap.dll提供的相同接口,而Wpcap.dll实际上是Libpcap.dll的一个超集,Wpcap.dll提供的一些编程接口是Windows平台特有的函数)。
4 基于WinPcap的网络数据获取流程
利用WinPcap实现网络数据获取既可以通过调用Packet.dll中的API实现,也可以通过调用Wpcap.dll中的API实现。此处考虑到与操作系统的无关性,介绍基于Windows的Wpcap.dll的网络数据获取。过程可分为四步:获取NIC的有关信息、建立网络侦听、设置过滤条件、进行循环捕获,基本流程如图3所示。
图3 数据捕获的流程图
Wpcap.dll中定义了多个函数和数据类型,在C程序中使用Wpcap.dll时必须在程序的预处理部分包含“Pcap.h”头文件,在C ++中必须包含“Pcap c ++.h”头文件[5]。
获取NIC的有关信息。有两种获取NIC信息的方法:一种是由用户自己指定;一种是调用Pcap接口函数自动搜索本地主机可用的网络接口,常使用第二种方法。获取NIC相关信息的函数为Pcap_lookupdev和pcap_lookupnet。Pcap_lookupdev用来寻找本地主机可用的网络接口,返回类型为字符型指针,用来表示本地接口网络接口。pcap_lookupnet用来获取本地主机的IP地址和子网掩码,并用32位整数表示。pcap_lookupnet的返回值为int型,当函数调用失败则返回-1。
启动网络侦听。启用上一步骤中获得的网络接口,所使用的函数为Pcap_open_live,它负责按照用户指定的参数和系统默认的初始化WinPcap。Pcap_open_live的返回值类型为Pcap_t型指针,作为侦听句柄。Pcap_t是Wpcap.dll定义的数据类型。
设置过滤条件。设置过滤条件有两个步骤:一是将用户输入的字符型的过滤条件转换成系统认可的bpf_program型,bpf_program是WinPcap定义的数据结构;另一步骤是将转换后的过滤条件传递给侦听句柄。
进行循环捕获。前面所有的步骤都是对NPF的初始化,完成初始化之后,最后一个步骤就是进行数据的循环捕获。Pcap库提供了两个函数实现这个功能:Pcap_dispath和Pcap_loop,它们实现的功能基本相同,调用成功时返回读取到的字节数,否则返回0。它们的区别在于Pcap_loop在读取超时(在Pcap_open_live中设置)的时候不会返回,而Pcap_dispath遇到读取超时就返回0。用户对数据包的所有操作都是在回调函数中完成的,回调函数被定义成一个全局的函数,对每一个循环中读取的数据包按用户的定义进行操作。
5 结论
WinPcap系统是一个功能强大的用于网络数据获取开发包,它直接和网卡打交道,获取数据链层的数据,能捕获数据链路层的所有数据包。WinPcap的分层思想为Windows平台提供了一个完整的、简单的、系统无关的编程接口,为在Windows平台下开发高性能的网络数据获取软件提供了方便。WinPcap的两级缓存的设计,极大地提高了数据包的捕获率,使丢包率降到了很低的程度,尤其是它内核级缓存的动态循环存储的思想,是它在数据捕获的速度方面优于UNIX中的Libpcap。总之,基于WinPcap的网络数据获取系统实验方案具有结构简单、捕获数据快、协议识别率高等特点,它的三个模块的相互套用,实现了网络数据获取的基本功能。
参考文献:
[1]王威伟,郑雪峰.局域网中网络监听与防范技术[J].计算机工程与设计,2005,26(11):3056-3058.
[2]吴玉,娄智.基于操作系统内核的包过滤防火墙系统[J].湖南工程学院学报,2006,16(2):39-41.
[3]胡晓元,史涪山.WinPcap包截获系统的分析及其应用[J].计算机工程,2005,31(2):96-98.
[4]赵新辉,李祥.捕获网络数据包的方法[J].计算机应用研究,2004,8:242-243,255.
[5]DAVID J.KRUGLINSHKI.著.潘爱民.译.Visual C++技术内幕[M].北京:希望电子出版社,2002.
本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文。