五种常用的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\n");
         if (hDevice == INVALID_HANDLE_VALUE)
         {
                  printf("获取驱动句柄失败: %s with Win32 error code: %d\n","MyDriver", GetLastError() );
                  getchar();
                  return -1;
         }
         //add_code
         int a=55;
         int b=33;
         int r= add(hDevice,a,b);
         printf("%d+%d=%d\n",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("进入派遣函数\n");
         if (dev!=myDevice)
         {
                  status=0;
                  return status;
         }
         switch(irp_stack->MajorFunction)
         {
         case IRP_MJ_DEVICE_CONTROL:
                  DbgPrint("IRP_MJ_DEVICE_CONTROL!!!!!!!!!!!!!!!!!!!!!!\n");
                  //得到输入缓冲区大小
                  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!!!!!!!!!!!!!!!!!\n");
                          *outputBuffer=inputBuffer[0]+inputBuffer[1];
                          KdPrint((("计算结果为:%d\n"),*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(("离开派遣函数\n"));//调试信息
         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("设备创建成功!\n");
                  status=IoCreateSymbolicLink(&SymLinkName,&DeviceName);
                  if(NT_SUCCESS(status))
                  {
                          DbgPrint("符号链接创建成功!\n");
                          return status;
                  }
         }
         return status;
}
void  unLoadDriver(PDRIVER_OBJECT db)
{       
         IoDeleteSymbolicLink(&SymLinkName);
         DbgPrint("符号链接删除成功!\n");
         IoDeleteDevice(db->DeviceObject);
         DbgPrint("设备删除成功!\n");
}
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;
}
需要创建设备,创建符号链接, 添加卸载函数,派遣函数. 在派遣函数中处理用户层数据