From 03e8d39e17bb56fe42666026020e61608863a292 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 28 Jul 2018 12:33:27 +0200 Subject: [PATCH] ADD: amiboo stuff --- client/libluamiibo.so | Bin 0 -> 23648 bytes client/lualibs/amiibolib.lua | 90 +++++++++++++++++++++++++++++++++++ client/lualibs/emulator.lua | 84 ++++++++++++++++++++++++++++++++ 3 files changed, 174 insertions(+) create mode 100644 client/libluamiibo.so create mode 100644 client/lualibs/amiibolib.lua create mode 100644 client/lualibs/emulator.lua diff --git a/client/libluamiibo.so b/client/libluamiibo.so new file mode 100644 index 0000000000000000000000000000000000000000..2cd716aa08e79dba46e064f833fcfa2facce5fac GIT binary patch literal 23648 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 literal 0 HcmV?d00001 diff --git a/client/lualibs/amiibolib.lua b/client/lualibs/amiibolib.lua new file mode 100644 index 000000000..c5cccb81c --- /dev/null +++ b/client/lualibs/amiibolib.lua @@ -0,0 +1,90 @@ +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 diff --git a/client/lualibs/emulator.lua b/client/lualibs/emulator.lua new file mode 100644 index 000000000..36ef38ac1 --- /dev/null +++ b/client/lualibs/emulator.lua @@ -0,0 +1,84 @@ +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 emuMemclearCmd = Command:new{cmd = cmds.CMD_MIFARE_EML_MEMCLR, arg1 = 0, arg2 = 0, arg3 = 0} + + local _, err = reader.sendToDevice(emuMemclearCmd) + 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 emuMemsetCmd = Command:new{cmd = cmds.CMD_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 = reader.sendToDevice(emuMemsetCmd) + if err then + print('Failed setting memory', err) + return false + end + end + + print('Emulator memory set') + return true +end + +-- Read 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 emuMemGetCmd = Command:new{cmd = cmds.CMD_MIFARE_EML_MEMGET, + arg1 = i * MAX_BLOCKS, + arg2 = MAX_BLOCKS, + arg3 = 0} + + local response, err = reader.sendToDevice(emuMemGetCmd) + 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