概述
驱动程序与应用程序的通信离不开派遣函数,派遣函数是Windows驱动编程中的重要概念,一般情况下驱动程序负责处理I/O特权请求,而大部分IO的处理请求是在派遣函数中处理的,当用户请求数据时,操作系统会提前处理好请求,并将其派遣到指定的内核函数中执行,接下来将详细说明派遣函数的使用并通过派遣函数读取Shadow SSDT中的内容。
先来简单介绍一下 IRP(I/O Request Package)
输入输出请求包,该请求包在Windows内核中是一个非常重要的数据结构,当我们的上层应用与底层的驱动程序通信时,应用程序就会发出I/O请求,操作系统将该请求转化为相应的IRP数据,然后会根据不同的请求数据将请求派遣到相应的驱动函数中执行,这一点有点类似于Windows的消息机制。
创建设备对象: 在使用派遣函数的之前需要创建设备对象,因为后期的读写都要通过设备对象来连接。
#include <ntddk.h>
VOID UnDriver(PDRIVER_OBJECT pDriver)
{
PDEVICE_OBJECT pDev; // 用来取得要删除设备对象
UNICODE_STRING SymLinkName; // 局部变量symLinkName
//删掉所有设备
pDev = pDriver->DeviceObject;
IoDeleteDevice(pDev); // 调用IoDeleteDevice用于删除设备
RtlInitUnicodeString(&SymLinkName, L"\??\My_Driver"); // 初始化字符串将symLinkName定义成需要删除的符号链接名称
IoDeleteSymbolicLink(&SymLinkName); // 调用IoDeleteSymbolicLink删除符号链接
DbgPrint("删除设备与符号链接成功...");
}
NTSTATUS CreateDriverObject(IN PDRIVER_OBJECT pDriver)
{
NTSTATUS Status; // 接收驱动程序的返回状态
PDEVICE_OBJECT pDevObj; // 用于返回创建设备
UNICODE_STRING DriverName; // 用于存放设备的名称
UNICODE_STRING SymLinkName; // 用于存放符号链接名称
RtlInitUnicodeString(&DriverName, L"\Device\My_Device"); // 将DrvierName填充为\Device\My_Device
// 使用命令IoCreateDevice用来创建设备,并将创建后的状态保存在status
Status = IoCreateDevice(pDriver, 0, &DriverName, FILE_DEVICE_UNKNOWN, 0, TRUE, &pDevObj);
DbgPrint("当前命令IoCreateDevice状态: %d", Status);
if (!NT_SUCCESS(Status))
{
// 调用IoCreateDevice成功与失败都会返回参数,将返回参数给Status用于判断
// STATUS_INSUFFICIENT_RESOURCES 资源不足
// STATUS_OBJECT_NAME_EXISTS 指定对象名存在
// STATUS_OBJECT_NAME_COLLISION 对象名有冲突
if (Status == STATUS_OBJECT_NAME_COLLISION)
{
DbgPrint("对象名冲突..");
}
DbgPrint("创建失败.");
}
pDevObj->Flags |= DO_BUFFERED_IO; // flags 标识有没有do_buffered_io位标识
RtlInitUnicodeString(&SymLinkName, L"\??\My_Device"); // 对symLinkName初始化字串为 "\??\My_Device"
// 创建设备链接,驱动程序虽然有设备名称,但是这种设备名只能在内核态可见
// 而对于应用程序是不可见的,因此驱动需要要暴露一个符号链接,该链接指向真正的设备名称
Status = IoCreateSymbolicLink(&SymLinkName, &DriverName); // 调用命令IoCreateSymbolicLink用于创建符号链接
DbgPrint("当前命令IoCreateSymbolicLink状态: %d", Status);
if (!NT_SUCCESS(Status)) // 如果status不等于0 就执行
{
IoDeleteDevice(pDevObj); // 调用命令IoDeleteDevice删除当前pDevObj设备
DbgPrint("删除设备成功...");
return Status;
}
else
{
DbgPrint("创建符号链接成功...");
}
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING RegistryPath)
{
CreateDriverObject(pDriver);
pDriver->DriverUnload = UnDriver;
return STATUS_SUCCESS;
}
简单的驱动通信: 注册两个派遣函数,当设备创建的时候触发,以及关闭时触发。
#include <ntddk.h>
VOID UnDriver(PDRIVER_OBJECT pDriver)
{
PDEVICE_OBJECT pDev; // 用来取得要删除设备对象
UNICODE_STRING SymLinkName; // 局部变量symLinkName
pDev = pDriver->DeviceObject;
IoDeleteDevice(pDev); // 调用IoDeleteDevice用于删除设备
RtlInitUnicodeString(&SymLinkName, L"\??\My_Driver"); // 初始化字符串将symLinkName定义成需要删除的符号链接名称
IoDeleteSymbolicLink(&SymLinkName); // 调用IoDeleteSymbolicLink删除符号链接
DbgPrint("删除设备与符号链接成功...");
}
NTSTATUS DispatchCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
pIrp->IoStatus.Status = STATUS_SUCCESS; // 返回成功
DbgPrint("派遣函数 IRP_MJ_CREATE 成功执行 !n");
IoCompleteRequest(pIrp, IO_NO_INCREMENT); // 指示完成此IRP
return STATUS_SUCCESS; // 返回成功
}
NTSTATUS DispatchClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
pIrp->IoStatus.Status = STATUS_SUCCESS; // 返回成功
DbgPrint("派遣函数 IRP_MJ_CLOSE 成功执行 !n");
IoCompleteRequest(pIrp, IO_NO_INCREMENT); // 指示完成此IRP
return STATUS_SUCCESS; // 返回成功
}
NTSTATUS CreateDriverObject(IN PDRIVER_OBJECT pDriver)
{
NTSTATUS Status;
PDEVICE_OBJECT pDevObj;
UNICODE_STRING DriverName;
UNICODE_STRING SymLinkName;
RtlInitUnicodeString(&DriverName, L"\Device\My_Device");
Status = IoCreateDevice(pDriver, 0, &DriverName, FILE_DEVICE_UNKNOWN, 0, TRUE, &pDevObj);
DbgPrint("命令 IoCreateDevice 状态: %d", Status);
// DO_BUFFERED_IO 设置读写方式 Flags的三个不同的值分别为:DO_BUFFERED_IO、DO_DIRECT_IO和0
pDevObj->Flags |= DO_BUFFERED_IO;
RtlInitUnicodeString(&SymLinkName, L"\??\My_Device");
Status = IoCreateSymbolicLink(&SymLinkName, &DriverName);
DbgPrint("当前命令IoCreateSymbolicLink状态: %d", Status);
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING RegistryPath)
{
CreateDriverObject(pDriver); // 调用创建设备子过程
// 注册两个派遣函数,分别对应创建与关闭,派遣函数名可自定义
pDriver->MajorFunction[IRP_MJ_CREATE] = DispatchCreate; // 创建成功派遣函数
pDriver->MajorFunction[IRP_MJ_CLOSE] = DispatchClose; // 关闭派遣函数
DbgPrint("驱动加载完成...");
pDriver->DriverUnload = UnDriver;
return STATUS_SUCCESS;
}
客户端代码
#include <windows.h>
#include <stdio.h>
#include <winioctl.h>
int main()
{
HANDLE hDevice = CreateFile(L"\\.\My_Device", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hDevice == INVALID_HANDLE_VALUE) //判断hDevice返回值是否为空
{
printf("获取驱动句柄失败!错误: %dn", GetLastError());
getchar();
}
getchar();
CloseHandle(hDevice);
return 0;
}
读取驱动中的数据: 实现读取内核缓冲区中的数据,并打印出来。
#include <ntddk.h>
VOID UnDriver(PDRIVER_OBJECT pDriver)
{
PDEVICE_OBJECT pDev; // 用来取得要删除设备对象
UNICODE_STRING SymLinkName; // 局部变量symLinkName
pDev = pDriver->DeviceObject;
IoDeleteDevice(pDev); // 调用IoDeleteDevice用于删除设备
RtlInitUnicodeString(&SymLinkName, L"\??\My_Driver"); // 初始化字符串将symLinkName定义成需要删除的符号链接名称
IoDeleteSymbolicLink(&SymLinkName); // 调用IoDeleteSymbolicLink删除符号链接
DbgPrint("删除设备与符号链接成功...");
}
NTSTATUS DispatchCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
pIrp->IoStatus.Status = STATUS_SUCCESS; // 返回成功
DbgPrint("派遣函数 IRP_MJ_CREATE 成功执行 !n");
IoCompleteRequest(pIrp, IO_NO_INCREMENT); // 指示完成此IRP
return STATUS_SUCCESS; // 返回成功
}
NTSTATUS DispatchClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
pIrp->IoStatus.Status = STATUS_SUCCESS; // 返回成功
DbgPrint("派遣函数 IRP_MJ_CLOSE 成功执行 !n");
IoCompleteRequest(pIrp, IO_NO_INCREMENT); // 指示完成此IRP
return STATUS_SUCCESS; // 返回成功
}
NTSTATUS DispatchRead(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
NTSTATUS Status = STATUS_SUCCESS;
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(pIrp);
ULONG ulReadLength = Stack->Parameters.Read.Length;
pIrp->IoStatus.Status = Status;
pIrp->IoStatus.Information = ulReadLength;
DbgPrint("应用要读取的长度:%dn", ulReadLength);
// 将内核中的缓冲区全部填充为0x68 方便演示读取的效果
memset(pIrp->AssociatedIrp.SystemBuffer, 0x68, ulReadLength);
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return Status;
}
NTSTATUS CreateDriverObject(IN PDRIVER_OBJECT pDriver)
{
NTSTATUS Status;
PDEVICE_OBJECT pDevObj;
UNICODE_STRING DriverName;
UNICODE_STRING SymLinkName;
RtlInitUnicodeString(&DriverName, L"\Device\My_Device");
Status = IoCreateDevice(pDriver, 0, &DriverName, FILE_DEVICE_UNKNOWN, 0, TRUE, &pDevObj);
DbgPrint("命令 IoCreateDevice 状态: %d", Status);
pDevObj->Flags |= DO_BUFFERED_IO;
RtlInitUnicodeString(&SymLinkName, L"\??\My_Device");
Status = IoCreateSymbolicLink(&SymLinkName, &DriverName);
DbgPrint("当前命令IoCreateSymbolicLink状态: %d", Status);
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING RegistryPath)
{
CreateDriverObject(pDriver); // 调用创建设备
pDriver->MajorFunction[IRP_MJ_CREATE] = DispatchCreate; // 创建成功派遣函数
pDriver->MajorFunction[IRP_MJ_CLOSE] = DispatchClose; // 关闭派遣函数
pDriver->MajorFunction[IRP_MJ_READ] = DispatchRead;
DbgPrint("驱动加载完成...");
pDriver->DriverUnload = UnDriver;
return STATUS_SUCCESS;
}
客户端代码
#include <windows.h>
#include <stdio.h>
#include <winioctl.h>
int main()
{
HANDLE hDevice = CreateFile(L"\\.\My_Device", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hDevice == INVALID_HANDLE_VALUE)
{
printf("获取驱动句柄失败: %dn", GetLastError());
getchar();
}
UCHAR buffer[10];
ULONG ulRead;
ReadFile(hDevice, buffer, 10, &ulRead, 0);
for (int i = 0; i < (int)ulRead; i++)
{
printf("%02X", buffer[i]);
}
getchar();
CloseHandle(hDevice);
return 0;
}
向驱动派发命令: 向驱动程序中发送一个结构,驱动程序内部通过DbgPrint打印出来。
#include <ntddk.h>
#define My_Code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS)
typedef struct Hread {
ULONG Flage;
ULONG Addr;
ULONG WriteBufferAddr;
ULONG Size;
ULONG Pid;
}_Hread, *PtrHread;
typedef struct _DEVICE_EXTENSION {
UNICODE_STRING SymLinkName;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{
PDEVICE_OBJECT pDevObj;
pDevObj = pDriverObject->DeviceObject;
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
UNICODE_STRING pLinkName = pDevExt->SymLinkName;
IoDeleteSymbolicLink(&pLinkName);
IoDeleteDevice(pDevObj);
}
NTSTATUS DefDispatchRoutine(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
NTSTATUS status = STATUS_SUCCESS;
pIrp->IoStatus.Status = status;
pIrp->IoStatus.Information = 0;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status;
}
NTSTATUS IoctlDispatchRoutine(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
NTSTATUS Status = STATUS_UNSUCCESSFUL;
ULONG_PTR Informaiton = 0;
PVOID InputData = NULL;
ULONG InputDataLength = 0;
PVOID OutputData = NULL;
ULONG OutputDataLength = 0;
PIO_STACK_LOCATION IoStackLocation = IoGetCurrentIrpStackLocation(pIrp); // Irp堆栈
InputData = pIrp->AssociatedIrp.SystemBuffer;
OutputData = pIrp->AssociatedIrp.SystemBuffer;
InputDataLength = IoStackLocation->Parameters.DeviceIoControl.InputBufferLength; // 输入数据大小
OutputDataLength = IoStackLocation->Parameters.DeviceIoControl.OutputBufferLength; // 输出数据大小
ULONG Code = IoStackLocation->Parameters.DeviceIoControl.IoControlCode;
switch (Code)
{
case My_Code:
PtrHread PtrBuff = (PtrHread)InputData;
ULONG RetFlage = PtrBuff->Flage;
ULONG RetAddr = PtrBuff->Addr;
ULONG RetBufferAddr = PtrBuff->WriteBufferAddr;
ULONG Size = PtrBuff->Size;
ULONG Pid = PtrBuff->Pid;
DbgPrint("读取文件标志:%d", RetFlage);
DbgPrint("读取写入地址:%x", RetAddr);
DbgPrint("读取缓冲区大小:%d", RetBufferAddr);
DbgPrint("读取当前大小:%d", Size);
DbgPrint("要操作进程PID: %d", Pid);
// 通过内存返回数据.
char *retBuffer = "hello lyshark";
memcpy(OutputData, retBuffer , strlen(retBuffer));
Informaiton = strlen(retBuffer) + 1;
Status = STATUS_SUCCESS;
// 通过内存返回数据,另一种通信方式.
PVOID addr = (PVOID)"ok";
RtlCopyMemory(OutputData, addr, 4);
Informaiton = 4;
Status = STATUS_SUCCESS;
break;
}
pIrp->IoStatus.Status = Status; // 设置IRP完成状态,会设置用户模式下的GetLastError
pIrp->IoStatus.Information = Informaiton; // 设置操作的字节
IoCompleteRequest(pIrp, IO_NO_INCREMENT); // 完成IRP,不增加优先级
return Status;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath)
{
pDriverObject->DriverUnload = DriverUnload;//注册驱动卸载函数
pDriverObject->MajorFunction[IRP_MJ_CREATE] = DefDispatchRoutine; // 注册派遣函数
pDriverObject->MajorFunction[IRP_MJ_CLOSE] = DefDispatchRoutine;
pDriverObject->MajorFunction[IRP_MJ_WRITE] = DefDispatchRoutine;
pDriverObject->MajorFunction[IRP_MJ_READ] = DefDispatchRoutine;
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IoctlDispatchRoutine;
NTSTATUS status;
PDEVICE_OBJECT pDevObj;
PDEVICE_EXTENSION pDevExt;
//创建设备名称的字符串
UNICODE_STRING devName;
RtlInitUnicodeString(&devName, L"\Device\MyDevice");
//创建设备
status = IoCreateDevice(pDriverObject, sizeof(DEVICE_EXTENSION), &devName, FILE_DEVICE_UNKNOWN, 0, TRUE, &pDevObj);
pDevObj->Flags |= DO_BUFFERED_IO;//将设备设置为缓冲I/O设备
pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;//得到设备扩展
//创建符号链接
UNICODE_STRING symLinkName;
RtlInitUnicodeString(&symLinkName, L"\??\MyDevice");
pDevExt->SymLinkName = symLinkName;
status = IoCreateSymbolicLink(&symLinkName, &devName);
return STATUS_SUCCESS;
}
客户端
#include "stdafx.h"
#include<Windows.h>
// 自定义的控制信号
#define My_Code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS)
typedef struct Hread {
ULONG Flage;
ULONG Addr;
ULONG WriteBufferAddr;
ULONG Size;
ULONG Pid;
}_Hread, *PtrHread;
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE handle = CreateFileA("\\.\MyDevice", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
unsigned char RetBufferData[20] = { 0 };
DWORD ReturnLength = 4;
_Hread buf;
buf.Flage = 2;
buf.Addr = 0x401234;
buf.WriteBufferAddr = 1024;
buf.Size = 100;
buf.Pid = 2566;
DeviceIoControl(handle, My_Code, &buf, 20, (LPVOID)RetBufferData, 4, &ReturnLength, 0);
printf("返回的数据: %s", RetBufferData);
getchar();
CloseHandle(handle);
return 0;
}
驱动读写操作: 网上找到一个驱动读写相关的案例,看着不错这里就转过来啦,我就不自己写了。
这个驱动读写转载于:吾无法无天的博客_CSDN博客-Windows内核研究,好玩的技术,VT(CPU虚拟化技术)领域博主
服务端:
#pragma once
#include<ntifs.h>
#include<windef.h>
#define READCODE CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ALL_ACCESS)
#define WRITECODE CTL_CODE(FILE_DEVICE_UNKNOWN,0x801,METHOD_BUFFERED,FILE_ALL_ACCESS)
#define DEVICENAME L"\Device\ReadWriteDevice"
#define SYMBOLNAME L"\??\ReadWriteSymbolName"
typedef struct DATA
{
DWORD pid;//要读写的进程ID
unsigned __int64 address;//要读写的地址
DWORD size;//读写长度
BYTE* data;//要读写的数据,
}Data;
void DriverUnload(PDRIVER_OBJECT driver)
{
if (driver->DeviceObject)
{
UNICODE_STRING SymbolName;
RtlInitUnicodeString(&SymbolName, SYMBOLNAME);
IoDeleteSymbolicLink(&SymbolName);
IoDeleteDevice(driver->DeviceObject);
}
DbgPrint("驱动已卸载");
}
NTSTATUS CreateDevice(PDRIVER_OBJECT driver)
{
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_OBJECT device = NULL;
UNICODE_STRING DeviceName;
RtlInitUnicodeString(&DeviceName, DEVICENAME);
status = IoCreateDevice(
driver,
sizeof(driver->DriverExtension),
&DeviceName,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&device
);
if (status == STATUS_SUCCESS)
{
UNICODE_STRING SymbolName;
RtlInitUnicodeString(&SymbolName, SYMBOLNAME);
status = IoCreateSymbolicLink(&SymbolName, &DeviceName);
if (status != STATUS_SUCCESS)
{
DbgPrint("创建符号链接失败");
IoDeleteDevice(device);
}
}
DbgPrint("驱动设备已创建");
return status;
}
BOOL ReadMemory(Data* data)
{
BOOL bRet = TRUE;
PEPROCESS process = NULL;
PsLookupProcessByProcessId(data->pid, &process);
if (process == NULL)
{
DbgPrint("获取进程对象失败");
return FALSE;
}
BYTE* GetData;
__try
{
GetData = ExAllocatePool(PagedPool, data->size);
}
__except (1)
{
DbgPrint("内存分配失败");
return FALSE;
}
KAPC_STATE stack = { 0 };
KeStackAttachProcess(process, &stack);
__try
{
ProbeForRead(data->address, data->size, 1);
RtlCopyMemory(GetData, data->address, data->size);
}
__except (1)
{
DbgPrint("读取内存出错");
bRet = FALSE;
}
ObDereferenceObject(process);
KeUnstackDetachProcess(&stack);
RtlCopyMemory(data->data, GetData, data->size);
ExFreePool(GetData);
return bRet;
}
BOOL WriteMemory(Data* data)
{
BOOL bRet = TRUE;
PEPROCESS process = NULL;
PsLookupProcessByProcessId(data->pid, &process);
if (process == NULL)
{
DbgPrint("获取进程对象失败");
return FALSE;
}
//在进入进程地址空间之前先赋值
BYTE* GetData;
__try
{
GetData = ExAllocatePool(PagedPool, data->size);
}
__except (1)
{
DbgPrint("内存分配失败");
return FALSE;
}
for (int i = 0; i < data->size; i++)
{
GetData[i] = data->data[i];
}
KAPC_STATE stack = { 0 };
KeStackAttachProcess(process, &stack);
PMDL mdl = IoAllocateMdl(data->address, data->size, 0, 0, NULL);
if (mdl == NULL)
{
DbgPrint("创建MDL失败");
return FALSE;
}
MmBuildMdlForNonPagedPool(mdl);
BYTE* ChangeData = NULL;
__try
{
ChangeData = MmMapLockedPages(mdl, KernelMode);
RtlCopyMemory(ChangeData, GetData, data->size);
}
__except (1)
{
DbgPrint("内存映射失败,%d", sizeof(ChangeData));
bRet = FALSE;
goto END;
}
END:
IoFreeMdl(mdl);
ExFreePool(GetData);
KeUnstackDetachProcess(&stack);
ObDereferenceObject(process);
return bRet;
}
NTSTATUS DriverIrpCtl(PDEVICE_OBJECT device, PIRP pirp)
{
PIO_STACK_LOCATION stack;
stack = IoGetCurrentIrpStackLocation(pirp);
Data* data;
switch (stack->MajorFunction)
{
case IRP_MJ_CREATE:
{
DbgPrint("设备已打开");
break;
}
case IRP_MJ_CLOSE:
{
DbgPrint("设备已关闭");
break;
}
case IRP_MJ_DEVICE_CONTROL:
{
data = pirp->AssociatedIrp.SystemBuffer;
DbgPrint("PID:%d 地址:%x 大小:%d", data->pid, data->address, data->size);
switch (stack->Parameters.DeviceIoControl.IoControlCode)
{
case READCODE:
{
ReadMemory(data);
break;
}
case WRITECODE:
{
WriteMemory(data);
break;
}
}
pirp->IoStatus.Information = sizeof(data);
break;
}
}
pirp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(pirp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING path)
{
DbgPrint("驱动已加载,路径:%wZ", path);
driver->DriverUnload = DriverUnload;
CreateDevice(driver);
driver->MajorFunction[IRP_MJ_CREATE] = DriverIrpCtl;
driver->MajorFunction[IRP_MJ_CLOSE] = DriverIrpCtl;
driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DriverIrpCtl;
return STATUS_SUCCESS;
}
客户端:
#include "stdafx.h"
#include<Windows.h>
#include <string.h>
#define READCODE CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ALL_ACCESS)
#define WRITECODE CTL_CODE(FILE_DEVICE_UNKNOWN,0x801,METHOD_BUFFERED,FILE_ALL_ACCESS)
typedef struct DATA
{
DWORD pid;//要读写的进程ID
unsigned __int64 address;//要读写的地址
DWORD size;//读写长度
BYTE* data;//要读写的数据,
}Data;
/* 驱动内存写入,如下
Data data;
data.pid = GetDlgItemInt(IDC_EDIT_PID);
data.address = GetDlgItemInt(IDC_EDIT_address);
data.size = GetDlgItemInt(IDC_EDIT_Size);
data.data = new BYTE[data.size];
for (int i = 0; i < data.size; i++)
{
data.data[i] = 90909090; // 写入Nop指令
}
DWORD dwSize = 0;
DeviceIoControl(DeviceHandle,WRITECODE,&data,sizeof(data),&data,sizeof(data),&dwSize,NULL);
delete[] data.data;
*/
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE handle = CreateFileA("\??\ReadWriteSymbolName", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
Data data;
DWORD dwSize = 0;
data.pid = 908;
data.address = 4198400;
data.size = 4;
data.data = new BYTE[data.size];
DeviceIoControl(handle, READCODE, &data, sizeof(data), &data, sizeof(data), &dwSize, NULL);
for (int i = 0; i < data.size; i++)
{
printf("%x", data.data[i]);
}
getchar();
CloseHandle(handle);
return 0;
}
上方的代码,经过修改后可以正常完成编译链接,并读出内存数据。
最后
以上就是壮观宝贝为你收集整理的驱动通信:驱动与应用的通信的全部内容,希望文章能够帮你解决驱动通信:驱动与应用的通信所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复