wuxo84
驱动牛犊
驱动牛犊
  • 注册日期2007-08-03
  • 最后登录2007-08-05
  • 粉丝0
  • 关注0
  • 积分40分
  • 威望5点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
阅读:4147回复:40

通过tdi如何监听、判断外部对本机的访问请求

楼主#
更多 发布于:2007-08-05 01:44
请问大家:
我最近有个新任务,意思就是:

取代各通信程序(例如apache)的监听端口,在他们之前统一分配一个唯一的监控端口,对来访的消息进行监控,然后根据来访的消息进行判断,首先判断出是不是我们自己的用户,如果是继续判断他选择的应用是什么(比如说浏览网页,即想要与apache进行通信),最后给他开辟对应应用程序的端口放他进来,比如他想浏览网页,那么就把apache的端口给他打开。

我觉得这就是个类似于防火墙的东西。我想虽然这个唯一的监控端口可以控制所有的应用端口开闭,但既然是测试,我就只针对一个apache来做,也就是说一个访问网页的请求过来,我先在apache之前拦下它(通过唯一的那个控制/监听端口),然后判断它是不是自己的用户,如果合法,我再把apache端口给他打开,让他访问。

要做这个东西,应该是用到tdi吧?我最近一直在研究tdi,所以希望以这个方向为突破口。可是思路是什么呢?请问各位有例子或者建议吗?还有,我应该怎么建这个模型呢?如何给老板演示呢?如何知道(监听到)访问请求?

谢谢各位了,急!大家多帮我,我是菜鸟!
我的邮箱:wuxo@sina.com
如果哪位好心人能帮我编写一些简单的例子,真的是感激不尽!!!
 
niumowangmeng
驱动牛犊
驱动牛犊
  • 注册日期2008-02-22
  • 最后登录2008-06-07
  • 粉丝0
  • 关注0
  • 积分150分
  • 威望16点
  • 贡献值0点
  • 好评度15点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2008-03-23 21:36
我也想学习看来的看开源的防火墙了,呵呵
wuxo84_temp
驱动牛犊
驱动牛犊
  • 注册日期2007-08-05
  • 最后登录2007-08-15
  • 粉丝0
  • 关注0
  • 积分280分
  • 威望29点
  • 贡献值0点
  • 好评度28点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2007-08-13 11:07

谢谢各位,我从新开贴,探讨一些与驱动有关的,比较基本的问题,希望大家多来参与,任何人都可以发问题,大家一起探讨。
希望大家首先心态要好,本着共同学习共同进步的原则。
ProPlayboy
驱动大牛
驱动大牛
  • 注册日期2005-07-07
  • 最后登录2022-02-15
  • 粉丝0
  • 关注0
  • 积分1016分
  • 威望811点
  • 贡献值0点
  • 好评度719点
  • 原创分0分
  • 专家分0分
  • 社区居民
地板#
发布于:2007-08-10 23:09
    TRANSPORT_ADDRESS *pTransAddr=(TRANSPORT_ADDRESS*)pRemoteAddress;

    TDI_ADDRESS_IP *pIPAddress=(TDI_ADDRESS_IP*)(unsigned char*)&pTransAddr->Address[0].Address;
    
    ulRemoteIP=htonl(pIPAddress->in_addr);
    
    nRemotePort=ntohs(pIPAddress->sin_port);
人不靓仔心灵美,版头不正红花仔!
ProPlayboy
驱动大牛
驱动大牛
  • 注册日期2005-07-07
  • 最后登录2022-02-15
  • 粉丝0
  • 关注0
  • 积分1016分
  • 威望811点
  • 贡献值0点
  • 好评度719点
  • 原创分0分
  • 专家分0分
  • 社区居民
地下室#
发布于:2007-08-10 23:04
我再回答一次,这个贴子。以后靠你自己了。你并没有去搜索以前的贴子,也没有去认真的看资料,这种态度不行的!这也是其它的牛不想回答的原因!我不是好心,纯粹路过,兼测试驱动!所以不必谢我!
人不靓仔心灵美,版头不正红花仔!
wuxo84_temp
驱动牛犊
驱动牛犊
  • 注册日期2007-08-05
  • 最后登录2007-08-15
  • 粉丝0
  • 关注0
  • 积分280分
  • 威望29点
  • 贡献值0点
  • 好评度28点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2007-08-10 17:49
