mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2024-12-28 03:14:53 +08:00
ADD: 'script run ntag_3d.lua' - script to program xyz related ntag213f / magic ntag
This commit is contained in:
parent
07d51ec4a4
commit
cd1f5a58f5
1 changed files with 383 additions and 0 deletions
383
client/scripts/ntag_3d.lua
Normal file
383
client/scripts/ntag_3d.lua
Normal file
|
@ -0,0 +1,383 @@
|
|||
local getopt = require('getopt')
|
||||
local lib14a = require('read14a')
|
||||
|
||||
copyright = 'Copyright (c) 2017 IceSQL AB. All rights reserved.'
|
||||
author = "Christian Herrmann"
|
||||
version = 'v1.0.3'
|
||||
desc = [[
|
||||
This script writes a empty template for 3D printing system onto a empty NTAG213 or MAGIC NTAG21*
|
||||
|
||||
Thanks to @jack for his invaluable input on some of the configuration.
|
||||
]]
|
||||
example =[[
|
||||
-- This will generate GOLD, PLA, TH, EU, 200m, tagbased uid.
|
||||
script run ntag_3d -c 46 -m 50 -p 5448 -s 4555 -l 200
|
||||
|
||||
-- This will generate GOLD, PLA, TH, EU, 200m, userbased uid.
|
||||
script run ntag_3d -u 11223344556677 -c 46 -m 50 -p 5448 -s 4555 -l 200
|
||||
|
||||
-- This will generate GOLD, PLA, TH, EU, 200m, userbased uid. and configure a MAGIC NTAG.
|
||||
script run ntag_3d -u 11223344556677 -c 46 -m 50 -p 5448 -s 4555 -l 200 -1
|
||||
]]
|
||||
usage = [[
|
||||
script run calc_ntag_3d -h -t -u <uid> -c <color> -m <material> -p <region> -s <region> -l <length>
|
||||
|
||||
Arguments:
|
||||
-h : this help
|
||||
-t : selftest
|
||||
-u <UID> : UID
|
||||
-c <COLOR> : color of filament
|
||||
-m <MATERIAL> : material of filament
|
||||
-p <REGION> : Manufacturer region
|
||||
-s <REGION> : Sales region
|
||||
-l <LENGTH> : Spool length. Use only 100,200,300. 300 has problems on OSX
|
||||
]]
|
||||
|
||||
local DEBUG = true
|
||||
local TIMEOUT = 10000 -- 10 seconds
|
||||
local bxor = bit32.bxor
|
||||
local band = bit32.band
|
||||
local rshift = bit32.rshift
|
||||
|
||||
local _regions = {
|
||||
{'4742', 'GB'},
|
||||
{'5457', 'TW'},
|
||||
{'4555', 'EU'},
|
||||
{'5553', 'US'},
|
||||
{'454E', 'EN'},
|
||||
{'4A50', 'JP'},
|
||||
{'434E', 'CN'},
|
||||
{'5448', 'TH'},
|
||||
{'4153', 'AS'},
|
||||
{'5246', 'RF'},
|
||||
{'4746', 'GF'},
|
||||
{'4341', 'CA'},
|
||||
{'504D', 'PM'},
|
||||
{'5044', 'PD'},
|
||||
}
|
||||
local _manufacturers = {
|
||||
{'5457', 'TW'},
|
||||
{'434E', 'CN'},
|
||||
{'5448', 'TH'},
|
||||
}
|
||||
local _sales = {
|
||||
{'4742', 'GB'},
|
||||
{'4555', 'EU'},
|
||||
{'5553', 'US'},
|
||||
{'454E', 'EN'},
|
||||
{'504D', 'PM'},
|
||||
}
|
||||
local _materials = {
|
||||
{'20', 'Other material'},
|
||||
{'41', 'ABS'},
|
||||
{'46', 'Flexible TPE Tree'},
|
||||
{'46', 'TPE'},
|
||||
{'46', 'PVA'},
|
||||
{'47', 'PETG'},
|
||||
{'50', 'PLA'},
|
||||
{'51', 'PLA'},
|
||||
{'54', 'Tough PLA'},
|
||||
{'55', 'UVCR'},
|
||||
{'56', 'Water Soluble PVA'},
|
||||
}
|
||||
local _colors = {
|
||||
{'30', 'Bronze'},
|
||||
{'31', 'Silver'},
|
||||
{'32', 'Clear Red'},
|
||||
{'33', 'Clear'},
|
||||
{'34', 'Bottle Green'},
|
||||
{'35', 'Neon Magenta'},
|
||||
{'36', 'SteelBlue'},
|
||||
{'37', 'Sun Orange'},
|
||||
{'38', 'Pearl White'},
|
||||
{'39', 'Copper'},
|
||||
{'41', 'Purple'},
|
||||
{'42', 'Blue'},
|
||||
{'43', 'Neon Tangerine'},
|
||||
{'44', 'Viridity'},
|
||||
{'45', 'Olivine'},
|
||||
{'46', 'Gold'},
|
||||
{'47', 'Green'},
|
||||
{'48', 'Neon Green'},
|
||||
{'49', 'Snow White'},
|
||||
{'4A', 'Neon Yellow'},
|
||||
{'4B', 'Black'},
|
||||
{'4C', 'Violet'},
|
||||
{'4D', 'Grape Purple'},
|
||||
{'4E', 'Purpurine'},
|
||||
{'4F', 'Clear Yellow'},
|
||||
{'50', 'Clear Green'},
|
||||
{'51', 'Clear Tangerine'},
|
||||
{'52', 'Red'},
|
||||
{'53', 'Cyber Yellow'},
|
||||
{'54', 'Tangerine'},
|
||||
{'55', 'Clear Blue'},
|
||||
{'56', 'Clear Purple'},
|
||||
{'57', 'White'},
|
||||
{'58', 'Clear Magenta'},
|
||||
{'59', 'Yellow'},
|
||||
{'5A', 'Nature'},
|
||||
}
|
||||
---
|
||||
--
|
||||
local function find( arr, name )
|
||||
if not name then return nil end
|
||||
name = name:lower()
|
||||
for k, v in pairs(arr) do
|
||||
if ( v[2]:lower() == name or v[1]:lower() == name ) then
|
||||
return v
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
---
|
||||
--
|
||||
local function list( arr, desc )
|
||||
print ('Value\t'..desc)
|
||||
print (string.rep('=', 20))
|
||||
for k, v in pairs(arr) do
|
||||
print(("%s\t%s"):format(v[1],v[2]))
|
||||
end
|
||||
end
|
||||
---
|
||||
-- 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)
|
||||
return nil,err
|
||||
end
|
||||
---
|
||||
-- Usage help
|
||||
local function help()
|
||||
print(copyright)
|
||||
print(version)
|
||||
print(desc)
|
||||
print('Example usage')
|
||||
print(example)
|
||||
end
|
||||
--
|
||||
-- Exit message
|
||||
local function ExitMsg(msg)
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
print(msg)
|
||||
print()
|
||||
end
|
||||
---
|
||||
--
|
||||
local function write_tag(uid, t)
|
||||
|
||||
print('Writing to tag')
|
||||
core.console('hf mf dbg 0')
|
||||
|
||||
local cmd = ''
|
||||
local pwd, pack = core.keygen_algo_d(uid)
|
||||
|
||||
for i= 8, 23 do
|
||||
cmd = ('hf mfu wrbl b %02d d %s k %08X'):format(i, t[i], pwd)
|
||||
core.console(cmd)
|
||||
end
|
||||
|
||||
--cfg1
|
||||
core.console(('hf mfu wrbl b 42 d %s k %08X'):format(t[42], pwd))
|
||||
--cfg0
|
||||
core.console(('hf mfu wrbl b 41 d %s k %08X'):format(t[41], pwd))
|
||||
--dynamic
|
||||
core.console(('hf mfu wrbl b 40 d %s k %08X'):format(t[40], pwd))
|
||||
|
||||
core.console('hf mf dbg 1')
|
||||
print('Done')
|
||||
end
|
||||
---
|
||||
-- configures a magic NTAG for NTAG213, with UID and PWD,PACK.
|
||||
local function configure_magic_ntag(uid)
|
||||
|
||||
print('Configuring MAGIC NTAG')
|
||||
-- Save the global args, those are *our* arguments
|
||||
local myargs = args
|
||||
|
||||
local pwd, pack = core.keygen_algo_d(uid)
|
||||
|
||||
-- Set the arguments for mfu_magic script v1.0.8
|
||||
-- -t 12 == configure NTAG213F
|
||||
-- -u == set UID
|
||||
-- -p == set pwd
|
||||
-- -a == set pack
|
||||
args =('-t 12 -u %s -p %08X -a %04X'):format(uid, pwd, pack)
|
||||
require('../scripts/mfu_magic')
|
||||
|
||||
-- Set back args. Not that it's used, just for the karma...
|
||||
args = myargs
|
||||
|
||||
print('Done')
|
||||
end
|
||||
---
|
||||
-- generates random hex numbers between 31-39
|
||||
local function random_num_hex(length)
|
||||
local str = ""
|
||||
local i
|
||||
for i = 1, length, 1 do
|
||||
str = str..math.random(31, 39)
|
||||
end
|
||||
return str
|
||||
end
|
||||
---
|
||||
--
|
||||
local function nwo( val )
|
||||
local b1 = band(val, 0xFF)
|
||||
local b2 = band( rshift(val, 8), 0xFF)
|
||||
local b3 = band( rshift(val, 16), 0xFF)
|
||||
local b4 = band( rshift(val, 24), 0xFF)
|
||||
return ('%02X%02X%02X%02X'):format(b1, b2, b3, b4)
|
||||
end
|
||||
---
|
||||
-- NTAG213 template
|
||||
local function template_NTAG213(uid, material, color, length, manufacture, sales)
|
||||
local pwd, pack = core.keygen_algo_d(uid)
|
||||
|
||||
local m = tonumber(length, 10) * 1000
|
||||
local m_str = nwo(m)
|
||||
|
||||
local t = {}
|
||||
-- default empty file
|
||||
for i = 0,42 do
|
||||
t[i] = '00000000'
|
||||
end
|
||||
-- t[4] = '0103A00C' --
|
||||
-- t[5] = '340300FE' --
|
||||
-- 6,7
|
||||
t[8] = '5A'..material..color..'00' -- 5A, material, color, 00
|
||||
t[9] = '00'..random_num_hex(3) -- 00, three bytes serial number
|
||||
t[10] = m_str -- total capacity
|
||||
t[11] = m_str -- total capacity
|
||||
t[12] = 'D2002D00' -- fixed
|
||||
t[13] = manufacture..sales -- regioner,
|
||||
t[14] = random_num_hex(4) -- serial number
|
||||
-- 15,16
|
||||
t[17] = '34000000' -- fixed
|
||||
-- 18,19
|
||||
-- remaining capacity of spool
|
||||
t[20] = m_str
|
||||
t[21] = nwo( bxor( m, 0x54321248))
|
||||
t[22] = nwo( bxor( (m - 3876923 ), 0x31275455))
|
||||
t[23] = nwo( bxor( (m + 6923923 ), 0x76235481))
|
||||
-- 24-39
|
||||
t[40] = '000000BD' --dynamic
|
||||
t[41] = '07000008' --cfg0
|
||||
t[42] = '80050000' --cfg1
|
||||
t[43] = ('%08X'):format(pwd)
|
||||
t[44] = ('%04X0000'):format(pack)
|
||||
return t
|
||||
end
|
||||
---
|
||||
-- outputs the called arguments
|
||||
local function print_conf(uid, material, color, length, producer, sales )
|
||||
print('Create tag as following')
|
||||
print( string.rep('--',16) )
|
||||
print('UID ', uid)
|
||||
print('Material ', material[2])
|
||||
print('Color ', color[2])
|
||||
print('Spool length ', length)
|
||||
print('Region')
|
||||
print(' manufacturer', producer[2])
|
||||
print(' sales ', sales[2])
|
||||
print( string.rep('--',16) )
|
||||
end
|
||||
---
|
||||
-- self test
|
||||
local function selftest()
|
||||
list(_regions, 'Regions')
|
||||
list(_materials, 'Materials')
|
||||
list(_colors, 'Colors')
|
||||
return nil
|
||||
end
|
||||
---
|
||||
-- The main entry point
|
||||
local function main(args)
|
||||
|
||||
math.randomseed(os.time());
|
||||
math.random();
|
||||
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
print()
|
||||
|
||||
local uid = '04C5DF4A6D5180'
|
||||
local useUID = false
|
||||
local useMAGIC = false
|
||||
local material, color, length, producer, sales
|
||||
|
||||
if #args == 0 then return help() end
|
||||
|
||||
-- Read the parameters
|
||||
for o, a in getopt.getopt(args, 'ht1u:l:m:c:p:s:') do
|
||||
if o == "h" then return help() end
|
||||
if o == "t" then return selftest() end
|
||||
if o == "u" then uid = a; useUID = true end
|
||||
if o == "m" then material = a end
|
||||
if o == "c" then color = a end
|
||||
if o == "l" then length = tonumber(a) end
|
||||
if o == "p" then producer = a end
|
||||
if o == "s" then sales = a end
|
||||
if o == "1" then useMAGIC = true end
|
||||
end
|
||||
|
||||
color = find(_colors, color)
|
||||
if not color then list(_colors, 'Colors'); return oops('\n\nNot valid color') end
|
||||
|
||||
material = find(_materials, material)
|
||||
if not material then list(_materials, 'Materials'); return oops('\n\nNot valid material') end
|
||||
|
||||
producer = find(_manufacturers, producer)
|
||||
if not producer then list(_manufacturers, 'Regions Manufacturers'); return oops('\n\nNo valid manufacturer region') end
|
||||
|
||||
sales = find(_sales, sales)
|
||||
if not sales then list(_sales, 'Regions Sales'); return oops('\n\nNo valid sales region') end
|
||||
|
||||
if length > 300 then
|
||||
return oops('\n\nNot valid spool length. Must be lesser than 300')
|
||||
end
|
||||
|
||||
if useUID then
|
||||
-- uid string checks
|
||||
if uid == nil then return oops('empty uid string') end
|
||||
if #uid == 0 then return oops('empty uid string') end
|
||||
if #uid ~= 14 then return oops('uid wrong length. Should be 7 hex bytes') end
|
||||
else
|
||||
-- GET TAG UID
|
||||
local tag, err = lib14a.read1443a(false, true)
|
||||
if not tag then return oops(err) end
|
||||
core.clearCommandBuffer()
|
||||
uid = tag.uid
|
||||
end
|
||||
|
||||
--print
|
||||
print_conf(uid, material, color, length, producer, sales )
|
||||
|
||||
-- create template
|
||||
local t = template_NTAG213(uid, material[1], color[1], length, producer[1], sales[1])
|
||||
|
||||
-- using MAGIC NTAG
|
||||
if useMAGIC then
|
||||
configure_magic_ntag(uid)
|
||||
end
|
||||
|
||||
-- write template data to tag
|
||||
write_tag(uid, t)
|
||||
end
|
||||
|
||||
main(args)
|
Loading…
Reference in a new issue