Zenella

AMD Zen 5 Microcode Update Reversing — Binary Ninja Plugin

Binary Ninja Python GPL v3 AMD Zen 5

What is Zenella?

Zenella is a lightweight Binary Ninja plugin that applies a known data-structure layout to AMD Zen 5 microcode .bin blobs (typically 0x3820 bytes). It turns raw binary noise into a navigable, annotated structure — without attempting to disassemble microcode.

📋

Struct Mapping

Defines 10 typed structures covering the full 0x3820-byte patch layout — header, crypto blocks, options, match/mask registers, and the µcode region.

🔍

Instant Navigation

Binary Ninja's Linear view becomes immediately navigable. Header fields are parsed, random blocks labeled, and µcode is represented as an array of 4-byte micro-ops.

Three Commands

One command to define types, one to apply at offset 0, and one to apply wherever your cursor sits — ideal for blobs embedded inside larger firmware images.

🧩

API Compatible

Ships multiple fallback code-paths for enum and structure construction, so it works across older and newer Binary Ninja Python API variants without modification.

Patch Memory Layout

Every AMD Zen 5 microcode blob is exactly 0x3820 bytes. Zenella maps the following regions:

Header 0x0000 – 0x001F 32 B
Signature 0x0020 – 0x011F 256 B
Modulus 0x0120 – 0x021F 256 B
Check 0x0220 – 0x031F 256 B
Options 0x0320 – 0x0323 4 B
Revision 0x0324 – 0x0327 4 B
Match Registers 0x0328 – 0x034F 40 B
Mask Registers 0x0350 – 0x037F 48 B
Microcode Region 0x0380 – 0x381F 13472 B — 3368 µops
SymbolOffsetSizeTypeDescription
amd_mc_header 0x0000 0x20 AMD_MC_Header Date, revision, loader ID, checksum, CPUID flags
amd_mc_signature 0x0020 0x100 u8[256] RSA-style signature block
amd_mc_modulus 0x0120 0x100 u8[256] Public-key modulus block
amd_mc_check 0x0220 0x100 u8[256] Check block (possibly Montgomery-related constant)
amd_mc_options 0x0320 0x04 AMD_MC_UcodeOptions autorun, encrypted, loader ID copy
amd_mc_rev 0x0324 0x04 u32 Revision copy (extended header)
amd_mc_match_regs 0x0328 0x28 AMD_MC_MatchRegisterBlock 10 × u32 match registers
amd_mc_mask_regs 0x0350 0x30 AMD_MC_MaskRegisterBlock 12 × u32 mask registers
amd_ucode_region 0x0380 0x34A0 AMD_Zen_MicrocodeRegion 3368 × 4-byte micro-ops (opcode, b1, imm16)

Menu Commands

After installation the plugin registers three commands under AMD Microcode in the Binary Ninja Plugins menu:

AMD Microcode › Define types (self-contained)

Define Types

Registers all AMD microcode structs and enumerations in the current database — without applying anything to the binary view. Useful for inspecting the type library before committing to a layout pass.

  • All enums and structs become available in the type browser
  • Safe to run multiple times (idempotent)
AMD Microcode › Apply layout at file start (0x0)

Apply at 0x0 recommended

Defines types (if not already defined) and then applies the full 9-region layout starting at offset 0x0000. This is the go-to command for standalone microcode .bin files.

  • Creates named data variables with descriptive comments
  • Triggers a Binary Ninja analysis update
  • Warns in the log if fewer than 0x3820 bytes are available
AMD Microcode › Apply layout at cursor

Apply at Cursor

Same as above, but uses the current cursor address as the blob base. Essential when the microcode is embedded inside a larger firmware image at a non-zero offset.

  • Navigate to the blob header, then invoke this command
  • Partial layout is applied with a log warning if truncated
Binary Ninja plugin menu screenshot

Plugin commands as they appear in Binary Ninja's Plugins menu

