驱动读写进程内存R3,R0通信
stdafx.h 头文件代码 #ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later.
#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
#endif #ifdef __cplusplus
extern "C"
{ #endif #include <ntddk.h>
#include <ntddstor.h>
#include <mountdev.h>
#include <ntddvol.h> #ifdef __cplusplus
}
#endif
驱动读写 C++代码 #include <ntifs.h>
#include <ntddk.h>
#include "stdafx.h" extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath); #define arraysize(p) (sizeof(p)/sizeof((p)[0]))
NTSTATUS ControlCode(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp);
NTSTATUS CreateMyDevice(IN PDRIVER_OBJECT pDriverObject);
NTSTATUS NtCreateMessage(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp);
int ReadProcessMemory(PVOID Address, SIZE_T BYTE_size, int PID);
int WriteProcessMemory(VOID* Address, SIZE_T BYTE_size, VOID *VirtualAddress, int PID);
#define READPROCESSMEMORY CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define WRITEPROCESSMEMORY CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define WRITEPROCESSMEMORY_BYTE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS) //卸载回调
void UnloadDriver(PDRIVER_OBJECT pDriverObject)
{
//用来取得要删除设备对象
PDEVICE_OBJECT pDev;
UNICODE_STRING symLinkName;
pDev = pDriverObject->DeviceObject;
//删除设备
IoDeleteDevice(pDev); //取符号链接名字
RtlInitUnicodeString(&symLinkName, L"\\??\\My_DriverLinkName");
//删除符号链接
IoDeleteSymbolicLink(&symLinkName);
KdPrint(("驱动成功卸载\n"));
} NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,PUNICODE_STRING RegistryPath)
{
//设置卸载函数
pDriverObject->DriverUnload = UnloadDriver;
//处理R3的CreateFile操作不然会失败
pDriverObject->MajorFunction[IRP_MJ_CREATE] = NtCreateMessage;
//处理R3的控制代码
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ControlCode;
//创建相应的设备
CreateMyDevice(pDriverObject);
KdPrint(("驱动成功加载\n"));
return STATUS_SUCCESS;
}
//处理控制IO代码
NTSTATUS ControlCode(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp)
{
NTSTATUS status = STATUS_SUCCESS;
KdPrint(("Enter HelloDDKDeviceIOControl\n")); //得到当前堆栈
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
//得到输入缓冲区大小
ULONG cbin = stack->Parameters.DeviceIoControl.InputBufferLength;
//得到输出缓冲区大小
ULONG cbout = stack->Parameters.DeviceIoControl.OutputBufferLength;
//得到IOCTL码
ULONG code = stack->Parameters.DeviceIoControl.IoControlCode; ULONG info = ; switch (code)
{
case READPROCESSMEMORY://读4字节整数型
{
//显示输入缓冲区数据
int PID = , Address = , BYTE_size=;
int *InputBuffer = (int*)pIrp->AssociatedIrp.SystemBuffer;
_asm
{
MOV EAX,InputBuffer
MOV EBX, DWORD PTR DS : [EAX]
MOV PID,EBX
MOV EBX, DWORD PTR DS : [EAX + ]
MOV Address,EBX
MOV EBX,DWORD PTR DS:[EAX + ]
MOV BYTE_size, EBX
}
//操作输出缓冲区
int *OutputBuffer = (int*)pIrp->AssociatedIrp.SystemBuffer;
*OutputBuffer = ReadProcessMemory((VOID*)Address, BYTE_size, PID);
//设置实际操作输出缓冲区长度
info = ;
break;
}
case WRITEPROCESSMEMORY://写4字节整数型
{
//显示输入缓冲区数据
int PID = , Address = ,buff ,BYTE_size = ;
int *InputBuffer = (int*)pIrp->AssociatedIrp.SystemBuffer;
_asm
{
MOV EAX, InputBuffer
MOV EBX, DWORD PTR DS : [EAX]
MOV PID, EBX
MOV EBX, DWORD PTR DS : [EAX + ]
MOV Address, EBX
MOV EBX, DWORD PTR DS : [EAX + ]
MOV buff, EBX
MOV EBX, DWORD PTR DS : [EAX + 0xC]
MOV BYTE_size, EBX
}
//操作输出缓冲区
int *OutputBuffer = (int*)pIrp->AssociatedIrp.SystemBuffer;
*OutputBuffer = WriteProcessMemory((VOID*)Address, BYTE_size, &buff, PID);
//设置实际操作输出缓冲区长度
info = ;
break;
}
case WRITEPROCESSMEMORY_BYTE://写字节集
{
//显示输入缓冲区数据
int PID = , Address = , buff, BYTE_size = ;
int *InputBuffer = (int*)pIrp->AssociatedIrp.SystemBuffer;
_asm
{
MOV EAX, InputBuffer
MOV EBX, DWORD PTR DS : [EAX]
MOV PID, EBX
MOV EBX, DWORD PTR DS : [EAX + ]
MOV Address, EBX
MOV EBX, DWORD PTR DS : [EAX + ]
MOV buff, EBX
MOV EBX, DWORD PTR DS : [EAX + 0xC]
MOV BYTE_size, EBX
}
//操作输出缓冲区
int *OutputBuffer = (int*)pIrp->AssociatedIrp.SystemBuffer;
*OutputBuffer = WriteProcessMemory((VOID*)Address, BYTE_size, (VOID*)buff, PID);
//设置实际操作输出缓冲区长度
info = ;
break;
}
default:
status = STATUS_INVALID_VARIANT;
}
// 完成IRP
pIrp->IoStatus.Status = status;
pIrp->IoStatus.Information = info;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status;
} typedef struct _DEVICE_EXTENSION {
PDEVICE_OBJECT pDevice;
UNICODE_STRING ustrDeviceName; //设备名称
UNICODE_STRING ustrSymLinkName; //符号链接名 PUCHAR buffer;//缓冲区
ULONG file_length;//模拟的文件长度,必须小于MAX_FILE_LENGTH
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
#pragma INITCODE /*指的代码运行后 就从内存释放掉*/
//创建符号链接
NTSTATUS CreateMyDevice(IN PDRIVER_OBJECT pDriverObject)
{
NTSTATUS status;
PDEVICE_OBJECT pDevObj;
PDEVICE_EXTENSION pDevExt; //创建设备名称
UNICODE_STRING devName;
RtlInitUnicodeString(&devName, L"\\Device\\My_DriverLinkName"); //创建设备
status = IoCreateDevice(pDriverObject,sizeof(DEVICE_EXTENSION),&devName,FILE_DEVICE_UNKNOWN,, FALSE,&pDevObj);
if (!NT_SUCCESS(status))
return status; pDevObj->Flags |= DO_DIRECT_IO;
pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
pDevExt->pDevice = pDevObj;
pDevExt->ustrDeviceName = devName; //申请模拟文件的缓冲区
pDevExt->buffer = (PUCHAR)ExAllocatePool(PagedPool, );
//设置模拟文件大小
pDevExt->file_length = ; //创建符号链接
UNICODE_STRING symLinkName;
RtlInitUnicodeString(&symLinkName, L"\\??\\My_DriverLinkName");
pDevExt->ustrSymLinkName = symLinkName;
status = IoCreateSymbolicLink(&symLinkName, &devName); if (!NT_SUCCESS(status))
{
IoDeleteDevice(pDevObj);
return status;
}
return STATUS_SUCCESS;
} //处理其他IO消息直接返回成功
#pragma PAGEDCODE
NTSTATUS NtCreateMessage(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp)
{ NTSTATUS status = STATUS_SUCCESS;
// 完成IRP
pIrp->IoStatus.Status = status;
pIrp->IoStatus.Information = ; // bytes xfered
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status;
} //读内存整数型
int ReadProcessMemory(VOID* Address, SIZE_T BYTE_size, int PID)
{
PEPROCESS pEProcess;
PVOID buff1;
VOID *buff2;
int MemoryNumerical =;
KAPC_STATE KAPC = { };
__try
{
//得到进程EPROCESS
PsLookupProcessByProcessId((HANDLE)PID, &pEProcess);
//分配内存
buff1 = ExAllocatePoolWithTag((POOL_TYPE), BYTE_size, );
buff2 = buff1;
*(int*)buff1 = ;
//附加到要读写的进程
KeStackAttachProcess((PRKPROCESS)pEProcess, &KAPC);
// 判断内存是否可读
ProbeForRead(Address, BYTE_size, );
//复制内存
memcpy(buff2, Address, BYTE_size);
// 剥离附加的进程
KeUnstackDetachProcess(&KAPC);
//读内存
MemoryNumerical = *(int*)buff2;
// 释放申请的内存
ExFreePoolWithTag(buff2, );
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
KdPrint(("错误\n"));
}
return MemoryNumerical; }
//写内存整数型
int WriteProcessMemory(VOID* Address, SIZE_T BYTE_size, VOID *VirtualAddress,int PID)
{
PEPROCESS pEProcess;
PVOID buff1;
VOID *buff2;
int MemoryNumerical = ;
KAPC_STATE KAPC = { };
__try
{
//得到进程EPROCESS
PsLookupProcessByProcessId((HANDLE)PID, &pEProcess);
//分配内存
buff1 = ExAllocatePoolWithTag((POOL_TYPE), BYTE_size, );
buff2 = buff1;
*(int*)buff1 = ;
if (MmIsAddressValid((PVOID)VirtualAddress))
{
//复制内存
memcpy(buff2, VirtualAddress, BYTE_size);
}
else
{
return ;
}
//附加到要读写的进程
KeStackAttachProcess((PRKPROCESS)pEProcess, &KAPC);
if (MmIsAddressValid((PVOID)Address))
{
//判断地址是否可写
ProbeForWrite(Address, BYTE_size, );
//复制内存
memcpy(Address, buff2, BYTE_size);
}
else
{
return ;
}
// 剥离附加的进程
KeUnstackDetachProcess(&KAPC);
ExFreePoolWithTag(buff2, );
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
KdPrint(("错误\n"));
}
return ;
}
R3通信代码 #include <stdio.h>
#include <windows.h>
#include<winioctl.h>
#define READPROCESSMEMORY CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define WRITEPROCESSMEMORY CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define WRITEPROCESSMEMORY_BYTE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)
int ReadMemory(HANDLE hDevice, int PID,int Address,int size)//读内存
{ int port[];
int bufret;
DWORD dwWrite;
port[]=PID;
port[]=Address;
port[]=size;
DeviceIoControl(hDevice,READPROCESSMEMORY, &port, , &bufret, , &dwWrite, NULL);
return bufret; } int WriteMemory_int(HANDLE hDevice, int PID,int Address,int buff,int size)//写内存整数型
{ int port[];
int bufret;
DWORD dwWrite;
port[]=PID;
port[]=Address;
port[]=buff;
port[]=size;
DeviceIoControl(hDevice,WRITEPROCESSMEMORY, &port, , &bufret, , &dwWrite, NULL);
return bufret; } int WriteMemory_byte(HANDLE hDevice, int PID,int Address,BYTE *buff,int size)//写内存字节集
{
int port[];
int bufret;
DWORD dwWrite;
port[]=PID;
port[]=Address;
port[]=(int)buff;
port[]=size;
DeviceIoControl(hDevice,WRITEPROCESSMEMORY_BYTE, &port, , &bufret, , &dwWrite, NULL);
return bufret; }
int main(int argc, char* argv[])
{
HANDLE hDevice = CreateFileW(L"\\\\.\\My_DriverLinkName", GENERIC_READ | GENERIC_WRITE,,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL );
if (hDevice == INVALID_HANDLE_VALUE)
{
printf("获取驱动失败: %s with Win32 error code: %d\n","MyDriver", GetLastError() );
getchar();
return -;
}
int PID=;
printf("输入进程ID!\n");
scanf("%d",&PID);
BYTE a[]={0x01,0x02,0x03,0x04,0x05};
int r=WriteMemory_byte(hDevice,PID,,a,);//写内存字节集
printf("0x8BDBE0=%d\n",r);
getchar();
getchar();
return ;
}
驱动读写进程内存R3,R0通信的更多相关文章
- 学习笔记:Linux下共享内存的方式实现进程间的相互通信
一.常用函数 函数系列头文件 #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> ft ...
- 一个驱动导致的内存泄漏问题的分析过程(meminfo->pmap->slabtop->alloc_calls)
关键词:sqllite.meminfo.slabinfo.alloc_calls.nand.SUnreclaim等等. 下面记录一个由于驱动导致的内存泄漏问题分析过程. 首先介绍问题背景,在一款嵌入式 ...
- c#读写共享内存操作函数封装
原文 c#读写共享内存操作函数封装 c#共享内存操作相对c++共享内存操作来说原理是一样,但是c#会显得有点复杂. 现把昨天封装的读写共享内存封装的函数记录下来,一方面希望给需要这块的有点帮助,另一方 ...
- Linux和进程内存模型
一.Linux和进程内存模型 jvm是一个进程的身份运行在linux系统上,了解linux和进程的内存关系,是理解jvm和Linux内存关系的基础. 硬件.系统.进程三个层面的内存之间的概要关系 1. ...
- Linux进程内存分析和内存泄漏定位
在Linux产品开发过程中,通常需要注意系统内存使用量,和评估单一进程的内存使用情况,便于我们选取合适的机器配置,来部署我们的产品. Linux本身提供了一些工具方便我们达成这些需求,查看进程实时资源 ...
- 转 linux进程内存到底怎么看 剖析top命令显示的VIRT RES SHR值
引 言: top命令作为Linux下最常用的性能分析工具之一,可以监控.收集进程的CPU.IO.内存使用情况.比如我们可以通过top命令获得一个进程使用了多少虚拟内存(VIRT).物理内存(RES). ...
- linux进程内存到底怎么看 剖析top命令显示的VIRT RES SHR值
引 言: top命令作为Linux下最常用的性能分析工具之一,可以监控.收集进程的CPU.IO.内存使用情况.比如我们可以通过top命令获得一个进程使用了多少虚拟内存(VIRT).物理内存(RES). ...
- [转]Linux中进程内存与cgroup内存的统计
From: http://hustcat.github.io/about/ Linux中进程内存与cgroup内存的统计 在Linux内核,对于进程的内存使用与Cgroup的内存使用统计有一些相同和不 ...
- Linux系统下输出某进程内存占用信息的c程序实现
在实际工作中有时需要程序打印出某个进程的内存占用情况以作参考, 下面介绍一种通过Linux下的伪文件系统/proc 计算某进程内存占用的程序实现方法. 首先, 为什么会有所谓的 伪文件 呢. Linu ...
随机推荐
- 关于ETL的几种运行
一:代码部分 1.新建maven项目 2.添加需要的java代码 3.书写mapper类 4.书写runner类 二:运行方式 1.本地运行 2. 3. 三:本地运行方式 1.解压hadoop到本地 ...
- Lucene的中文分词器IKAnalyzer
分词器对英文的支持是非常好的. 一般分词经过的流程: 1)切分关键词 2)去除停用词 3)把英文单词转为小写 但是老外写的分词器对中文分词一般都是单字分词,分词的效果不好. 国人林良益写的IK Ana ...
- 小学生玩ACM----深搜
Square Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Su ...
- mysql批量删除指定前缀或后缀表
今天突然发现我们数据库中多出很多表,后缀名为"copy",预计是navicat直接拷贝导致的,然后要对这些有同样后缀名的表进行删除,假设一个一个选择会非常麻烦,表计较多,在网上找了 ...
- 《Android开发艺术探索》读书笔记 (10) 第10章 Android的消息机制
第10章 Android的消息机制 10.1 Android消息机制概述 (1)Android的消息机制主要是指Handler的运行机制,其底层需要MessageQueue和Looper的支撑.Mes ...
- python之 sys.exit() os._exit() exit() quit()的简单使用
python之sys.exit() os._exit() exit() quit()的简单使用 1>sys.exit() >>> import sys>>> ...
- mysql sql语句大全(2)
1.说明:创建数据库 CREATE DATABASE database-name 2.说明:删除数据库 drop database dbname 3.说明:备份sql server --- 创建 备份 ...
- Web api 文档以及测试工具配置
第一步: 创建web api 在nuget 上搜索 webapitestclient (包含预发行版) 然后在 /Areas/HelpPage/Views/Help/Api.cshtml 末尾 添加 ...
- nodejs抓取网页内容
function loadPage(url) { var http = require('http'); var pm = new Promise(function (resolve, reject) ...
- (转)Div左右两侧等高
一. 利用背景图,做出左右等高的模拟效果 这种方法不是真正的左右等高,而是在外框元素中添加一张背景图片,当内容增多时,背景会纵向重复,就会形成左右等高的效果. 这种方法不是真正的div自动等高,而 ...