NTSTATUS RtlSuperCopyMemory(IN VOID UNALIGNED* Destination, IN CONST VOID UNALIGNED* Source, IN ULONG Length)
{
//Change memory properties.
PMDL g_pmdl = IoAllocateMdl(Destination, Length, 0, 0, NULL);
if (!g_pmdl)
return STATUS_UNSUCCESSFUL;
MmBuildMdlForNonPagedPool(g_pmdl);
unsigned int* Mapped = (unsigned int*)MmMapLockedPages(g_pmdl, KernelMode);
if (!Mapped)
{
IoFreeMdl(g_pmdl);
return STATUS_UNSUCCESSFUL;
}
KIRQL kirql = KeRaiseIrqlToDpcLevel();
RtlCopyMemory(Mapped, Source, Length);
KeLowerIrql(kirql);
//Restore memory properties.
MmUnmapLockedPages((PVOID)Mapped, g_pmdl);
IoFreeMdl(g_pmdl);
return STATUS_SUCCESS;
}
inline BOOLEAN __forceinline IsAddressSafe(ULONG64 StartAddress, PSYSTEM_ROUTINE_ADDRESS g_pSRA)
{
if (StartAddress <= 0x1000)
return FALSE;
//cannonical check. Bits 48 to 63 must match bit 47
UINT_PTR toppart = (StartAddress >> 47);
if (toppart & 1)
{
//toppart must be 0x1ffff
if (toppart != 0x1ffff)
return FALSE;
}
else
{
//toppart must be 0
if (toppart != 0)
return FALSE;
}
UINT_PTR kernelbase = 0x7fffffffffffffffULL;
if (StartAddress < kernelbase && g_pSRA->pfn_MmIsAddressValid((PVOID)StartAddress))
{
return TRUE;
}
else
{
PHYSICAL_ADDRESS physical;
physical.QuadPart = 0;
physical = g_pSRA->pfn_MmGetPhysicalAddress((PVOID)StartAddress);
return (physical.QuadPart != 0) && g_pSRA->pfn_MmIsAddressValid(StartAddress);
}
}
在内核中请检查 目标地址 以及Buff 地址 是否正常 可使用__try 或者MDL 判断 在或者使用 IsAddressSafe
在内存加载驱动中 通常使用 MDL 映射强写 而非使用 写Cr0 因为你必须判断 内核地址是否可读