读书笔记_windows下的混合钩子(HOOK)_part 4_使用MDL修改内存保护机制

 

MDL(Memory Descriptor List),指内存描述符表,它包含了该内存区域的起始地址、拥有者进程、字节数量以及标志。MDL结构定义在ntddk.h中,具体结构如下:

Typedef struct _MDL{

      Struct _MDL *Next;

      CSHORT Size;

      CSHORT MdlFlags;

      Struct _EPROCESS *Process;

      PVOID MappedSystemVa;

      PVOID StartVa;

      ULONG ByteCount;

      ULONG ByteOffset;

} MDL, *PMDL;

为了修改内存标志,需要声明一个结构,该结构用于强制转换由Windows内核导出的KeServiceDescriptorTable变量的类型。该结构如下:

typedef struct ServiceDescriptorEntry {

        unsigned int *ServiceTableBase;

        unsigned int *ServiceCounterTableBase; //Used only in checked build

        unsigned int NumberOfServices;

        unsigned char *ParamTableBase;

} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;

 

 

《Rootkits》书中给的源码如下所示,尽管去能够在windows XP下编译过,并且能够执行,但其中的有些函数已经过时,已有新的函数替代了。下面分别描述:

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);

 

 

MmCreateMdl函数的定义如下

PMDL 
  MmCreateMdl(
    IN PMDL 
 MemoryDescriptorList  OPTIONAL,
    IN PVOID 
 Base,
    IN SIZE_T
  Length
    );

新的函数为

PMDL 
  IoAllocateMdl(
    __in_opt PVOID
  VirtualAddress,
    __in ULONG
  Length,
    __in BOOLEAN
  SecondaryBuffer,
    __in BOOLEAN
  ChargeQuota,
    __inout_opt PIRP
  Irp  OPTIONAL
    );

 

IoAllocateMdl的作用是分配一个MDL结构,也就是将系统的一段内存空间映射到另外一个地方,然后修改这部分内存的保护属性,并修改其内容,以达到修改受保护内存的目的。第一参数为MDL内存的起始地址,第二个参数为MDL的长度。

由于IoAllocateMdl创建的MDL都是指向非分页的虚拟内存的buffer中的,所以需要MmBuildMdlForNonPagedPool函数来在物理内存上更新这个MDL。

 

MmMapLocakedPages函数的定义如下

PVOID 
  MmMapLockedPages(
    IN PMDL 
 MemoryDescriptorList,
    IN KPROCESSOR_MODE
  AccessMode
    );

新的函数为MmMapLockedPagesSpecifyCache,它的定义为

PVOID
  MmMapLockedPagesSpecifyCache(
    __in PMDLX  
MemoryDescriptorList,
    __in KPROCESSOR_MODE  
AccessMode,
    __in MEMORY_CACHING_TYPE  
CacheType,
    __in_opt PVOID  
BaseAddress,
    __in ULONG  
BugCheckOnFailure,
    __in MM_PAGE_PRIORITY  
Priority
    );

它的作用是用来锁定内存中的MDL页,允许用户修改其属性。

 所以使用新函数后修改的代码如下:

//g_pmdlSystemCall = MmCreateMdl(NULL, KeServiceDescriptorTable.ServiceTableBase, //KeServiceDescriptorTable.NumberOfServices*4);

g_pmdlSystemCall = IoAllocateMdl(KeServiceDescriptorTable.ServiceTableBase, KeServiceDescriptorTable.NumberOfServices*4,FALSE, FALSE, NULL );

   if(!g_pmdlSystemCall)

      return STATUS_UNSUCCESSFUL;

   MmBuildMdlForNonPagedPool(g_pmdlSystemCall);

   // Change the flags of the MDL

   // MappedSystemCallTable = MmMapLockedPages(g_pmdlSystemCall, KernelMode);

   MappedSystemCallTable = MmMapLockedPagesSpecifyCache(g_pmdlSystemCall, KernelMode, MmWriteCombined, NULL, FALSE, 0);

   MappedSystemCallTable = MmMapLockedPages(g_pmdlSystemCall, KernelMode);

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值