首页 > 代码库 > 驱动编程:NtReadVirtualMemory
驱动编程:NtReadVirtualMemory
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);
}
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。