Skip to content

Instantly share code, notes, and snippets.

@rob-brown
Last active February 19, 2022 01:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rob-brown/488685b35012e71c3de9f696438ccee9 to your computer and use it in GitHub Desktop.
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
Copy link

15696 commented Feb 19, 2022

Very helpful thanks

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