博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
驱动通信:驱动与应用的通信(3)
阅读量:5118 次
发布时间:2019-06-13

本文共 20022 字,大约阅读时间需要 66 分钟。

驱动程序与应用程序的通信离不开派遣函数,派遣函数是Windows驱动编程中的重要概念,一般情况下驱动程序负责处理I/O特权请求,而大部分IO的处理请求是在派遣函数中处理的,当用户请求数据时,操作系统会提前处理好请求,并将其派遣到指定的内核函数中执行,接下来将详细说明派遣函数的使用并通过派遣函数读取Shadow SSDT中的内容。

先来简单介绍一下 IRP(I/O Request Package) 输入输出请求包,该请求包在Windows内核中是一个非常重要的数据结构,当我们的上层应用与底层的驱动程序通信时,应用程序就会发出I/O请求,操作系统将该请求转化为相应的IRP数据,然后会根据不同的请求数据将请求派遣到相应的驱动函数中执行,这一点有点类似于Windows的消息机制。

创建设备对象: 在使用派遣函数的之前需要创建设备对象,因为后期的读写都要通过设备对象来连接。

#include 
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 
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 
#include
#include
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("获取驱动句柄失败!错误: %d\n", GetLastError()); getchar(); } getchar(); CloseHandle(hDevice); return 0;}

读取驱动中的数据: 实现读取内核缓冲区中的数据,并打印出来。

#include 
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("应用要读取的长度:%d\n", 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 
#include
#include
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("获取驱动句柄失败: %d\n", 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 
#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
// 自定义的控制信号#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;}

驱动读写操作: 网上找到一个驱动读写相关的案例,看着不错这里就转过来啦,我就不自己写了。

这个驱动读写转载于:

服务端:

#pragma once#include
#include
#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
#include
#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;}

上方的代码,经过修改后可以正常完成编译链接,并读出内存数据。

1379525-20190928075815990-1927849784.png

转载于:https://www.cnblogs.com/LyShark/p/11570449.html

你可能感兴趣的文章
分布式锁的思路以及实现分析
查看>>
腾讯元对象存储之文件删除
查看>>
jdk环境变量配置
查看>>
安装 Express
查看>>
包含列的索引:SQL Server索引的阶梯级别5
查看>>
myeclipse插件安装
查看>>
浙江省第十二届省赛 Beauty of Array(思维题)
查看>>
NOIP2013 提高组 Day1
查看>>
个人对vue生命周期的理解
查看>>
cocos2dx 3.x simpleAudioEngine 长音效被众多短音效打断问题
查看>>
存储(硬件方面的一些基本术语)
查看>>
观察者模式
查看>>
Weka中数据挖掘与机器学习系列之基本概念(三)
查看>>
Win磁盘MBR转换为GUID
查看>>
大家在做.NET B/S项目的时候多用什么设技术啊?
查看>>
Java SE和Java EE应用的性能调优
查看>>
Android设计模式系列--原型模式
查看>>
免费的论文查重网站
查看>>
C语言程序第一次作业
查看>>
leetcode-Sort List
查看>>