1 local cmds
= require('commands')
2 local getopt
= require('getopt')
3 local bin
= require('bin')
4 local utils
= require('utils')
5 local ansicolors
= require('ansicolors')
6 local amiibo_tools
= require('amiibo_tools')
9 author
= 'George Talusan'
12 This script will try to load a binary datadump of an Amiibo.
13 It will recalculate PWD and PACK if necessary.
16 1. script run hf_mfu_amiibo_sim
17 2. script run hf_mfu_amiibo_sim -f myfile
20 script run hf_mfu_amiibo_sim [-h] [-f <filename>]
24 -f : filename for the datadump to read (bin)
27 local DEBUG
= false -- the debug flag
29 local bxor
= bit32
.bxor
30 local sub
= string.sub
31 local format = string.format
34 -- A debug printout-function
35 local function dbg(args
)
36 if not DEBUG
then return end
37 if type(args
) == 'table' then
48 -- This is only meant to be used when errors occur
49 local function oops(err
)
51 core
.clearCommandBuffer()
61 print(ansicolors
.cyan
..'Usage'..ansicolors
.reset
)
63 print(ansicolors
.cyan
..'Arguments'..ansicolors
.reset
)
65 print(ansicolors
.cyan
..'Example usage'..ansicolors
.reset
)
70 local function ExitMsg(msg
)
71 print( string.rep('--',20) )
72 print( string.rep('--',20) )
77 local function LoadEmulator(uid
, blocks
)
78 io
.write('Sending Amiibo to emulator memory')
84 core
.clearCommandBuffer()
85 cmd
= Command
:newNG
{cmd
= cmds
.CMD_HF_MIFARE_EML_MEMSET
, data
= ('%02x%02x%02x%s'):format(i
, 1, 4, blockdata
)}
86 local err
, msg
= cmd
:sendNG(true)
87 if err
== nil then return err
, msg
end
92 local function main(args
)
93 print( string.rep('--',20) )
94 print( string.rep('--',20) )
96 local result
, err
, hex
97 local inputTemplate
= 'dumpdata.bin'
99 for o
, a
in getopt
.getopt(args
, 'hf:u:') do
100 if o
== 'h' then return help() end
101 if o
== 'f' then inputTemplate
= a
end
104 print(('Loading data from %s'):format(inputTemplate
))
105 hex
, err
= utils
.ReadDumpFile(inputTemplate
)
106 if not hex
then return oops(err
) end
108 -- only deal with missing PWD and PACK, or with 56 emu hdr
109 if #hex
~= 1064 and #hex
~= 1080 and #hex
~= 1192 then return oops('Expecting either a plain binary or emulator dump') end
111 local amiibo_offset
= (#hex
== 1064 or #hex
== 1080) and 0 or 112
112 local amiibo_info
= hex
:sub(amiibo_offset
+ 169, amiibo_offset
+ 169 + 15):lower()
113 local amiibo_game
= amiibo_info
:sub(1, 3)
114 local amiibo_type
= amiibo_info
:sub(7, 8)
115 local amiibo_series
= amiibo_info
:sub(13, 14)
117 dbg('raw: '..ansicolors
.green
..amiibo_info
..ansicolors
.reset
)
118 print('game: '..ansicolors
.green
..amiibo_tools
.db
.game_series
[("0x%s"):format(amiibo_game
)]..ansicolors
.reset
)
119 print('character: '..ansicolors
.green
..amiibo_tools
.db
.amiibos
[("0x%s"):format(amiibo_info
)].name
..ansicolors
.reset
)
120 print('type: '..ansicolors
.green
..amiibo_tools
.db
.types
[("0x%s"):format(amiibo_type
)]..ansicolors
.reset
)
121 print('series: '..ansicolors
.green
..amiibo_tools
.db
.amiibo_series
[("0x%s"):format(amiibo_series
)]..ansicolors
.reset
)
126 -- add empty header if necessary
127 if (#hex
== 1064 or #hex
== 1080) then
129 blocks
[i
] = '00000000'
131 blocks
[2] = '00000086'
134 for i
= 1, #hex
, 8 do
135 blocks
[blockindex
] = hex
:sub(i
, i
+7)
136 blockindex
= blockindex
+ 1
139 -- force lock bytes, otherwise the Amiibo won't be recognized
140 blocks
[16] = blocks
[16]:sub(1, 4)..'0FE0'
143 local uid
= blocks
[14]:sub(1, 6)..blocks
[15]:sub(1, 8)
144 blocks
[147] = ("%08x"):format(bxor(bxor(tonumber(sub(uid
, 2, 10), 16), tonumber(sub(uid
, 6, 14), 16)), 0xaa55aa55))
145 blocks
[148] = "80800000"
147 err
= LoadEmulator(uid
, blocks
)
148 if err
then return oops(err
) end
149 core
.clearCommandBuffer()
150 core
.console(("hf mfu sim -t 7 -u %s"):format(uid
))