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通信的更多相关文章

  1. 学习笔记:Linux下共享内存的方式实现进程间的相互通信

    一.常用函数 函数系列头文件 #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> ft ...

  2. 一个驱动导致的内存泄漏问题的分析过程(meminfo->pmap->slabtop->alloc_calls)

    关键词:sqllite.meminfo.slabinfo.alloc_calls.nand.SUnreclaim等等. 下面记录一个由于驱动导致的内存泄漏问题分析过程. 首先介绍问题背景,在一款嵌入式 ...

  3. c#读写共享内存操作函数封装

    原文 c#读写共享内存操作函数封装 c#共享内存操作相对c++共享内存操作来说原理是一样,但是c#会显得有点复杂. 现把昨天封装的读写共享内存封装的函数记录下来,一方面希望给需要这块的有点帮助,另一方 ...

  4. Linux和进程内存模型

    一.Linux和进程内存模型 jvm是一个进程的身份运行在linux系统上,了解linux和进程的内存关系,是理解jvm和Linux内存关系的基础. 硬件.系统.进程三个层面的内存之间的概要关系 1. ...

  5. Linux进程内存分析和内存泄漏定位

    在Linux产品开发过程中,通常需要注意系统内存使用量,和评估单一进程的内存使用情况,便于我们选取合适的机器配置,来部署我们的产品. Linux本身提供了一些工具方便我们达成这些需求,查看进程实时资源 ...

  6. 转 linux进程内存到底怎么看 剖析top命令显示的VIRT RES SHR值

    引 言: top命令作为Linux下最常用的性能分析工具之一,可以监控.收集进程的CPU.IO.内存使用情况.比如我们可以通过top命令获得一个进程使用了多少虚拟内存(VIRT).物理内存(RES). ...

  7. linux进程内存到底怎么看 剖析top命令显示的VIRT RES SHR值

    引 言: top命令作为Linux下最常用的性能分析工具之一,可以监控.收集进程的CPU.IO.内存使用情况.比如我们可以通过top命令获得一个进程使用了多少虚拟内存(VIRT).物理内存(RES). ...

  8. [转]Linux中进程内存与cgroup内存的统计

    From: http://hustcat.github.io/about/ Linux中进程内存与cgroup内存的统计 在Linux内核,对于进程的内存使用与Cgroup的内存使用统计有一些相同和不 ...

  9. Linux系统下输出某进程内存占用信息的c程序实现

    在实际工作中有时需要程序打印出某个进程的内存占用情况以作参考, 下面介绍一种通过Linux下的伪文件系统/proc 计算某进程内存占用的程序实现方法. 首先, 为什么会有所谓的 伪文件 呢. Linu ...

随机推荐

  1. cf602B Approximating a Constant Range

    B. Approximating a Constant Range time limit per test 2 seconds memory limit per test 256 megabytes ...

  2. 「书评」SAP内存计算——HANA

    因为工作关系,长期跟SAP打交道,所以去年就对HANA有了一些了解,只是公司目前的应用规模还较小,暂时没有上马HANA的打算,但是提前作一些学习还是很有必要的.正好清华大学出版社最近出版了这本< ...

  3. Apache Kylin

    日前,eBay公司隆重宣布已经正式向开源业界推出分布式分析引擎:Kylin(http://kylin.io).作为一套旨在对Hadoop环境下分析流程进行加速.且能够与SQL兼容性工具顺利协作的解决方 ...

  4. 3rd day

    今天学习创建了几个简单的表:

  5. 字符集转换 字符类型转换 utf-8 gb2312 url

    vs默认是GB2312编码,你看到的程序源代码是,输出结果是,内部存储是, 1 如果你想改变内部存储可以用下面的这些函数 2 如果你想改变源代码的存储方式你可以用文本编辑工具修改之后重新编译 3 如果 ...

  6. 杠杠做的全屏随鼠标滚动显示图片,类似于PPT效果

    图片有22张,是一张张加载的,耐心点,鼠标一直尝试向下滚就行了. 图片来自<天空之境:乌尤尼盐沼>,一个好美好美的地方 引个流,欢迎去我的博客看看:http://blog.cxycs.co ...

  7. Haskell 差点儿无痛苦上手指南

    趁着自己重装Linux 虚拟机的机会,把安装 haskell 的过程记录一下,顺便帮那些还犹豫徘徊在haskell门外的读者入门. 基本概念: Haskell : 是一门通用函数式语言,差点儿能够进行 ...

  8. qt优点

    (1)优良的跨平台特性.  Qt支持下列操作系统:Microsoft Windows 95/98.Microsoft Windows NT.Linux.Solaris.SunOS.HP-UX.Digi ...

  9. [转] doxygen使用总结

    doxygen [功能] 为许多种语言编写的程序生成文档的工具. [举例] *生成一个模板配置文件,模板文件中有详细的注释: $doxgen -g test 这样,会生成一个test文件,1500多行 ...

  10. iOS开发系列之触摸事件

    基础知识 三类事件中触摸事件在iOS中是最常用的事件,这里我们首先介绍触摸事件. 在下面的例子中定义一个KCImage,它继承于UIView,在KCImage中指定一个图片作为背景.定义一个视图控制器 ...