type
PMDL = ^_MDL;
_MDL = packed record
Next: PMDL;
Size: USHORT;
MdlFlags: USHORT;
Process: Pointer;
MappedSystemVa: PVOID;
StartVa: PVOID;
ByteCount: ULONG;
ByteOffset: ULONG;
end;
MDL = _MDL;
const
MDL_MAPPED_TO_SYSTEM_VA = $0001;
MDL_PAGES_LOCKED = $0002;
MDL_SOURCE_IS_NONPAGED_POOL = $0004;
MDL_ALLOCATED_FIXED_SIZE = $0008;
MDL_PARTIAL = $0010;
MDL_PARTIAL_HAS_BEEN_MAPPED = $0020;
MDL_IO_PAGE_READ = $0040;
MDL_WRITE_OPERATION = $0080;
MDL_PARENT_MAPPED_SYSTEM_VA = $0100;
MDL_LOCK_HELD = $0200;
MDL_PHYSICAL_VIEW = $0400;
MDL_IO_SPACE = $0800;
MDL_NETWORK_HEADER = $1000;
MDL_MAPPING_CAN_FAIL = $2000;
MDL_ALLOCATED_MUST_SUCCEED = $4000;
//
读写只读内存(源于Gates大叔)
function
WriteReadOnlyMemoryGates(lpDest, lpSource: Pointer; Length: Integer):
NTSTATUS;
var
tempSpinLock: KSPIN_LOCK;
oldirql: KIRQL;
mdl: PMDL;
writableAddress: Pointer;
begin
Result := STATUS_UNSUCCESSFUL;
mdl := MmCreateMdl(nil, lpDest, Length);
if
(mdl <> nil)
then
begin
MmBuildMdlForNonPagedPool(mdl);
mdl^.MdlFlags := mdl^.MdlFlags or MDL_MAPPED_TO_SYSTEM_VA;
writableAddress := MmMapLockedPages(mdl, KernelMode);
if
(writableAddress <> nil)
then
begin
oldirql := 0;
KeInitializeSpinLock(@tempSpinLock);
fast_KfAcquireSpinLock(@tempSpinLock);
memcpy(writableAddress, lpSource, Length);
fast_KfReleaseSpinLock(@tempSpinLock, oldirql);
MmUnmapLockedPages(writableAddress, mdl);
Result := STATUS_SUCCESS;
end;
MmUnlockPages(mdl);
IoFreeMdl(mdl);
end;
end;