Reading pageable memory at HIGH_LEVEL

Forum for discussion about kernel-mode development.

Reading pageable memory at HIGH_LEVEL

Postby pwl » Fri Jul 07, 2017 6:22 pm

I've a small hypervisor that is able to intercept some exceptions. Let's call it exception EXC. When EXC is raised in kernelmode, hypervisor gets control via VmExit and I'm able to dereference memory at GUEST_RIP (pointing to kernelspace) to find out what instruction raised EXC. When GUEST_RIP points to userspace, attempts to deref this memory ends with bugcheck 0xD1:

Code: Select all
The DRIVER_IRQL_NOT_LESS_OR_EQUAL bug check has a value of 0x000000D1. This indicates that a kernel-mode driver attempted to access pageable memory at a process IRQL that was too high.


My questions are:
1. Is it safe to simply dereference kernel memory inside a kernel driver?
2. How to solve the bugcheck issue?
3. Assuming GUEST_RIP points to userspace, is it necessary to set cr3 to GUEST_CR3 before reading GUEST_RIP memory? Guest's RIP comes from a random userspace process and each process has its own cr3 value.
pwl
 
Posts: 6
Joined: Sat Jul 01, 2017 7:44 pm
Reputation point: 0

Re: Reading pageable memory at HIGH_LEVEL

Postby pwl » Sun Jul 09, 2017 9:30 am

I tried this:

Code: Select all

NTSTATUS
ReadPageableMemory(
   PVOID VirtualAddress,
   ULONG Length,
   PUCHAR DestBuffer
)
{
   mdl = IoAllocateMdl(VirtualAddress, Length, FALSE, FALSE, NULL);
   if (!mdl)
   {
      ...
   }
   try {      
      MmProbeAndLockPages(mdl, UserMode, IoReadAccess);
   }
   except(EXCEPTION_EXECUTE_HANDLER)
   {
      ...
   }
   SrcBuffer = MmGetSystemAddressForMdlSafe(mdl, HighPagePriority | MdlMappingNoExecute);
   if (!SrcBuffer) {
      ...
   }
   RtlCopyMemory(DestBuffer, SrcBuffer, Length);
   MmUnlockPages(mdl);
   IoFreeMdl(mdl);
        ...


I invoke it like this

Code: Select all
KeLowerIrql(GuestIrql);
HostCr3 = __readcr3();
__writecr3(VmxRead(GUEST_CR3));
ReadPageableMemory((PVOID)GuestRip, sizeof(GuestInstrBuf), GuestInstrBuf);
KeRaiseIrql(HIGH_LEVEL, &GuestIrql);
__writecr3(HostCr3);


The result is, the hypervisor works for some time (seconds), then either:
- vmware hangs
- VmxReads from VMCS start to fail without providing error codes
- BugCheck 101 happens with processors stuck in ReadPageableMemory (apparently TLB flushes happen inside and it's time consuming)

I just need to read few bytes to identify the instruction at GuestRIP.
pwl
 
Posts: 6
Joined: Sat Jul 01, 2017 7:44 pm
Reputation point: 0


Return to Kernel-Mode Development

Who is online

Users browsing this forum: No registered users and 2 guests