代码最新版,请执教,谢谢
#include <ntddk.h>
#include <tdikrnl.h>


//定义了一个上下文信息结构,为了保存需要的信息
typedef struct{
    PFILE_OBJECT fileobj;       //address object
    PVOID        old_handler;   //old event handler
    PVOID        old_context;   //old event handler context
}TDI_EVENT_CONTEXT;


//自己的回调函数
NTSTATUS mytdi_event_connect(
    IN PVOID TdiEventContext,
    IN LONG RemoteAddressLength,
    IN PVOID RemoteAddress,
    IN LONG UserDataLength,
    IN PVOID UserData,
    IN LONG OptionsLength,
    IN PVOID Options,
    OUT CONNECTION_CONTEXT *ConnectionContext,
    OUT PIRP *AcceptIrp)
{
    KdPrint(("oh? someone is coming~ no way~!!!\n"));
    return STATUS_CONNECTION_REFUSED;
}


//TDI派遣函数
NTSTATUS TDIDeviceDispatch(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
    NTSTATUS status;
    PIO_STACK_LOCATION irps= IoGetCurrentIrpStackLocation(irp);
  
    if(irps->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL && irps->MinorFunction == TDI_SET_EVENT_HANDLER)
    {
        TDI_REQUEST_KERNEL_SET_EVENT r = (TDI_REQUEST_KERNEL_SET_EVENT)&irps->Parameters;
        if(r->EventType == TDI_EVENT_CONNECT && r->EventHandler != NULL)
        {
            TDI_EVENT_CONTEXT cxt;
            cxt->fileobj = irps->FileObject;   //这么写对么???
            cxt->old_handler = r->EventHandler;
            ctx->old_context = r->EventContext;
            
            r->EventHandler = mytdi_event_connect;  
            r->EventContext = ctx;          

            //自己的调用函数处理完毕后,调用原来的回调函数
            status = ((PTDI_IND_CONNECT)(ctx->old_handler))
                (ctx->old_context,
                RemoteAddressLength,
                RemoteAddress,
                UserDataLength,
                UserData,
                OptionsLength,
                Options,
                ConnectionContext,
                AcceptIrp);
        }
    }
}


////卸载驱动
NTSTATUS ReleaseTDIDevices(void)
{
    NTSTATUS Status;
    UNICODE_STRING usDriverName;
    PDRIVER_OBJECT DriverObjectToHookPtr;
    UINT i;

    RtlInitUnicodeString(&usDriverName,L"\\Driver\\Tcpip");

    Status = ObReferenceObjectByName(&usDriverName,OBJ_CASE_INSENSITIVE,NULL,0,IoDriverObjectType,KernelMode,NULL,&DriverObjectToHookPtr);
    if(Status != STATUS_SUCCESS)
        return Status;

    for(i = 0;i < IRP_MJ_MAXIMUM_FUNCTION;i++)
        DriverObjectToHookPtr->MajorFunction = RealTDIDriverObject.MajorFunction;

    return STATUS_SUCCESS;
}


//TDI入口函数
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{
    NTSTATUS ntStatus=STATUS_SUCCESS;
    DRIVER_OBJECT RealTDIDriverObject;
    UNICODE_STRING myDriverName;
    PDRIVER_OBJECT DriverObjectToHookPtr;
    UINT i;

    RtlInitUnicodeString(&myDriverName,L"\\Driver\\Tcpip");

    Status = ObReferenceObjectByName(
        &myDriverName,
        OBJ_CASE_INSENSITIVE,
        NULL,
        0,
        IoDriverObjectType,
        KernelMode,
        NULL,
        &DriverObjectToHookPtr
        );
    
    if(Status != STATUS_SUCCESS)
    {
        KdPrint(("failed at: ObReferenceObjectByName\n"));
        return Status;
    }

    for(i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
    {
        RealTDIDriverObject.MajorFunction = DriverObjectToHookPtr->MajorFunction;
        DriverObjectToHookPtr->MajorFunction = TDIDeviceDispatch;
    }

    return STATUS_SUCCESS;
}
wuxo84_temp
驱动牛犊
驱动牛犊
  • 注册日期2007-08-05
  • 最后登录2007-08-15
  • 粉丝0
  • 关注0
  • 积分280分
  • 威望29点
  • 贡献值0点
  • 好评度28点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2007-08-10 14:51
目前我所能完成的代码,麻烦斑竹帮我看一下吧,谢谢

//定义了一个上下文信息结构,为了保存需要的信息
typedef struct{
    PFILE_OBJECT fileobj;       //address object
    PVOID        old_handler;   //old event handler
    PVOID        old_context;   //old event handler context
}TDI_EVENT_CONTEXT;

DRIVER_OBJECT RealTDIDriverObject;

//TDI入口函数
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{
    NTSTATUS ntStatus=STATUS_SUCCESS;
    UNICODE_STRING myDriverName;
    PDRIVER_OBJECT DriverObjectToHookPtr;
    UINT i;

    RtlInitUnicodeString(&myDriverName,L"\\Driver\\Tcpip");

    Status = ObReferenceObjectByName(
        &myDriverName,
        OBJ_CASE_INSENSITIVE,
        NULL,
        0,
        IoDriverObjectType,
        KernelMode,
        NULL,
        &DriverObjectToHookPtr
        );
    
    if(Status != STATUS_SUCCESS)
    {
        KdPrint(("failed on: ObReferenceObjectByName\n"));
        return Status;
    }

    for(i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
    {
        RealTDIDriverObject.MajorFunction = DriverObjectToHookPtr->MajorFunction;
        DriverObjectToHookPtr->MajorFunction = TDIDeviceDispatch;
    }

    return STATUS_SUCCESS;
}

//TDI派遣函数
NTSTATUS TDIDeviceDispatch(IN PDEVICE_OBJECT DriverObject, IN PIRP irp)
{
    PIO_STACK_LOCATION irps= IoGetCurrentIrpStackLocation(irp);
  
    if(irps->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL && irps->MinorFunction == TDI_SET_EVENT_HANDLER)
    {
        TDI_REQUEST_KERNEL_SET_EVENT r = (TDI_REQUEST_KERNEL_SET_EVENT)&irps->Parameters;
        if(r->EventType == TDI_EVENT_CONNECT && r->EventHandler != NULL)
        {
            TDI_EVENT_CONTEXT cxt;
            cxt->fileobj = irps->FileObject;   //这么写对么???
            cxt->old_handler = r->EventHandler;
            ctx->old_context = r->EventContext;
            
            r->EventHandler = my_handler;   //my_handler大致应该怎么写???
            r->EventContext = ctx->old_context;

            //自己的调用函数处理完毕后,调用原来的回调函数
            status = ((PTDI_IND_CONNECT)(ctx->old_handler))
                (ctx->old_context,
                RemoteAddressLength,
                RemoteAddress,
                UserDataLength,
                UserData,
                OptionsLength,
                Options,
                ConnectionContext,
                AcceptIrp);

            //......要控制自己的回调函数返回值还是原回调函数返回值????
        }
    }
}
wuxo84_temp
驱动牛犊
驱动牛犊
  • 注册日期2007-08-05
  • 最后登录2007-08-15
  • 粉丝0
  • 关注0
  • 积分280分
  • 威望29点
  • 贡献值0点
  • 好评度28点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2007-08-10 14:12
请问版主:
在得知TDI_EVENT_CONNECT请求之后,如何写自己的回调函数?逻辑是要先获得对方的IP,然后与我写的一个值对比,比如192.168.0.1,如果相同返回STATUS_MORE_PROCESSING_REQUIRED ,如果不是这台机器返回STATUS_CONNECTION_REFUSED,之后调用原有的回调函数。

自己的回调函数是应该定义成这种格式么?直接提取RemoteAddress???怎么比对呢???谢谢~
NTSTATUS
mytdi_event_connect(
IN PVOID TdiEventContext,
IN LONG RemoteAddressLength,
IN PVOID RemoteAddress,
IN LONG UserDataLength,
IN PVOID UserData,
IN LONG OptionsLength,
IN PVOID Options,
OUT CONNECTION_CONTEXT
OUT PIRP *AcceptIrp)
wuxo84_temp
驱动牛犊
驱动牛犊
  • 注册日期2007-08-05
  • 最后登录2007-08-15
  • 粉丝0
  • 关注0
  • 积分280分
  • 威望29点
  • 贡献值0点
  • 好评度28点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2007-08-10 10:15
ok
我知道了,RegistryPath是驱动在注册表里的路径是吧?
入口函数是由系统调用的,不用管它的参数。分派函数也是这样对吧??

to ProPlayboy
麻烦您指导我一下关于RemoteAddressLength, RemoteAddress这方面的东西可以吗?
wuxo84_temp
驱动牛犊
驱动牛犊
  • 注册日期2007-08-05
  • 最后登录2007-08-15
  • 粉丝0
  • 关注0
  • 积分280分
  • 威望29点
  • 贡献值0点
  • 好评度28点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2007-08-10 10:05
您说我要都会了,我还这么着急干吗???
DriverEntry()是入口函数我知道,就想问您一下后面那个参数的意义?
如果对您小菜一碟的话,希望您能指点我。
我初学tdi,有很多很幼稚的问题,希望您能帮我,谢谢
ProPlayboy
驱动大牛
驱动大牛
  • 注册日期2005-07-07
  • 最后登录2022-02-15
  • 粉丝0
  • 关注0
  • 积分1016分
  • 威望811点
  • 贡献值0点
  • 好评度719点
  • 原创分0分
  • 专家分0分
  • 社区居民
10楼#
发布于:2007-08-09 23:43
连最基本的DriverEntry()都不懂,你怎么写啊?  
人不靓仔心灵美,版头不正红花仔!
ProPlayboy
驱动大牛
驱动大牛
  • 注册日期2005-07-07
  • 最后登录2022-02-15
  • 粉丝0
  • 关注0
  • 积分1016分
  • 威望811点
  • 贡献值0点
  • 好评度719点
  • 原创分0分
  • 专家分0分
  • 社区居民
11楼#
发布于:2007-08-09 23:39
人不靓仔心灵美,版头不正红花仔!
wuxo84_temp
驱动牛犊
驱动牛犊
  • 注册日期2007-08-05
  • 最后登录2007-08-15
  • 粉丝0
  • 关注0
  • 积分280分
  • 威望29点
  • 贡献值0点
  • 好评度28点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2007-08-09 17:59
引用第24楼ProPlayboy于2007-08-09 14:16发表的  :
RemoteAddressLength, RemoteAddress, 在EventConnect中,通过这二个参数获取Remote的IP,Port


to ProPlayboy
您能把这里将得再细一些吗?如果您有时间的话,您能写几行代码吗?我理解起来太抽象了,当然我会去查ddk的~~~有劳您啦!!
wuxo84_temp
驱动牛犊
驱动牛犊
  • 注册日期2007-08-05
  • 最后登录2007-08-15
  • 粉丝0
  • 关注0
  • 积分280分
  • 威望29点
  • 贡献值0点
  • 好评度28点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2007-08-09 15:50
二位前辈,我大致的写了一些代码,您们帮我看看我理解的对不对,或者是不是靠近了,至少没走偏~~~
DRIVER_OBJECT RealTDIDriverObject;

//TDI入口函数
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
//以上的两个形参是从什么地方传递进来的?代表什么意思呢-尤其是后面那个?直接这么写就可以了?
{
    NTSTATUS ntStatus=STATUS_SUCCESS;
    UNICODE_STRING myDriverName;
    PDRIVER_OBJECT DriverObjectToHookPtr;
    UINT i;

    RtlInitUnicodeString(&myDriverName,L"\\Driver\\Tcpip");

    Status = ObReferenceObjectByName(
        &myDriverName,
        OBJ_CASE_INSENSITIVE,
        NULL,
        0,
        IoDriverObjectType,
        KernelMode,
        NULL,
        &DriverObjectToHookPtr
        );
    
    if(Status != STATUS_SUCCESS)
        return Status;

    for(i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
    {
        RealTDIDriverObject.MajorFunction = DriverObjectToHookPtr->MajorFunction;
        DriverObjectToHookPtr->MajorFunction = hook_disp(DriverObjectToHookPtr,...);
        //以上实参是应该填DriverObjectToHookPtr吧?第二个参数irp怎么得到?
    }

    return STATUS_SUCCESS;
}

//TDI派遣函数
NTSTATUS hook_disp(IN PDEVICE_OBJECT DriverObject, IN PIRP irp)

{
    PIO_STACK_LOCATION irps= IoGetCurrentIrpStackLocation(irp);
  
    //case....

  case IRP_MJ_INTERNAL_DEVICE_CONTROL:
    switch(irps->MinorFunction)
        {
      //case....

            case TDI_SET_EVENT_HANDLER:
                switch(((TDI_REQUEST_KERNEL_SET_EVENT*)&(irps->Parameters))->EventType)
                {
                    case TDI_EVENT_CONNECT:
                        //自己的判断逻辑代码

                    //case....
        }
        break;
            
            //case....
        }

    //case....
}
ProPlayboy
驱动大牛
驱动大牛
  • 注册日期2005-07-07
  • 最后登录2022-02-15
  • 粉丝0
  • 关注0
  • 积分1016分
  • 威望811点
  • 贡献值0点
  • 好评度719点
  • 原创分0分
  • 专家分0分
  • 社区居民
14楼#
发布于:2007-08-09 14:34
。。。那么快就回贴了。。。我在测试中,路过。。。
人不靓仔心灵美,版头不正红花仔!
wuxo84_temp
驱动牛犊
驱动牛犊
  • 注册日期2007-08-05
  • 最后登录2007-08-15
  • 粉丝0
  • 关注0
  • 积分280分
  • 威望29点
  • 贡献值0点
  • 好评度28点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2007-08-09 14:31
cool~~~~
谢谢二位前辈~~~~再去学习一下~~~~
ProPlayboy
驱动大牛
驱动大牛
  • 注册日期2005-07-07
  • 最后登录2022-02-15
  • 粉丝0
  • 关注0
  • 积分1016分
  • 威望811点
  • 贡献值0点
  • 好评度719点
  • 原创分0分
  • 专家分0分
  • 社区居民
16楼#
发布于:2007-08-09 14:18
,我是路过的。。。
人不靓仔心灵美,版头不正红花仔!
ProPlayboy
驱动大牛
驱动大牛
  • 注册日期2005-07-07
  • 最后登录2022-02-15
  • 粉丝0
  • 关注0
  • 积分1016分
  • 威望811点
  • 贡献值0点
  • 好评度719点
  • 原创分0分
  • 专家分0分
  • 社区居民
17楼#
发布于:2007-08-09 14:16
RemoteAddressLength, RemoteAddress, 在EventConnect中,通过这二个参数获取Remote的IP,Port
人不靓仔心灵美,版头不正红花仔!
ProPlayboy
驱动大牛
驱动大牛
  • 注册日期2005-07-07
  • 最后登录2022-02-15
  • 粉丝0
  • 关注0
  • 积分1016分
  • 威望811点
  • 贡献值0点
  • 好评度719点
  • 原创分0分
  • 专家分0分
  • 社区居民
18楼#
发布于:2007-08-09 14:14
EventType,EventHandler,EventContext指的是你回调的函数类型,函数地址,及参数。
TDI_REQUEST_KERNEL_SET_EVENT是给你安装Event回调使用的,具体查DDK。
gettcpportbyfile一看就知道不是TDI提供的了.
人不靓仔心灵美,版头不正红花仔!
zhaock
驱动太牛
驱动太牛
  • 注册日期2002-01-26
  • 最后登录2018-06-02
  • 粉丝3
  • 关注2
  • 积分73328分
  • 威望362317点
  • 贡献值1点
  • 好评度226点
  • 原创分0分
  • 专家分0分
  • 社区居民
19楼#
发布于:2007-08-09 12:23
1.这个是安装TDI_EVENT_CONNECT函数,tcp协议会在收到第一个syn包的时候,调用这个回调.你在这里替换这个函数,你就可以实现hook tdi_event_connect的目的了
2.监听外部访问请求,处理TDI_EVENT_CONNECT,就够了
上一页
游客

返回顶部