skitter-creek-bath-salts: rewiring DRAM address translation on AMD Family 16h
Unlocking _everything_ on the CPU with DRAM scrambling
At a glance
- What is it?
- A research project that pokes the DRAM controller on AMD Family 16h CPUs to scramble physical address translation, exposing carveouts that the kernel cannot see. It is a hardware research artifact, not a tool for production systems.
- Who is it for?
- skitter-creek-bath-salts is for hardware security researchers, firmware engineers, and people who already own AMD Family 16h hardware and are comfortable recovering a machine that will not POST. It is not for production servers, cloud hosts, or anyone who needs a supported, documented interface.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 36 days ago.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 16, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem: memory the kernel is not allowed to see
A modern CPU builds memory access out of layers of translation. The README walks through the gauntlet a virtual address survives before a bit of DRAM is touched: canonical-form check, segment base addition, TLB probe, page walk from CR3, per-level privilege and execute checks, EPT or NPT re-walk for guests, IOMMU page walk for device-initiated access, memory-type resolution through MTRRs and PAT, cache probes, coherence traffic, and finally the memory controller. Somewhere near the bottom, the memory controller applies channel, rank, and bank interleave hashes, a bank swizzle, chip-select normalization, and sub-channel selection before producing DRAM coordinates.
The project's claim is that if you modify those bottom layers, you can rewire the physical DRAM address translations. Once the translations break, the security primitives built on top of them break too. The README lists four targets: the Platform Security Processor, System Management Mode, C6 DRAM, and CPU microcode. Each is a region or a mechanism that normally sits outside what the kernel can address.
The intended audience is narrow. This is not an administrator's tool. It is for people who study how x86 platforms enforce isolation and who want a concrete implementation to read and modify. The README states the project was developed and tested on AMD Family 16h CPUs, described as the last generation whose datasheets document the DRAM controller's translation registers and show that they cannot be locked.
How the DRAM controller rewire works in practice
The mechanism is a poke at the DRAM controller registers, not a software exploit. The README's diagram places the relevant logic in the MCT/IMC block, below the data fabric and below the cache hierarchy. The address that arrives there has already been resolved by the MMU, checked against MTRRs and PAT, and routed by the uncore. What the memory controller does with it is a set of hashes and remaps: a DRAM hole remap above TOM, a memory-region exclusion remap for reserved ranges, channel interleave hashes, rank interleave hashes, bank interleave hashes, a bank swizzle or XOR scramble that the README calls vendor- and BIOS-configurable, chip-select normalization, and sub-channel selection on DDR5 and LPDDR5.
Changing those parameters changes which physical DRAM cell an address reaches. That is the whole trick. The README does not present a single exploit primitive; it presents a family of address transformations that can be aimed. The repository layout reflects that: a kernel directory and a userspace directory, both built from the top-level Makefile, plus analysis and data directories that hold the supporting work.
The README is explicit that the same odyssey of *p is similar across generations and architectures, and that the underlying transforms extend to ARM and RISC-V. It also says the project shows only how to begin. That is a fair description of the artifact. The code demonstrates the technique on one documented family; it does not claim portability to the hardware you are likely to be running.
Building skitter-creek-bath-salts and a first run
The repository uses a plain Makefile with no configure step and no package manifest. The default target recurses into the kernel and userspace directories, so building the whole tree is one command from the repository root. You need a C toolchain and headers for the kernel module build.
makeThe top-level Makefile defines exactly two targets. The default target runs make -C kernel followed by make -C userspace, and the clean target runs the corresponding clean in both directories. If you only want the userspace portion, invoke it directly.
make -C userspaceBefore loading anything, confirm the CPU. The README names AMD Family 16h as the target, and says 17h and beyond leave the relevant information out of their datasheets. On a machine that is not Family 16h, the register layout the code expects is not the register layout the hardware has. The README's quick start sections are organized around the four unlock targets, and the repository ships a USAGE.md alongside README.md, so that file is the place to look for the exact invocation and module loading sequence rather than guessing at flags. The README does not document a rollback procedure for a machine whose memory map has been scrambled.
What the README does not tell you about recovery
The most important limitation is not in the code. It is in what happens when an address translation you rewired no longer points where the rest of the system expects. The README does not document rollback. It does not describe a safe mode, a recovery jumper, or a procedure for restoring the DRAM controller registers after a failed experiment. A kernel module that changes physical address decoding can make the running system unable to find its own memory, and the failure mode of a bad memory-controller configuration is a machine that does not reach firmware setup.
The project also does not ship releases. The repository has no retrieved releases, so there is no versioned artifact to pin and no changelog describing what changed between states. You are building from the default branch, which had its last push on 2026-08-13. That is recent enough that the code is not abandoned, but a research repository with no releases is a moving target: the tree you build today is whatever the branch contains today.
Finally, the README's own scope statement is a limitation. Family 16h is old hardware. If you are working on a current server or laptop, the documented registers are not there to be poked, and the project gives you a technique to study rather than a tool to run.
Alternatives: reading the pipeline versus rewriting it
If your goal is to understand the x86 address translation pipeline rather than to break it, the README's own diagram is the more useful artifact. It lays out the full path from a 64-bit virtual address through canonical-form checks, segment bases, TLB probing, the five-level page walk, EPT and NPT re-walks for guests, IOMMU walks, MTRR and PAT resolution, cache coherence, and the memory controller hashes. That diagram is a study aid that runs on any machine and cannot brick anything.
If your goal is to inspect memory regions that the operating system does not expose, the conventional approach is a platform-specific interface: a hypervisor that maps the region into a guest, a firmware or BMC path that reads it before the OS starts, or vendor tooling for the specific chipset. Those approaches work within the platform's documented model instead of scrambling the translations underneath it. The difference in approach is the point. skitter-creek-bath-salts changes what an address means; the conventional tools ask the platform to hand over a mapping. The first can reach regions the second cannot, and it can also take the machine down with it.
For later CPU families, where the DRAM controller translation registers are not documented, there is no drop-in alternative from this project. The README says the odyssey is similar across generations and architectures, which is a statement about the shape of the problem, not a promise that the code ports.
Licence, maintenance and what an upgrade costs
The project is MIT licensed. That is permissive: you can read it, modify it, and redistribute it, including in closed work, provided the licence and copyright notice are preserved. It says nothing about the warranty question, and the usual MIT disclaimer of warranty is the relevant clause here, because a memory-controller misconfiguration is a hardware-level failure. This is not legal advice; read the LICENSE file in the repository for the exact terms.
Maintenance is best described by the facts rather than by an adjective. The repository is not archived, and the last push was on 2026-08-13. There are no retrieved releases, so there is no upgrade path in the sense of moving from one tagged version to the next. An upgrade means pulling the default branch and rebuilding with make, then re-verifying that the register offsets still match your hardware, because nothing in the repository guarantees that the branch you build is the branch someone validated against a specific Family 16h part.
The cost of adopting this is therefore not licence fees or subscription seats. It is the time to build a kernel module and userspace component, the risk of an unrecoverable machine, and the ongoing need to re-read the tree whenever you rebuild it. For a lab machine with a socketed flash chip and an external programmer, that is a reasonable budget. For anything else, it is not.
Editorial conclusion
skitter-creek-bath-salts is for hardware security researchers, firmware engineers, and people who already own AMD Family 16h hardware and are comfortable recovering a machine that will not POST. It is not for production servers, cloud hosts, or anyone who needs a supported, documented interface. Before running anything, verify that your CPU is Family 16h, that the DRAM controller translation registers are documented for your part, and that you have a hardware recovery path such as a socketed SPI flash or an external programmer. The README itself frames the project as showing only how to begin, and that framing is accurate: the code targets one generation whose datasheets still document the registers, and later families leave that information out.
Frequently asked questions
What is skitter-creek-bath-salts?
It is a C research project that modifies the DRAM controller's address translation registers on AMD Family 16h CPUs to scramble platform memory and expose protected DRAM regions. The README describes four unlock targets: the Platform Security Processor, System Management Mode, C6 DRAM, and CPU microcode.
How do I build skitter-creek-bath-salts?
Run make from the repository root. The top-level Makefile's default target runs make -C kernel and then make -C userspace, and a clean target is provided for both directories. There is no configure step or package manifest.
Which CPUs does skitter-creek-bath-salts support?
The README states the project was developed and tested on AMD Family 16h CPUs, described as the last generation whose datasheets document the DRAM controller's translation registers. It says 17h and beyond leave that information out.
Community notes