Windows2003 内核级进程隐藏、侦测技术(2)
作者:佚名; 更新时间:2014-12-05
程序不支持这个请求,MajorFunction表就会指向I/O管理器函数_IopInvalidDeviceRequest,该函数返回一个错误给原始的调用者。驱动程序的作者有责任提供所有的驱动程序支持的派遣例程。所有的驱动程序必须支持IRP_MJ_CREATE功能代码,因为这个功能代码是用来响应Win32用户模式的CreateFile调用,如果不支持这功能代码,Win32程序就没有办法获得设备的句柄,类似的,驱动程序必须支持IRP_MJ_CLOSE功能代码,因为它用来响应Win32用户模式的CloseHandle调用。顺便提一下,系统自动调用CloseHandle函数,因为在程序退出的时候,所有的句柄都没有被关闭。

 static NTSTATUS MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)

{

    NTSTATUS status;

    PIO_STACK_LOCATION irpSp;

    //得到当前IRP (I/O请求包)

    irpSp = IoGetCurrentIrpStackLocation( Irp );

    switch (irpSp->MajorFunction)

    {

        case IRP_MJ_CREATE:

            DbgPrint("IRP_MJ_CREATE\n");

            Irp->IoStatus.Status = STATUS_SUCCESS;

            Irp->IoStatus.Information = 0L;

            break;

        case IRP_MJ_CLOSE:

            DbgPrint("IRP_MJ_CLOSE\n");

            Irp->IoStatus.Status = STATUS_SUCCESS;

            Irp->IoStatus.Information = 0L;

            break;

    }

    IoCompleteRequest(Irp, 0);

    return STATUS_SUCCESS;

}

  大部分的I/O管理器的操作支持一个标准的读写提取,IRP_MJ_DEVICE_CONTROL允许扩展的I/O请求,使用用户模式的DeviceIoControl函数来调用,I/O管理器创建一个IRP,这个IRP的MajorFunction和IoControlCode是被DeviceIoControl函数指定其内容。传递给驱动程序的IOCTL遵循一个特殊的结构,它有32-bit大小,DDK包含一个方便的产生IOCTL值的机制的宏,CTL_CODE。可以使用CTL_CODE宏来定义我们自己的IOCTL。

例如:

#define IOCTL_MISSLEDEVICE_AIM  CTL_CODE \

( FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ACCESS_ANY )

 NTSTATUS DispatchIoControl( IN PDEVICE_OBJECT pDO, IN PIRP pIrp )

{

    NTSTATUS status = STATUS_SUCCESS;     

    PDEVICE_EXTENSION pDE;

    PVOID userBuffer;

    ULONG inSize;

    ULONG outSize;

    ULONG controlCode;                 // IOCTL请求代码

    PIO_STACK_LOCATION pIrpStack;   //堆栈区域存储了用户缓冲区信息

     pIrpStack = IoGetCurrentIrpStackLocation( pIrp );

    // 取出IOCTL请求代码

    controlCode = pIrpStack-> Parameters.DeviceIoControl.IoControlCode;

    // 得到请求缓冲区大小

    inSize = pIrpStack-> Parameters.DeviceIoControl.InputBufferLength;

    OutSize = pIrpStack-> Parameters.DeivceIoControl.OutputBufferLength;

    //现在执行二次派遣

    switch (controlCode)

    {

        case IOCTL_MISSLEDEVICEAIM:

       ......

        case IOCTL_DEVICE_LAUNCH:

        ......

        default:    // 驱动程序收到了未被承认的控制代码

        status = STATUS_INVALID_DEVICE_REQUEST;

    }

    pIrp->IoStatus.Information = 0; // 数据没有传输

    IoCompleteRequest( pIrp, IO_NO_INCREMENT ) ;     

    return status;

}

  5.驱动程序的安装

    SC管理器(即服务控制管理器)可以控制服务和驱动程序。

    加载和运行一个服务需要执行的典型操作步骤:

    1.调用OpenSCManager()以获取一个管理器句柄

    2.调用CreateService()来向系统中添加一个服务

    3.调用StartService()来运行一个服务

    4.调用CloseServiceHandle()来释放管理器或服务句柄

 BOOL    InstallDriver()

{

    SC_HANDLE hSCManager = NULL;

    hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);

    if(hSCManager == NULL)

    {

fprintf(stderr, "OpenSCManager() failed. --err: %d\n", GetLastError());

        return FALSE;

    }

    SC_HANDLE schService;

schService = CreateService( hSCManager, //SCManager database

                           "MyDriver",             // name of service

                            "MyDriver",             // name to display

                           SERVICE_ALL_ACCESS,     // desired access

                           SERVICE_KERNEL_DRIVER,   // service type

                            SERVICE_AUTO_START,    // start type

                    SERVICE_ERROR_NORMAL, // error control type

                            DriverPath,              // service's binary

                            NULL,                 // no load ordering group

                            NULL,                    // no tag identifier

                            NULL,                    // no dependencies

                            NULL,                    // LocalSystem account

                            NULL                     // no password

                            );

    if (schService == NULL)

    {

        if(GetLastError() == ERROR_SERVICE_EXISTS)

        {

            printf("Service has already installed!\n");

        }

        printf("Install driver false!");

        return FALSE;

    }

    BOOL    nRet = StartService(schService, 0, NULL);

    if(!nRet)

    {

      if(GetLastError() == ERROR_SERVICE_ALREADY_RUNNING)

        {

            printf("Service is already running!\n");

            return FALSE;

       

核心期刊快速发表
Copyright@2000-2030 论文期刊网 Corporation All Rights Reserved.
《中华人民共和国信息产业部》备案号:ICP备07016076号;《公安部》备案号:33010402003207
本网站专业、正规提供职称论文发表和写作指导服务,并收录了海量免费论文和数百个经国家新闻出版总署审批过的具有国内统一CN刊号与国际标准ISSN刊号的合作期刊,供诸位正确选择和阅读参考,免费论文版权归原作者所有,谨防侵权。联系邮箱:256081@163.com