驱动读写进程内存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 ...
随机推荐
- MYSQL: Cannot delete or update a parent row: a foreign key constraint fails
这可能是MySQL在InnoDB中设置了foreign key关联,造成无法更新或删除数据.可以通过设置FOREIGN_KEY_CHECKS变量来避免这种情况. SET FOREIGN_KEY_CHE ...
- Jenkins 九: 小技巧
1. 问题: jenkins的项目默认存放在 JENKINS_HOME下面的 workspace路径下,导致每次找项目都很不方便. 解决思路:更改jenkins的项目存放地址. 解决方法: 1) 将 ...
- DNA Sequence - POJ 2778(AC自动机+矩阵乘法)
题目大意:DNA序列是有 ATGC 组成的,现在知道一些动物的遗传片段有害的,那么如果给出这些有害的片段,能否求出来所有长度为 N 的基因中有多少是不包含这些有害片段的. 分析:也是断断续续做了一 ...
- 区别assign VS weak,__block VS __weak
在objective-c中,类中的全局变量经常使用如下的方式申明. @property(nonatomic(1),strong(2))UIImageView *imageView; 其中的1,2处是对 ...
- Appium移动自动化测试(一)--安装Appium(转)
Appium移动自动化测试(一)--安装Appium 2015-05-30 17:48 by 虫师, 70668 阅读, 13 评论, 收藏, 编辑 Appium 自动化测试是很早之前就想学习和研究的 ...
- webservice使用基本技巧
一,webService基本概念 webService也叫XMLWeb SerVice WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求,轻量级的独 ...
- 【教训】rm -fr ./* 教训
昨晚犯了一个重大错误,运行了 rm -rf ./* 本来是要删除一个不重要的目录的,结果在它的父目录下运行了上面命令,结果...都没了... 幸好数据库文件没有被删掉,数据还在,网站程序被删掉了,不久 ...
- Upgrade to Python 2.7.9 on CentOS5.5
1. Install python2.7 #cd /tmp #wget https://www.python.org/ftp/python/2.7.9/Python-2.7.9.tgz --no-ch ...
- Activity 【生命周期】
不同情况下的回调 我们打开应用时先后调用了onCreate()->onStart()->onResume 当我们按BACK键时,我们这个应用程序将结束,这时候我们将先后调用onPause( ...
- 【开源java游戏框架libgdx专题】-08-中文显示与绘制
libgdx虽然是由美国人Mario Zechner(即BadlogicGames)写的开源引擎,由于Libgdx底层是用OpenGL实现的,所以Libgdx是可以支持中文的,在libgdx中的汉字都 ...