【驱动系列】最简单的X64驱动

[复制链接]
查看: 160   回复: 0

45

主题

45

帖子

356

积分

超级版主

Rank: 8Rank: 8

积分
356
发表于 2021-7-1 09:27:49 | 显示全部楼层 |阅读模式
本帖最后由 飞郁乄九州寒 于 2021-7-1 10:08 编辑

PE结构图:
PE结构图_1.jpg

在游戏外挂和反外挂的对抗中
驱动有其重要的作用
但是随着Windows 系统的升级  很多东西出现了局限性,不过我们还是需要了解学习一下
其最基础的知识

创建驱动设备对象的符号链接
//环境设置:
//属性页->C / C++->警告等级 : 等级3 / W3
//属性页->C / C++->将警告视为错误 : 否 / WX -
//属性页->Inf2Cat->Run Inf2Cat : 否
//属性页->Driver Settings->Target Os Version : 设置版本 Windows 7 Windows 10任选
//属性页->Driver Settings->Target PlatForm : Desktop
//属性页->StampInf->Endable ArchiteCture : 否


  1. //KdPrint类似于 控制台的printf
  2. //DriverEntry类似于 C / C++里的main
  3. #include <ntifs.h>

  4. #pragma code_seg("PAGE")
  5. //创建驱动设备对象
  6. NTSTATUS CreateDevice(PDRIVER_OBJECT driver)
  7. {
  8.         NTSTATUS status;
  9.         UNICODE_STRING uzDriverName;
  10.         PDEVICE_OBJECT device;
  11.         RtlInitUnicodeString(&uzDriverName, L"\\DEVICE\\uzDriverName001");
  12.         //创建驱动设备
  13.         status = IoCreateDevice(driver, sizeof(driver->DriverExtension), &uzDriverName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &device);


  14.         if (status == STATUS_SUCCESS)
  15.         {
  16.                 KdPrint(("yjx:驱动设备对象 %wZ 创建成功,OK -----------\n", &uzDriverName));
  17.                 //为设备对象绑定一个符号链接
  18.                 UNICODE_STRING uzSymbolName; //符号链接名字                 
  19.                 RtlInitUnicodeString(&uzSymbolName, L"\\??\\uzDriverName001"); //CreateFile
  20.                 status = IoCreateSymbolicLink(&uzSymbolName, &uzDriverName);
  21.                 if (status==STATUS_SUCCESS)
  22.                 {
  23.                         KdPrint(("yjx:创建符号链接 %wZ 成功 ", &uzSymbolName));
  24.                 }
  25.                 else
  26.                 {
  27.                         KdPrint(("yjx:创建符号链接 %wZ 失败 ", &uzSymbolName));
  28.                 }
  29.         }
  30.         else
  31.         {

  32.                 KdPrint(("yjx:驱动设备对象 %wZ 创建失败,准备删除Device -----------\n", &uzDriverName));
  33.                 IoDeleteDevice(device);
  34.         }
  35.         return status;
  36. }
  37. //驱动卸载例程
  38. void UnLoad(PDRIVER_OBJECT driver)
  39. {
  40.         NTSTATUS status = 0;
  41.         IoDeleteDevice(driver->DeviceObject); //删除设备对象,如果此处不删除 卸载不干净 再次用IoCreateDevice创建同名驱动 会蓝屏
  42.         //删除符号链接
  43.         UNICODE_STRING uzSymbolName; //符号链接名字
  44.         RtlInitUnicodeString(&uzSymbolName, L"\\??\\uzDriverName001");
  45.         status=IoDeleteSymbolicLink(&uzSymbolName);
  46.         if (!status) //if(status == STATUS_SUCCESS)
  47.         {
  48.                 KdPrint(("yjx:删除符号链接 %wZ 成功 ",&uzSymbolName));
  49.         }
  50.         else
  51.         {
  52.                 KdPrint(("yjx:删除符号链接 %wZ 失败 ", &uzSymbolName));
  53.         }
  54.         KdPrint(("yjx:驱动卸载成功\n"));
  55. }

  56. NTSTATUS DriverEntry(PDRIVER_OBJECT driver,PVOID szReg) //main
  57. {
  58.         KdPrint(("yjx:进入了我们的驱动 \n")); //printf
  59.         driver->DriverUnload = UnLoad;
  60.         NTSTATUS status=CreateDevice(driver);//创建了设备对象

  61.         return STATUS_SUCCESS;
  62. }



  63. IRP 派遣函数


  64. driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceIrpCtl;//DeviceIoControl
  65. driver->MajorFunction[IRP_MJ_CREATE] = DeviceIrpCtl; //CreateFile
  66. driver->MajorFunction[IRP_MJ_CLOSE] = DeviceIrpCtl;//卸载驱动 CloseHandle


  67. NTSTATUS DeviceIrpCtl(PDEVICE_OBJECT device,PIRP pirp)
  68. {
  69.         KdPrint(("yjx:进入派遣函数"));
  70.         PIO_STACK_LOCATION irpStackL;
  71.         ULONG CtlCode;
  72.         ULONG InputBuffLength;


  73.         irpStackL=IoGetCurrentIrpStackLocation(pirp); //获取应用层传来的参数

  74.         switch(irpStackL->MajorFunction)
  75.          {
  76.           IRP_MJ_DEVICE_CONTROL;
  77.           IRP_MJ_CREATE;
  78.           IRP_MJ_CLOSE;
  79.          }

  80.         pirp->IoStatus.Status = STATUS_SUCCESS;
  81.         pirp->IoStatus.Information = 4;//返回给DeviceIoControl中的 倒数第二个参数lpBytesReturned
  82.         IoCompleteRequest(pirp, IO_NO_INCREMENT);//调用方已完成所有I/O请求处理操作 并且不增加优先级
  83.         KdPrint(("yjx:离开派遣函数"));
  84.         return STATUS_SUCCESS;
  85. }



  86. //打开驱动设备
  87. void CIoControlIrpDlg::OnBnClickedCreate()
  88. {
  89.         // TODO: 在此添加控件通知处理程序代码
  90.         DeviceHandle = CreateFileW(
  91.                 L"\\??\\uzDriverName001",
  92.                 GENERIC_READ | GENERIC_WRITE,
  93.                 FILE_SHARE_READ | FILE_SHARE_WRITE,
  94.                 NULL,
  95.                 OPEN_EXISTING,
  96.                 FILE_ATTRIBUTE_NORMAL,
  97.                 NULL);

  98. }


  99. void CIoControlIrpDlg::OnBnClickedButtonClose()
  100. {
  101.         // TODO: 在此添加控件通知处理程序代码
  102.         if (DeviceHandle)
  103.         {
  104.                 CloseHandle(DeviceHandle);
  105.                 DeviceHandle = NULL;
  106.         }
  107. }


  108. R3应用层与R0驱动层简单通信

  109. #define IO_IS_OK_TEST   CTL_CODE(FILE_DEVICE_UNKNOWN,         0x803,         METHOD_BUFFERED,FILE_ANY_ACCESS) //测试

  110. //WriteFile ReadFile
  111. BOOL DeviceIoControl(
  112.   HANDLE hDevice,              // 设备驱动的句柄 由CreateFile获取
  113.   DWORD dwIoControlCode,       // 操作控制码
  114.   LPVOID lpInBuffer,           // 输入缓冲区指针 要传入驱动的 参数
  115.   DWORD nInBufferSize,         // 输入缓冲区大小
  116.   LPVOID lpOutBuffer,          // 输出缓冲区指针
  117.   DWORD nOutBufferSize,        // 输出缓冲区大小
  118.   LPDWORD lpBytesReturned,     // 存放返回的字节数的指针
  119.   LPOVERLAPPED lpOverlapped    // 异步结构指针,同步或者异步
  120. );


  121. BOOL  WINAPI IoControlIsOK()
  122. {
  123.         DWORD nTypeCode = IO_IS_OK_TEST;
  124.         ULONG64 BufferInData = 0;;
  125.         DWORD NumberOfBytesRead = 0;
  126.         BOOL IsOK = DeviceIoControl(
  127.                 GetDeviceHandle(), //CreateFile函数打开的设备句柄
  128.                 nTypeCode,//自定义的控制码
  129.                 &BufferInData,//输入缓冲区
  130.                 sizeof(BufferInData),//输入缓冲区大小
  131.                 &BufferInData,////输出缓冲区
  132.                 sizeof(BufferInData),//输出缓冲区的大小
  133.                 &NumberOfBytesRead,//实际返回的字节数,对应驱动程序中pIrp->IoStatus.Information。
  134.                 NULL); ////重叠操作结构指针。同步设为NULL,DeviceIoControl将进行阻塞调用;否则,应在编程时按异步操作设计
  135.         DbgPrintA("yjx:IsOK=%d,NumberOfBytesRead=%d  BufferInData=%d", IsOK, NumberOfBytesRead, BufferInData);
  136.         return NumberOfBytesRead;
  137. }

  138. #include
  139. #define IO_IS_OK_TEST   CTL_CODE(FILE_DEVICE_UNKNOWN,         0x803,         METHOD_BUFFERED,FILE_ANY_ACCESS) //测试
  140. void CMFCIRPCTRLDlg::OnBnClickedButtonIoCtl()
  141. {
  142.         // TODO: 在此添加控件通知处理程序代码
  143.         INT64 InBuf[3] = { 0x123456,0x123456789ABCDEF,0x888888ABC }; //输入缓冲区
  144.         INT64 OutBuf[6] = { 0 };
  145.         DWORD dwSize = 0;
  146.         DeviceIoControl(
  147.                 DeviceHandle,
  148.                 IO_IS_OK_TEST,
  149.                 InBuf,//输入缓冲区指针
  150.                 sizeof(InBuf),//2*8,//输入缓冲区大小
  151.                 OutBuf,//输出缓冲区
  152.                 sizeof(OutBuf), //输出缓冲区大小 6*8 =48
  153.                 &dwSize,//返回 字节数 pIrp->IoStatus.Information //IRP.IOStatus.InforMation
  154.                 NULL //同步异步
  155.         );
  156.         CString csStr;
  157.         csStr.Format(L"yjx:EXE:%llx,%llx,%llx,%llx,%llx,%llx dwSize=%llx .....OK\n", OutBuf[0], OutBuf[1], OutBuf[2], OutBuf[3], OutBuf[4], OutBuf[5], dwSize);
  158.         OutputDebugStringW(csStr);
  159. }


  160. //驱动层 获取用户层参数
  161. Irp->AssociatedIrp.SystemBuffer;
  162. driver->Flags |= DO_BUFFERED_IO; //IO访问方式  重要 对应 METHOD_BUFFERED
  163.         inBufLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
  164.         outBufLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
  165.         ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;

复制代码




来亦何哀, 去亦何苦?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Powered by Discuz! X3.4 © 2001-2018 Comsenz Inc.