• 驱动基本框架和与ring3通信


    五种常用的IRP类型:
    #define IRP_MJ_CREATE                     0x00 //CreateFile()
    #define IRP_MJ_CLOSE                      0x02 //CloseHandle() 
    #define IRP_MJ_READ                       0x03//ReadFile
    #define IRP_MJ_WRITE                      0x04//WriteFile
    #define IRP_MJ_DEVICE_CONTROL           0x0e//DeviceIoControl 
    入口函数中注册派遣函数
    加载中驱动签名:
     1.64bit的Windows要求对驱动进行数字签名.
    2.引导驱动程序(start为0),由winload.exe的例程进行检查,不通过就不允许启动
    3.非引导驱动程序有ntoskrnl.exe使用ci.dll的导出函数进行签名检查
    如何对付签名?
    1.购买证书并进行合法签名
    2.利用第三方签名驱动漏洞
     
     通信方式:
    BOOL DeviceIoControl(  HANDLE hDevice,   DWORD dwIoControlCode,
      LPVOID lpInBuffer,   DWORD nInBufferSize,   LPVOID lpOutBuffer,
      DWORD nOutBufferSize,   LPDWORD lpBytesReturned,   LPOVERLAPPED lpOverlapped);
    缓冲模式
    用户层:
    通过打开符号链接,获取设备访问. 将数据传输到驱动层.
    并接受并处理驱动层处理完发送来的数据
    // 与驱动通信exe端.cpp : 定义控制台应用程序的入口点。
    #include "stdafx.h"
    #include<Windows.h>
    #include<winioctl.h>
    /*
             CTL_CODE宏,通信结构,参数一是未知设备,第个参数是功能号,800-fff之间,用于区分函数,
             第个参数是通信模式,这里是缓冲模式,第个参数是需要哪些访问权限
    */
    #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,   0x800,          METHOD_BUFFERED,FILE_ANY_ACCESS)
    #define sub_code CTL_CODE(FILE_DEVICE_UNKNOWN,   0x801,          METHOD_BUFFERED,FILE_ANY_ACCESS)
    #define SymLinkName L"\\.\freesec_tx"
    int port[2],bufret;
    DWORD dwWrite;
    int add(HANDLE hDevice,int a,int b)
    {
             port[0]=a;
             port[1]=b;
             //该函数用于与驱动通信参数:设备句柄,CTL宏,函数参数地址,参数大小,驱动处理完返回
             //给exe的字符串,返回字符串缓冲大小,实际返回字符串大小.NULL
             //驱动参数对应关系:
             //irp_stack->Parameters.DeviceIoControl.InputBufferLength;
             //irp_stack->Parameters.DeviceIoControl.OutputBufferLength;
             //irp_stack->Parameters.DeviceIoControl.IoControlCode;
             DeviceIoControl(hDevice, add_code , &port, 8, &bufret, 4, &dwWrite, NULL);
             //驱动将函数执行结果存储在bufret中.
             return bufret;
    }
    int _tmain(int argc, _TCHAR* argv[])
    {
             HANDLE hDevice =
                      CreateFile(SymLinkName, //\??My_DriverLinkName
                      GENERIC_READ | GENERIC_WRITE,
                      0,              // share mode none
                      NULL,       // no security
                      OPEN_EXISTING,
                      FILE_ATTRIBUTE_SYSTEM,
                      0 );            // no template
             printf("start
    ");
             if (hDevice == INVALID_HANDLE_VALUE)
             {
                      printf("获取驱动句柄失败: %s with Win32 error code: %d
    ","MyDriver", GetLastError() );
                      getchar();
                      return -1;
             }
             //add_code
             int a=55;
             int b=33;
             int r= add(hDevice,a,b);
             printf("%d+%d=%d
    ",a,b,r);
             getchar();
             return 0;
    }

    驱动:

    //_stdcall
    #include<ntddk.h>
    #include <ntstrsafe.h>
    #define INCLUDE    code_seg("INIT")
    #pragma INCLUDE
    #define symlink_name L"\??\freesec_tx"
    #define device_name L"\device\device_tx"
    #define add_func CTL_CODE(FILE_DEVICE_UNKNOWN,    0x800,          METHOD_BUFFERED,FILE_ANY_ACCESS)
    #define sub_func CTL_CODE(FILE_DEVICE_UNKNOWN,    0x801,          METHOD_BUFFERED,FILE_ANY_ACCESS)
    PDEVICE_OBJECT myDevice;
    UNICODE_STRING DeviceName;
    UNICODE_STRING SymLinkName;
    NTSTATUS MyDisPatcher(PDEVICE_OBJECT dev,PIRP irp)
    {       
             
             NTSTATUS status=0;
             ULONG inputBufferSize;
             ULONG outputBufferSize;
             ULONG functionCode;
             int* inputBuffer;
             int* outputBuffer;
             PIO_STACK_LOCATION irp_stack=IoGetCurrentIrpStackLocation(irp);//这个栈主要用于获取非函数参数
             DbgPrint("进入派遣函数
    ");
             if (dev!=myDevice)
             {
                      status=0;
                      return status;
             }
             switch(irp_stack->MajorFunction)
             {
             case IRP_MJ_DEVICE_CONTROL:
                      DbgPrint("IRP_MJ_DEVICE_CONTROL!!!!!!!!!!!!!!!!!!!!!!
    ");
                      //得到输入缓冲区大小
                      inputBufferSize = irp_stack->Parameters.DeviceIoControl.InputBufferLength;
                      //得到输出缓冲区大小
                      outputBufferSize = irp_stack->Parameters.DeviceIoControl.OutputBufferLength;
                      //得到IOCTL码
                      functionCode = irp_stack->Parameters.DeviceIoControl.IoControlCode;
                      //获取参数缓冲区,这是输入输出共享的
                      inputBuffer=(int*)irp->AssociatedIrp.SystemBuffer;
                      outputBuffer=(int*)irp->AssociatedIrp.SystemBuffer;
                      switch(functionCode)
                      {
                      case add_func:
                              DbgPrint("add_func!!!!!!!!!!!!!!!!!
    ");
                              *outputBuffer=inputBuffer[0]+inputBuffer[1];
                              KdPrint((("计算结果为:%d
    "),*outputBuffer));
                              break;
                      case sub_func:
                              break;
                      default:
                              break;
                      }
                      break;
             case IRP_MJ_CREATE:
                      break;
             case IRP_MJ_CLOSE:
                      break;
             case IRP_MJ_READ:
                      break;
             case IRP_MJ_WRITE:
                      break;
             default:
                      break;
             }
             irp->IoStatus.Information=4;//设置操作的字节数为,这里无实际意义
             irp->IoStatus.Status=STATUS_SUCCESS;//返回成功
             IoCompleteRequest(irp,IO_NO_INCREMENT);//指示完成此IRP
             KdPrint(("离开派遣函数
    "));//调试信息
             return status;
    }
    NTSTATUS MyCreateDevice(PDRIVER_OBJECT db)
    {
             NTSTATUS status;
             RtlInitUnicodeString(&DeviceName,device_name);
             RtlInitUnicodeString(&SymLinkName,symlink_name);
             status=IoCreateDevice(db,0,&DeviceName,FILE_DEVICE_UNKNOWN,0,1,&myDevice);
             if (NT_SUCCESS(status))
             {       
                      db->DeviceObject=myDevice;
                      DbgPrint("设备创建成功!
    ");
                      status=IoCreateSymbolicLink(&SymLinkName,&DeviceName);
                      if(NT_SUCCESS(status))
                      {
                              DbgPrint("符号链接创建成功!
    ");
                              return status;
                      }
             }
             return status;
    }
    void  unLoadDriver(PDRIVER_OBJECT db)
    {       
             IoDeleteSymbolicLink(&SymLinkName);
             DbgPrint("符号链接删除成功!
    ");
             IoDeleteDevice(db->DeviceObject);
             DbgPrint("设备删除成功!
    ");
    }
    NTSTATUS DriverEntry(PDRIVER_OBJECT db, PUNICODE_STRING us)
    {
             NTSTATUS status;
             db->DriverUnload=unLoadDriver;
             status=MyCreateDevice(db);
             db->MajorFunction[IRP_MJ_CREATE]=MyDisPatcher;
             db->MajorFunction[IRP_MJ_CLOSE]=MyDisPatcher;
             db->MajorFunction[IRP_MJ_READ]=MyDisPatcher;
             db->MajorFunction[IRP_MJ_WRITE]=MyDisPatcher;
             db->MajorFunction[IRP_MJ_DEVICE_CONTROL]=MyDisPatcher;      
             return status;
    }
    需要创建设备,创建符号链接, 添加卸载函数,派遣函数. 在派遣函数中处理用户层数据
  • 相关阅读:
    P2590 [ZJOI2008]树的统计(树链剖分)
    P4315 月下“毛景树”(树链剖分)
    P4092 [HEOI2016/TJOI2016]树(树链剖分+倍增LCA)(直接暴力好像最快)
    P4427 [BJOI2018]求和(倍增LCA、树链剖分)
    P3128 [USACO15DEC]Max Flow P(树链剖分)
    P3038 [USACO11DEC]Grass Planting G(树链剖分)
    高精度运算模板
    利用伪元素(:after)来清除浮动和画三角形
    什么是 daemon 与服务 (service)
    数据库系统简介
  • 原文地址:https://www.cnblogs.com/freesec/p/6706467.html
Copyright © 2020-2023  润新知