阅读:1921回复:7
在驱动中,如何对于任意内存空间读写?
在驱动中,如何对于任意内存空间读写?
在9x下很简单,用指针直接就可以操作! 在nt/2000/xp系统下,对于一个线性地址,是不是首先要转化成物理地址,再读写,如果有写保护,还应去掉其写保护标志位?有没有例子? 我找到一份代码,没有看懂! NTSTATUS WriteReadOnlyMemory (char *dest, char *source, int length) { KSPIN_LOCK tempSpinLock; KIRQL oldirql; PMDL mdl; PVOID writableAddress; mdl = IoAllocateMdl((PVOID) dest, length, FALSE, FALSE, NULL); if (mdl == NULL) return STATUS_UNSUCCESSFUL; MmBuildMdlForNonPagedPool(mdl); MmProbeAndLockPages(mdl, KernelMode, IoWriteAccess); writableAddress = MmMapLockedPages(mdl, KernelMode); if (writableAddress == NULL) { MmUnlockPages(mdl); IoFreeMdl(mdl); return STATUS_UNSUCCESSFUL; } KeInitializeSpinLock(&tempSpinLock); KeAcquireSpinLock(&tempSpinLock, &oldirql); RtlCopyMemory(writableAddress, source, length); KeReleaseSpinLock(&tempSpinLock, oldirql); MmUnmapLockedPages(writableAddress, mdl); MmUnlockPages(mdl); IoFreeMdl(mdl); return STATUS_SUCCESS; } |
|
沙发#
发布于:2004-04-05 13:28
首先你要确保该地址存在,不然当然不行,其次在XP以后系统有内核写保护,防止RING0驱动改写核心结构,X86下需要屏蔽CR0的位16 WP保护位就可以在RING0读写任意存在的地址了。
|
|
|
板凳#
发布于:2004-04-05 19:31
这段代码运行后 必定死机 为什么?
#include "mem.h" #include "debug.h" #define PROCESS_NAME_OFFSET 0x01234567 VOID ReadMem() { PVOID ioBuffer[16]; RtlCopyMemory (ioBuffer, (char *)PROCESS_NAME_OFFSET, 16); InterruptDrv_KDPRINT( ("ReadMem function x%\n",ioBuffer) ); } VOID WriteMem() { } |
|
地板#
发布于:2004-04-05 20:22
如何读/写 地址 0x01234567 ?假设这个地址有效!
|
|
地下室#
发布于:2004-04-07 10:18
因为该地址无效,访问当然有问题
即使对某些程序有效,也不是对所有程序有效 你必须做地址转换才可以 这段代码运行后 必定死机 为什么? |
|
|
5楼#
发布于:2004-04-07 11:03
是要对地址的有效性进行检测!
|
|
6楼#
发布于:2004-04-07 11:14
如果你在内核层的话,可以直接搜索页表,然后把不存在的地址指向一个存在的物理页,然后就可以往里面写了,当然你实际写的是另一个线性地址的物理地址,只不过欺骗了操作系统而已,嘿嘿......
|
|
|
7楼#
发布于:2004-04-07 11:22
在windows 2000/xp下,对内存读写实施了更加有效的保护,直接利用线性地址在应用程序中读写内存将死机,而在驱动程序中,也只能对部分地址进行读写
|
|