如何写windows系统已保护的内存区域

windows系统在某些版本下对某些内存区域启用了写保护的功能,因为这些区域一般合法程序是不可能修改其内容的,那么我们如何来写这些内存呢?

PS:1) 这些系统包括:windows xp与windows 2003
   2) CPU提供写保护的功能是从486开始的
   3) 一般合法程序不包括杀毒软件,因为他们在Hook SSDT中是直接改ServiceTableBase,而没有用inline的方法
  
我们就用SSDT做例子吧,在Hook SSDT时不用innline hook方法,我们就要修改SSDT这个系统服务描述表;而这个表是被写保护了,在ring0下也是没有写的权限。

方法一:
首先我们来看一下CR0寄存器的格式
|31|30|       |18|17|16|          5|4|3|2|0|1|
|P |C |       |A |  |W |          N|E|T|E|M|P|
|G |D |       |M |  |P |          E|T|S|M|P|E|

我们主要注意这个WP这位,其他的请参考IA-32 Volume 3A;
WP——Write Protect,当设置为1时只提供读页权限
PE——Paging,当设置为1时提供分页
MP——Protection Enable,当设置为1时进入保护模式
所以我们只要把WP这一位设置为0时,就可以修改SSDT了

 //1 关闭写保护
 __asm
 {
  push eax
  mov  eax, CR0
  and  eax, 0FFFEFFFFh
  mov  CR0, eax
  pop  eax
 }

 //2 打开写保护
 __asm
 {
  push eax
  mov  eax, CR0
  or   eax, NOT 0FFFEFFFFh
  mov  CR0, eax
  pop  eax
 }
通过上面的第一组指令我们就可以正常修改SSDT,记得修改后要还原。


方法二:
此方法是盖茨提供的,在内存描述表(MDL)中描述一块内存区域,MDL包含此内存区域的起始地址,拥有者进程,字节数量以及标志。
//在ddk中的描述
typedef struct _MDL {
    struct _MDL *Next;
    CSHORT Size;
    CSHORT MdlFlags;
    struct _EPROCESS *Process;
    PVOID MappedSystemVa;
    PVOID StartVa;
    ULONG ByteCount;
    ULONG ByteOffset;
} MDL, *PMDL;

#define MDL_MAPPED_TO_SYSTEM_VA     0x0001
#define MDL_PAGES_LOCKED            0x0002
#define MDL_SOURCE_IS_NONPAGED_POOL 0x0004
#define MDL_ALLOCATED_FIXED_SIZE    0x0008
#define MDL_PARTIAL                 0x0010
#define MDL_PARTIAL_HAS_BEEN_MAPPED 0x0020
#define MDL_IO_PAGE_READ            0x0040
#define MDL_WRITE_OPERATION         0x0080
#define MDL_PARENT_MAPPED_SYSTEM_VA 0x0100
#define MDL_LOCK_HELD               0x0200
#define MDL_PHYSICAL_VIEW           0x0400
#define MDL_IO_SPACE                0x0800
#define MDL_NETWORK_HEADER          0x1000
#define MDL_MAPPING_CAN_FAIL        0x2000
#define MDL_ALLOCATED_MUST_SUCCEED  0x4000


// Declarations

#pragma pack(1)

typedef struct ServiceDescriptorEntry {

        unsigned int *ServiceTableBase;

        unsigned int *ServiceCounterTableBase;

        unsigned int NumberOfServices;

        unsigned char *ParamTableBase;

} SSDT;

#pragma pack()

__declspec(dllimport) SSDTKeServiceDescriptorTable;

PMDL  g_pmdlSystemCall;
PVOID *MappedSystemCallTable;

// save old system call locations
// Map the memory into our domain to change the permissions on
// the MDL
g_pmdlSystemCall = MmCreateMdl(NULL,
                   KeServiceDescriptorTable.ServiceTableBase,
                   KeServiceDescriptorTable.NumberOfServices*4);

if(!g_pmdlSystemCall)
   return STATUS_UNSUCCESSFUL;

MmBuildMdlForNonPagedPool(g_pmdlSystemCall);

// Change the flags of the MDL
g_pmdlSystemCall->MdlFlags = g_pmdlSystemCall->MdlFlags |
                             MDL_MAPPED_TO_SYSTEM_VA;

MappedSystemCallTable = MmMapLockedPages(g_pmdlSystemCall, KernelMode);



MappedSystemCallTable就是SSDT的地址,现在可以放心的操作它吧!用完了最好MmFreePagesFromMdl。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值