1 local cmds = require('commands')
2 local getopt = require('getopt')
3 local lib14a = require('read14a')
4 local utils = require('utils')
7 script run ufodump -b 10
12 This is a script that reads AZTEK iso14443a tags.
13 It starts from block 0, and ends at default block 20. Use 'b' to say different endblock.
15 xor: the first three block (0,1,2) is not XORED. The rest seems to be xored.
19 b endblock in decimal (1-255, default 20)
23 local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
24 local DEBUG = false -- the debug flag
26 -- A debug printout-function
33 -- This is only meant to be used when errors occur
36 core.clearCommandBuffer()
42 print("Example usage")
46 -- writes data to ascii textfile.
47 function writeDumpFile(uid, blockData)
48 local destination = string.format("%s.eml", uid)
49 local file = io.open(destination, "w")
51 return nil, string.format("Could not write to file %s", destination)
53 local rowlen = string.len(blockData[1])
55 for i,block in ipairs(blockData) do
56 if rowlen ~= string.len(block) then
57 print(string.format("WARNING: Dumpdata seems corrupted, line %d was not the same length as line 1",i))
59 file:write(block.."\n")
65 --- Picks out and displays the data read from a tag
66 -- Specifically, takes a usb packet, converts to a Command
67 -- (as in commands.lua), takes the data-array and
68 -- reads the number of bytes specified in arg1 (arg0 in c-struct)
69 -- and displays the data
70 -- @blockno just to print which block the data belong to
71 -- @param usbpacket the data received from the device
72 function showdata(blockno, data)
73 local xorkey = '55AA55AA55AA55AA6262'
78 local item = string.sub(data, i, i+3)
79 local xor = string.sub(xorkey, i, i+3)
82 rs = bit32.bxor(tonumber(item,16) , tonumber(xor,16))
84 rs = tonumber(item, 16)
86 dex = (dex..'%04X'):format(rs)
89 print( (" %02d | %s"):format(blockno,s))
92 -- Send a "raw" iso14443a package, ie "hf 14a raw" command
93 function sendRaw(rawdata, options)
94 --print(">> ", rawdata)
95 local flags = lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT + lib14a.ISO14A_COMMAND.ISO14A_RAW + lib14a.ISO14A_COMMAND.ISO14A_APPEND_CRC
96 local command = Command:new{cmd = cmds.CMD_READER_ISO_14443a,
97 arg1 = flags, -- Send raw
98 -- arg2 contains the length, which is half the length
99 -- of the ASCII-string rawdata
100 arg2 = string.len(rawdata)/2,
102 return lib14a.sendToDevice(command, options.ignore_response)
105 -- Sends an instruction to do nothing, only disconnect
106 function disconnect()
107 local command = Command:new{cmd = cmds.CMD_READER_ISO_14443a, arg1 = 0, }
108 -- We can ignore the response here, no ACK is returned for this command
109 -- Check /armsrc/iso14443a.c, ReaderIso14443a() for details
110 return lib14a.sendToDevice(command, true)
111 --core.console("hf 14a raw -r")
114 -- The main entry point
117 local ignore_response = false
120 -- Read the parameters
121 for o, a in getopt.getopt(args, 'hb:') do
122 if o == "h" then return help() end
123 if o == "b" then endblock = a end
125 endblock = endblock or 20
127 -- First of all, connect
128 info, err = lib14a.read1443a(true)
129 if err then disconnect() return oops(err) end
130 core.clearCommandBuffer()
135 print(("\nFound Card UID [%s]\n"):format(info.uid))
137 print("blk | data | xored")
138 print("----+------------------+-------------------")
139 for block = 00, endblock do
140 local cmd = string.format("10%02x00", block)
141 res, err = sendRaw(cmd , {ignore_response = ignore_response})
142 if err then disconnect() return oops(err) end
144 local cmd_response = Command.parse(res)
145 local len = tonumber(cmd_response.arg1) * 2
146 local data = string.sub(tostring(cmd_response.data), 0, len-4)
148 showdata(block, data)
149 table.insert(blockData, data)
151 print("----+------------------+-------------------")
154 local filename, err = writeDumpFile(info.uid, blockData)
155 if err then return oops(err) end
157 print(string.format("\nDumped data into %s", filename))
163 -------------------------
165 -------------------------
168 dbg("Performing test")
172 -- Flip the switch here to perform a sanity check.
173 -- It read a nonce in two different ways, as specified in the usage-section
174 if "--test"==args then