forked from iceman1001/proxmark3
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7c56c2c
commit 03e8d39
Showing
3 changed files
with
174 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <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 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 |