这是在阅读<<rookit:windows内核安全的防护>>一书时遇到的问题,下面是原文:
在内存描述符表(Memory Descriptor List,MDL)中描述一块内存区域。MDL包含了该内存区域的起始地址、拥有者进程、字节数量以及标志:
// MDL references defined in 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;
// MDL Flags
#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
为了修改内存标志,以下代码首先声明一个结构,该结构用于强制转换由Windows内核导出的KeServiceDescriptorTable变量的类型。调用MmCreateMdl时,需要KeServiceDescriptorTable基地址以及它所包含的项数。它们定义了MDL所描述的内存区域的起始地址和大小。然后rootkit从不分页的内存池中构建MDL。
rootkit将MDL的标志与前面提及的MDL_MAPPED_TO_SYSTEM_VA进行或操作,以便允许写入一块内存区域。然后调用MmMapLockedPages来锁定内存中的MDL页。
现在就可以开始钩住SSDT。在以下代码中,MappedSystemCallTable 代表了与原始SSDT相同的地址,但现在可以向其中执行写入操作。
// Declarations
#pragma pack(1)
typedef struct ServiceDescriptorEntry {
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase;
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
} SSDT_Entry;
#pragma pack()
__declspec(dllimport) SSDT_Entry KeServiceDescriptorTable;
PMDL g_pmdlSystemCall;
PVOID *MappedSystemCallTable;
// Code
// 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);
我想问的是:
1.为什么rootkit要从不分页的内存池中构建MDL?
2.为什么rootkit要将MDL的标志与MDL_MAPPED_TO_SYSTEM_VA进行或操作,才能写入内存区域。然后还要调用MmMapLockedPages来锁定内存中的MDL页呢?
关于windows编程我比较菜,望大虾指点一下,谢谢!
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)