Skip to content

Instantly share code, notes, and snippets.

@rob-brown
Last active January 17, 2025 23:27
Show Gist options
  • Select an option

  • Save rob-brown/488685b35012e71c3de9f696438ccee9 to your computer and use it in GitHub Desktop.

Select an option

Save rob-brown/488685b35012e71c3de9f696438ccee9 to your computer and use it in GitHub Desktop.
HexFiend Amiibo Binary Templates
little_endian
# HexFiend Reference: https://github.com/HexFiend/HexFiend/blob/master/templates/Reference.md
proc parse_system {} {
goto 0
section "System" {
hex 1 "BCC1 (UID3 ^ UID4 ^ UID5 ^ UID6)"
hex 1 "Internal (Always 0x48)"
hex 2 "Static Lock (Always 0x0FE0)"
hex 4 "Capability Container (CC)"
hex 32 "Unfixed Hash (Data Hash)"
hex 1 "Always 0xA5"
uint16 "Amiibo Write Counter"
hex 1 "?"
section "Settings" {
hex 1 "Flags"
hex 1 "Country Code ID"
uint16 "CRC Counter"
uint16 "Init Date"
uint16 "Write Date"
hex 4 "CRC"
big_endian
utf16 20 "Nickname"
little_endian
section "Owner Mii" {
parse_mii
}
hex 8 "Program ID"
uint16 "Config Write Counter"
hex 4 "App ID"
hex 2 "?"
hex 32 "Hash"
}
}
}
proc parse_ssbu_app {} {
goto 0xDC
section "App" {
hex 4 "Checksum"
hex 2 "?"
parse_learning
parse_type
hex 8 "Reserved? (Always 0)"
section "Spirit Abilities" {
uint8 "Ability 1" ;# 0xEC
uint8 "Ability 2" ;# 0xED
uint8 "Ability 3" ;# 0xEE
}
section "Mii Fighter" {
set mii_attack [uint8] ;# 0xEF
entry "Neutral Special" [expr ($mii_attack & 0b00000011) >> 0] 1 0xEF
entry "Side Special" [expr ($mii_attack & 0b00001100) >> 2] 1 0xEF
entry "Up Special" [expr ($mii_attack & 0b00110000) >> 4] 1 0xEF
entry "Down Special" [expr ($mii_attack & 0b11000000) >> 6] 1 0xEF
uint16 "Hat" ;# 0xF0
uint16 "Outfit" ;# 0xF2
hex 88 "Mii Data"
# Custom moves at 0xFF? (Ask MiDe)
}
parse_experience
section "Spirit Stats" {
int16 "Attack Stat" ;# 0x150
int16 "Defense Stat" ;# 0x152
hex 2 "Speed Stat from Smash 4? (Always 0)"
}
uint16 "Gift" ;# 0x156
uint8 "Journey Victories?" ;# 0x158
hex 11 "?"
hex 4 "Reserved? (Always 0)"
section "Behavior" {
section "Personality" {
set aggression [uint16 "Aggression"] ;# 0x168
entry "Attack Bit 1" [expr ($aggression & 0x0080) >> 7] 2 0x168
entry "Attack Bit 2" [expr ($aggression & 0x8000) >> 15] 2 0x168
entry "Attack Bits 3" [expr ($aggression & 0x3F00) >> 8] 2 0x168
entry "Double-jump Bit" [expr ($aggression & 0x4000) >> 14] 2 0x168
uint16 "Edge guard" ;# 0x16A
uint16 "Anticipation" ;# 0x16C
uint16 "Defensiveness" ;# 0x16E
}
hex 1 "?"
section "Other Attacks" {
uint8 "Grab" ;# 0x171
hex 2 "?"
uint8 "Smash Attack Charge" ;# 0x174
set dash [uint8];
# A value of 1 and high smash attack charging value wil cause charging, a value of 0 means no charging regardless of the other byte.
entry "Smash Attack Charge Toggle" [expr ($dash & 0x1)] 1 0x175 ;# 0x175b8
entry "Dash Attack" [expr ($dash & 0xFE) >> 1] 1 0x175 ;# 0x175b0-7
hex 1 "?"
# Meteor contains footstool?
uint8 "Meteor Edgeguard" ;# 0x177
uint8 "Parry" ;# 0x178
}
hex 2 "?"
section "Items" {
uint16 "Smashball Collector" ;# 0x17B
uint16 "Special Flag Collector" ;# 0x17D
hex 1 "?"
uint8 "Item Grabber" ;# 0x180
}
uint8 "Taunt" ;# 0x181
hex 6 "?"
section "Main Move Set" {
section "Basic Attacks" {
uint8 "Jab" ;# 0x188
uint8 "Forward Tilt" ;# 0x189
uint8 "Up Tilt 1" ;# 0x18A
uint8 "Up Tilt 2" ;# 0x18B
set down_tilt [uint8 "Down Tilt"] ;# 0x18C
entry "Hard Punish Forward Smash" [expr ($down_tilt & 0x10) >> 4] 1 0x18C
}
section "Smash Attacks" {
uint8 "Forward Smash" ;# 0x18D
uint8 "Up Smash" ;# 0x18E
uint8 "Down Smash" ;# 0x18F
uint8 "Down Smash (common) + Neutral Special (rare)" ;# 0x190
}
section "Grounded Attacks" {
uint8 "Grounded Neutral Special" ;# 0x191
uint8 "Grounded Side Special" ;# 0x192
uint8 "Grounded Up Special" ;# 0x193
uint8 "Grounded Down Special" ;# 0x194
uint8 "Up Special Ambiguous" ;# 0x195
}
section "Basic Aerial Attacks" {
set fair [uint8 "Forward Air"] ;# 0x196
entry "Neutral air off 1" [expr ($fair & 0x08) >> 3] 1 0x196
set bair [uint8 "Back Air"] ;# 0x197
entry "Neutral air off 2" [expr ($bair & 0x02) >> 1] 1 0x197
set uair [uint8 "Up Air"] ;# 0x198
entry "Neutral air off 3" [expr ($uair & 0x02) >> 1] 1 0x198
uint8 "Down Air" ;# 0x199
}
section "Special Aerial Attacks" {
uint8 "Aerial Neutral Special" ;# 0x19A
uint8 "Aerial Side Special" ;# 0x19B
uint8 "Aerial Up Special" ;# 0x19C
uint8 "Aerial Down Special" ;# 0x19D
}
}
hex 4 "?"
}
uint8 "Mii Voice (or Pokemon Trainer starter)" ;# 0x1A2
uint8 "Costume" ;# 0x1A3b4-b8
hex 16 "Reserved? (Always 0)"
}
}
proc parse_learning {} {
set byte [uint8]
set learning [expr ($byte & 0x1)]
set journey [expr ($byte & 0x2)]
if { $learning == 0 } {
entry "Learning" "Off (0)" 1 0xE2
} else {
entry "Learning" "On (1)" 1 0xE2
}
if { $journey == 0 } {
entry "On a Journey" "No (0)" 1 0xE2
} else {
entry "On a Journey" "Yes (1)" 1 0xE2
}
}
proc parse_type {} {
set type [uint8]
switch [expr $type >> 6] {
0 {
entry "Type" "Neutral (0)" 1 0xE3
}
1 {
entry "Type" "Sword (1)" 1 0xE3
}
2 {
entry "Type" "Shield (2)" 1 0xE3
}
3 {
entry "Type" "Grab (3)" 1 0xE3
}
default {
entry "Type" "Invalid!" 1 0xE3
}
}
if {[expr $type & 0x1] == 0} {
entry "Amiibox Modded" "False" 1 0xE3
} else {
entry "Amiibox Modded" "True" 1 0xE3
}
}
proc parse_experience {} {
section "Experience" {
set level [uint16 "Level Experience"]
if { $level >= 3912 } {
entry "Amiibo Level" "50" 2 0x14C
} elseif { $level >= 3669 } {
entry "Amiibo Level" "49" 2 0x14C
} elseif { $level >= 3429 } {
entry "Amiibo Level" "48" 2 0x14C
} elseif { $level >= 3209 } {
entry "Amiibo Level" "47" 2 0x14C
} elseif { $level >= 2999 } {
entry "Amiibo Level" "46" 2 0x14C
} elseif { $level >= 2799 } {
entry "Amiibo Level" "45" 2 0x14C
} elseif { $level >= 2619 } {
entry "Amiibo Level" "44" 2 0x14C
} elseif { $level >= 2459 } {
entry "Amiibo Level" "43" 2 0x14C
} elseif { $level >= 2329 } {
entry "Amiibo Level" "42" 2 0x14C
} elseif { $level >= 2220 } {
entry "Amiibo Level" "41" 2 0x14C
} elseif { $level >= 2115 } {
entry "Amiibo Level" "40" 2 0x14C
} elseif { $level >= 2012 } {
entry "Amiibo Level" "39" 2 0x14C
} elseif { $level >= 1910 } {
entry "Amiibo Level" "38" 2 0x14C
} elseif { $level >= 1816 } {
entry "Amiibo Level" "37" 2 0x14C
} elseif { $level >= 1724 } {
entry "Amiibo Level" "36" 2 0x14C
} elseif { $level >= 1637 } {
entry "Amiibo Level" "35" 2 0x14C
} elseif { $level >= 1555 } {
entry "Amiibo Level" "34" 2 0x14C
} elseif { $level >= 1478 } {
entry "Amiibo Level" "33" 2 0x14C
} elseif { $level >= 1406 } {
entry "Amiibo Level" "32" 2 0x14C
} elseif { $level >= 1339 } {
entry "Amiibo Level" "31" 2 0x14C
} elseif { $level >= 1277 } {
entry "Amiibo Level" "30" 2 0x14C
} elseif { $level >= 1222 } {
entry "Amiibo Level" "29" 2 0x14C
} elseif { $level >= 1167 } {
entry "Amiibo Level" "28" 2 0x14C
} elseif { $level >= 1112 } {
entry "Amiibo Level" "27" 2 0x14C
} elseif { $level >= 1058 } {
entry "Amiibo Level" "26" 2 0x14C
} elseif { $level >= 1004 } {
entry "Amiibo Level" "25" 2 0x14C
} elseif { $level >= 950 } {
entry "Amiibo Level" "24" 2 0x14C
} elseif { $level >= 896 } {
entry "Amiibo Level" "23" 2 0x14C
} elseif { $level >= 843 } {
entry "Amiibo Level" "22" 2 0x14C
} elseif { $level >= 790 } {
entry "Amiibo Level" "21" 2 0x14C
} elseif { $level >= 737 } {
entry "Amiibo Level" "20" 2 0x14C
} elseif { $level >= 684 } {
entry "Amiibo Level" "19" 2 0x14C
} elseif { $level >= 632 } {
entry "Amiibo Level" "18" 2 0x14C
} elseif { $level >= 580 } {
entry "Amiibo Level" "17" 2 0x14C
} elseif { $level >= 528 } {
entry "Amiibo Level" "16" 2 0x14C
} elseif { $level >= 476 } {
entry "Amiibo Level" "15" 2 0x14C
} elseif { $level >= 426 } {
entry "Amiibo Level" "14" 2 0x14C
} elseif { $level >= 376 } {
entry "Amiibo Level" "13" 2 0x14C
} elseif { $level >= 330 } {
entry "Amiibo Level" "12" 2 0x14C
} elseif { $level >= 284 } {
entry "Amiibo Level" "11" 2 0x14C
} elseif { $level >= 238 } {
entry "Amiibo Level" "10" 2 0x14C
} elseif { $level >= 195 } {
entry "Amiibo Level" "9" 2 0x14C
} elseif { $level >= 155 } {
entry "Amiibo Level" "8" 2 0x14C
} elseif { $level >= 120 } {
entry "Amiibo Level" "7" 2 0x14C
} elseif { $level >= 90 } {
entry "Amiibo Level" "6" 2 0x14C
} elseif { $level >= 63 } {
entry "Amiibo Level" "5" 2 0x14C
} elseif { $level >= 41 } {
entry "Amiibo Level" "4" 2 0x14C
} elseif { $level >= 22 } {
entry "Amiibo Level" "3" 2 0x14C
} elseif { $level >= 8 } {
entry "Amiibo Level" "2" 2 0x14C
} else {
entry "Amiibo Level" "1" 2 0x14C
}
set cpu [uint16 "CPU Experience"]
if { $cpu >= 2765 } {
entry "CPU Level" "9" 2 0x14E
} elseif { $cpu >= 2065 } {
entry "CPU Level" "8" 2 0x14E
} elseif { $cpu >= 1603 } {
entry "CPU Level" "7" 2 0x14E
} elseif { $cpu >= 1141 } {
entry "CPU Level" "6" 2 0x14E
} elseif { $cpu >= 749 } {
entry "CPU Level" "5" 2 0x14E
} elseif { $cpu >= 434 } {
entry "CPU Level" "4" 2 0x14E
} elseif { $cpu >= 210 } {
entry "CPU Level" "3" 2 0x14E
} elseif { $cpu >= 63 } {
entry "CPU Level" "2" 2 0x14E
} else {
entry "CPU Level" "1" 2 0x14E
}
}
}
proc parse_amiibo_number {} {
section "Amiibo Number" {
hex 2 "Character #"
hex 1 "Variation"
set form [uint8]
switch $form {
0 {
entry "Form" "Figurine (0)" 1 0x1DF
}
1 {
entry "Form" "Card (1)" 1 0x1DF
}
2 {
entry "Form" "Yarn (2)" 1 0x1DF
}
default {
entry "Form" "Unknown" 1 0x1DF
}
}
hex 2 "Amiibo #"
hex 1 "Set"
hex 1 "0x02"
}
}
proc parse_remainder {} {
goto 0x1B4
section "System" {
hex 32 "Locked Hash (Tag Hash)"
hex 1 "UID0 (Always 0x04)"
hex 1 "UID1"
hex 1 "UID2"
hex 1 "BCC0 (UID0 ^ UID1 ^ UID2 ^ 0x88)"
hex 1 "UID3"
hex 1 "UID4"
hex 1 "UID5"
hex 1 "UID6"
parse_amiibo_number
hex 36 "Keygen Salt"
hex 3 "Dynamic Lock (Always 0x01000F)"
hex 1 "RFUI (Always 0xBD)"
hex 4 "CFG0 (Always 0x00000004)"
hex 4 "CFG1 (Always 0x5F000000)"
hex 4 "PWD"
hex 2 "PACK"
hex 2 "RFUI"
}
}
proc parse_mii {} {
# See https://www.3dbrew.org/wiki/Mii#Checksum
set start [pos]
hex 1 "0x3"
set byte [uint8]
set allow_copying [expr ($byte & 0x1)]
set profanity_flag [expr ($byte & 0x2)]
set region_lock [expr ($byte & 0xC)]
set character_set [expr ($byte & 0x30)]
entry "Allow Copying" $allow_copying 1 [expr $start + 1]
entry "Profanity Flag" $profanity_flag 1 [expr $start + 1]
entry "Region Lock" $region_lock 1 [expr $start + 1]
entry "Character Set" $character_set 1 [expr $start + 1]
hex 1 "Mii position"
set version [expr [uint8] >> 4]
entry "Version" $version 1 [expr $start + 3]
hex 8 "System ID"
hex 4 "Mii ID"
hex 6 "Creator's MAC"
hex 2 "Padding"
set bytes [uint16]
if {[expr $bytes & 0x1] == 0} {
entry "Gender" "Male" 2 [expr $start + 0x18]
} else {
entry "Gender" "Female" 2 [expr $start + 0x18]
}
entry "Birthday Month" [expr ($bytes & 0x1E) >> 1] 2 [expr $start + 0x18]
entry "Birthday Day" [expr ($bytes & 0x3E0) >> 5] 2 [expr $start + 0x18]
entry "Favorite Color" [expr ($bytes & 0x3C00) >> 10] 2 [expr $start + 0x18]
entry "Favorite Mii" [expr ($bytes & 0x4000) >> 14] 2 [expr $start + 0x18]
utf16 20 "Amiibo Name"
hex 2 "Width and Height"
hex 1 "Sharing, face shape, and skin color"
hex 1 "Wrinkles and makeup"
hex 1 "Hair style"
hex 1 "Hair color and flip hair"
hex 4 "Eyes"
hex 4 "Eyebrows"
hex 2 "Nose"
hex 2 "Mouse"
hex 2 "Mouse and mustache"
hex 2 "Beard and mustache"
hex 2 "Glasses"
hex 2 "Mole"
utf16 20 "Author Name"
hex 2 "0x0000"
hex 2 "Mii Checksum"
}
parse_system
parse_ssbu_app
parse_remainder
little_endian
proc parse_amiibo_number {} {
section "Amiibo Number" {
hex 2 "Character #"
hex 1 "Variation"
hex 1 "Form"
hex 2 "Amiibo #"
hex 1 "Set"
hex 1 "0x02"
}
}
section "Not Encrypted" {
set uid0 [hex 1 "UID0"]
set uid1 [hex 1 "UID1"]
set uid2 [hex 1 "UID2"]
uint8 "Actual BCC0"
entry "Expected BCC0" [expr $uid0 ^ $uid1 ^ $uid2 ^ 0x88]
set uid3 [hex 1 "UID3"]
set uid4 [hex 1 "UID4"]
set uid5 [hex 1 "UID5"]
set uid6 [hex 1 "UID6"]
uint8 "Actual BCC1"
entry "Expected BCC1" [expr $uid3 ^ $uid4 ^ $uid5 ^ $uid6]
hex 1 "Internal (Always 0x48)"
hex 2 "Static Lock (Always 0x0FE)"
hex 4 "Capability Container (CC)"
hex 1 "0xA5"
uint16 "Write counter"
uint8 "?"
}
section "Encrypted" {
uint16 "Settings"
uint16 "CRC Counter"
uint16 "Init Date"
uint16 "Write Date"
uint32 "CRC"
hex 20 "Nickname"
}
section "Not Encrypted" {
hex 32 "Locked Hash"
parse_amiibo_number
uint32 "?"
hex 32 "Keygen Salt"
hex 32 "Unfixed Hash"
}
section "Encrypted" {
hex 96 "Owner Mii"
hex 8 "Title ID"
uint16 "Write Counter"
uint32 "Amiibo AppID"
uint16 "?"
hex 32 "Hash"
hex 216 "App Data"
}
section "Not Encrypted" {
hex 3 "Dynamic Lock (Always 0x01000F)"
hex 1 "RFUI (Always 0xBD)"
hex 4 "CFG0 (Always 0x00000004)"
hex 4 "CFG1 (Always 0x5F000000)"
hex 4 "PWD"
hex 2 "PACK"
hex 2 "RFUI"
}
@15696

15696 commented Feb 19, 2022

Copy link
Copy Markdown

Very helpful thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment