当前位置: 首页 > news >正文

做网站商城网站添加备案

做网站商城,网站添加备案,济南有哪些网站是做家具团购的,网站运营招聘转载请标明是引用于 http://blog.csdn.net/chenyujing1234 欢迎大家拍砖! 一、编译过程 弄了半天终于编译通过了#xff0c;看来驱动的开发确实没有应用来得简单啊。 由于DDK提供的ndis.h有4个#xff0c;什么时候要调用哪个我确实不清楚#xff1a; #xff08;1…转载请标明是引用于 http://blog.csdn.net/chenyujing1234  欢迎大家拍砖! 一、编译过程 弄了半天终于编译通过了看来驱动的开发确实没有应用来得简单啊。 由于DDK提供的ndis.h有4个什么时候要调用哪个我确实不清楚 1我先用#include d:\winddk\7600.16385.1\inc\ddk\ndis.h 结果报错了 [plain] view plain copy 11errors in directory e:\g2\fft\usbdri~1\ndismo~1\ndismo~4\driver3  11e:\g2\fft\usbdriver\ndismonitor\ndismonitor_v1-00_kernel_vs\driver3\ndishook.c(380) : error C2037: left of ProtocolNextOpen specifies undefined struct/union _NDIS_OPEN_BLOCK  11e:\g2\fft\usbdriver\ndismonitor\ndismonitor_v1-00_kernel_vs\driver3\ndishook.c(393) : error C2037: left of AdapterHandle specifies undefined struct/union _NDIS_OPEN_BLOCK  11e:\g2\fft\usbdriver\ndismonitor\ndismonitor_v1-00_kernel_vs\driver3\ndishook.c(734) : error C2037: left of ReceiveHandler specifies undefined struct/union _NDIS_OPEN_BLOCK   定位代码是在 [cpp] view plain copy NDIS_OPEN_BLOCK* GetNextOpen( IN NDIS_OPEN_BLOCK* pnobOpenBlock )  {      // Return the information required.        return pnobOpenBlock-ProtocolNextOpen;  }   我想是因为找不到结构体NDIS_OPEN_BLOCK的定义的原因。关于此结构体请参考文章NDIS的NDIS_PROTOCOL_BLOCK和NDIS_OPEN_BLOCK的介绍。 于是在DDK包中执行ProtocolNextOpen这个变量总共出现在三个地方 怪不得会编译出错原来在 d:\winddk\7600.16385.1\inc\ddk\ndis.h中根据就没有此成员变量。 看一看以上三个含有ProtocolNextOpen的地方的定义吧 1、1D:\WINDDK\3790.1830\inc\ddk\w2k\ndis.h 1、2 D:\WINDDK\3790.1830\inc\ddk\wnet\ndis.h 1、3D:\WINDDK\3790.1830\inc\ddk\wxp\ndis.h 综上看来我们有两种可选 D:\WINDDK\3790.1830\inc\ddk\w2k\ndis.h D:\WINDDK\3790.1830\inc\ddk\wxp\ndis.h 2试看看D:\WINDDK\3790.1830\inc\ddk\wxp\ndis.h吧 报以下错误 [plain] view plain copy 11d:\winddk\3790.1830\inc\ddk\wxp\ndis.h(7156) : error C2011: _MAP_REGISTER_ENTRY : struct type redefinition  11d:\winddk\3790.1830\inc\ddk\wxp\ndis.h(10163) : error C2061: syntax error : identifier W_SEND_HANDLER  11d:\winddk\3790.1830\inc\ddk\wxp\ndis.h(10164) : error C2061: syntax error : identifier WTransferDataHandler  11d:\winddk\3790.1830\inc\ddk\wxp\ndis.h(10164) : error C2059: syntax error : ;  11d:\winddk\3790.1830\inc\ddk\wxp\ndis.h(10169) : error C2061: syntax error : identifier WSendPacketsHandler  11d:\winddk\3790.1830\inc\ddk\wxp\ndis.h(10169) : error C2059: syntax error : ;  11d:\winddk\3790.1830\inc\ddk\wxp\ndis.h(10171) : error C2061: syntax error : identifier CancelSendPacketsHandler  11d:\winddk\3790.1830\inc\ddk\wxp\ndis.h(10171) : error C2059: syntax error : ;  11d:\winddk\3790.1830\inc\ddk\wxp\ndis.h(10182) : error C2061: syntax error : identifier QC   这么多错误我想放弃引方案。 3试看看D:\WINDDK\3790.1830\inc\ddk\w2k\ndis.h 只有两个报错 [plain] view plain copy 11d:\winddk\3790.1830\inc\ddk\w2k\ndis.h(5567) : error C2011: _MAP_REGISTER_ENTRY : struct type redefinition  11d:\winddk\3790.1830\inc\ddk\w2k\ndis.h(5567) : error C2011: _MAP_REGISTER_ENTRY : struct type redefinition  11d:\winddk\3790.1830\inc\ddk\w2k\ndis.h(5567) : error C2011: _MAP_REGISTER_ENTRY : struct type redefinition  11d:\winddk\3790.1830\inc\ddk\w2k\ndis.h(5567) : error C2011: _MAP_REGISTER_ENTRY : struct type redefinition  11d:\winddk\3790.1830\inc\ddk\w2k\ndis.h(5567) : error C2011: _MAP_REGISTER_ENTRY : struct type redefinition  11d:\winddk\3790.1830\inc\ddk\w2k\ndis.h(5567) : error C2011: _MAP_REGISTER_ENTRY : struct type redefinition  11d:\winddk\3790.1830\inc\ddk\w2k\ndis.h(5567) : error C2011: _MAP_REGISTER_ENTRY : struct type redefinition  11d:\winddk\3790.1830\inc\ddk\w2k\ndis.h(5567) : error C2011: _MAP_REGISTER_ENTRY : struct type redefinition   3、1既然是重定义那么我把它的定义屏蔽掉吧 3、2再试看看这个错误消除了现在还剩下一个错 [plain] view plain copy 11d:\winddk\3790.1830\inc\ddk\w2k\ndis.h(9297) : error C1083: Cannot open include file: afilter.h: No such file or directory  1Compiling - ndishook.c  11d:\winddk\3790.1830\inc\ddk\w2k\ndis.h(9297) : error C1083: Cannot open include file: afilter.h: No such file or directory  1Compiling - vpcknt.c  11d:\winddk\3790.1830\inc\ddk\w2k\ndis.h(9297) : error C1083: Cannot open include file: afilter.h: No such file or directory  1Compiling - ndishook.c  11d:\winddk\3790.1830\inc\ddk\w2k\ndis.h(9297) : error C1083: Cannot open include file: afilter.h: No such file or directory   这个好解决给它指定绝对路径嘛 改进经网友xkjcf要求把绝对路径去掉 3、2、1在sources文件中添加INCLUDES路径 路径总线 A、我测试发现“工具-选项-项目解决方案-C目录-包含里设置的INCLUDE路径”与sources路径下的INCLUDE路径有优先级 其中sources中的路径有更高的优先级。 B、在sources文件中若是有多个路径且都含有同一个.h文件那么此时包哪一个是没有顺序关系的。 eg 在此sources下有 两个路径下都有usbdlib.h 文件可是我在引用它时 却引用到了后者的路径以致报错 3、2、2 再试看看哈哈^-^ 另人兴奋的.sys文件产生了。 二、源码分析 1、DriverEntry 与我数的Windows驱动的入口开发一样这里的DriverEntry没有什么特别的地方 1、1 创建设备和设备SymbolicLink名字。 [cpp] view plain copy ntStatus  IoCreateDevice( DriverObject,          sizeof( DEVICE_EXTENSION ),           uszDriverString,          FILE_DEVICE_UNKNOWN,          0,          FALSE,           pDeviceObject );   [cpp] view plain copy // Point uszDeviceString at the device name.        RtlInitUnicodeString(  uszDeviceString, L\\DosDevices\\ SYSDRIVER_NAME_WIDE );        // Create symbolic link to the user-visible name.        ntStatus  IoCreateSymbolicLink(  uszDeviceString,  uszDriverString );   创建SymbolicLink时名字为\\DosDevices\\VPCKnt。 这里说明驱动中的SymbolicLink命名的一个特点DosDevices的符号链接名就是??, 所以\\DosDevices\\XXXX其实就是\\??\\XXXX [cpp] view plain copy TEXT(a\\\\.\VPCKnt/a),    1、2   分配派遣函数 [cpp] view plain copy DriverObject-DriverUnload                            VPCKernelNtDriverUnload;  DriverObject-MajorFunction[ IRP_MJ_CREATE ]          VPCKernelNtDispatchCreate;  DriverObject-MajorFunction[ IRP_MJ_CLOSE ]           VPCKernelNtDispatchClose;  DriverObject-MajorFunction[ IRP_MJ_DEVICE_CONTROL ]  VPCKernelNtDispatchIoctl;   以上函数是包含完成NDIS抓包的所有逻辑我们重点分析。 1、3   PDEVICE_EXTENSION扩展附加及初始化 PDEVICE_EXTENSION为我们息定义的结构体把它附加到设备象中这样以后在派遣函数中我们就可以从扩展数据中获得我们自定义的数据 [cpp] view plain copy typedef struct _DEVICE_EXTENSION   {       // Boolean表明是否用户态的service/application已经创建文件对象      ULONG           WasCreated;      FAST_MUTEX      WasCreatedFastMutex;        // InterceptNDIS表明是否我们不得不去中断NDIS活动      ULONG           InterceptNDIS;        // 关于NDIS Hook的状态信息      PNT_PROTOCOL_LIST           NdisProtocolList;      PNDISHOOK_HANDLER_STUB      NdisStubsList;      DWORD                       NdisStubsNum;        // 客户端想要表现的Open Adapter的列表      OALIST_ITEM*                OaList;      DWORD                       OaListItems;      NDIS_SPIN_LOCK              OaListSpinLock;        // 等待被接收的包列表      NEXT_PACKET*                PacketsBuff;      DWORD                       PacketsBuffMaxItems;      DWORD                       PacketsBuffStart /* first allocated; -1  empty */, PacketsBuffEnd /* first free */;      DWORD                       PacketsLost;      PKEVENT                     PacketsReadyEvent;      NDIS_SPIN_LOCK              PacketsBuffSpinLock;        // Loopback trick stuff.      DWORD       dwLtLoopbackAdapterIpAddress;   // tipically: 0xA9FE1981; zero if lt is disabled.      DWORD       dwLtTrickNatIpAddress;          // tipically: 0xA9FE1980; zero if lt is disabled.        // Other.      NDIS_SPIN_LOCK              ReceiveWorkItemSpinLock;      DWORD                       ReceiveWorkItemIdCounter;        NDIS_SPIN_LOCK              PacketSerialCounterSpinLock;      DWORD                       PacketSerialCounter;    } DEVICE_EXTENSION, *PDEVICE_EXTENSION;   [cpp] view plain copy extension  pDeviceObject-DeviceExtension;   初始化同步操作互斥体及其他逻辑变量 [cpp] view plain copy // Initialize WasCreated and its mutex.      extension-WasCreated  0;      ExInitializeFastMutex(  extension-WasCreatedFastMutex );        // Initialize InterceptNDIS.      extension-InterceptNDIS  0;        // 初始化NDIS状态变量      extension-NdisProtocolList  NULL;      extension-NdisStubsList  NULL;      extension-NdisStubsNum  0;        // 初始化OaList事件      extension-OaList  NULL;      extension-OaListItems  0;      NdisAllocateSpinLock(  extension-OaListSpinLock );        // 初始化包Buffer      extension-PacketsBuff  NULL;      extension-PacketsBuffMaxItems  0;      extension-PacketsBuffStart  -1;      extension-PacketsBuffEnd  0;      extension-PacketsLost  0;      extension-PacketsReadyEvent  NULL;        NdisAllocateSpinLock(  extension-PacketsBuffSpinLock );        // 初始化其他res....      NdisAllocateSpinLock(  extension-ReceiveWorkItemSpinLock );      extension-ReceiveWorkItemIdCounter  0;        NdisAllocateSpinLock(  extension-PacketSerialCounterSpinLock );      extension-PacketSerialCounter  0;        // Initialize the lt stuff.      extension-dwLtLoopbackAdapterIpAddress  0;      extension-dwLtTrickNatIpAddress  0;   2、IRP_MJ_CREATE派遣函数VPCKernelNtDispatchCreate 此函数相对简单只是根据DeviceExtension中自定义的数据来做“仅允许一个文件对象的创建”的处理而已。 3、 IRP_MJ_CLOSE派遣函数VPCKernelNtDispatchClose 标识客户端关闭了后去做清理工作 1擦除已经分配的打开的adapters [cpp] view plain copy ReleaseOaList ();   2停止中断 [cpp] view plain copy extension-InterceptNDIS  0;   3Unhook NDIS Handler functions Unhook NDIS其实就是重新装载原始的句柄指针在Unhook NDIS 的前后都调用KeDelayExecutionThread让CPU停下来半秒。 关于KeDelayExecutionThread请参考我的文章 DDK下的Sleep函数KeDelayExecutionThread [cpp] view plain copy KeDelayExecutionThread( UserMode, FALSE,  liWaitElapse );            // Unhook NDIS Handler functions.          if ( extension-NdisProtocolList )              UnhookInstalledProtocols(                  (PNT_PROTOCOL) ( (BYTE*) extension-NdisProtocolList  sizeof( NT_PROTOCOL_LIST ) ),                  extension-NdisProtocolList-dwProtocolsNum,                  (PNT_OPEN_ADAPTER) ( (BYTE*) extension-NdisProtocolList  sizeof( NT_PROTOCOL_LIST )  extension-NdisProtocolList-dwProtocolsNum * sizeof( NT_PROTOCOL ) ),                  extension-NdisProtocolList-dwOpenAdaptersNum );            KeDelayExecutionThread( UserMode, FALSE,  liWaitElapse );   以上UnhookIntalledProtocols函数的参数大家看得有点晕了其实这是作者对extension-NdisProtocoList的一个数据结构定义罢了 [cpp] view plain copy typedef struct _NT_PROTOCOL_LIST  {      // ...Info...      DWORD               dwProtocolsNum;      DWORD               dwOpenAdaptersNum;        // ...Data...      //      // x List of NT_PROTOCOL(s) follows.      // x List of NT_OPEN_ADAPTER(s) follows.      //  } NT_PROTOCOL_LIST, *PNT_PROTOCOL_LIST;   它的最前面是存着协议和Adapter数据的个数信息后面分别是存着协议数组和Adapter数据。 [cpp] view plain copy NTSTATUS UnhookInstalledProtocols( PNT_PROTOCOL pntpProtocols, DWORD dwProtocolsSize, PNT_OPEN_ADAPTER pntoaAdapters, DWORD dwAdaptersSize )  {      DWORD               i;      PNT_OPEN_ADAPTER    pntoaThisAdapter;        // 重载原始的句柄指针.      for ( i0; idwAdaptersSize; i )      {          pntoaThisAdapter   pntoaAdapters[ i ];            // Restore the Original Pointers.          if ( pntoaThisAdapter-Original_SendHandler )              RestoreHandlerPointerSecure(  pntoaThisAdapter-pobBlockPtr-SendHandler, pntoaThisAdapter-Original_SendHandler, pntoaThisAdapter-Stub_SendHandler );          if ( pntoaThisAdapter-Original_ReceiveHandler )              RestoreHandlerPointerSecure(  pntoaThisAdapter-pobBlockPtr-ReceiveHandler, pntoaThisAdapter-Original_ReceiveHandler, pntoaThisAdapter-Stub_ReceiveHandler );          if ( pntoaThisAdapter-Original_PostNt31ReceiveHandler )              RestoreHandlerPointerSecure(  pntoaThisAdapter-pobBlockPtr-PostNt31ReceiveHandler, pntoaThisAdapter-Original_PostNt31ReceiveHandler, pntoaThisAdapter-Stub_PostNt31ReceiveHandler );          if ( pntoaThisAdapter-Original_SendPacketsHandler )              RestoreHandlerPointerSecure(  pntoaThisAdapter-pobBlockPtr-SendPacketsHandler, pntoaThisAdapter-Original_SendPacketsHandler, pntoaThisAdapter-Stub_SendPacketsHandler );          if ( pntoaThisAdapter-Original_TransferDataHandler )              RestoreHandlerPointerSecure(  pntoaThisAdapter-pobBlockPtr-TransferDataHandler, pntoaThisAdapter-Original_TransferDataHandler, pntoaThisAdapter-Stub_TransferDataHandler );          if ( pntoaThisAdapter-Original_ReceivePacketHandler )              RestoreHandlerPointerSecure(  pntoaThisAdapter-pobBlockPtr-ReceivePacketHandler, pntoaThisAdapter-Original_ReceivePacketHandler, pntoaThisAdapter-Stub_ReceivePacketHandler );          if ( pntoaThisAdapter-Original_TDCompleteHandler  pntoaThisAdapter-pmbMiniportPtr )              RestoreHandlerPointerSecure(  pntoaThisAdapter-pmbMiniportPtr-TDCompleteHandler, pntoaThisAdapter-Original_TDCompleteHandler, pntoaThisAdapter-Stub_TDCompleteHandler );      }        // Return to the caller.      return STATUS_SUCCESS;  }   4释放内存 4、1释放协议数组中每个成员中的pbWorkItemHeader [cpp] view plain copy static VOID ReleaseReceiveWorkItems ()  {      PDEVICE_EXTENSION   extension  g_pDeviceObject-DeviceExtension;      int                 i, c;      NT_PROTOCOL*        pBase  NULL;      NT_PROTOCOL*        pThis  NULL;        if ( extension-NdisProtocolList  NULL ||          extension-NdisProtocolList-dwProtocolsNum  0 )      {          return;      }        pBase  (NT_PROTOCOL*) ( (BYTE*) extension-NdisProtocolList  sizeof( NT_PROTOCOL_LIST ) );      NdisAcquireSpinLock(  extension-ReceiveWorkItemSpinLock );          c  extension-NdisProtocolList-dwProtocolsNum;          for ( i0; ic; i  )          {              pThis   pBase[ i ];                if ( pThis-pbWorkItemHeader )              {                  // free...                  ExFreePool( pThis-pbWorkItemHeader );                  pThis-pbWorkItemHeader  NULL;                  pThis-uiWorkItemHeaderSize  0;              }          }      NdisReleaseSpinLock(  extension-ReceiveWorkItemSpinLock );  }   4、2释放包Buffer [cpp] view plain copy static VOID ReleasePackets ()   5、IRP_MJ_DEVICE_CONTROL派遣函数VPCKernelNtDispatchIoctl 此函数主要主是一个switch ..... case 语句case了应用程序对函数的的四种IOCTROL码。 5、1IOCTL_VPCKNT_GET_VERSION 因为Irp-AssociatedIrp.SystemBuffer指向的Buffer就是应用层得到的Out Buffer所以把版本号写到这块内存就对了。 5、2IOCTL_VPCKNT_INITIALIZE_HOOK 5、2、1分配包Buffer 分配的包的最大个数由上层决定默认是32。 [cpp] view plain copy extension-PacketsBuff  (NEXT_PACKET*) ExAllocatePool( NonPagedPool,                          ihiHookInput.dwPacketsBuffMaxItems * sizeof( NEXT_PACKET ) );    if ( extension-PacketsBuff )  {      extension-PacketsBuffMaxItems  ihiHookInput.dwPacketsBuffMaxItems;      memset( extension-PacketsBuff, 0, ihiHookInput.dwPacketsBuffMaxItems * sizeof( NEXT_PACKET ) );  }   5、2、2获得包准备好事件 调用ObReferenceObjectByHandle由应用层的hNotificationEvent得到对应的PKEVENT。原理参考Window XP驱动开发(二十二) 驱动程序的同步处理 [cpp] view plain copy if ( ihiHookInput.hNotificationEvent )                  {                      NTSTATUS        ntEvRes  ObReferenceObjectByHandle( ihiHookInput.hNotificationEvent,                          0, (POBJECT_TYPE) NULL, UserMode, (PVOID)  extension-PacketsReadyEvent, (POBJECT_HANDLE_INFORMATION) NULL);                        if ( ntEvRes ! STATUS_SUCCESS )                          extension-PacketsReadyEvent  NULL;                  }   5、2、3注册协议并安装协议 关于这部分的内容特别重要我们将在“6、核心源码”中分析。 [cpp] view plain copy __try                      {                          nsRegRes  RegisterFakeProtocol(  hFakeProtocolHandle, SYSDRIVER_NAME_ANSI );                            if ( nsRegRes  STATUS_SUCCESS )                          {                              nsHookRes  HookInstalledProtocols(                                   pplProtocolList,  pnhhsStubsList,  dwStubsNum,                                  hFakeProtocolHandle );                          }                      }                      __except ( EXCEPTION_EXECUTE_HANDLER )                      {                      }   安装后得到Ndis Hook的结果即下图的数据结构 5、2、4把Ndis Hook的结果返回到应用程序的Out Buffer中 [cpp] view plain copy pbOutputBufferPayload  (BYTE*) Irp-AssociatedIrp.SystemBuffer  sizeof( ihoHookOutput );                      // Inform about the Ndis Hook results.                      if ( nsHookRes  STATUS_SUCCESS ) // NDIS Hook Ok.                      {                          // Info.                          ihoHookOutput.bNdisHookSucceeded  1;                          ihoHookOutput.dwProtocolListBufferSize  sizeof( NT_PROTOCOL_LIST )                               pplProtocolList-dwProtocolsNum * sizeof( NT_PROTOCOL )                               pplProtocolList-dwOpenAdaptersNum * sizeof( NT_OPEN_ADAPTER );                            // Data.                            memcpy( pbOutputBufferPayload, pplProtocolList, ihoHookOutput.dwProtocolListBufferSize );                          pbOutputBufferPayload  ihoHookOutput.dwProtocolListBufferSize;                      }                      else // NDIS Hook Failed.                      {                          // Info.                            ihoHookOutput.bNdisHookSucceeded  0;                          ihoHookOutput.dwProtocolListBufferSize  0;                      }                        // Copy the Header structure.                      * (INITIALIZE_HOOK_OUTPUT*) Irp-AssociatedIrp.SystemBuffer  ihoHookOutput;   5、3IOCTL_VPCKNT_SUBMIT_OALIST 5、4IOCTL_VPCKNT_GET_NEXT_PACKET 6、核心源码分析 6、1 注册协议 注册的PROTOCOL_CHARACTERISTICS为NDIS 4.0版本的。 [cpp] view plain copy NDIS40_PROTOCOL_CHARACTERISTICS     ndis40pcFakeProtCharacts;   在初始化ndis40pcFakeProtCharacts结构体时给它预留了15个自定义的函数根据实现需要可完成这15个函数的定义。 [cpp] view plain copy ndis40pcFakeProtCharacts.OpenAdapterCompleteHandler   FakeProtocol_OpenAdapterComplete;      ndis40pcFakeProtCharacts.CloseAdapterCompleteHandler   FakeProtocol_CloseAdapterComplete;      ndis40pcFakeProtCharacts.SendCompleteHandler   FakeProtocol_SendComplete;      ndis40pcFakeProtCharacts.TransferDataCompleteHandler   FakeProtocol_TransferDataComplete;      ndis40pcFakeProtCharacts.ResetCompleteHandler   FakeProtocol_ResetComplete;      ndis40pcFakeProtCharacts.RequestCompleteHandler   FakeProtocol_RequestComplete;      ndis40pcFakeProtCharacts.ReceiveHandler   FakeProtocol_Receive;      ndis40pcFakeProtCharacts.ReceiveCompleteHandler   FakeProtocol_ReceiveComplete;      ndis40pcFakeProtCharacts.StatusHandler   FakeProtocol_Status;      ndis40pcFakeProtCharacts.StatusCompleteHandler   FakeProtocol_StatusComplete;        NdisInitializeString(  ndis40pcFakeProtCharacts.Name, pszProtocolName );        ndis40pcFakeProtCharacts.ReceivePacketHandler   FakeProtocol_ReceivePacket;      ndis40pcFakeProtCharacts.BindAdapterHandler   FakeProtocol_BindAdapter;      ndis40pcFakeProtCharacts.UnbindAdapterHandler   FakeProtocol_UnbindAdapter;      ndis40pcFakeProtCharacts.PnPEventHandler   FakeProtocol_PnpEvent;      ndis40pcFakeProtCharacts.UnloadHandler   FakeProtocol_UnloadProtocol;   然后调用NdisRegisterProtocol注册。 6、2安装协议 6、2、1分配要求的内存 包括PNT_PROTOCOL1M作为协议数组、PNT_OPEN_ADAPTER1M作为协议Adpater 的数组、PNDISHOOK_HANDLER_STUB128K用于Hook句柄的存根 6、2、2循环访问列表协议获得已安装的列表协议句柄 循环获得协议的方法是调用GetNextProtocol函数此函数根据NDIS50_PROTOCOL_BLOCK结构体中的NextProtocol 来访问下一个协议能这样做的原因是因为协议之间是一条单链表。 这里把NDIS_HANDLE 强转为NDIS50_PROTOCOL_BLOCK类型再次说明了两者其实是同一结构的。 [cpp] view plain copy NDIS_HANDLE GetNextProtocol( IN NDIS_HANDLE hProtocolHandle )  {      DWORD                       dwNdisVersion;      NDIS50_PROTOCOL_BLOCK*      pn50pbProtBlockPtr;        // Return the Next Protocol in the Linked List.      dwNdisVersion  GetNdisVersion ();        if ( dwNdisVersion  0xFFFFFFFF )          return NULL;        switch( dwNdisVersion )      {      case 0x00050000:      case 0x00050001:            // Windows 2000 / Windows XP NDIS Version.            pn50pbProtBlockPtr  (NDIS50_PROTOCOL_BLOCK*) hProtocolHandle;            return (NDIS_HANDLE) pn50pbProtBlockPtr-NextProtocol;        default:            // Unrecognized NDIS Version. Exit.            return NULL;      }  }   6、2、3根据列表协议句柄获得对应的Characteristics数据结构。 [cpp] view plain copy NDIS50_PROTOCOL_CHARACTERISTICS* GetProtocolCharacteristics( IN NDIS_HANDLE hProtocolHandle )  {      DWORD                       dwNdisVersion;      NDIS50_PROTOCOL_BLOCK*      pn50pbProtBlockPtr;        // Return the Protocol Characteristics information for this protocol.      dwNdisVersion  GetNdisVersion ();      if ( dwNdisVersion  0xFFFFFFFF )          return NULL;        switch( dwNdisVersion )      {      case 0x00050000:      case 0x00050001:          // Windows 2000 / Windows XP NDIS Version.          pn50pbProtBlockPtr  (NDIS50_PROTOCOL_BLOCK*) hProtocolHandle;          return  pn50pbProtBlockPtr-ProtocolCharacteristics;      default:          // Unrecognized NDIS Version. Exit.            return NULL;      }  }   从以上两步的结果中提取信息进行编号保存在协议数组中。 6、2、4从协议句柄中获得协议中打开的Adapter。 从结果中提取信息进行编号保存在协议Adapter数组中。 综合6、2、36、2、4我们得到了协议、Characteristics及协议Adapter的关系图。 6、2、5Hook处理各种Handle 6、2、5、1Hook 发送句柄 首先判断原有的SendHandler是否可以Hook 其实原理很简单因为Hook的句柄我们会存在一个区域内通过判断是否在这个区域内能判断是不是Hook过。 [cpp] view plain copy static BOOLEAN CanHook( IN PVOID fnptr )  {      if ( fnptr  NULL || g_pbCanHookRefMemStart  NULL || g_pbCanHookRefMemEnd  NULL ) // # pointer problem...          return FALSE;      else if ( ((BYTE*)fnptr)  g_pbCanHookRefMemStart  ((BYTE*)fnptr)  g_pbCanHookRefMemEnd ) // # already hooked...          return FALSE;      else // # ok, can hook...          return TRUE;  }   然后填充存根代码 bPushImm32Opcode、dwOperationID、bJmpRel32Opcode分别填充固定的码值这没什么可讲 但dwJmpDisplacement值的得到有点费解若有知道的网友可否告诉我一下 [cpp] view plain copy static void FillStubCode( PNDISHOOK_HANDLER_STUB pnhhsThisStub, DWORD dwThisAdapterOrd, DWORD dwAddInfo )  {      // Fill the Stub structure.        pnhhsThisStub-bPushImm32Opcode  0x68;      pnhhsThisStub-dwOperationID  ( dwThisAdapterOrd  0x10 ) | dwAddInfo;      pnhhsThisStub-bJmpRel32Opcode  0xE9;      pnhhsThisStub-dwJmpDisplacement           (DWORD)  HandlerGeneralDispatcher -          ( (DWORD) pnhhsThisStub  FIELD_OFFSET( NDISHOOK_HANDLER_STUB, bJmpRel32Opcode ) ) -          5;  }   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!重点中的重点改日讲解 [cpp] view plain copy static PVOID                g_vpvHandlersVector[]                                   {                                       New_SendHandler,              // SENDHANDLER_FNID                                       New_ReceiveHandler,           // RECEIVEHANDLER_FNID                                       New_PostNt31ReceiveHandler,   // POSTNT31RECEIVEHANDLER_FNID                                       New_SendPacketsHandler,       // SENDPACKETSHANDLER_FNID                                       New_TransferDataHandler,      // TRANSFERDATAHANDLER_FNID                                       New_ReceivePacketHandler,     // RECEIVEPACKETHANDLER_FNID                                       New_TDCompleteHandler         // TDCOMPLETEHANDLER_FNID                                  };   [cpp] view plain copy static void __declspec(naked) HandlerGeneralDispatcher ( void )  {      __asm      {          // ### Load in EAX and ECX the Code found in the Stack. ###            mov     eax, dword ptr[ esp ]   // eax  Code: 0xYYYYZZZZ. (y  Adapter Ordinal, z  Handler Ordinal.)          mov     ecx, eax                // ecx  Code: 0xYYYYZZZZ.            shr     eax, 0x10               // eax  0x0000YYYY          and     ecx, 0xFFFF             // ecx  0x0000ZZZZ            mov     dword ptr[ esp ], eax   // Updates Code in Stack: 0x0000YYYY            // ### Call the appropriate Handler based on the Handler Ordinal. ###            lea     eax, [ offset g_vpvHandlersVector  ecx * 4 ];          call    dword ptr[ eax ]            // ### Pop in ECX the HookPrivateStorage parameter. ###            pop     ecx            // ### Check whether we have to call the Original Handler or we have to return control to the Caller. ###            cmp     ecx, 0x1000          ja      callOriginalHandler            // ### Return the Control to the Caller. ###            pop     edx          add     esp, ecx          jmp     edx    callOriginalHandler:            // ### Call the Original Handler. ###            jmp     ecx      }  }   最后将记录原有的发送句柄后目的是在UnhookInstalledProtocols时能重载原始句柄指指将自己的发送Handle附加到原有的发送句柄上。 [cpp] view plain copy pntoaThisAdapter-Original_SendHandler  pobAdapter-SendHandler;                              pntoaThisAdapter-Stub_SendHandler  pnhhsThisStub;                              pobAdapter-SendHandler  (SEND_HANDLER) pnhhsThisStub;   这样pobAdapter-SendHandler  就会调用我们自定义的New_SendHandler函数了。关于它的处理我们在“7、   自定义处理函数讲解”中进行讲解。 6、2、5、2Hook 接收句柄 与Hook 发送句柄类似。 6、2、5、3Hook postnt31接收句柄 与Hook 发送句柄类似。 6、2、5、4Hook 发送包句柄 与Hook 发送句柄类似。 6、2、5、5Hook 传送数据句柄 与Hook 发送句柄类似。 6、2、5、6Hook 接收包句柄 与Hook 发送句柄类似。 6、2、5、6Hook 传送数据完成句柄 与Hook 发送句柄类似。 7、自定义处理函数的讲解 7、1New_SendHandler 以入参HookPrivateStorage来标识哪一协议哪一Adapter 如果判断如果需要中断NDIS请求那么就调用Intercept_SendHandler将此数据包进行截获 截获完成后根据返回结果判断是否要将原始的处句柄返回回去默认是需要将原始句柄返回这样我们截获了包后此包能再次发送出去。 [cpp] view plain copy NDIS_STATUS __cdecl New_SendHandler( IN OUT DWORD HookPrivateStorage, IN OUT DWORD CallingFnRetAddress, IN OUT NDIS_HANDLE MacBindingHandle, IN OUT PNDIS_PACKET Packet )  {      NDIS_STATUS             nsRetStatus  NDIS_STATUS_SUCCESS;      SEND_HANDLER            pfnOriginal  NULL;      DWORD                   OpenAdapterId  HookPrivateStorage;      PDEVICE_EXTENSION       pdeExtension  g_pDeviceObject-DeviceExtension;      BOOLEAN                 bExecuteOriginalHandler  TRUE;        // Get a pointer to the Original Handler.      pfnOriginal  g_pntoaAdapters[ OpenAdapterId ].Original_SendHandler;        // Check if we have to intercept the NDIS Request.      if ( pdeExtension-InterceptNDIS )          bExecuteOriginalHandler  Intercept_SendHandler(               g_pntpProtocols[ g_pntoaAdapters[ OpenAdapterId ].dwProtocolOrd ],  g_pntoaAdapters[ OpenAdapterId ],               nsRetStatus,  MacBindingHandle,  Packet );        // Make call the Original Handler and return.        if ( bExecuteOriginalHandler )          HookPrivateStorage  (DWORD) pfnOriginal; // Original Handler.      else          HookPrivateStorage  2 * 0x4; // Passed Parameters Size.        return nsRetStatus;  }   7、1、1在Intercept_SendHandler里先判断此Adapter是不是要被处理 [cpp] view plain copy // process.      if ( HaveToProcess( pnoaAdapter ) )      {   判断原理是判断它是不是在OaList列表中。 7、1、2如果判断此Adapter是需要处理的那么就调用NdisPacket2MemoryRegion为此包分配分内存。 首先调用系统API NdisQueryPacket查询此PNDIS_PACKET包的PNDIS_BUFFER和总共的内存大小。 [cpp] view plain copy NdisQueryPacket( Packet,          NULL, NULL,           pnbCurrent,           uiTotalSize );   然后根据PNDIS_PACKET包的内存大小及我们要添加的头的大小算出自定义包所需要的内存大小 [cpp] view plain copy ulMemSize  ulHeaderBufferSize  uiTotalSize;      if ( ulMemSize  0 )          return NULL;        pbMem  (BYTE*) ExAllocatePool( NonPagedPool, ulMemSize );      if ( pbMem  NULL )          return NULL;   最后把输入的包的BUFFER复制到我们自定义的内存中。 [cpp] view plain copy while( pnbCurrent )      {          NdisQueryBuffer( pnbCurrent,  pvPtr,  uiPtrDim );            if ( pvPtr  NULL || uiCount  uiPtrDim  uiTotalSize )          {              ExFreePool( pbMem );              return NULL;          }          else          {              memcpy( pbMem  uiCount, pvPtr, uiPtrDim );              uiCount  uiPtrDim;          }            NdisGetNextBuffer( pnbCurrent,  pnbCurrent );      }   7、1、3把从7、1、2中得到的自定义数据内存保存到extern的包队列中并通过事件告知应用程序可以取包了。 [cpp] view plain copy VOID QueuePacket( IN PNT_OPEN_ADAPTER pnoaAdapter, IN BYTE* pbData, IN DWORD dwDataSize, BYTE bDirection, DWORD dwSerial )  {      PDEVICE_EXTENSION       extension  g_pDeviceObject-DeviceExtension;        // add.        NdisAcquireSpinLock(  extension-PacketsBuffSpinLock );            if ( extension-PacketsBuff  extension-PacketsBuffMaxItems )          {              NEXT_PACKET*        pThis   extension-PacketsBuff[ extension-PacketsBuffEnd ];                //              // manage the circular buffer.              //                // compare end and start.                if ( extension-PacketsBuffEnd  extension-PacketsBuffStart )              {                  // ### free ###                  if ( pThis-pbData )                      ExFreePool( pThis-pbData );                    // ### inc counter ###                  extension-PacketsLost ;                    // ### inc start pos ###                  extension-PacketsBuffStart ;                  if ( extension-PacketsBuffStart  extension-PacketsBuffMaxItems )                      extension-PacketsBuffStart  0;              }                // inc end pos.                extension-PacketsBuffEnd ;              if ( extension-PacketsBuffEnd  extension-PacketsBuffMaxItems )                  extension-PacketsBuffEnd  0;                if ( extension-PacketsBuffStart  -1 )                  extension-PacketsBuffStart  0;                //              // fill this one.              //                pThis-dwOpenAdapterOrdinal  pnoaAdapter-dwOrdinal;                pThis-dwPacketSerial  dwSerial;                pThis-pbData  pbData;              pThis-dwDataLength  dwDataSize;                pThis-bDirection  bDirection;                //              // set the user event.              //                if ( extension-PacketsReadyEvent )                  KeSetEvent( extension-PacketsReadyEvent, 0, FALSE );          }        NdisReleaseSpinLock(  extension-PacketsBuffSpinLock );        // return.        return;  }   7、1、4如果是ARP或IP协议那么发送包回到协议 [cpp] view plain copy VOID SendPacketHook( IN PNT_PROTOCOL pnpProtocol, IN PNT_OPEN_ADAPTER pnoaAdapter, IN BYTE* pbData, IN DWORD dwDataSize )
http://www.hkea.cn/news/14463356/

