return hex\r
end,\r
\r
+ ------------ FILE WRITING (EML)\r
+ --- Writes an eml-file.\r
+ -- @param uid - the uid of the tag. Used in filename\r
+ -- @param blockData. Assumed to be on the format {'\0\1\2\3,'\b\e\e\f' ..., \r
+ -- that is, blockData[row] contains a string with the actual data, not ascii hex representation \r
+ -- return filename if all went well, \r
+ -- @reurn nil, error message if unsuccessfulls \r
+ WriteDumpFile = function(uid, blockData)\r
+ local destination = string.format("%s.eml", uid)\r
+ local file = io.open(destination, "w")\r
+ if file == nil then \r
+ return nil, string.format("Could not write to file %s", destination)\r
+ end\r
+ local rowlen = string.len(blockData[1])\r
+\r
+ for i,block in ipairs(blockData) do\r
+ if rowlen ~= string.len(block) then\r
+ prlog(string.format("WARNING: Dumpdata seems corrupted, line %d was not the same length as line 1",i))\r
+ end\r
+\r
+ local formatString = string.format("H%d", string.len(block))\r
+ local _,hex = bin.unpack(formatString,block)\r
+ file:write(hex.."\n")\r
+ end\r
+ file:close() \r
+ return destination\r
+ end,\r
+ \r
------------ string split function\r
Split = function( inSplitPattern, outResults )\r
if not outResults then\r
if #s == 0 then return '' end\r
local t={}\r
for k in s:gmatch"(%x%x)" do\r
- table.insert(t, string.char(tonumber(k,16)))\r
+ local n = tonumber(k,16)\r
+ local c \r
+ if (n < 32) or (n == 127) then\r
+ c = '.';\r
+ else\r
+ c = string.char(n)\r
+ end\r
+ table.insert(t,c)\r
end\r
return table.concat(t) \r
end,\r
--- /dev/null
+local cmds = require('commands')
+local getopt = require('getopt')
+local lib14a = require('read14a')
+local utils = require('utils')
+example = [[
+ script run ufodump
+ script run ufodump -b 10
+]]
+author = "Iceman"
+desc =
+[[
+This is a script that reads AZTEK iso14443a tags.
+It starts from block 0, and ends at default block 20. Use 'b' to say different endblock.
+
+xor: the first three block (0,1,2) is not XORED. The rest seems to be xored.
+
+Arguments:
+ h this helptext
+ b endblock in decimal (1-255, default 20)
+]]
+
+-- Some globals
+local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
+local DEBUG = false -- the debug flag
+---
+-- A debug printout-function
+function dbg(args)
+ if DEBUG then
+ print("###", args)
+ end
+end
+---
+-- This is only meant to be used when errors occur
+function oops(err)
+ print("ERROR: ",err)
+ core.clearCommandBuffer()
+end
+---
+-- Usage help
+function help()
+ print(desc)
+ print("Example usage")
+ print(example)
+end
+--
+-- writes data to ascii textfile.
+function writeDumpFile(uid, blockData)
+ local destination = string.format("%s.eml", uid)
+ local file = io.open(destination, "w")
+ if file == nil then
+ return nil, string.format("Could not write to file %s", destination)
+ end
+ local rowlen = string.len(blockData[1])
+
+ for i,block in ipairs(blockData) do
+ if rowlen ~= string.len(block) then
+ print(string.format("WARNING: Dumpdata seems corrupted, line %d was not the same length as line 1",i))
+ end
+ file:write(block.."\n")
+ end
+ file:close()
+ return destination
+end
+--
+--- Picks out and displays the data read from a tag
+-- Specifically, takes a usb packet, converts to a Command
+-- (as in commands.lua), takes the data-array and
+-- reads the number of bytes specified in arg1 (arg0 in c-struct)
+-- and displays the data
+-- @blockno just to print which block the data belong to
+-- @param usbpacket the data received from the device
+function showdata(blockno, data)
+ local xorkey = '55AA55AA55AA55AA6262'
+ --local s = data.." | "..utils.ConvertHexToAscii(data).." | "
+ local s = data.." | "
+ local dex = ''
+ local rs
+ for i = 1, 20-4, 4 do
+ local item = string.sub(data, i, i+3)
+ local xor = string.sub(xorkey, i, i+3)
+
+ if blockno > 2 then
+ rs = bit32.bxor(tonumber(item,16) , tonumber(xor,16))
+ else
+ rs = tonumber(item, 16)
+ end
+ dex = (dex..'%04X'):format(rs)
+ end
+ --s = s..dex.." | "..utils.ConvertHexToAscii(dex)
+ s = s..dex.." | "
+ print( (" %02d | %s"):format(blockno,s))
+end
+--
+-- Send a "raw" iso14443a package, ie "hf 14a raw" command
+function sendRaw(rawdata, options)
+ --print(">> ", rawdata)
+ local flags = lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT + lib14a.ISO14A_COMMAND.ISO14A_RAW + lib14a.ISO14A_COMMAND.ISO14A_APPEND_CRC
+ local command = Command:new{cmd = cmds.CMD_READER_ISO_14443a,
+ arg1 = flags, -- Send raw
+ -- arg2 contains the length, which is half the length
+ -- of the ASCII-string rawdata
+ arg2 = string.len(rawdata)/2,
+ data = rawdata}
+ return lib14a.sendToDevice(command, options.ignore_response)
+end
+--
+-- Sends an instruction to do nothing, only disconnect
+function disconnect()
+ local command = Command:new{cmd = cmds.CMD_READER_ISO_14443a, arg1 = 0, }
+ -- We can ignore the response here, no ACK is returned for this command
+ -- Check /armsrc/iso14443a.c, ReaderIso14443a() for details
+ return lib14a.sendToDevice(command, true)
+ --core.console("hf 14a raw -r")
+end
+---
+-- The main entry point
+function main(args)
+
+ local ignore_response = false
+ local endblock = 20
+
+ -- Read the parameters
+ for o, a in getopt.getopt(args, 'hb:') do
+ if o == "h" then return help() end
+ if o == "b" then endblock = a end
+ end
+ endblock = endblock or 20
+
+ -- First of all, connect
+ info, err = lib14a.read1443a(true)
+ if err then disconnect() return oops(err) end
+ core.clearCommandBuffer()
+
+ local blockData = {}
+
+ -- Show tag info
+ print(("\nFound Card UID [%s]\n"):format(info.uid))
+
+ print("blk | data | xored")
+ print("----+------------------+-------------------")
+ for block = 00, endblock do
+ local cmd = string.format("10%02x00", block)
+ res, err = sendRaw(cmd , {ignore_response = ignore_response})
+ if err then disconnect() return oops(err) end
+
+ local cmd_response = Command.parse(res)
+ local len = tonumber(cmd_response.arg1) * 2
+ local data = string.sub(tostring(cmd_response.data), 0, len-4)
+
+ showdata(block, data)
+ table.insert(blockData, data)
+ end
+ print("----+------------------+-------------------")
+ disconnect()
+
+ local filename, err = writeDumpFile(info.uid, blockData)
+ if err then return oops(err) end
+
+ print(string.format("\nDumped data into %s", filename))
+end
+
+
+
+
+-------------------------
+-- Testing
+-------------------------
+function selftest()
+ DEBUG = true
+ dbg("Performing test")
+ main()
+ dbg("Tests done")
+end
+-- Flip the switch here to perform a sanity check.
+-- It read a nonce in two different ways, as specified in the usage-section
+if "--test"==args then
+ selftest()
+else
+ -- Call the main
+ main(args)
+end
\ No newline at end of file