mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2024-11-16 06:43:29 +08:00
152 lines
4.5 KiB
Lua
152 lines
4.5 KiB
Lua
local cmds = require('commands')
|
|
local getopt = require('getopt')
|
|
local bin = require('bin')
|
|
local utils = require('utils')
|
|
local ansicolors = require('ansicolors')
|
|
local amiibo_tools = require('amiibo_tools')
|
|
|
|
copyright = ''
|
|
author = 'George Talusan'
|
|
version = 'v0.0.2'
|
|
desc = [[
|
|
This script will try to load a binary datadump of an Amiibo.
|
|
It will recalculate PWD and PACK if necessary.
|
|
]]
|
|
example = [[
|
|
1. script run hf_mfu_amiibo_sim
|
|
2. script run hf_mfu_amiibo_sim -f myfile
|
|
]]
|
|
usage = [[
|
|
script run hf_mfu_amiibo_sim [-h] [-f <filename>]
|
|
]]
|
|
arguments = [[
|
|
-h : this help
|
|
-f : filename for the datadump to read (bin)
|
|
]]
|
|
|
|
local DEBUG = false -- the debug flag
|
|
|
|
local bxor = bit32.bxor
|
|
local sub = string.sub
|
|
local format = string.format
|
|
|
|
---
|
|
-- A debug printout-function
|
|
local function dbg(args)
|
|
if not DEBUG then return end
|
|
if type(args) == 'table' then
|
|
local i = 1
|
|
while result[i] do
|
|
dbg(result[i])
|
|
i = i+1
|
|
end
|
|
else
|
|
print('###', args)
|
|
end
|
|
end
|
|
---
|
|
-- This is only meant to be used when errors occur
|
|
local function oops(err)
|
|
print('ERROR:', err)
|
|
core.clearCommandBuffer()
|
|
return nil, err
|
|
end
|
|
---
|
|
-- Usage help
|
|
local function help()
|
|
print(copyright)
|
|
print(author)
|
|
print(version)
|
|
print(desc)
|
|
print(ansicolors.cyan..'Usage'..ansicolors.reset)
|
|
print(usage)
|
|
print(ansicolors.cyan..'Arguments'..ansicolors.reset)
|
|
print(arguments)
|
|
print(ansicolors.cyan..'Example usage'..ansicolors.reset)
|
|
print(example)
|
|
end
|
|
--
|
|
-- Exit message
|
|
local function ExitMsg(msg)
|
|
print( string.rep('--',20) )
|
|
print( string.rep('--',20) )
|
|
print(msg)
|
|
print()
|
|
end
|
|
|
|
local function LoadEmulator(uid, blocks)
|
|
io.write('Sending Amiibo to emulator memory')
|
|
local cmd, blockdata
|
|
for i=0,148,1 do
|
|
blockdata = blocks[i]
|
|
io.write('.')
|
|
io.flush()
|
|
core.clearCommandBuffer()
|
|
cmd = Command:newNG{cmd = cmds.CMD_HF_MIFARE_EML_MEMSET, data = ('%02x%02x%02x%s'):format(i, 1, 4, blockdata)}
|
|
local err, msg = cmd:sendNG(true)
|
|
if err == nil then return err, msg end
|
|
end
|
|
io.write('\n')
|
|
end
|
|
|
|
local function main(args)
|
|
print( string.rep('--',20) )
|
|
print( string.rep('--',20) )
|
|
|
|
local result, err, hex
|
|
local inputTemplate = 'dumpdata.bin'
|
|
|
|
for o, a in getopt.getopt(args, 'hf:u:') do
|
|
if o == 'h' then return help() end
|
|
if o == 'f' then inputTemplate = a end
|
|
end
|
|
|
|
print(('Loading data from %s'):format(inputTemplate))
|
|
hex, err = utils.ReadDumpFile(inputTemplate)
|
|
if not hex then return oops(err) end
|
|
|
|
-- only deal with missing PWD and PACK, or with 56 emu hdr
|
|
if #hex ~= 1064 and #hex ~= 1080 and #hex ~= 1192 then return oops('Expecting either a plain binary or emulator dump') end
|
|
|
|
local amiibo_offset = (#hex == 1064 or #hex == 1080) and 0 or 112
|
|
local amiibo_info = hex:sub(amiibo_offset + 169, amiibo_offset + 169 + 15):lower()
|
|
local amiibo_game = amiibo_info:sub(1, 3)
|
|
local amiibo_type = amiibo_info:sub(7, 8)
|
|
local amiibo_series = amiibo_info:sub(13, 14)
|
|
|
|
dbg('raw: '..ansicolors.green..amiibo_info..ansicolors.reset)
|
|
print('game: '..ansicolors.green..amiibo_tools.db.game_series[("0x%s"):format(amiibo_game)]..ansicolors.reset)
|
|
print('character: '..ansicolors.green..amiibo_tools.db.amiibos[("0x%s"):format(amiibo_info)].name..ansicolors.reset)
|
|
print('type: '..ansicolors.green..amiibo_tools.db.types[("0x%s"):format(amiibo_type)]..ansicolors.reset)
|
|
print('series: '..ansicolors.green..amiibo_tools.db.amiibo_series[("0x%s"):format(amiibo_series)]..ansicolors.reset)
|
|
|
|
local blocks = {}
|
|
local blockindex = 0
|
|
|
|
-- add empty header if necessary
|
|
if (#hex == 1064 or #hex == 1080) then
|
|
for i = 0, 13, 1 do
|
|
blocks[i] = '00000000'
|
|
end
|
|
blocks[2] = '00000086'
|
|
blockindex = 14
|
|
end
|
|
for i = 1, #hex, 8 do
|
|
blocks[blockindex] = hex:sub(i, i+7)
|
|
blockindex = blockindex + 1
|
|
end
|
|
|
|
-- force lock bytes, otherwise the Amiibo won't be recognized
|
|
blocks[16] = blocks[16]:sub(1, 4)..'0FE0'
|
|
|
|
-- add PWD and PACK
|
|
local uid = blocks[14]:sub(1, 6)..blocks[15]:sub(1, 8)
|
|
blocks[147] = ("%08x"):format(bxor(bxor(tonumber(sub(uid, 2, 10), 16), tonumber(sub(uid, 6, 14), 16)), 0xaa55aa55))
|
|
blocks[148] = "80800000"
|
|
|
|
err = LoadEmulator(uid, blocks)
|
|
if err then return oops(err) end
|
|
core.clearCommandBuffer()
|
|
core.console(("hf mfu sim -t 7 -u %s"):format(uid))
|
|
end
|
|
main(args)
|