Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/pietroborrello/CustomProcessingUnit
The first analysis framework for CPU microcode
https://github.com/pietroborrello/CustomProcessingUnit
Last synced: 2 months ago
JSON representation
The first analysis framework for CPU microcode
- Host: GitHub
- URL: https://github.com/pietroborrello/CustomProcessingUnit
- Owner: pietroborrello
- License: apache-2.0
- Created: 2022-08-07T00:47:46.000Z (over 2 years ago)
- Default Branch: master
- Last Pushed: 2023-03-13T16:54:52.000Z (over 1 year ago)
- Last Synced: 2023-11-07T16:17:50.546Z (about 1 year ago)
- Language: C
- Homepage:
- Size: 3.08 MB
- Stars: 349
- Watchers: 9
- Forks: 24
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
- awesome-tee-blockchain - pietroborrello/CustomProcessingUnit - The first analysis framework for CPU microcode (Repositories / C)
README
# Custom Processing Unit
[![DOI](https://zenodo.org/badge/522085221.svg)](https://zenodo.org/badge/latestdoi/522085221)
Custom Processing Unit is the first dynamic analysis framework able to hook, patch and trace CPU microcode at the software level.
It works by leveraging [undocumented instructions](https://github.com/chip-red-pill/udbgInstr) in Intel CPUs that allow access to the CRBUS.
Using our [microcode decompiler](https://github.com/pietroborrello/ghidra-atom-microcode) we reverse engineered how the CPU uses the CRBUS and by replicating the interactions we have full control of the CPU.Find the static analysis framework as subtree in [this](./ghidra-processor-module) folder, or at https://github.com/pietroborrello/ghidra-atom-microcode.
Check out our slides describing this work [here](./slides.pdf).
**Note**: Custom Processing Unit requires a Red-Unlocked CPU: currently, only [Goldmont CPUs](https://en.wikipedia.org/wiki/Goldmont) (GLM) have a [public Red Unlock](https://github.com/ptresearch/IntelTXE-PoC). We tested Gigabyte GB-BPCE-3350C with CPU stepping 0x9 and 0xa (cpuid 0x000506C9 and 0x000506CA).
Custom Processing Unit is made up of a UEFI application and a few libraries. The UEFI application interacts with the GLM CPU, while the libraries provide different helpers to compile microcode into the UEFI application and analyze its output.
## Prerequisites
1. Follow the steps to red unlock your Goldmont CPU from https://github.com/ptresearch/IntelTXE-PoC.
2. Create a bootable USB key with an EFI shell
3. Install [gnu-efi](https://wiki.osdev.org/GNU-EFI) on your main host## Setup
```
GNU_EFI_DIR= make
```This will build the source microcode files and the UEFI application into `cpu.efi`.
Copy `cpu.efi` into the `\EFI\` folder of the USB key, plug it in the GLM and boot into the EFI shell.Run `map -r` in the efi shell to identify the USB key device and `:` to mount it.
## Run Custom Processing Unit
Run `./cpu.efi` to print the help:
```
Usage:
patch: p
patch & exec: x
perf: f
zero out m&p: z
hook: h [m&p idx] [uop addr] [patch addr]
template: m
dump imms: di
dump rom: dr
dump msrs: dm
dump SMM: ds [address] [size]
cpuid: c [rax] [rcx]
rdmsr: rm [msr]
wrmsr: wm [msr]
read: r [cmd] [addr]
write: w [cmd] [addr] [value]
invoke: i [addr]
update ucode: u [size]
ldat read: lr [port] [array] [bank] [idx] [addr] [optional size]
ldat write: lw [port] [array] [bank] [idx] [addr] [value]
```### Simple instructions
`cpu` provides helpers to run simple instructions from the command line:
* cpuid
* rdmsr
* wrmsr### Complex actions
`cpu` provides interfaces to complex CPU routines that are interesting to execute to study cpu behavior:
* `u`: update the CPU ucode with the provided (signed) patch
* `f`: collect performance counters while running microcode### Raw udbgrd and udbwr
`cpu` provides raw interfaces to the undocumented instructions `udbrd` and `udbgwr`.
The most interesting commands they provide are:
* 0x0: access CRBUS
* 0x10: access UROM
* 0x40: access stgbuf
* 0xd8: invoke ucode routine from address### LDAT access
`cpu` exposes LDAT access routines to read and write. Specify the parameters `[port] [array] [bank] [idx] [addr]` to read or write there.
Interesting ports are:
* 0x6a0: microcode sequencer, which has access to the internal the ucode ROM and RAM
* 0x120: load/store buffers
* 0x3c0: instruction cache
* 0x630: ITLBPlease notice that accessing some of these internal components may cause the CPU to freeze.
### Patch microcode
`cpu` provides functionalities to install patches in the microcode.
1. Write your microcode patch in `bios/ucode_patches/ucode_patch.u` (look at the other patches for examples)
2. Build the UEFI application
3. Execute `cpu.efi p` to install the patch at the address provided in `.org`.Notice that in the microcode, only the addresses between 0x7c00 and 0x7e00 are writable and meaningful to patch.
Running `cpu.efi x`, it will also execute the microcode patched and print the `rax, rbx, rcx, rdx` registers as result.
### Match & Patch
To automatically execute microcode at certain CPU events or microcode points, `cpu` leverages the Match and Patch.
It defines a microcode address to hook and the microcode address to jump to when the hook is triggered.* `z`: resets all the match & patch.
* `h`: installs an hook, given an index (0-0x20), an address to hook (0-0x7c00) and a target address to execute (0x7c00-0x7e00).### Tracing microcode
By installing multiple hooks and continuously executing an instruction, `cpu` is able to trace the microoperations performed by such an instruction, and dump them. To trace:
1. Write the instruction to be traced after the `// [TRACED INSTRUCTION HERE]` in `get_trace_clock_at()`.
2. Build the UEFI application.
3. Trace with: `cpu.efi m`.
It will create a `trace.txt` file that contains all the addresses that have been hit.
4. Execute `uasm-lib/uasm.py -t trace.txt > parsed_trace.txt`.
It will generate a full trace of the microcode executed during the instruction.Notice that `uasm.py` will leverage the `ms_arrayX.txt` files in its folder to generate a disassembly of the microinstructions executed. These are for GLM with stepping 0x9 (cpuid 0x000506C9). Please generate the proper arrays in case you have a different stepping.
You can use the LDAT dump functionalities for this purpose.### Secret memory dumpers
The CPU has different inaccessible buffers from the architecture, for which we provide routines to dump:
* `smm`: SMROM (or any other address while disabling SMM protection)
* `rom`: internal ROM
* `imms`: CPU hardcoded immediates
* `msrs`: internal MSRs configurations### Writing microcode patches
We provide an assembler that generates header files to be compiled into the `cpu.efi` UEFI application.
Look into the provided patches in `bios/ucode_patches` for the syntax.
It supports simple operations and labels.
Assemble a microcode patch with `uasm.py -i ucode_patch.u -o ucode_patch.h`.
`cpu.efi` will be compiled and automatically include the microcode patch that you want to apply.#### Example
file: `code_patch.u`
```
.org 0x7c00rax:= ZEROEXT_DSZ32(0x00001337)
rbx:= ZEROEXT_DSZ32(0x00001337)
rcx:= ZEROEXT_DSZ32(0x00001337)
rdx:= ZEROEXT_DSZ32(0x00001337)
```recompile, then run in the GLM:
```
cpu.efi z # zero out match & patch
cpu.efi p # apply the patch
cpu.efi h 0 0x0428 0x7c00 # rdrand entry point
```
now every time `rdrand` is executed, it will return `0x1337` in the registers.### Cite Us
Our work has been published in a [paper](https://pietroborrello.com/publication/woot23/woot23.pdf) at [WOOT](https://wootconference.org/) 2023:
```
@inproceedings{Borrello2023CustomProcessingUnit,
title = {{CustomProcessingUnit}: Reverse Engineering and Customization of Intel Microcode},
author = {Borrello, Pietro and Easdon, Catherine and Schwarzl, Martin and Czerny, Roland and Schwarz, Michael},
booktitle = {IEEE Workshop on Offensive Technologies (WOOT 23)},
year = {2023},
}
```### Experiments
The experiments described in the paper can be run with:
```
cpu.efi e [exp_idx]
```with `[exp_idx]`:
0. Fast ucode breakpoints
1. Constant-Time ucode division
2. x86 PAC
3. Attack x86 PAC with PACMAN
4. Conditional Hardware Breakpoints