mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-14 10:37:23 -07:00
removed problematic code. Attribution to @jamchamb for his amii lua scripts
This commit is contained in:
parent
485eccd670
commit
aabf3ecafa
4 changed files with 0 additions and 409 deletions
Binary file not shown.
|
@ -1,90 +0,0 @@
|
|||
local luamiibo_open, err = package.loadlib("./libluamiibo.so", "luaopen_luamiibo")
|
||||
|
||||
if err then
|
||||
print(err)
|
||||
return
|
||||
end
|
||||
|
||||
local luamiibo = luamiibo_open()
|
||||
|
||||
local FLAG_SETTINGS_INITIALIZED = 4
|
||||
local FLAG_APPDATA_INITIALIZED = 3
|
||||
|
||||
local Amiibo = {}
|
||||
Amiibo.__index = Amiibo
|
||||
|
||||
function Amiibo:new (o)
|
||||
o = o or {}
|
||||
setmetatable(o, self)
|
||||
|
||||
if o.tag ~= nil then
|
||||
o:load_tag(o.tag)
|
||||
end
|
||||
return o
|
||||
end
|
||||
|
||||
function Amiibo:load_tag (tag)
|
||||
self.plain = luamiibo.unpack(tag)
|
||||
|
||||
-- UID
|
||||
local raw_uid = string.sub(self.plain, 469, 469 + 8)
|
||||
self.uid = string.sub(raw_uid, 1, 3) .. string.sub(raw_uid, 5, 8)
|
||||
|
||||
-- Settings
|
||||
local count, flags = bin.unpack('C', string.sub(self.plain, 45, 45))
|
||||
self.setting_flags = flags
|
||||
self.settings_initialized = self:check_flag(FLAG_SETTINGS_INITIALIZED)
|
||||
self.appdata_initialized = self:check_flag(FLAG_APPDATA_INITIALIZED)
|
||||
|
||||
local _, appdatacounter = bin.unpack('>S', string.sub(self.plain, 49, 50))
|
||||
self.appdata_counter = appdatacounter
|
||||
|
||||
self.figure_id = string.sub(self.plain, 477, 477 + 8)
|
||||
|
||||
-- UTF-16 nickname string
|
||||
self.nickname = string.sub(self.plain, 57, 76)
|
||||
end
|
||||
|
||||
|
||||
function Amiibo:export_tag ()
|
||||
return luamiibo.pack(self.plain)
|
||||
end
|
||||
|
||||
|
||||
function Amiibo:check_flag (power)
|
||||
local flag = math.pow(2, power)
|
||||
return flag == bit32.band(self.setting_flags, flag)
|
||||
end
|
||||
|
||||
|
||||
function Amiibo:get_pwd ()
|
||||
local xorkey = "\xaa\x55\xaa\x55"
|
||||
|
||||
local result = ''
|
||||
for i = 1, 4 do
|
||||
result = result ..
|
||||
bin.pack('C',
|
||||
bit32.bxor(self.uid:byte(i+1),
|
||||
self.uid:byte(i+3),
|
||||
xorkey:byte(i)))
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
-- Hack to make UTF-16 nicknames into regular char string
|
||||
-- Only works for ASCII nicknames
|
||||
function Amiibo:display_nickname()
|
||||
local nickname_tmp = self.nickname
|
||||
|
||||
local nickname = ''
|
||||
for i = 1, nickname_tmp:len() do
|
||||
if i % 2 == 0 then
|
||||
nickname = nickname .. nickname_tmp:sub(i, i)
|
||||
end
|
||||
end
|
||||
|
||||
return nickname
|
||||
end
|
||||
|
||||
return Amiibo
|
|
@ -1,84 +0,0 @@
|
|||
local cmds = require('commands')
|
||||
local utils = require('utils')
|
||||
local reader = require('read14a')
|
||||
|
||||
local Emulator = {
|
||||
_VERSION = 'emulator.lua 0.1.0',
|
||||
_DESCRIPTION = 'emulator memory interface',
|
||||
BLOCK_SZ = 512,
|
||||
BLOCK_COUNT = 512 / 16
|
||||
}
|
||||
|
||||
function Emulator:set_mem (data, clear_first)
|
||||
if clear_first then
|
||||
-- Clear out the emulator memory first
|
||||
local memclrCmd = Command:newMIX{cmd = cmds.CMD_HF_MIFARE_EML_MEMCLR}
|
||||
|
||||
local _, err = memclrCmd:sendMIX()
|
||||
if err then
|
||||
print('Failed to clear emulator memory:', err)
|
||||
return false
|
||||
else
|
||||
print('Cleared emulator memory')
|
||||
end
|
||||
end
|
||||
|
||||
-- Can fit 32 16 byte blocks per command (512 total bytes max)
|
||||
for i = 0, (data:len() / self.BLOCK_SZ) do
|
||||
local cur_out_block = data:sub((i*self.BLOCK_SZ) + 1, (i*self.BLOCK_SZ) + self.BLOCK_SZ)
|
||||
print(string.format('Transmission #%u: %u bytes', i, cur_out_block:len()))
|
||||
|
||||
-- arg1: start block number
|
||||
-- arg2: block count
|
||||
local memsetCmd = Command:newMIX{cmd = cmds.CMD_HF_MIFARE_EML_MEMSET,
|
||||
data = utils.hexlify(cur_out_block),
|
||||
arg1 = i * self.BLOCK_COUNT,
|
||||
arg2 = self.BLOCK_COUNT}
|
||||
|
||||
-- Send command and wait for response
|
||||
local _, err = memsetCmd:sendMIX()
|
||||
if err then
|
||||
print('Failed setting memory', err)
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
print('Emulator memory set')
|
||||
return true
|
||||
end
|
||||
|
||||
-- Read <size> bytes from emulator memory
|
||||
function Emulator:get_mem (size)
|
||||
local MAX_BLOCKS = 4
|
||||
local result = ''
|
||||
|
||||
-- We can request a maximum of 4 blocks (16 bytes each) per command,
|
||||
-- according to mifarecmd.c
|
||||
for i = 0, (size / (MAX_BLOCKS * 16)) do
|
||||
-- arg1: start block number
|
||||
-- arg2: block count (max 4)
|
||||
local getmemCmd = Command:newMIX{cmd = cmds.CMD_HF_MIFARE_EML_MEMGET,
|
||||
arg1 = i * MAX_BLOCKS,
|
||||
arg2 = MAX_BLOCKS,
|
||||
arg3 = 0}
|
||||
|
||||
local response, err = getmemCmd:sendMIX()
|
||||
if err then
|
||||
print('Failed getting memory:', err)
|
||||
return false
|
||||
end
|
||||
|
||||
-- USB data begins after four 64-bit values
|
||||
local data_begin = ((64/8) * 4) + 1
|
||||
response = string.sub(response, data_begin)
|
||||
|
||||
-- Truncate to the received 16 byte blocks
|
||||
response = string.sub(response, 1, 16 * MAX_BLOCKS)
|
||||
|
||||
result = result .. response
|
||||
end
|
||||
|
||||
return string.sub(result, 1, size)
|
||||
end
|
||||
|
||||
return Emulator
|
|
@ -1,235 +0,0 @@
|
|||
local utils = require('utils')
|
||||
local cmds = require('commands')
|
||||
local Amiibo = require('amiibolib')
|
||||
local reader = require('read14a')
|
||||
local bin = require('bin')
|
||||
local emu = require('emulator')
|
||||
local luamiibo_open, err = package.loadlib("./libluamiibo.so", "luaopen_luamiibo")
|
||||
|
||||
if err then
|
||||
print(err)
|
||||
return
|
||||
end
|
||||
|
||||
local luamiibo = luamiibo_open()
|
||||
|
||||
local function nfc_read_amiibo ()
|
||||
|
||||
local command = Command:newMIX{
|
||||
cmd = cmds.CMD_HF_MIFAREU_READCARD,
|
||||
arg1 = 0,
|
||||
arg2 = 135
|
||||
}
|
||||
|
||||
local result, err = command:sendMIX()
|
||||
if result then
|
||||
-- Do Mifare Ultralight read
|
||||
local count, cmd, arg0, data_len, offset = bin.unpack('LLLL', result)
|
||||
|
||||
if arg0 == 0 then
|
||||
return nil, "Card select failed"
|
||||
end
|
||||
|
||||
-- Do GetFromBigBuf
|
||||
local data = core.GetFromBigBuf(offset, data_len)
|
||||
|
||||
return data, err
|
||||
else
|
||||
return nil, "Couldn't read Amiibo"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function emulate_amiibo (amiibo_data)
|
||||
-- Make UID args
|
||||
-- Use known ID/sig for known ECDSA signature - REPLACE ME!
|
||||
local uid_bytes = '\x00\x04\xFF\xFF\xFF\xFF\xFF\xFF'
|
||||
local ecc_sig = ''
|
||||
.. '\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
.. '\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
.. '\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
.. '\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
|
||||
if amiibo_data:len() == 520 then
|
||||
-- Add common ending bytes
|
||||
print('Added missing ending bytes')
|
||||
amiibo_data = amiibo_data
|
||||
.. '\x01\x00\x0F\xBD\x00\x00\x00\x04'
|
||||
.. '\x5F\x00\x00\x00\x00\x00\x00\x00'
|
||||
.. '\x00\x00\x00\x00'
|
||||
end
|
||||
|
||||
if amiibo_data:len() == 572 then
|
||||
-- Get ECC signature and use original serial
|
||||
uid_bytes = '\x00' .. amiibo_data:sub(1,3) .. amiibo_data:sub(5,8)
|
||||
ecc_sig = amiibo_data:sub(541, 572)
|
||||
print('Amiibo image contains ECC signature', hexlify(ecc_sig))
|
||||
--amiibo_data = amiibo_data:sub(1,540)
|
||||
elseif amiibo_data:len() == 540 then
|
||||
if uid_bytes ~= '\x00\x04\xFF\xFF\xFF\xFF\xFF\xFF' then
|
||||
print('Using known ECC sig pair')
|
||||
else
|
||||
print('No known ECC/sig pair; using null signature')
|
||||
uid_bytes = '\x00' .. amiibo_data:sub(1,3) .. amiibo_data:sub(5,8)
|
||||
end
|
||||
amiibo_data = amiibo_data .. ecc_sig
|
||||
else
|
||||
print('Unusual Amiibo image size', amiibo_data:len())
|
||||
end
|
||||
|
||||
-- Send amiibo data to emulator memory. If the Amiibo was just scanned, this
|
||||
-- is already set!
|
||||
if not emu:set_mem(amiibo_data, false) then
|
||||
print('Failed to set emulator card memory')
|
||||
return
|
||||
end
|
||||
|
||||
-- Get UID parts
|
||||
local count, uid_first, uid_second = bin.unpack('>I>I', uid_bytes)
|
||||
print(string.format('Simulating with UID: 0x%04x 0x%04x', uid_first, uid_second))
|
||||
|
||||
-- Begin simulating NTAG215
|
||||
local simCmd = Command:newMIX{
|
||||
cmd = cmds.CMD_HF_ISO14443A_SIMULATE,
|
||||
arg1 = 7,
|
||||
arg2 = uid_first,
|
||||
arg3 = uid_second
|
||||
}
|
||||
local _, err = simCmd:sendMIX()
|
||||
if err then
|
||||
print('Failed to start simulator', err)
|
||||
return
|
||||
else
|
||||
print('Starting simulator')
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function test_packing()
|
||||
-- Load Pikachu dump instead
|
||||
local dumpfile = io.open("pika.bin", "rb")
|
||||
local pikachu = dumpfile:read("*all")
|
||||
|
||||
local unpacked_pika = luamiibo.unpack(pikachu)
|
||||
local packed_data = luamiibo.pack(unpacked_pika)
|
||||
|
||||
print('Original', utils.hexlify(pikachu))
|
||||
print('Unpacked', utils.hexlify(unpacked_pika))
|
||||
print('Packed', utils.hexlify(packed_data))
|
||||
end
|
||||
|
||||
|
||||
local function load_sim(argv)
|
||||
local tag = assert(io.open(argv[2], "rb"))
|
||||
local data = tag:read("*all")
|
||||
tag:close()
|
||||
|
||||
emulate_amiibo(data)
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
local function dump_sim(argv)
|
||||
local keypath = argv[2]
|
||||
if keypath == nil then
|
||||
keypath = 'amiitool_keys.bin'
|
||||
end
|
||||
luamiibo.load_keys(keypath)
|
||||
|
||||
-- Read all 135 pages
|
||||
dump = emu:get_mem(540)
|
||||
|
||||
if dump == false then
|
||||
print('Failed to read emulator memory')
|
||||
else
|
||||
local amiiboData = Amiibo:new{tag = dump}
|
||||
print('Dumped ' .. dump:len() .. ' bytes')
|
||||
print(hexlify(dump))
|
||||
print('Nickname: ' .. utils.hexlify(amiiboData:display_nickname()))
|
||||
|
||||
-- Write dump to file
|
||||
local filename = argv[2]
|
||||
if filename ~= nil then
|
||||
local outfile = assert(io.open(filename, "wb"))
|
||||
outfile:write(dump)
|
||||
outfile:close()
|
||||
print('Wrote to ' .. filename)
|
||||
else
|
||||
print('No output file specified')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function main(args)
|
||||
argv = {}
|
||||
for arg in string.gmatch(args, "%S+") do
|
||||
table.insert(argv, arg)
|
||||
end
|
||||
|
||||
-- Load and emulate Amiibo from image
|
||||
if argv[1] == 'help' then
|
||||
print('read - scan amiibo')
|
||||
print('load <amiibo.bin> - load and simulate amiibo')
|
||||
print('dump [output_file] - dump card memory')
|
||||
print('help - print this help')
|
||||
return
|
||||
elseif argv[1] == 'load' then
|
||||
load_sim(argv)
|
||||
return
|
||||
elseif argv[1] == 'dump' then
|
||||
dump_sim(argv)
|
||||
return
|
||||
elseif argv[1] ~= 'read' and argv[1] ~= nil then
|
||||
print('Unknown command')
|
||||
end
|
||||
|
||||
local keypath = argv[2]
|
||||
if keypath == nil then
|
||||
keypath = 'amiitool_keys.bin'
|
||||
end
|
||||
|
||||
if luamiibo.load_keys(keypath) then
|
||||
print('Loaded retail keys from ' .. keypath)
|
||||
else
|
||||
print('Failed to load retail keys from ' .. keypath)
|
||||
return
|
||||
end
|
||||
|
||||
local tag, err = nfc_read_amiibo()
|
||||
if err then
|
||||
print(err)
|
||||
return
|
||||
elseif tag:len() ~= 540 then
|
||||
print('Incorrect tag data size ' .. tag:len())
|
||||
return
|
||||
end
|
||||
|
||||
parsed_tag = reader.parse14443a(tag)
|
||||
print('Tag type:', parsed_tag.name)
|
||||
print('Tag UID:', parsed_tag.uid)
|
||||
print('Tag len:', tag:len())
|
||||
--print('Tag data:', utils.hexlify(tag))
|
||||
|
||||
local amiiboData = Amiibo:new{tag = tag}
|
||||
|
||||
--print('Unpacked:', utils.hexlify(amiiboData.plain))
|
||||
--print('Repacked:', utils.hexlify(amiiboData:export_tag()))
|
||||
|
||||
print('Figure ID:', utils.hexlify(amiiboData.figure_id))
|
||||
print('Settings init:', amiiboData.settings_initialized)
|
||||
|
||||
if amiiboData.settings_initialized then
|
||||
print('Nickname:', amiiboData:display_nickname())
|
||||
print('Appdata writes:', amiiboData.appdata_counter)
|
||||
end
|
||||
|
||||
print('UID:', utils.hexlify(amiiboData.uid))
|
||||
print('Write key:', utils.hexlify(amiiboData:get_pwd()))
|
||||
|
||||
--print('Attempting emulation...')
|
||||
--emulate_amiibo(amiiboData:export_tag())
|
||||
return
|
||||
end
|
||||
|
||||
main(args)
|
Loading…
Add table
Add a link
Reference in a new issue