首页
社区
课程
招聘
[原创]内核读写只读内存方法总结[Delphi描述]
发表于: 2008-4-26 16:24 12733

[原创]内核读写只读内存方法总结[Delphi描述]

2008-4-26 16:24
12733

以下代码均已Delphi描述...至于为什么...
首先我是一个Delphi Coder...虽然我大部分时间使用的是ASM编译器和C编译器
但是我喜欢Delphi...好了不废话了...

已知的三种方法:如果各位有更好的意见欢迎大家提出

[1]使内存可读写

1.stl+cr0:
这个方法大家想必经常使用...

(参考I-32.3A文档)
由于cr0是一个32位寄存器...假设大家的CPU是32位的.没有64位测试环境
按照图这个结构我们可以了解到的信息
第16位:WP——Write Protect,当设置为1时只提供读页权限
第0位:PE——Paging,当设置为1时提供分页
第1位:MP——Protection Enable,当设置为1时进入保护模式

按照这个说明写出代码:
//1 关闭写保护
asm
  push eax
  mov eax, CR0
  and eax, 0FFFEFFFFh
  mov CR0, eax
  pop eax
end;

//2 打开写保护
asm
  push eax
  mov eax, CR0
  or eax, NOT 0FFFEFFFFh
  mov CR0, eax
  pop eax
end;
也许大家看得有点模糊.其实这个代码就是修改第16位
NOT 0FFFEFFFFh = 00010000h
因为要设置第16位为1...所以结果也就是代码那种效果...
鄂~我也不知道说什么了.也就是位操作你也可以直接使用
//1 关闭写保护
asm
  push  eax
  mov   eax, cr0
  and   eax, not 000010000h
  mov   cr0, eax
  pop   eax
end;

//2 打开写保护
asm
  push  eax
  mov   eax, cr0
  or    eax, 000010000h
  mov   cr0, eax
  pop   eax
end;

一般使用的时候我们都会加上cli和sti,由于这两个指令只能控制当前CPU对于
多核系统是无法起到有效的互斥的...所以一般都是配合"自转锁"使用
关于自转锁的话题我们下面会详细的说的

2.通过内存描述表(MDL)中描述一块内存区域,MDL包含此内存区域的起始地址,
拥有者进程,字节数量以及标志.(据说是Bill提供的方法.难道和VirtualProtect一样?)

type
  PMDL = ^_MDL;
  _MDL = packed record
    Next: PMDL;
    Size: USHORT;
    MdlFlags: USHORT;
    Process: Pointer;
    MappedSystemVa: PVOID;
    StartVa: PVOID;
    ByteCount: ULONG;
    ByteOffset: ULONG;
  end;
  MDL = _MDL;

const
  MDL_MAPPED_TO_SYSTEM_VA     = $0001;
  MDL_PAGES_LOCKED            = $0002;
  MDL_SOURCE_IS_NONPAGED_POOL = $0004;
  MDL_ALLOCATED_FIXED_SIZE    = $0008;
  MDL_PARTIAL                 = $0010;
  MDL_PARTIAL_HAS_BEEN_MAPPED = $0020;
  MDL_IO_PAGE_READ            = $0040;
  MDL_WRITE_OPERATION         = $0080;
  MDL_PARENT_MAPPED_SYSTEM_VA = $0100;
  MDL_LOCK_HELD               = $0200;
  MDL_PHYSICAL_VIEW           = $0400;
  MDL_IO_SPACE                = $0800;
  MDL_NETWORK_HEADER          = $1000;
  MDL_MAPPING_CAN_FAIL        = $2000;
  MDL_ALLOCATED_MUST_SUCCEED  = $4000;

//  读写只读内存(源于Gates大叔)
function WriteReadOnlyMemoryGates(lpDest, lpSource: Pointer; Length: Integer): 

NTSTATUS;
var
  tempSpinLock: KSPIN_LOCK;
  oldirql: KIRQL;
  mdl: PMDL;
  writableAddress: Pointer;
begin
  Result := STATUS_UNSUCCESSFUL;
  mdl := MmCreateMdl(nil, lpDest, Length);
  if (mdl <> nil) then
  begin
    MmBuildMdlForNonPagedPool(mdl);
    mdl^.MdlFlags := mdl^.MdlFlags or MDL_MAPPED_TO_SYSTEM_VA;
    writableAddress := MmMapLockedPages(mdl, KernelMode);
    if (writableAddress <> nil) then
    begin
      oldirql := 0;

      KeInitializeSpinLock(@tempSpinLock);
      fast_KfAcquireSpinLock(@tempSpinLock);
      memcpy(writableAddress, lpSource, Length);
      fast_KfReleaseSpinLock(@tempSpinLock, oldirql);

      MmUnmapLockedPages(writableAddress, mdl);
      Result := STATUS_SUCCESS;

    end;
    MmUnlockPages(mdl);
    IoFreeMdl(mdl);
  end;
end;
//  写只读内存(源于Mark代码)
function WriteReadOnlyMemoryMark(lpDest, lpSource: Pointer; Length: Integer): 

NTSTATUS;
var
  tempSpinLock: KSPIN_LOCK;
  oldirql: KIRQL;
  mdl: PMDL;
  writableAddress: Pointer;
begin
  Result := STATUS_UNSUCCESSFUL;
  mdl := IoAllocateMdl(lpDest, Length, False, False, nil);
  if (mdl <> nil) then
  begin
    MmBuildMdlForNonPagedPool(mdl);
    MmProbeAndLockPages(mdl, KernelMode, IoWriteAccess);
    writableAddress := MmMapLockedPages(mdl, KernelMode);
    if (writableAddress <> nil) then
    begin
      oldirql := 0;

      KeInitializeSpinLock(@tempSpinLock);
      fast_KfAcquireSpinLock(@tempSpinLock);
      memcpy(writableAddress, lpSource, Length);
      fast_KfReleaseSpinLock(@tempSpinLock, oldirql);

      MmUnmapLockedPages(writableAddress, mdl);
      Result := STATUS_SUCCESS;
    end;
    MmUnlockPages(mdl);
    IoFreeMdl(mdl);
  end;
end;

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (6)
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
2
LZ是个 Delphi大王啊。

不懂 Delphi 和JAVA。

特来膜拜下大牛
123456~
2008-4-26 16:30
0
雪    币: 437
活跃值: (273)
能力值: ( LV12,RANK:240 )
在线值:
发帖
回帖
粉丝
3
delphi 让人爱不释手 转DELPHI用了一个多星期的时间 达到能以前写的程序能正常翻译= =
2008-4-26 17:59
0
雪    币: 451
活跃值: (78)
能力值: ( LV12,RANK:470 )
在线值:
发帖
回帖
粉丝
4
进来膜拜1下女王大牛
2008-4-26 18:28
0
雪    币: 209
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
文章中多处sti错写成了stl
2008-4-27 08:47
0
雪    币: 1956
活跃值: (1105)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
膜拜 小零 !!!
2008-4-27 19:30
0
雪    币: 290
活跃值: (11)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
7
经典!!!
差点被trap了
2008-4-27 20:27
0
游客
登录 | 注册 方可回帖
返回
//