标准MDL方法修改Page、NonPage内存的属性~

来源:http://hi.baidu.com/%E5%8F%AB%E6%88%91v%E6%A0%A1/blog/item/018a6000e7f80b1d738da5f6.html

 

typedef struct _REPROTECT_CONTEXT
{
PMDL   Mdl;
PUCHAR LockedVa;
} REPROTECT_CONTEXT, * PREPROTECT_CONTEXT;

 

NTSTATUS
MmLockVaForWrite(
__in PVOID Va,
__in ULONG Length,
__out PREPROTECT_CONTEXT ReprotectContext
)
{
NTSTATUS Status;

Status = STATUS_SUCCESS;

ReprotectContext->Mdl      = 0;
ReprotectContext->LockedVa = 0;

ReprotectContext->Mdl = IoAllocateMdl(
Va,
Length,
FALSE,
FALSE,
0
);

if (!ReprotectContext->Mdl)
{
return STATUS_INSUFFICIENT_RESOURCES;
}

//
// Retrieve a locked VA mapping.
//

__try
{
MmProbeAndLockPages(
ReprotectContext->Mdl,
KernelMode,
IoModifyAccess
);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
return GetExceptionCode();
}

ReprotectContext->LockedVa = (PUCHAR)MmMapLockedPagesSpecifyCache(
ReprotectContext->Mdl,
KernelMode,
MmCached,
0,
FALSE,
NormalPagePriority
);

if (!ReprotectContext->LockedVa)
{

IoFreeMdl(
ReprotectContext->Mdl
);

ReprotectContext->Mdl = 0;

return STATUS_ACCESS_VIOLATION;
}

//
// Reprotect.
//

Status = MmProtectMdlSystemAddress(
ReprotectContext->Mdl,
PAGE_EXECUTE_READWRITE
);

if (!NT_SUCCESS(Status))
{

MmUnmapLockedPages(
ReprotectContext->LockedVa,
ReprotectContext->Mdl
);
MmUnlockPages(
ReprotectContext->Mdl
);
IoFreeMdl(
ReprotectContext->Mdl
);

ReprotectContext->LockedVa = 0;
ReprotectContext->Mdl      = 0;
}

return Status;
}

NTSTATUS
MmUnlockVaForWrite(
__in PREPROTECT_CONTEXT ReprotectContext
)
{
if (ReprotectContext->LockedVa)
{
MmUnmapLockedPages(
ReprotectContext->LockedVa,
ReprotectContext->Mdl
);
MmUnlockPages(
ReprotectContext->Mdl
);
IoFreeMdl(
ReprotectContext->Mdl
);

ReprotectContext->LockedVa = 0;
ReprotectContext->Mdl      = 0;
}

return STATUS_SUCCESS;
}

评论关闭。