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;
}