百度空间 | 百度首页 
 
查看文章
 
NDIS中间层的防火墙实现技术简述
2009-06-21 18:36

NDIS中间层的防火墙实现技术简述

  2004年12月的时候,www.rootkit.com上面的一名黑客发表了一篇著名的文章:“Hooking into NDIS and TDI, part 1。这篇文章本意是为rootkit作者们提供一种挂接底层驱动实现端口重用的方法,但是这篇文章揭示了一个全新的技术:通过动态的注册ndis假协议,可以获得ndis protocol的链表地址。得到这个地址之后就能不通过重起,就能替换并监控每个ndis protocol的send(packets)handler和receive(packet)handler,并且可以动态的卸载监控模块不需要重起。在这篇文章出现之后,很多防火墙厂商都悄悄地对自己的产品进行了升级。目前的ZoneAlarm等产品就是使用这种技术,可以在安装后即时发挥作用。这个例子更充分的体现了,黑客和反黑技术本来就是相辅相成的,本源同一的。

  这里给出一个寻找该链表头的代码例子:

  该函数返回的NDIS_HANDLE就是链表头地址。

NDIS_HANDLE RegisterBogusNDISProtocol(void)

{
  NTSTATUS Status = STATUS_SUCCESS;
  NDIS_HANDLE hBogusProtocol = NULL;
  NDIS_PROTOCOL_CHARACTERISTICS BogusProtocol;
  NDIS_STRING ProtocolName;

  NdisZeroMemory(&BogusProtocol,sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
  BogusProtocol.MajorNdisVersion = 0x04;
  BogusProtocol.MinorNdisVersion = 0x0;

  NdisInitUnicodeString(&ProtocolName,L"BogusProtocol");
  BogusProtocol.Name = ProtocolName;
  BogusProtocol.ReceiveHandler = DummyNDISProtocolReceive;
  BogusProtocol.BindAdapterHandler = dummyptbindadapt;
  BogusProtocol.UnbindAdapterHandler = dummyptunbindadapt;

  NdisRegisterProtocol(&Status,&hBogusProtocol,&BogusProtocol,
    sizeof(NDIS_PROTOCOL_CHARACTERISTICS));

  if(Status == STATUS_SUCCESS){ return hBogusProtocol;}
  else {
#ifdef bydbg
    DbgPrint("ndishook:cannot register bogus protocol:%x\n",Status);

    DbgBreakPoint();
#endif
    return NULL;
  }
}

  得到这个ndis protocol的链表后,遍历表中的每一个ndis protocol,对于每一个ndis protocol,又各有一个链表,用来描述和该ndis protocol有联系的所有ndis miniport和该ndis protocol绑定的状态。每个这种状态块,叫做一个ndis open block。每个绑定的send(packets)handler和receive(packet)handler都在这个ndis open block里面。

struct _NDIS_OPEN_BLOCK
{
#ifdef __cplusplus
  NDIS_COMMON_OPEN_BLOCK NdisCommonOpenBlock;
#else
  NDIS_COMMON_OPEN_BLOCK;
#endif

#if defined(NDIS_WRAPPER)
  
  //
  // The stuff below is for CO drivers/protocols. This part is not allocated for CL drivers.
  //
  struct _NDIS_OPEN_CO
  {
  ....
  };
#endif
};

typedef struct _NDIS_COMMON_OPEN_BLOCK
{
  PVOID            MacHandle;     // needed for backward compatibility
  NDIS_HANDLE         BindingHandle;   // Miniport's open context


  PNDIS_MINIPORT_BLOCK    MiniportHandle;   // pointer to the miniport
  PNDIS_PROTOCOL_BLOCK    ProtocolHandle;   // pointer to our protocol
  NDIS_HANDLE         ProtocolBindingContext;// context when calling ProtXX funcs
  PNDIS_OPEN_BLOCK      MiniportNextOpen;  // used by adapter's OpenQueue
  PNDIS_OPEN_BLOCK      ProtocolNextOpen;  // used by protocol's OpenQueue
  NDIS_HANDLE         MiniportAdapterContext; // context for miniport
  BOOLEAN           Reserved1;
  BOOLEAN           Reserved2;
  BOOLEAN           Reserved3;
  BOOLEAN           Reserved4;
  PNDIS_STRING        BindDeviceName;
  KSPIN_LOCK         Reserved5;
  PNDIS_STRING        RootDeviceName;

  //
  // These are referenced by the macros used by protocols to call.
  // All of the ones referenced by the macros are internal NDIS handlers for the miniports
  //
  union
  {
    SEND_HANDLER      SendHandler;
    WAN_SEND_HANDLER    WanSendHandler;
  };
  TRANSFER_DATA_HANDLER    TransferDataHandler;

  //
  // These are referenced internally by NDIS
  //
  SEND_COMPLETE_HANDLER    SendCompleteHandler;
  TRANSFER_DATA_COMPLETE_HANDLER TransferDataCompleteHandler;
  RECEIVE_HANDLER       ReceiveHandler;
  RECEIVE_COMPLETE_HANDLER  ReceiveCompleteHandler;
  WAN_RECEIVE_HANDLER     WanReceiveHandler;
  REQUEST_COMPLETE_HANDLER  RequestCompleteHandler;

  //
  // NDIS 4.0 extensions
  //
  RECEIVE_PACKET_HANDLER   ReceivePacketHandler;
  SEND_PACKETS_HANDLER    SendPacketsHandler;

  //
  // More Cached Handlers
  //
  RESET_HANDLER        ResetHandler;
  REQUEST_HANDLER       RequestHandler;
  RESET_COMPLETE_HANDLER   ResetCompleteHandler;

  STATUS_HANDLER       StatusHandler;
  STATUS_COMPLETE_HANDLER   StatusCompleteHandler;
  
#if defined(NDIS_WRAPPER)
  ....
#endif

} NDIS_COMMON_OPEN_BLOCK;

  需要处理的,是ndis open block里面的SendHandler,ReceiveHandler,WanReceiveHandler,ReceivePacketHandler和SendPacketsHandler。

  一定要注意的是,不同于很多文章中的描述,主要处理SendHandler和ReceiveHandler,正确的应该是主要处理ReceivePacketHandler和SendPacketsHandler,现在的主流网卡和系统驱动,都是使用后面两者。

  值得注意的是,在Windows9x/Me/NT的DDK中,NDIS_PROTOCOL_BLOCK的定义是很明确的,而在Windows   2000/xp的DDK中,并没有该结构的详细定义,也就是说该结构在Windows2000/xp下是非公开的,因此开发人员需要利用各种调试工具来发掘该结构的详细定义。也正是因为如此,这种方法对平台的依赖性比较大,需要在程序中判断不同的操作系统版本而使用不同的结构定义。


 
网友评论:
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
验证码: 请点击后输入四位验证码,字母不区分大小写
      

     

©2009 Baidu