NtReadVirtualMemory函数位于ntdll中,作用就是把用户态的函数调用翻译成相应的系统调用,进入内核态。内核中一般有一个相同名字的处理函数,接收到该类型的系统调用后做实际的工作。
NTSTATUS STDCALL NtReadVirtualMemory(IN HANDLE ProcessHandle, IN PVOID BaseAddress, OUT PVOID Buffer, IN ULONG NumberOfBytesToRead, OUT PULONG NumberOfBytesRead) { NTSTATUS Status; PMDL Mdl; PVOID SystemAddress; PEPROCESS Process; DPRINT("NtReadVirtualMemory(ProcessHandle %x, BaseAddress %x, " "Buffer %x, NumberOfBytesToRead %d)\n",ProcessHandle,BaseAddress, Buffer,NumberOfBytesToRead); Status = ObReferenceObjectByHandle(ProcessHandle, PROCESS_VM_WRITE, NULL, UserMode, (PVOID*)(&Process), NULL);
if (Status != STATUS_SUCCESS) { return(Status); }
}
struct _EPROCESS { /* Microkernel specific process state. */ KPROCESS Pcb;
}
typedef struct _KPROCESS { DISPATCHER_HEADER DispatcherHeader; /* 000 */ LIST_ENTRY ProfileListHead; /* 010 */ PHYSICAL_ADDRESS DirectoryTableBase; /* 018 这是cr3*/
}
Mdl = MmCreateMdl(NULL,Buffer, NumberOfBytesToRead); MmProbeAndLockPages(Mdl,UserMode,IoWriteAccess);
KeAttachProcess(Process);
SystemAddress = MmGetSystemAddressForMdl(Mdl); memcpy(SystemAddress, BaseAddress, NumberOfBytesToRead);
KeDetachProcess();
if (Mdl->MappedSystemVa != NULL) { MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl); } MmUnlockPages(Mdl); ExFreePool(Mdl); ObDereferenceObject(Process); *NumberOfBytesRead = NumberOfBytesToRead; return(STATUS_SUCCESS); }
memcpy(Buffer, BaseAddress, NumberOfBytesToRead);
VOID STDCALL KeAttachProcess (PEPROCESS Process) { KIRQL oldlvl; PETHREAD CurrentThread; PULONG AttachedProcessPageDir; ULONG PageDir; DPRINT("KeAttachProcess(Process %x)\n",Process); CurrentThread = PsGetCurrentThread(); if (CurrentThread->OldProcess != NULL) { DbgPrint("Invalid attach (thread is already attached)\n"); KEBUGCHECK(0); } KeRaiseIrql(DISPATCH_LEVEL, &oldlvl); KiSwapApcEnvironment(&CurrentThread->Tcb, &Process->Pcb);
/* The stack of the current process may be located in a page which is
not present in the page directory of the process we‘re attaching to.
That would lead to a page fault when this function returns. However,
since the processor can‘t call the page fault handler ‘cause it can‘t
push EIP on the stack, this will show up as a stack fault which will
crash the entire system.
To prevent this, make sure the page directory of the process we‘re
attaching to is up-to-date. */
AttachedProcessPageDir = ExAllocatePageWithPhysPage(Process->Pcb.DirectoryTableBase);
MmUpdateStackPageDir(AttachedProcessPageDir, &CurrentThread->Tcb);
ExUnmapPage(AttachedProcessPageDir);
CurrentThread->OldProcess = PsGetCurrentProcess();
CurrentThread->ThreadsProcess = Process;
PageDir = Process->Pcb.DirectoryTableBase.u.LowPart;
DPRINT("Switching process context to %x\n",PageDir);
Ke386SetPageTableDirectory(PageDir);
KeLowerIrql(oldlvl);
}
驱动编程:NtReadVirtualMemory,布布扣,bubuko.com
原文:http://www.cnblogs.com/alsofly/p/3734814.html