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(
INPMDLMemoryDescriptorListOPTIONAL,
INPVOIDBase,
INSIZE_TLength );
|
新的函数为
PMDL
IoAllocateMdl(
__in_optPVOIDVirtualAddress,
__inULONGLength,
__inBOOLEANSecondaryBuffer,
__inBOOLEANChargeQuota,
__inout_optPIRPIrpOPTIONAL
);
|
IoAllocateMdl的作用是分配一个MDL结构,也就是将系统的一段内存空间映射到另外一个地方,然后修改这部分内存的保护属性,并修改其内容,以达到修改受保护内存的目的。第一参数为MDL内存的起始地址,第二个参数为MDL的长度。
由于IoAllocateMdl创建的MDL都是指向非分页的虚拟内存的buffer中的,所以需要MmBuildMdlForNonPagedPool函数来在物理内存上更新这个MDL。
MmMapLocakedPages函数的定义如下
PVOID
MmMapLockedPages(
INPMDLMemoryDescriptorList,
INKPROCESSOR_MODEAccessMode );
|
新的函数为MmMapLockedPagesSpecifyCache,它的定义为
PVOID
MmMapLockedPagesSpecifyCache(
__inPMDLXMemoryDescriptorList,
__inKPROCESSOR_MODEAccessMode,
__inMEMORY_CACHING_TYPECacheType,
__in_optPVOIDBaseAddress,
__inULONGBugCheckOnFailure,
__inMM_PAGE_PRIORITYPriority );
|
它的作用是用来锁定内存中的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);
|
分享到:
相关推荐
PB串口通讯数据监控,使用钩子HOOK API
windows hookHOOK API是指截获特定进程或系统对某个API函数的调用,使得API的执行流程...Windows下的应用程序都建立在API函数至上,所以截获API是一项相当有用的技术,它使得用户有机会干预其它应用程序的程序流程。
一个网友写的非常清晰明白的鼠标钩子看星星的程序
VC++ 2008编译的钩子源代码,编译通过,没错误
WINCE下的键盘钩子程序,让你轻松捕获键盘消息
API Hook基本原理和实现,钩子的特性
VB内嵌汇编实现单个类文件实现子类化钩子.
通过例子介绍了Windows系统服务调用的基本知识及Hook SSDT的方法
键盘钩子 hook 键盘钩子 hook 键盘钩子 hook 键盘钩子 hook 键盘钩子 hook 键盘钩子 hook 键盘钩子 hook 键盘钩子 hook
hook function for windows 7
这是一个记录键盘输入的钩子,可是监听键盘输入,特定路径文本输出,并且还是实现任务栏托盘显示。
windows CE的键盘钩子,已经过测试,sdk下测试。
枚举全局钩子_如何枚举系统中所有的钩子hook
delphi开发的钩子测试程序,源代码中包含了各种系统钩子的使用方法。
钩子函数运用,结合java语言获取键盘、鼠标响应监控信息。
Driver_hook Driver_hook Driver_hook Driver_hook
线程钩子的事例代码。适合初学者。大家自己看吧。
一个简单的鼠标钩子程序 实现适时获取当前鼠标所在窗口的标题,并将其显示在一个EDITBOX中
c++钩子函数:copy hook c++调用钩子函数监视复制文件操作
对Windows API函数进行HOOK测试源码