Page 1 of 1

Can the entire physical memory be read by kernel mode programs?

PostPosted:Sun Jun 09, 2019 3:18 am
by joetoe
Is there any part of physical memory which no program or software can read? Do current systems (PCs where you can Windows 10 etc.) have such protection mechanism?

Re: Can the entire physical memory be read by kernel mode programs?

PostPosted:Fri Jun 14, 2019 4:54 am
by feryno
I found that when hyper-v running some areas of physical memory are protected (e.g. securekernel.exe). It must be done using virtualization features (AMD Nested paging / Intel EPT). In this case, it is not memory in RAM (machine memory = host physical memory) but the physical memory the kernelmode sees (guest physical memory) which is protected.
When you have more that 4 GiB of physical memory, there are holes in range 3-4 GiB so the rest of physical memory continues above 4 GiB. Some areas in the 3-4 GiB range are really holes (after mapping their PA and reading them you'll see that they are filled with 0xFF, they are readonly and cannot be written), some contain various hardware things (ACPI tables, APIC, UEFI/BIOS firmware) - some are readonly and some writeable.
Latest versions of w10 do not allow to map physical memory of paging tables (MmMapIoSpace fails there even the physical memory exists) so you must try other method (there is a thread about this problem at kernelmode).

I came to the first problem while investigating something completely different. I was monitoring MSR LSTAR changes using parent hypervisor with nested capabilities in L0, hyper-v was child in L1, OS running in L2. I was curios what else is written (wrmsr) into the MSR than nt!KiSystemCall64Shadow. I was unable to read that VA using kd (I was able to read only the VA of nt!KiSystemCall64Shadow). Using parent in L0 I found that is had private paging tables different from ntoskrnl.exe (CR3). So I tried kd to read that PA obtained as CR3 value, but kd failed. So at the end I used hv in L0 to parse paging tables (as I already had CR3 and VA) and obtained bytes of code. After scanning all files the hexadecimal pattern was present only in securekernel.exe. It is something like lightweight version of ntoskrnl.exe (about 10 times smaller, without a lot of subsystems), much more secured (only trustlets allowed to run there). It is protected not only at VA basis (separate paging tables where ntoskrnl.exe is not mapped) but also at PA level (few MiB of contiguous PA containing paging tables, securekernel.exe code/data etc). The securekernel.exe appears not to be loaded when no hyper-v. So you need enterprise version of w10, after installation enable hyper-v role. In my experiments, securekernel!KiSystemCall64 was always launched as the first one, nt!KiSystemCall64Shadow as the second one and then OS switched frequently between them while running. That explained why I found 2 different values in the MSR I was monitoring.