NTSTATUS WriteMemoryNormalMdl(IN HANDLE PID, IN PVOID BaseAddress, IN SIZE_T Length, IN PVOID Buffer)
{
BOOLEAN attach = FALSE;
ULONG64 cr0 = 0;
NTSTATUS Status = STATUS_SUCCESS;
PEPROCESS pEProcess = NULL;
KAPC_STATE ApcState = { 0 };
Status = PsLookupProcessByProcessId(PID, &pEProcess);
if (!NT_SUCCESS(Status) && !MmIsAddressValid(pEProcess)) { return STATUS_UNSUCCESSFUL; }
__try
{
PMDL mdl = IoAllocateMdl(Buffer, Length, 0, 0, NULL);
MmBuildMdlForNonPagedPool(mdl);
unsigned char* Map = (unsigned char*)MmMapLockedPages(mdl, KernelMode);
if (!Map)
{
IoFreeMdl(mdl);
return NULL;
}
if (PsGetCurrentProcess() != pEProcess)
{
KeStackAttachProcess(pEProcess, &ApcState);
attach = TRUE;
}
__try {
if (MmIsAddressValid(BaseAddress))
{
cr0 = __readcr0();
cr0 &= 0xfffffffffffeffff;
__writecr0(cr0);
_disable();
RtlCopyMemory(BaseAddress, Map, Length);
KeLowerIrql(KeRaiseIrqlToDpcLevel());
cr0 = __readcr0();
cr0 |= 0x10000;
_enable();
__writecr0(cr0);
}
}
__except (1)
{
DbgPrint("MMC 无法访问地址.\n");
}
if (attach)KeUnstackDetachProcess(&ApcState);
DbgPrint("MMC 释放内存\n");
MmUnmapLockedPages((PVOID)Map, mdl);
IoFreeMdl(mdl);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
KeUnstackDetachProcess(&ApcState);
Status = STATUS_UNSUCCESSFUL;
}
ObDereferenceObject(pEProcess);
return Status;
}
NTSTATUS write(PEPROCESS pProcess, PVOID Address, PVOID AllocatedBuffer, SIZE_T size, SIZE_T* written)
{
ULONG_PTR process_dirbase = GetProcessCr3(pProcess);
NTSTATUS NtRet{};
SIZE_T CurOffset = 0;
SIZE_T TotalSize = size;
while (TotalSize)
{
ULONG64 CurPhysAddr = TranslateLinearAddress(process_dirbase, (ULONG64)Address + CurOffset);
if (!CurPhysAddr) return STATUS_UNSUCCESSFUL;
ULONG64 WriteSize = min(PAGE_SIZE - (CurPhysAddr & 0xFFF), TotalSize);
SIZE_T BytesWritten = 0;
NtRet = WritePhysicalAddress((PVOID)CurPhysAddr, (PVOID)((ULONG64)AllocatedBuffer + CurOffset), WriteSize, &BytesWritten);
TotalSize -= BytesWritten;
CurOffset += BytesWritten;
if (NtRet != STATUS_SUCCESS) break;
if (BytesWritten == 0) break;
}
*written = CurOffset;
return NtRet;
}