No description, website, or topics provided.
Branch: master
Clone or download
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
Demo
SecureMemoryEncryptionDriver Important comment change Feb 6, 2019
VirtualAllocSecure Style nits Jan 21, 2019
.gitignore Major update to allow for -in-kernel allocation and release API Jan 21, 2019
README.md Update README Jan 21, 2019
VirtualAllocSecure.sln First commit (untested code) Jan 19, 2019
demo.gif

README.md

VirtualAllocSecure

VirtualAllocSecure is a Proof-of-Concept for Windows that hacks page table entries to enable AMD's Secure Memory Encryption on supported processors.

Demo gif

Background

Secure Memory Encryption is a technology available on certain SKUs of AMDs recent processors that transparently encrypts memory contents before writing to DRAM. This technology could be valuable in protecting secrets from physical attacks on the memory bus and is used in AMD's Secure Encrypted Virtualization technology.

PoC

The dynamically-linked library (VirtualAllocSecure.dll) exposes VirtualAllocSecure and VirtualFreeSecure functions which call into a companion driver (SecureMemoryEncryptionDriver) to allocate encrypted memory usable by the caller process. When VirtualAllocSecure is called, the driver will allocate a non-paged region of memory and map this region into the user-mode process. It will then enable memory encryption (for the user-mode mapping only) by manually setting the C-bit in the relevant PTEs. VirtualFreeSecure* reverses this process.

The reason a kernel pool allocation is used instead of calling VirtualAlloc to allocate user-mode pages before fiddling with the relevant PTE bits is because Mm will periodically enumerate the working set (in order to age + trim). This is unfortunately true even if the backing physical pages are locked in memory. During this process, the page tables are walked which will result in a bugcheck since SME uses what Mm considers to be valid PFN bits and hence will cause an invalid lookup in the PFN database). Anything that walks the page tables of the pool might similarly result in a bugcheck but at least this doesn't happen as immediately as using an allocation off the process working set.

NOTE: This is extremely hacky and could will lead to system instability!

Tested on my Ryzen 2700X with virtualization functionality disabled in the BIOS

Library usage

typedef PVOID(*VirtualAllocSecure)(SIZE_T Size, ULONG Protect);
typedef PVOID(*VirtualFreeSecure)(PVOID Address);

HMODULE lib = LoadLibraryA("VirtualAllocSecure.dll");

VirtualAllocSecure pVirtualAllocSecure = (VirtualAllocSecure)GetProcAddress(lib, "VirtualAllocSecure");
VirtualFreeSecure pVirtualFreeSecure = (VirtualFreeSecure)GetProcAddress(lib, "VirtualFreeSecure");

PCHAR buffer = pVirtualAllocSecure(size, PAGE_READWRITE);
pVirtualFreeSecure(buffer);