Proxmark3 (iceman) Lua script to easily write Galaxy's Edge kyber crystal data to EM4305 rfid tags
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
local cmds = require('commands') | |
local getopt = require('getopt') | |
local bin = require('bin') | |
local utils = require('utils') | |
local cmds = require('commands') | |
local ansicolors = require('ansicolors') | |
copyright = 'Various copyrights - Based on hf_mfu_amiibo_sim.lua' | |
author = 'Chris Jones <cmsj@tenshu.net>' | |
version = 'v2.0' | |
desc = [[ | |
Easily write Disney kyber crystal information to EM4305 tags. | |
Before using this script, please make sure your rfid tag is working properly, e.g. with: lf em 4x05 info | |
Save this script to ~/.proxmark3/luascripts/ | |
]] | |
example = [[ | |
1. script run kyber -c oldluke | |
2. script run kyber -c red | |
3. script run kyber -l | |
]] | |
usage = [[ | |
script run kyber [-h] [-l] -c NAME | |
]] | |
arguments = [[ | |
-h : this help | |
-l : show all of the krystal names available, and their color | |
-c NAME : the name of a crystal to write to the tag, or the name of one of the available colors | |
-i : identify a crystal | |
]] | |
local DEBUG = false -- the debug flag | |
local format = string.format | |
local addr4 = "0001805F" | |
local addr5 = "000001FF" | |
local crystals = { | |
quigonjinn = {"0C803000", "green"}, | |
yoda = {"00C03000", "green"}, | |
yoda8ball = {"5D183000", "green"}, | |
oldobiwan = {"29803000", "blue"}, | |
oldluke = {"25C03000", "blue"}, | |
mace1 = {"6F803000", "purple"}, | |
mace2 = {"63C03000", "purple"}, | |
templeguard = {"7B003000", "yellow"}, | |
mazkanata = {"77403000", "yellow"}, | |
chirrut = {"14403000", "white"}, | |
ahsoka = {"18003000", "white"}, | |
vader = {"5E003000", "red"}, | |
vader8ball = {"3E183000", "red"}, | |
palpatine = {"52403000", "red"}, | |
maul = {"46C03000", "red"}, | |
dooku = {"31403000", "red"}, | |
snoke = {"1B183000", "black"} | |
} | |
--- | |
-- 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(ansicolors.red..'ERROR: '..err..ansicolors.clear) | |
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 | |
--- | |
-- Print crystal list | |
local function list_crystals() | |
local tkeys = {} | |
for k in pairs(crystals) do table.insert(tkeys, k) end | |
table.sort(tkeys) | |
print(ansicolors.cyan..'Available crystal names:'..ansicolors.reset) | |
for _,k in ipairs(tkeys) do | |
v = crystals[k] | |
print(" "..k.." ("..v[2]..")") | |
end | |
end | |
-- | |
-- Identify a crystal | |
local function identify() | |
local res = nil | |
-- Check address 4 | |
res = core.em4x05_read("4", "", "") | |
if res == nil then | |
oops("Error reading crystal (address 4), check alignment and try again") | |
return | |
end | |
local r_addr4 = string.upper(("%08x"):format(res)) | |
if r_addr4 ~= addr4 then | |
oops("Incorrect value read for address 4. Expected: "..addr4.." got: "..r_addr4) | |
return | |
end | |
print("Address 4 matches expected value ("..addr4..")") | |
-- Check address 5 | |
res = core.em4x05_read("5", "", "") | |
if res == nil then | |
oops("Error reading crystal (address 5), check alignment and try again") | |
return | |
end | |
local r_addr5 = string.upper(("%08x"):format(res)) | |
if r_addr5 ~= addr5 then | |
oops("Incorrect value read for address 5. Expected: "..addr5.." got: "..r_addr5) | |
return | |
end | |
print("Address 5 matches expected value ("..addr5..")") | |
res = core.em4x05_read("6", "", "") | |
if res == nil then | |
oops("Error reading crystal (address 6), check alignment and try again") | |
return | |
end | |
local id = string.upper(("%08x"):format(res)) | |
local name = nil | |
print("Address 6 contains value ("..id..")") | |
for k,v in pairs(crystals) do | |
-- print("Checking: "..v[1].." against: "..id.."...") | |
if v[1] == id then | |
name = k | |
--print("Crystal identified as: "..k) | |
break | |
end | |
end | |
if name == nil then | |
oops("Unknown crystal: "..id) | |
return nil | |
end | |
local color = crystals[name][2] | |
local bgcolor = nil | |
if color == "purple" then color = "magenta" end | |
bgcolor = ansicolors["on"..color] | |
print("Crystal identified as: "..bgcolor..ansicolors[color].." "..name.." "..ansicolors.clear) | |
end | |
-- | |
-- Exit message | |
local function ExitMsg(msg) | |
print( string.rep('--',20) ) | |
print( string.rep('--',20) ) | |
print(msg) | |
print() | |
end | |
local function main(args) | |
print( string.rep('--',20) ) | |
print( string.rep('--',20) ) | |
local result, err, hex | |
local inputTemplate = nil | |
for o, a in getopt.getopt(args, 'hlic:') do | |
if o == 'h' then return help() end | |
if o == 'l' then return list_crystals() end | |
if o == 'i' then return identify() end | |
if o == 'c' then inputTemplate = a end | |
end | |
if inputTemplate == nil then | |
oops("No crystal name specified") | |
return help() | |
end | |
local crystal = nil | |
-- Check if the supplied input template is either a key in our data, or a color name | |
if crystals[inputTemplate] ~= nil then | |
crystal = crystals[inputTemplate] | |
else | |
for k,v in pairs(crystals) do | |
if v[2] == inputTemplate then | |
crystal = v | |
break | |
end | |
end | |
end | |
if crystal == nil then | |
return oops("Unable to find a matching crystal for: "..inputTemplate) | |
end | |
print((ansicolors.green..'Preparing crystal for: %s'..ansicolors.clear):format(inputTemplate)) | |
print(string.format("Crystal data: \n color: %s\n addr4: %s\n addr5: %s\n addr6: %s", crystal[2], addr4, addr5, crystal[1])) | |
core.clearCommandBuffer() | |
print(ansicolors.green.."\nWriting crystal values:"..ansicolors.clear) | |
core.console(("lf em 4x05 write -a 04 -d %s"):format(addr4)) | |
core.console(("lf em 4x05 write -a 05 -d %s"):format(addr5)) | |
core.console(("lf em 4x05 write -a 06 -d %s"):format(crystal[1])) | |
print(ansicolors.green.."\nChecking crystal values:"..ansicolors.clear) | |
identify() | |
-- print(ansicolors.green.."\nReading values, please check they are correct:"..ansicolors.clear) | |
-- core.console("lf em 4x05 read -a 04") | |
-- core.console("lf em 4x05 read -a 05") | |
-- core.console("lf em 4x05 read -a 06") | |
end | |
main(args) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment