寒江独钓-Windows内核安全编程笔记-第3章代码和笔记

3 篇文章 1 订阅

第3章代码 

// #include 
   
   
    
    
#include 
    
    
     
     
#define NTSTRSAFE_LIB
#include 
     
     
      
      

#define  CPP_MAX_COM_ID 32
#define     DELAY_ONE_MICROSECOND (-10)
#define     DELAY_ONE_MILLISECOND (DELAY_ONE_MICROSECOND*1000)
#define     DELAY_ONE_SECOND (DELAY_ONE_MILLISECOND*1000)
static PDEVICE_OBJECT s_fltobj[CPP_MAX_COM_ID] = {0};
static PDEVICE_OBJECT s_nextobj[CPP_MAX_COM_ID] = {0};


NTSTATUS ccpAttachDevice(
    PDRIVER_OBJECT driver
    , PDEVICE_OBJECT oldobj
    , PDEVICE_OBJECT *fltobj
    , PDEVICE_OBJECT *next)
{
    NTSTATUS status;
    PDEVICE_OBJECT topdev = NULL;
    // IoCreateDevice 创建设备对象
    // driver 驱动程序对象 , oldobj->DeviceType设备的类型
    // fltobj指向接收DEVICE_OBJECT结构体的指针
    status = IoCreateDevice (driver, 0, NULL, oldobj->DeviceType, 0, FALSE, fltobj);
    if (status != STATUS_SUCCESS)
    {
        return status;
    }

    if (oldobj -> Flags & DO_BUFFERED_IO)
    {
        (*fltobj)->Flags |= DO_BUFFERED_IO;
    }
    if (oldobj->Flags & DO_DIRECT_IO)
    {
        (*fltobj)->Flags |= DO_DIRECT_IO;
    }
    if (oldobj->Flags & FILE_DEVICE_SECURE_OPEN)
    {
        (*fltobj)->Characteristics |= FILE_DEVICE_SECURE_OPEN;
    }
    (*fltobj)->Flags |= DO_POWER_PAGABLE;
    // 将调用方的设备对象附加到设备对象链中的最高层,并返回之前在设备对象链中最高的设备对象。
    // fltobj需要附着的源设备对象, oldobj附着到的目标设备对象
    // 把fltobj放到oldobj所在的链的顶端
    topdev = IoAttachDeviceToDeviceStack (*fltobj, oldobj);
    if (NULL == topdev)
    {
        // 从系统中删除一个设备对象fltobj
        // VOID IoDeleteDevice(
        //     _In_ PDEVICE_OBJECT DeviceObject
        //     );
        //     DeviceObject 要删除的设备对象指针
        IoDeleteDevice (*fltobj);
        *fltobj = NULL;
        status = STATUS_UNSUCCESSFUL;
        return status;
    }
    *next = topdev;

    (*fltobj)->Flags = (*fltobj)->Flags & ~DO_DEVICE_INITIALIZING;
    return STATUS_SUCCESS;
}

PDEVICE_OBJECT cppOpenCom(ULONG id, NTSTATUS *status)
{
    UNICODE_STRING name_str;
    static WCHAR name[32] = {0};
    PFILE_OBJECT fileobj = NULL;
    PDEVICE_OBJECT devobj = NULL;
    memset (name, 0, sizeof(WCHAR)*32);
    RtlStringCchPrintfW(name, 32, L"\\Device\\Serial%d", id);
    RtlInitUnicodeString (&name_str, name);
    // 获取命名对象
    // IoGetDeviceObjectPointer返回一个指向命名对象设备堆栈顶部的对象指针和
    // 相应的文件对象指针
    // The IoGetDeviceObjectPointer routine returns a pointer to the top object 
    // in the named device object's stack and a pointer to the corresponding file object, 
    // if the requested access to the objects can be granted.
    *status = IoGetDeviceObjectPointer(&name_str, FILE_ALL_ACCESS, &fileobj, &devobj);
    if (*status == STATUS_SUCCESS)
    {
        // 解除引用。
        // ObDereferenceObject检查给定对象的引用计
        // The ObDereferenceObject routine decrements the given object's reference count
        // and performs retention checks.
        ObDereferenceObject(fileobj);
    }
    return devobj;
}




void cppAttachAllCom(PDRIVER_OBJECT driver)
{
    ULONG i;
    PDEVICE_OBJECT com_ob;
    NTSTATUS status;
    for (i = 0; i < CPP_MAX_COM_ID; ++i)
    {
        com_ob = cppOpenCom (i, &status);
        if (NULL == com_ob)
        {
            continue;
        }
        ccpAttachDevice(driver, com_ob, &s_fltobj[i], &s_nextobj[i]);
    }
}

NTSTATUS ccpDispatch(PDEVICE_OBJECT device, PIRP irp)
{
    PIO_STACK_LOCATION irpsp = IoGetCurrentIrpStackLocation (irp);
    NTSTATUS status;
    ULONG i, j;
    for (i = 0; i < CPP_MAX_COM_ID; ++i)
    {
        if (device == s_fltobj[i])
        {
            if (irpsp->MajorFunction == IRP_MJ_POWER)
            {
                // The PoStartNextPowerIrp routine signals the power manager that 
                // the driver is ready to handle the next power IRP.
                // (Windows Server 2003, Windows XP, and Windows 2000 only.)
                PoStartNextPowerIrp (irp);
                // The IoSkipCurrentIrpStackLocation macro modifies the system's
                // IO_STACK_LOCATION array pointer, so that when the current
                // driver calls the next-lower driver, that driver receives
                // the same IO_STACK_LOCATION structure that
                // the current driver received.
                IoSkipCurrentIrpStackLocation (irp);
                // The PoCallDriver routine passes a power IRP to the next-lower 
                // driver in the device stack. 
                // (Windows Server 2003, Windows XP, and Windows 2000 only.)
                return PoCallDriver (s_nextobj[i], irp);
            }
            if (irpsp->MajorFunction == IRP_MJ_WRITE)
            {
                ULONG len = (irpsp->Parameters.Write.Length);
                PUCHAR buf = NULL;
                if (irp->MdlAddress != NULL)
                {
                    // The MmGetSystemAddressForMdlSafe macro returns a 
                    // nonpaged system-space virtual address for the buffer that
                    // the specified MDL describes.
                    buf = (PUCHAR)MmGetSystemAddressForMdlSafe(
                        irp->MdlAddress, NormalPagePriority);
                }
                else
                {
                    buf = (PUCHAR)irp->UserBuffer;
                }
                if (NULL == buf)
                {
                    buf = (PUCHAR)irp->AssociatedIrp.SystemBuffer;
                }

                for (j = 0; j < len; ++j)
                {
                    DbgPrint("comcap: Send Data: %2x\r\n", buf[j]);
                }
            }

            IoSkipCurrentIrpStackLocation (irp);
            // The IoCallDriver routine sends an IRP to the driver associated with
            // a specified device object.
            // 发送irp给s_nextobj[i]
            return IoCallDriver (s_nextobj[i], irp);
        }
    }
    irp->IoStatus.Information = 0;
    irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
    // The IoCompleteRequest routine indicates that the caller has completed all processing
    // for a given I/O request and is returning the given IRP to the I/O manager.
    // 调用者已完成所有处理对于一个给定的I / O请求和返回给定的irp到I / O管理器。
    IoCompleteRequest(irp, IO_NO_INCREMENT);
    return STATUS_SUCCESS;
}


void ccpUnload(PDRIVER_OBJECT drv)
{
    ULONG i;
    LARGE_INTEGER interval;
    for (i = 0; i < CPP_MAX_COM_ID; ++i)
    {
        if (NULL != s_nextobj[i])
        {
            // The IoDetachDevice routine releases an attachment between the caller's 
            // device object and a lower driver's device object.
            // 从设备链上删除 s_nextobj[i]
            // s_nextobj[i] 下层堆栈上的设备对象  
            IoDetachDevice (s_nextobj[i]);
        }
    }
    interval.QuadPart = 5*1000*DELAY_ONE_MILLISECOND;
    // The KeDelayExecutionThread routine puts the current thread into an alertable or
    // nonalertable wait state for a specified interval.
    // 延时
    KeDelayExecutionThread (KernelMode, FALSE, &interval);
    for (i = 0; i < CPP_MAX_COM_ID; ++i)
    {
        if (NULL != s_fltobj[i])
        {
            IoDeleteDevice (s_fltobj[i]);
        }
    }
}

NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
    size_t i;
#if DBG
    _asm int 3;
#endif
    for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; ++i)
    {             
        driver->MajorFunction[i] = ccpDispatch;
    }

    driver->DriverUnload = ccpUnload ;
    cppAttachAllCom (driver);
    return STATUS_SUCCESS;
}
     
     
    
    
   
   


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值