1 local cmds
= require('commands')
2 local getopt
= require('getopt')
3 local lib14a
= require('read14a')
4 local utils
= require('utils')
5 local ansicolors
= require('ansicolors')
11 This is a script that reads AZTEK ISO14443a tags.
12 It starts from block 0 and ends at default block 20. Use 'b' to say different endblock.
13 xor: the first three block (0,1,2) is not XORED. The rest seems to be xored.
17 script run hf_14a_aztek
20 script run hf_14a_aztek -b 10
23 script run hf_14a_aztek [-h] [-b]
27 -b endblock in decimal (1-255, default 20)
31 local DEBUG
= false -- the debug flag
33 -- A debug printout-function
34 local function dbg(args
)
35 if not DEBUG
then return end
36 if type(args
) == 'table' then
47 -- This is only meant to be used when errors occur
48 local function oops(err
)
50 core
.clearCommandBuffer()
60 print(ansicolors
.cyan
..'Usage'..ansicolors
.reset
)
62 print(ansicolors
.cyan
..'Arguments'..ansicolors
.reset
)
64 print(ansicolors
.cyan
..'Example usage'..ansicolors
.reset
)
68 --- Picks out and displays the data read from a tag
69 -- Specifically, takes a usb packet, converts to a Command
70 -- (as in commands.lua), takes the data-array and
71 -- reads the number of bytes specified in arg1 (arg0 in c-struct)
72 -- and displays the data
73 -- @blockno just to print which block the data belong to
74 -- @param usbpacket the data received from the device
75 function showdata(blockno
, data
)
76 local xorkey
= '55AA55AA55AA55AA6262'
81 local item
= string.sub(data
, i
, i
+3)
82 local xor
= string.sub(xorkey
, i
, i
+3)
85 rs
= bit32
.bxor(tonumber(item
,16) , tonumber(xor
,16))
87 rs
= tonumber(item
, 16)
89 dex
= (dex
..'%04X'):format(rs
)
92 print( (" %02d | %s"):format(blockno
,s
))
95 -- Send a "raw" iso14443a package, ie "hf 14a raw" command
96 function sendRaw(rawdata
, options
)
98 local flags
= lib14a
.ISO14A_COMMAND
.ISO14A_NO_DISCONNECT
99 + lib14a
.ISO14A_COMMAND
.ISO14A_RAW
100 + lib14a
.ISO14A_COMMAND
.ISO14A_APPEND_CRC
101 + lib14a
.ISO14A_COMMAND
.ISO14A_NO_RATS
103 local command
= Command
:newMIX
{cmd
= cmds
.CMD_HF_ISO14443A_READER
,
104 arg1
= flags
, -- Send raw
105 -- arg2 contains the length, which is half the length
106 -- of the ASCII-string rawdata
107 arg2
= string.len(rawdata
)/2,
110 return command
:sendMIX(options
.ignore_response
)
113 -- The main entry point
116 local ignore_response
= false
119 -- Read the parameters
120 for o
, a
in getopt
.getopt(args
, 'hb:') do
121 if o
== 'h' then return help() end
122 if o
== 'b' then endblock
= a
end
124 endblock
= endblock
or 20
126 -- First of all, connect
127 info
, err
= lib14a
.read(true, true)
132 core
.clearCommandBuffer()
137 print(('\nFound Card UID [%s]\n'):format(info
.uid
))
139 print('blk | data | xored')
140 print('----+------------------+-------------------')
141 for block
= 00, endblock
do
142 local cmd
= string.format('10%02x00', block
)
143 res
, err
= sendRaw(cmd
, {ignore_response
= ignore_response
})
149 local cmd_response
= Command
.parse(res
)
150 local len
= tonumber(cmd_response
.arg1
) * 2
151 local data
= string.sub(tostring(cmd_response
.data
), 0, len
-4)
153 showdata(block
, data
)
154 table.insert(blockData
, data
)
156 print("----+------------------+-------------------")
159 local filename
, err
= utils
.WriteDumpFile(info
.uid
, blockData
)
160 if err
then return oops(err
) end
162 print(string.format('\nDumped data into %s', filename
))
165 -------------------------
167 -------------------------
170 dbg('Performing test')
174 -- Flip the switch here to perform a sanity check.
175 -- It read a nonce in two different ways, as specified in the usage-section
176 if '--test' == args
then