驱动开发:通过内存拷贝读写内存
2023-06-13 09:16:01 时间
内核中读写内存的方式有很多,典型的读写方式有CR3读写,MDL读写,以及今天要给大家分享的内存拷贝实现读写,拷贝读写的核心是使用MmCopyVirtualMemory
这个内核API函数实现,通过调用该函数即可很容易的实现内存的拷贝读写。
封装KeReadProcessMemory()
内存读取。
#include <ntifs.h>
#include <windef.h>
#include <stdlib.h>
NTKERNELAPI NTSTATUS PsLookupProcessByProcessId(HANDLE ProcessId, PEPROCESS *Process);
NTKERNELAPI CHAR* PsGetProcessImageFileName(PEPROCESS Process);
NTSTATUS NTAPI MmCopyVirtualMemory(PEPROCESS SourceProcess, PVOID SourceAddress, PEPROCESS TargetProcess, PVOID TargetAddress, SIZE_T BufferSize, KPROCESSOR_MODE PreviousMode, PSIZE_T ReturnSize);
// 定义全局EProcess结构
PEPROCESS Global_Peprocess = NULL;
// 普通Ke内存读取
NTSTATUS KeReadProcessMemory(PVOID SourceAddress, PVOID TargetAddress, SIZE_T Size)
{
__try
{
PEPROCESS TargetProcess = PsGetCurrentProcess();
SIZE_T Result;
if (NT_SUCCESS(MmCopyVirtualMemory(Global_Peprocess, SourceAddress, TargetProcess, TargetAddress, Size, KernelMode, &Result)))
return STATUS_SUCCESS;
else
return STATUS_ACCESS_DENIED;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
return STATUS_ACCESS_DENIED;
}
return STATUS_ACCESS_DENIED;
}
VOID UnDriver(PDRIVER_OBJECT driver)
{
DbgPrint("Uninstall Driver Is OK \n");
}
// By:lyshark.cnblogs.com
NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{
DbgPrint("hello lyshark \n");
// 根据PID打开进程
DWORD PID = 6672;
NTSTATUS nt = PsLookupProcessByProcessId((HANDLE)PID, &Global_Peprocess);
DWORD ref_value = 0;
// 将地址处读取4字节到ref_value中
NTSTATUS read_nt = KeReadProcessMemory((PVOID)0x0009EDC8, &ref_value, 4);
DbgPrint("读出数据: %d \n", ref_value);
Driver->DriverUnload = UnDriver;
return STATUS_SUCCESS;
}
读取效果如下:
封装KeWriteProcessMemory()
内存读取。
#include <ntifs.h>
#include <windef.h>
#include <stdlib.h>
NTKERNELAPI NTSTATUS PsLookupProcessByProcessId(HANDLE ProcessId, PEPROCESS *Process);
NTKERNELAPI CHAR* PsGetProcessImageFileName(PEPROCESS Process);
NTSTATUS NTAPI MmCopyVirtualMemory(PEPROCESS SourceProcess, PVOID SourceAddress, PEPROCESS TargetProcess, PVOID TargetAddress, SIZE_T BufferSize, KPROCESSOR_MODE PreviousMode, PSIZE_T ReturnSize);
// 定义全局EProcess结构
PEPROCESS Global_Peprocess = NULL;
// 普通Ke内存写入
NTSTATUS KeWriteProcessMemory(PVOID SourceAddress, PVOID TargetAddress, SIZE_T Size)
{
PEPROCESS SourceProcess = PsGetCurrentProcess();
PEPROCESS TargetProcess = Global_Peprocess;
SIZE_T Result;
if (NT_SUCCESS(MmCopyVirtualMemory(SourceProcess, SourceAddress, TargetProcess, TargetAddress, Size, KernelMode, &Result)))
return STATUS_SUCCESS;
else
return STATUS_ACCESS_DENIED;
}
VOID UnDriver(PDRIVER_OBJECT driver)
{
DbgPrint("Uninstall Driver Is OK \n");
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{
DbgPrint("hello lyshark \n");
// 根据PID打开进程
DWORD PID = 6672;
NTSTATUS nt = PsLookupProcessByProcessId((HANDLE)PID, &Global_Peprocess);
DWORD ref_value = 10;
// 将地址处写出4字节
NTSTATUS read_nt = KeWriteProcessMemory((PVOID)0x0009EDC8, &ref_value, 4);
DbgPrint("写入数据: %d \n", ref_value);
Driver->DriverUnload = UnDriver;
return STATUS_SUCCESS;
}
写出内存效果:
相关文章
- JVM内存与垃圾回收篇第7章本地方法栈
- 驱动开发:内核CR3切换读写内存
- Linux下驱动开发_块设备驱动开发(内存模拟存储)
- C/C++ 遍历进程内存块
- 【Linux 内核 内存管理】RCU 机制 ③ ( RCU 模式下添加链表项 list_add_rcu 函数 | RCU 模式下删除链表项 list_del_rcu 函数 )
- Spark内存管理机制详解大数据
- Java 内存区域分配和垃圾回收(GC)机制详解编程语言
- 探索Linux系统中内存占用的神秘面纱(linux查内存占用)
- 小妙用Redis:节省内存空间(redis内存占用)
- SqlServer如何优化内存占用?(sqlserver占内存)
- Oracle驱动数据处理的内存引擎(Oracle内存引擎)
- Oracle内存分配精准掌握至关重要(oracle内存分配多少)
- 如何实现Redis内存分配策略(怎么给redis分配内存)
- 解析Linux系统中JVM内存2GB上限的详解
- C语言内嵌汇编API内存搜索引擎实例