相关文章:

  • 东莞网站推广哪里找saas软件
  • 公司需要网站 该怎么做张家港手机网站设计
  • 郑州网站推广公司信息如何远程连接 网站 数据库
  • 双语版网站引导页高台网站建设
  • 从化网站开发做网站和做电脑软件差别大吗
  • 找加工订单的网站花店网站设计
  • 广西建设厅招投标中心网站网站建设费用会计分录
  • 网站二维码怎么制作福田网站建设seo新科
  • 公司网站建设找谁做wordpress 图片 不显示缩略图
  • es网站开发做国学类网站合法吗
  • 装修网站开发思路wordpress 选择语言
  • 电子网站开发专业网站定制流程
  • 织梦系统做网站简单的购物网站源码
  • 常州外贸公司网站建设如何建一个电商平台
  • 网站建设海报素材推广优化网站排名教程
  • 商城网站制作报价网站建设开发软件有哪些方面
  • 嘉定区网站建设手机如何做微电影网站
  • 淘宝客网站都用什么做html怎么做网站
  • 做网站现在什么最赚钱广州网站优化推广
  • 邢台网站建设58昆山做网站需要多少钱
  • 重庆光龙网站建设广告设计专业分析
  • 哪里的网站建设好大连app制作
  • vps设置网站访问用户权限怎么才能登网站做外贸
  • 中国建设银行网站功能模块和城乡建设厅网站
  • 网站怎么做镜像一级的vi设计公司
  • php做网站特效卖小程序赚钱吗
  • 保险网站建设平台广安门外网站建设
  • 外贸网站推广外包做设计应该看哪些网站
  • 建设厅官方网站职称网站建设的审批部门是
  • dede旅游网站源码 多城市完成一个个人主页网站的制作