• tiechui_lesson14_网络连接请求的拦截


    这一节主要学习网络请求的过滤,铁锤大佬讲了些关于IRP的知识。

    笔记

    先祭出一张灵魂作画,这是用来描述IRP的流转形式的。
    IRP抽线作画
    通过这幅图着重解释了一下IoSkipCurrentIrpStackLocation(pirp);的过程,就是在流转到当前的IRP请求之后,不做任何处理,将当前的IRP堆栈传到下一层,使之和上一次内容一样,就相当于“跳过”了。

    VOID
    IoSkipCurrentIrpStackLocation (
        _Inout_ PIRP Irp
    ){
        NT_ASSERT(Irp->CurrentLocation <= Irp->StackCount);
        Irp->CurrentLocation++;
        Irp->Tail.Overlay.CurrentStackLocation++;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述
    各种IRP也是分层过滤的,一层一层的传递,然后不同的驱动设备都可以修改。

    在拦截IRP这一步就很简单,下边是效果,网络请求也可以拦截到。
    在这里插入图片描述

    接下来是对请求IRP中的内容进行解析,一般是IRP堆栈里边有很多结构,我们需要通过文档或是经验贴,定义或者强转成我们需要的内容。

    具体的分发例程:

    NTSTATUS MyDispath(
    	PDEVICE_OBJECT pdevice,
    	PIRP pirp
    ) {
    	PIO_STACK_LOCATION pripstack = NULL;
    
    	// 我们只关心TCP请求,且流入本驱动的
    	if (pdevice == pfilterdevobj)
    	{
    		pripstack = IoGetCurrentIrpStackLocation(pirp);
    
    		if (pripstack ==NULL)
    		{
    			return STATUS_UNSUCCESSFUL;
    		}
    
    		if (pripstack->MinorFunction == TDI_CONNECT)
    		{
    			PTDI_REQUEST_KERNEL_CONNECT ptdiconnect =
    				(PTDI_REQUEST_KERNEL_CONNECT)(&pripstack->Parameters);
    
    			PTA_ADDRESS ta_addr =
    				((PTRANSPORT_ADDRESS)(ptdiconnect->RequestConnectionInformation->RemoteAddress))->Address;
    
    			PTDI_ADDRESS_IP tdi_addr =
    				(PTDI_ADDRESS_IP)(ta_addr->Address);
    
    			DWORD address = tdi_addr->in_addr;
    
    			USHORT port = tdi_addr->sin_port;
    
    			NETWORK_ADDRESS data = { 0 };
    
    			data.address[0] = ((PCHAR)&address)[0];
    			data.address[1] = ((PCHAR)&address)[1];
    			data.address[2] = ((PCHAR)&address)[2];
    			data.address[3] = ((PCHAR)&address)[3];
    			data.post[0] = ((PCHAR)&port)[0];
    			data.post[1] = ((PCHAR)&port)[1];
    
    			port = HTONS(port);
    
    			DbgPrint("connect %d.%d.%d.%d:%d\n", data.address[0],
    				data.address[1],
    				data.address[2],
    				data.address[3], port);
    
    			DbgPrint("connect io address <%x>\n", address);
    		}
    
    	}
    	
    
    	IoSkipCurrentIrpStackLocation(pirp);
    
    	return IoCallDriver(pdodevobj, pirp);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    里边在端口的转换时,使用了HTONS

    HTONS本身所做的就是将USHORT从主机序转化为网络序
    参考:用C语言进一步优化Windows Shellcode

    然后里边对结构内容的查找,涉及很多类型和指针的调用,其实也米有难得地方,对应好结构的说明进行指定或强转。(很复杂就是😗)

    在这里插入图片描述

    小结

    锤哥在视频里边花了很多时间来调试找错误,来接解决端口显示异常的问题,感谢大佬,很受用!

    ”本着调试的精神来解决问题“ Getit✅

  • 相关阅读:
    Maven的安装配置,及IDEA使用Maven
    Android -BLE 蓝牙模块开发
    Apache Shiro 集成-spring
    vue keepAlive的使用
    7-Spring架构源码分析-IoC 之注册 BeanDefinitions
    猿创征文|运维工具介绍
    jenkins
    微信小程序实现上下手势滑动切换
    STM32ADC模拟/数字转换详解
    爱迪转债上市价格预测
  • 原文地址:https://blog.csdn.net/lsj1997718117/article/details/130901407