Defined Data Types

Zenella creates the following types in the Binary Ninja database. All structures are packed (no implicit padding).

AMD_MC_Header 0x20 bytes

u16year
u8day
u8month
u32update_revision
AMD_MC_LoaderIdTagloader_id
u8data_size
u8init_flag
u32data_checksum
u16nb_ven
u16nb_dev
u16sb_ven
u16sb_dev
AMD_MC_CpuIdproc_sig
u8bios_revision
u8flags
u8[2]reserved, reserved2

AMD_Zen_MicroOp 4 bytes

AMD_Zen_Opcodeopcode
u8b1
u16imm16

AMD_Zen_Opcode enum

0xDEAMD_ZEN_TYPE5_READ
0xBEAMD_ZEN_TYPE7_ALU_OR
0xA0AMD_ZEN_TYPE3_WRITE
0xFFAMD_ZEN_TYPE_REG_NOP
0x00AMD_ZEN_UOP_UNKNOWN

AMD_MC_UcodeOptions 4 bytes

u8autorun
u8encrypted
u16loaderid

AMD_MC_LoaderIdTag enum (u16)

0x8004AMD_MC_LOADER_8004
0x8005AMD_MC_LOADER_8005
0x8010AMD_MC_LOADER_8010
0x8015AMD_MC_LOADER_8015
0x8016AMD_MC_LOADER_8016

AMD_MC_MatchRegisterBlock 40 bytes

u32[10]match_reg

AMD_MC_MaskRegisterBlock 48 bytes

u32[12]mask_reg

AMD_MC_CpuId 4 bytes

u32proc_sig

AMD_MC_Patch 0x3820 bytes — top-level container

AMD_MC_Headerheader
u8[256]signature
u8[256]modulus
u8[256]check
AMD_MC_UcodeOptionsoptions
u32rev
AMD_MC_MatchRegisterBlockmatch_regs
AMD_MC_MaskRegisterBlockmask_regs
AMD_Zen_MicrocodeRegionmicrocode — 3368 × AMD_Zen_MicroOp

Installation

1

Open the plugin folder

In Binary Ninja go to Plugins → Open Plugin Folder…

~/Library/Application Support/Binary Ninja/plugins/   # macOS
%APPDATA%\Binary Ninja\plugins\                       # Windows
~/.binaryninja/plugins/                               # Linux
2

Copy the plugin file

Place amd_zen_ucode.py into the plugins directory.

cp amd_zen_ucode.py ~/Library/Application\ Support/Binary\ Ninja/plugins/
3

Restart Binary Ninja

After restarting you will see the AMD Microcode submenu appear in Plugins. No additional dependencies are required — the plugin uses only the Binary Ninja Python API that ships with the desktop application.

Requirements

  • Binary Ninja Desktop with Python scripting enabled (standard install)
  • No external Python packages — uses Binary Ninja's embedded Python runtime
  • Works across multiple Binary Ninja API versions (tested against older and newer builds)

Common Workflow

📂

Open the blob

Drop the AMD microcode .bin file into Binary Ninja. Use Raw or PE binary view depending on your source.

▶️

Run the command

Go to Plugins → AMD Microcode → Apply layout at file start (0x0). For embedded blobs, navigate to the blob header first then use Apply layout at cursor.

🔎

Navigate the structure

Switch to Linear view. All regions are now labeled. Click any field in amd_mc_header to inspect date, revision, loader ID, and checksum immediately.

🧪

Analyze micro-ops

Jump to amd_ucode_region. Each 4-byte entry is typed as AMD_Zen_MicroOp — opcode, operand byte, and 16-bit immediate are broken out. Known opcodes are resolved to enum names.

Live demo — applying the layout to a Zen 5 microcode blob

Note: Zenella deliberately does not disassemble microcode. It maps bytes to structs and adds sparse comments for quick triage. Full microcode ISA reversing is a separate research effort.