+++ /dev/null
---[[
-These are command definitions. This file should correspond exactly to usb_cmd.h.
---]]
---// For the bootloader
-local _commands = {
- CMD_DEVICE_INFO = 0x0000,
- CMD_SETUP_WRITE = 0x0001,
- CMD_FINISH_WRITE = 0x0003,
- CMD_HARDWARE_RESET = 0x0004,
- CMD_START_FLASH = 0x0005,
- CMD_NACK = 0x00fe,
- CMD_ACK = 0x00ff,
-
- --// For general mucking around
- CMD_DEBUG_PRINT_STRING = 0x0100,
- CMD_DEBUG_PRINT_INTEGERS = 0x0101,
- CMD_DEBUG_PRINT_BYTES = 0x0102,
- CMD_LCD_RESET = 0x0103,
- CMD_LCD = 0x0104,
- CMD_BUFF_CLEAR = 0x0105,
- CMD_READ_MEM = 0x0106,
- CMD_VERSION = 0x0107,
-
- --// For low-frequency tags
- CMD_READ_TI_TYPE = 0x0202,
- CMD_WRITE_TI_TYPE = 0x0203,
- CMD_DOWNLOADED_RAW_BITS_TI_TYPE = 0x0204,
- CMD_ACQUIRE_RAW_ADC_SAMPLES_125K = 0x0205,
- CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K = 0x0206,
- CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K = 0x0207,
- CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K = 0x0208,
- CMD_DOWNLOADED_SIM_SAMPLES_125K = 0x0209,
- CMD_SIMULATE_TAG_125K = 0x020A,
- CMD_HID_DEMOD_FSK = 0x020B,
- CMD_HID_SIM_TAG = 0x020C,
- CMD_SET_LF_DIVISOR = 0x020D,
- CMD_LF_SIMULATE_BIDIR = 0x020E,
- CMD_SET_ADC_MUX = 0x020F,
- CMD_HID_CLONE_TAG = 0x0210,
- CMD_EM410X_WRITE_TAG = 0x0211,
- CMD_INDALA_CLONE_TAG = 0x0212,
- --// for 224 bits UID
- CMD_INDALA_CLONE_TAG_L = 0x0213,
- CMD_T55XX_READ_BLOCK = 0x0214,
- CMD_T55XX_WRITE_BLOCK = 0x0215,
- CMD_T55XX_READ_TRACE = 0x0216,
- CMD_PCF7931_READ = 0x0217,
- CMD_EM4X_READ_WORD = 0x0218,
- CMD_EM4X_WRITE_WORD = 0x0219,
- --/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */
-
- --// For the 13.56 MHz tags
- CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693 = 0x0300,
- CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443 = 0x0301,
- CMD_READ_SRI512_TAG = 0x0303,
- CMD_READ_SRIX4K_TAG = 0x0304,
- CMD_READER_ISO_15693 = 0x0310,
- CMD_SIMTAG_ISO_15693 = 0x0311,
- CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693 = 0x0312,
- CMD_ISO_15693_COMMAND = 0x0313,
- CMD_ISO_15693_COMMAND_DONE = 0x0314,
- CMD_ISO_15693_FIND_AFI = 0x0315,
- CMD_ISO_15693_DEBUG = 0x0316,
-
- --// For Hitag2 transponders
- CMD_SNOOP_HITAG = 0x0370,
- CMD_SIMULATE_HITAG = 0x0371,
- CMD_READER_HITAG = 0x0372,
-
- CMD_SIMULATE_TAG_HF_LISTEN = 0x0380,
- CMD_SIMULATE_TAG_ISO_14443 = 0x0381,
- CMD_SNOOP_ISO_14443 = 0x0382,
- CMD_SNOOP_ISO_14443a = 0x0383,
- CMD_SIMULATE_TAG_ISO_14443a = 0x0384,
- CMD_READER_ISO_14443a = 0x0385,
- CMD_SIMULATE_TAG_LEGIC_RF = 0x0387,
- CMD_READER_LEGIC_RF = 0x0388,
- CMD_WRITER_LEGIC_RF = 0x0389,
- CMD_EPA_PACE_COLLECT_NONCE = 0x038A,
-
- CMD_SNOOP_ICLASS = 0x0392,
- CMD_SIMULATE_TAG_ICLASS = 0x0393,
- CMD_READER_ICLASS = 0x0394,
-
- --// For measurements of the antenna tuning
- CMD_MEASURE_ANTENNA_TUNING = 0x0400,
- CMD_MEASURE_ANTENNA_TUNING_HF = 0x0401,
- CMD_MEASURED_ANTENNA_TUNING = 0x0410,
- CMD_LISTEN_READER_FIELD = 0x0420,
-
- --// For direct FPGA control
- CMD_FPGA_MAJOR_MODE_OFF = 0x0500,
-
- --// For mifare commands
- CMD_MIFARE_SET_DBGMODE = 0x0600,
- CMD_MIFARE_EML_MEMCLR = 0x0601,
- CMD_MIFARE_EML_MEMSET = 0x0602,
- CMD_MIFARE_EML_MEMGET = 0x0603,
- CMD_MIFARE_EML_CARDLOAD = 0x0604,
- CMD_MIFARE_EML_CSETBLOCK = 0x0605,
- CMD_MIFARE_EML_CGETBLOCK = 0x0606,
-
- CMD_SIMULATE_MIFARE_CARD = 0x0610,
-
- CMD_READER_MIFARE = 0x0611,
- CMD_MIFARE_NESTED = 0x0612,
-
- CMD_MIFARE_READBL = 0x0620,
- CMD_MIFARE_READSC = 0x0621,
- CMD_MIFARE_WRITEBL = 0x0622,
- CMD_MIFARE_CHKKEYS = 0x0623,
-
- CMD_MIFARE_SNIFFER = 0x0630,
-
- CMD_UNKNOWN = 0xFFFF,
-}
-
-
-local _reverse_lookup,k,v = {}
-for k, v in pairs(_commands) do
- _reverse_lookup[v] = k
-end
-_commands.tostring = function(command)
- if(type(command) == 'number') then
- return ("%s (%d)"):format(_reverse_lookup[command]or "ERROR UNDEFINED!", command)
- end
- return ("Error, numeric argument expected, got : %s"):format(tostring(command))
-end
-
-Command = {
-
- new = function(self, o)
-
- local o = o or {} -- create object if user does not provide one
- setmetatable(o, self) -- DIY inheritance a'la javascript
- self.__index = self
-
- o.cmd = o.cmd or _commands.CMD_UNKNOWN
- --o.arg1 = "test"
- o.arg1 = o.arg1 or 0
- o.arg2 = o.arg2 or 0
- o.arg3 = o.arg3 or 0
- local data = o.data or "0"
-
- if(type(data) == 'string') then
- -- We need to check if it is correct length, otherwise pad it
- local len = string.len(data)
- if(len < 1024) then
- --Should be 1024 hex characters to represent 512 bytes of data
- data = data .. string.rep("0",1024 - len )
- end
- if(len > 1024) then
- -- OOps, a bit too much data here
- print( ( "WARNING: data size too large, was %s chars, will be truncated "):format(len) )
- --
- data = data:sub(1,1024)
- end
- else
- print(("WARNING; data was NOT a (hex-) string, but was %s"):format(type(data)))
- end
- o.data = data
-
- return o
- end,
- parse = function (packet)
- local count,cmd,arg1,arg2,arg3,data = bin.unpack('LLLLH512',packet)
- return Command:new{cmd = cmd, arg1 = arg1, arg2 = arg2, arg3 = arg3, data = data}
- end,
-}
-function Command:__tostring()
- local output = ("%s\r\nargs : (%s, %s, %s)\r\ndata:\r\n%s\r\n"):format(
- _commands.tostring(self.cmd),
- tostring(self.arg1),
- tostring(self.arg2),
- tostring(self.arg3),
- tostring(self.data))
- return output
-end
-function Command:getBytes()
- --If a hex-string has been used
- local data = self.data
- local cmd = self.cmd
- local arg1, arg2, arg3 = self.arg1, self.arg2, self.arg3
-
-
- return bin.pack("LLLLH",cmd, arg1, arg2, arg3,data);
-end
-return _commands
\ No newline at end of file
+++ /dev/null
-
---[[This file is an adaptation from the following source:
-
-https://github.com/attractivechaos/klib/blob/master/lua/klib.lua
-
-]]
-
---[[
- The MIT License
-
- Copyright (c) 2011, Attractive Chaos <attractor@live.co.uk>
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
-]]--
-
-
-local function split(txt)
- local retval = {};
- for i in string.gmatch(txt, "%S+") do
- table.insert(retval,i)
- end
- return retval
-end
-
-
--- Description: getopt() translated from the BSD getopt(); compatible with the default Unix getopt()
---[[ Example:
- for o, a in os.getopt(arg, 'a:b') do
- print(o, a)
- end
-]]--
-
-local function getopt(args, ostr)
- -- Modification to handle strings instead of tables:
- if type(args) == 'string' then
- args = split(args)
- end
-
- local arg, place = nil, 0;
- return function ()
- if place == 0 then -- update scanning pointer
- place = 1
- if #args == 0
- or args[1]:sub(1, 1) ~= '-' then
- place = 0; return nil end
- if #args[1] >= 2 then
- place = place + 1
- if args[1]:sub(2, 2) == '-' then -- found "--"
- place = 0
- table.remove(args, 1);
- return nil;
- end
- end
- end
- local optopt = args[1]:sub(place, place);
- place = place + 1;
- local oli = ostr:find(optopt);
- if optopt == ':' or oli == nil then -- unknown option
- if optopt == '-' then return nil end
- if place > #args[1] then
- table.remove(args, 1);
- place = 0;
- end
- return '?';
- end
- oli = oli + 1;
- if ostr:sub(oli, oli) ~= ':' then -- do not need argument
- arg = nil;
- if place > #args[1] then
- table.remove(args, 1);
- place = 0;
- end
- else -- need an argument
- if place <= #args[1] then -- no white space
- arg = args[1]:sub(place);
- else
- table.remove(args, 1);
- if #args == 0 then -- an option requiring argument is the last one
- place = 0;
- if ostr:sub(1, 1) == ':' then return ':' end
- return '?';
- else arg = args[1] end
- end
- table.remove(args, 1);
- place = 0;
- end
- return optopt, arg;
- end
-end
-
-return { getopt = getopt }
--- /dev/null
+--[[
+These are command definitions. This file should correspond exactly to usb_cmd.h.
+--]]
+--// For the bootloader
+local _commands = {
+ CMD_DEVICE_INFO = 0x0000,
+ CMD_SETUP_WRITE = 0x0001,
+ CMD_FINISH_WRITE = 0x0003,
+ CMD_HARDWARE_RESET = 0x0004,
+ CMD_START_FLASH = 0x0005,
+ CMD_NACK = 0x00fe,
+ CMD_ACK = 0x00ff,
+
+ --// For general mucking around
+ CMD_DEBUG_PRINT_STRING = 0x0100,
+ CMD_DEBUG_PRINT_INTEGERS = 0x0101,
+ CMD_DEBUG_PRINT_BYTES = 0x0102,
+ CMD_LCD_RESET = 0x0103,
+ CMD_LCD = 0x0104,
+ CMD_BUFF_CLEAR = 0x0105,
+ CMD_READ_MEM = 0x0106,
+ CMD_VERSION = 0x0107,
+
+ --// For low-frequency tags
+ CMD_READ_TI_TYPE = 0x0202,
+ CMD_WRITE_TI_TYPE = 0x0203,
+ CMD_DOWNLOADED_RAW_BITS_TI_TYPE = 0x0204,
+ CMD_ACQUIRE_RAW_ADC_SAMPLES_125K = 0x0205,
+ CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K = 0x0206,
+ CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K = 0x0207,
+ CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K = 0x0208,
+ CMD_DOWNLOADED_SIM_SAMPLES_125K = 0x0209,
+ CMD_SIMULATE_TAG_125K = 0x020A,
+ CMD_HID_DEMOD_FSK = 0x020B,
+ CMD_HID_SIM_TAG = 0x020C,
+ CMD_SET_LF_DIVISOR = 0x020D,
+ CMD_LF_SIMULATE_BIDIR = 0x020E,
+ CMD_SET_ADC_MUX = 0x020F,
+ CMD_HID_CLONE_TAG = 0x0210,
+ CMD_EM410X_WRITE_TAG = 0x0211,
+ CMD_INDALA_CLONE_TAG = 0x0212,
+ --// for 224 bits UID
+ CMD_INDALA_CLONE_TAG_L = 0x0213,
+ CMD_T55XX_READ_BLOCK = 0x0214,
+ CMD_T55XX_WRITE_BLOCK = 0x0215,
+ CMD_T55XX_READ_TRACE = 0x0216,
+ CMD_PCF7931_READ = 0x0217,
+ CMD_EM4X_READ_WORD = 0x0218,
+ CMD_EM4X_WRITE_WORD = 0x0219,
+ --/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */
+
+ --// For the 13.56 MHz tags
+ CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693 = 0x0300,
+ CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443 = 0x0301,
+ CMD_READ_SRI512_TAG = 0x0303,
+ CMD_READ_SRIX4K_TAG = 0x0304,
+ CMD_READER_ISO_15693 = 0x0310,
+ CMD_SIMTAG_ISO_15693 = 0x0311,
+ CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693 = 0x0312,
+ CMD_ISO_15693_COMMAND = 0x0313,
+ CMD_ISO_15693_COMMAND_DONE = 0x0314,
+ CMD_ISO_15693_FIND_AFI = 0x0315,
+ CMD_ISO_15693_DEBUG = 0x0316,
+
+ --// For Hitag2 transponders
+ CMD_SNOOP_HITAG = 0x0370,
+ CMD_SIMULATE_HITAG = 0x0371,
+ CMD_READER_HITAG = 0x0372,
+
+ CMD_SIMULATE_TAG_HF_LISTEN = 0x0380,
+ CMD_SIMULATE_TAG_ISO_14443 = 0x0381,
+ CMD_SNOOP_ISO_14443 = 0x0382,
+ CMD_SNOOP_ISO_14443a = 0x0383,
+ CMD_SIMULATE_TAG_ISO_14443a = 0x0384,
+ CMD_READER_ISO_14443a = 0x0385,
+ CMD_SIMULATE_TAG_LEGIC_RF = 0x0387,
+ CMD_READER_LEGIC_RF = 0x0388,
+ CMD_WRITER_LEGIC_RF = 0x0389,
+ CMD_EPA_PACE_COLLECT_NONCE = 0x038A,
+
+ CMD_SNOOP_ICLASS = 0x0392,
+ CMD_SIMULATE_TAG_ICLASS = 0x0393,
+ CMD_READER_ICLASS = 0x0394,
+
+ --// For measurements of the antenna tuning
+ CMD_MEASURE_ANTENNA_TUNING = 0x0400,
+ CMD_MEASURE_ANTENNA_TUNING_HF = 0x0401,
+ CMD_MEASURED_ANTENNA_TUNING = 0x0410,
+ CMD_LISTEN_READER_FIELD = 0x0420,
+
+ --// For direct FPGA control
+ CMD_FPGA_MAJOR_MODE_OFF = 0x0500,
+
+ --// For mifare commands
+ CMD_MIFARE_SET_DBGMODE = 0x0600,
+ CMD_MIFARE_EML_MEMCLR = 0x0601,
+ CMD_MIFARE_EML_MEMSET = 0x0602,
+ CMD_MIFARE_EML_MEMGET = 0x0603,
+ CMD_MIFARE_EML_CARDLOAD = 0x0604,
+ CMD_MIFARE_EML_CSETBLOCK = 0x0605,
+ CMD_MIFARE_EML_CGETBLOCK = 0x0606,
+
+ CMD_SIMULATE_MIFARE_CARD = 0x0610,
+
+ CMD_READER_MIFARE = 0x0611,
+ CMD_MIFARE_NESTED = 0x0612,
+
+ CMD_MIFARE_READBL = 0x0620,
+ CMD_MIFARE_READSC = 0x0621,
+ CMD_MIFARE_WRITEBL = 0x0622,
+ CMD_MIFARE_CHKKEYS = 0x0623,
+
+ CMD_MIFARE_SNIFFER = 0x0630,
+
+ CMD_UNKNOWN = 0xFFFF,
+}
+
+
+local _reverse_lookup,k,v = {}
+for k, v in pairs(_commands) do
+ _reverse_lookup[v] = k
+end
+_commands.tostring = function(command)
+ if(type(command) == 'number') then
+ return ("%s (%d)"):format(_reverse_lookup[command]or "ERROR UNDEFINED!", command)
+ end
+ return ("Error, numeric argument expected, got : %s"):format(tostring(command))
+end
+
+Command = {
+
+ new = function(self, o)
+
+ local o = o or {} -- create object if user does not provide one
+ setmetatable(o, self) -- DIY inheritance a'la javascript
+ self.__index = self
+
+ o.cmd = o.cmd or _commands.CMD_UNKNOWN
+ --o.arg1 = "test"
+ o.arg1 = o.arg1 or 0
+ o.arg2 = o.arg2 or 0
+ o.arg3 = o.arg3 or 0
+ local data = o.data or "0"
+
+ if(type(data) == 'string') then
+ -- We need to check if it is correct length, otherwise pad it
+ local len = string.len(data)
+ if(len < 1024) then
+ --Should be 1024 hex characters to represent 512 bytes of data
+ data = data .. string.rep("0",1024 - len )
+ end
+ if(len > 1024) then
+ -- OOps, a bit too much data here
+ print( ( "WARNING: data size too large, was %s chars, will be truncated "):format(len) )
+ --
+ data = data:sub(1,1024)
+ end
+ else
+ print(("WARNING; data was NOT a (hex-) string, but was %s"):format(type(data)))
+ end
+ o.data = data
+
+ return o
+ end,
+ parse = function (packet)
+ local count,cmd,arg1,arg2,arg3,data = bin.unpack('LLLLH512',packet)
+ return Command:new{cmd = cmd, arg1 = arg1, arg2 = arg2, arg3 = arg3, data = data}
+ end,
+}
+function Command:__tostring()
+ local output = ("%s\r\nargs : (%s, %s, %s)\r\ndata:\r\n%s\r\n"):format(
+ _commands.tostring(self.cmd),
+ tostring(self.arg1),
+ tostring(self.arg2),
+ tostring(self.arg3),
+ tostring(self.data))
+ return output
+end
+function Command:getBytes()
+ --If a hex-string has been used
+ local data = self.data
+ local cmd = self.cmd
+ local arg1, arg2, arg3 = self.arg1, self.arg2, self.arg3
+
+
+ return bin.pack("LLLLH",cmd, arg1, arg2, arg3,data);
+end
+return _commands
\ No newline at end of file
--- /dev/null
+
+--[[This file is an adaptation from the following source:
+
+https://github.com/attractivechaos/klib/blob/master/lua/klib.lua
+
+]]
+
+--[[
+ The MIT License
+
+ Copyright (c) 2011, Attractive Chaos <attractor@live.co.uk>
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+]]--
+
+
+local function split(txt)
+ local retval = {};
+ for i in string.gmatch(txt, "%S+") do
+ table.insert(retval,i)
+ end
+ return retval
+end
+
+
+-- Description: getopt() translated from the BSD getopt(); compatible with the default Unix getopt()
+--[[ Example:
+ for o, a in os.getopt(arg, 'a:b') do
+ print(o, a)
+ end
+]]--
+
+local function getopt(args, ostr)
+ -- Modification to handle strings instead of tables:
+ if type(args) == 'string' then
+ args = split(args)
+ end
+
+ local arg, place = nil, 0;
+ return function ()
+ if place == 0 then -- update scanning pointer
+ place = 1
+ if #args == 0
+ or args[1]:sub(1, 1) ~= '-' then
+ place = 0; return nil end
+ if #args[1] >= 2 then
+ place = place + 1
+ if args[1]:sub(2, 2) == '-' then -- found "--"
+ place = 0
+ table.remove(args, 1);
+ return nil;
+ end
+ end
+ end
+ local optopt = args[1]:sub(place, place);
+ place = place + 1;
+ local oli = ostr:find(optopt);
+ if optopt == ':' or oli == nil then -- unknown option
+ if optopt == '-' then return nil end
+ if place > #args[1] then
+ table.remove(args, 1);
+ place = 0;
+ end
+ return '?';
+ end
+ oli = oli + 1;
+ if ostr:sub(oli, oli) ~= ':' then -- do not need argument
+ arg = nil;
+ if place > #args[1] then
+ table.remove(args, 1);
+ place = 0;
+ end
+ else -- need an argument
+ if place <= #args[1] then -- no white space
+ arg = args[1]:sub(place);
+ else
+ table.remove(args, 1);
+ if #args == 0 then -- an option requiring argument is the last one
+ place = 0;
+ if ostr:sub(1, 1) == ':' then return ':' end
+ return '?';
+ else arg = args[1] end
+ end
+ table.remove(args, 1);
+ place = 0;
+ end
+ return optopt, arg;
+ end
+end
+
+return { getopt = getopt }
--- /dev/null
+
+
+local _keys = {
+
+ --[[
+
+ These keys are from the pm3 c-codebase.
+
+ --]]
+ 'ffffffffffff', -- Default key (first key used by program if no user defined key)
+ '000000000000', -- Blank key
+ 'a0a1a2a3a4a5', -- NFCForum MAD key
+ 'b0b1b2b3b4b5',
+ 'aabbccddeeff',
+ '4d3a99c351dd',
+ '1a982c7e459a',
+ 'd3f7d3f7d3f7',
+ '714c5c886e97',
+ '587ee5f9350f',
+ 'a0478cc39091',
+ '533cb6c723f6',
+ '8fd0a4f256e9',
+
+
+ --[[
+ The data below is taken form the Slurp project,
+ https://github.com/4ZM/slurp/blob/master/res/xml/mifare_default_keys.xml
+ released as GPLV3.
+
+ --]]
+
+ '000000000000', -- Default key
+ 'ffffffffffff', -- Default key
+ 'b0b1b2b3b4b5', -- Key from mfoc
+ '4d3a99c351dd', -- Key from mfoc
+ '1a982c7e459a', -- Key from mfoc
+ 'aabbccddeeff', -- Key from mfoc
+ '714c5c886e97', -- Key from mfoc
+ '587ee5f9350f', -- Key from mfoc
+ 'a0478cc39091', -- Key from mfoc
+ '533cb6c723f6', -- Key from mfoc
+ '8fd0a4f256e9', -- Key from mfoc
+ -- Data from: http://pastebin.com/wcTHXLZZ
+ 'a64598a77478', -- RKF SL Key A
+ '26940b21ff5d', -- RKF SL Key A
+ 'fc00018778f7', -- RKF SL Key A
+ '00000ffe2488', -- RKF SL Key B
+ '5c598c9c58b5', -- RKF SL Key B
+ 'e4d2770a89be', -- RKF SL Key B
+ -- Data from: http://pastebin.com/svGjN30Q
+ '434f4d4d4f41', -- RKF JOJO GROUP Key A
+ '434f4d4d4f42', -- RKF JOJO GROUP Key B
+ '47524f555041', -- RKF JOJO GROUP Key A
+ '47524f555042', -- RKF JOJO GROUP Key B
+ '505249564141', -- RKF JOJO PRIVA Key A
+ '505249564142', -- RKF JOJO PRIVA Key B
+ -- Data from: http://pastebin.com/d7sSetef
+ 'fc00018778f7', -- RKF Rejskort Danmark Key A
+ '00000ffe2488', -- RKF Rejskort Danmark Key B
+ '0297927c0f77', -- RKF Rejskort Danmark Key A
+ 'ee0042f88840', -- RKF Rejskort Danmark Key B
+ '722bfcc5375f', -- RKF Rejskort Danmark Key A
+ 'f1d83f964314', -- RKF Rejskort Danmark Key B
+ -- Data from: http://pastebin.com/pvJX0xVS
+ '54726176656C', -- Transport Key A
+ '776974687573', -- Transport Key B
+ '4AF9D7ADEBE4', -- Directory and event log Key A
+ '2BA9621E0A36', -- Directory and event log Key B
+ -- Data from: http://pastebin.com/Dnnc5dFC
+ -- New cards are not encrypted (MF Ultralight)
+ 'fc00018778f7', -- Västtrafiken Key A
+ '00000ffe2488', -- Västtrafiken Key B
+ '0297927c0f77', -- Västtrafiken Key A
+ 'ee0042f88840', -- Västtrafiken Key B
+ '54726176656c', -- Västtrafiken Key A
+ '776974687573', -- Västtrafiken Key B
+ -- Data from: http://pastebin.com/y3PDBWR1
+ '000000000001',
+ 'a0a1a2a3a4a5',
+ '123456789abc',
+ 'b127c6f41436',
+ '12f2ee3478c1',
+ '34d1df9934c5',
+ '55f5a5dd38c9',
+ 'f1a97341a9fc',
+ '33f974b42769',
+ '14d446e33363',
+ 'c934fe34d934',
+ '1999a3554a55',
+ '27dd91f1fcf1',
+ 'a94133013401',
+ '99c636334433',
+ '43ab19ef5c31',
+ 'a053a292a4af',
+ '434f4d4d4f41',
+ '434f4d4d4f42',
+ '505249565441',
+ '505249565442',
+ -- Data from,:, http://pastebin.com/TUXj17K3
+ 'fc0001877bf7', -- RKF ÖstgötaTrafiken Key A
+ '00000ffe2488', -- RKF ÖstgötaTrafiken Key B
+ '0297927c0f77', -- RKF ÖstgötaTrafiken Key A
+ 'ee0042f88840', -- RKF ÖstgötaTrafiken Key B
+ '54726176656c', -- RKF ÖstgötaTrafiken Key A
+ '776974687573', -- RKF ÖstgötaTrafiken Key B
+
+ --[[
+ The keys below are taken from from https://code.google.com/p/mifare-key-cracker/downloads/list
+ --]]
+
+ 'bd493a3962b6',
+ '010203040506',
+ '111111111111',
+ '222222222222',
+ '333333333333',
+ '444444444444',
+ '555555555555',
+ '666666666666',
+ '777777777777',
+ '888888888888',
+ '999999999999',
+ 'aaaaaaaaaaaa',
+ 'bbbbbbbbbbbb',
+ 'cccccccccccc',
+ 'dddddddddddd',
+ 'eeeeeeeeeeee',
+ '0123456789ab',
+ '123456789abc',
+ }
+
+---
+-- The keys above have just been pasted in, for completeness sake. They contain duplicates.
+-- We need to weed the duplicates out before we expose the list to someone who actually wants to use them
+-- @param list a list to do 'uniq' on
+
+local function uniq(list)
+
+ local foobar = {}
+ --print("list length ", #list)
+ for _, value in pairs(list) do
+ value = value:lower()
+ if not foobar[value] then
+ foobar[value] = true
+ table.insert(foobar, value);
+ end
+ end
+ --print("final list length length ", #foobar)
+ return foobar
+end
+
+return uniq(_keys)
\ No newline at end of file
--- /dev/null
+--[[
+ This is a library to read 14443a tags. It can be used something like this
+
+ local reader = require('read14a')
+ result, err = reader.read1443a()
+ if not result then
+ print(err)
+ return
+ end
+ print(result.name)
+
+--]]
+-- Loads the commands-library
+local cmds = require('commands')
+local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
+local ISO14A_COMMAND = {
+ ISO14A_CONNECT = 1,
+ ISO14A_NO_DISCONNECT = 2,
+ ISO14A_APDU = 4,
+ ISO14A_RAW = 8,
+ ISO14A_REQUEST_TRIGGER = 0x10,
+ ISO14A_APPEND_CRC = 0x20,
+ ISO14A_SET_TIMEOUT = 0x40
+}
+
+local ISO14443a_TYPES = {}
+ISO14443a_TYPES[0x00] = "NXP MIFARE Ultralight | Ultralight C"
+ISO14443a_TYPES[0x04] = "NXP MIFARE (various !DESFire !DESFire EV1)"
+ISO14443a_TYPES[0x08] = "NXP MIFARE CLASSIC 1k | Plus 2k"
+ISO14443a_TYPES[0x09] = "NXP MIFARE Mini 0.3k"
+ISO14443a_TYPES[0x10] = "NXP MIFARE Plus 2k"
+ISO14443a_TYPES[0x11] = "NXP MIFARE Plus 4k"
+ISO14443a_TYPES[0x18] = "NXP MIFARE Classic 4k | Plus 4k"
+ISO14443a_TYPES[0x20] = "NXP MIFARE DESFire 4k | DESFire EV1 2k/4k/8k | Plus 2k/4k | JCOP 31/41"
+ISO14443a_TYPES[0x24] = "NXP MIFARE DESFire | DESFire EV1"
+ISO14443a_TYPES[0x28] = "JCOP31 or JCOP41 v2.3.1"
+ISO14443a_TYPES[0x38] = "Nokia 6212 or 6131 MIFARE CLASSIC 4K"
+ISO14443a_TYPES[0x88] = "Infineon MIFARE CLASSIC 1K"
+ISO14443a_TYPES[0x98] = "Gemplus MPCOS"
+
+
+local function tostring_1443a(sak)
+ return ISO14443a_TYPES[sak] or ("Unknown (SAK=%x)"):format(sak)
+end
+
+local function parse1443a(data)
+ --[[
+
+ Based on this struct :
+
+ typedef struct {
+ byte_t uid[10];
+ byte_t uidlen;
+ byte_t atqa[2];
+ byte_t sak;
+ byte_t ats_len;
+ byte_t ats[256];
+ } __attribute__((__packed__)) iso14a_card_select_t;
+
+ --]]
+
+ local count,uid,uidlen, atqa, sak, ats_len, ats= bin.unpack('H10CH2CC',data)
+ uid = uid:sub(1,2*uidlen)
+ --print("uid, atqa, sak: ",uid, atqa, sak)
+ --print("TYPE: ", tostring_1443a(sak))
+ return { uid = uid, atqa = atqa, sak = sak, name = tostring_1443a(sak)}
+end
+
+--- Sends a USBpacket to the device
+-- @param command - the usb packet to send
+-- @param ignoreresponse - if set to true, we don't read the device answer packet
+-- which is usually recipe for fail. If not sent, the host will wait 2s for a
+-- response of type CMD_ACK
+-- @return packet,nil if successfull
+-- nil, errormessage if unsuccessfull
+
+local function sendToDevice(command, ignoreresponse)
+ core.clearCommandBuffer()
+ local err = core.SendCommand(command:getBytes())
+ if err then
+ print(err)
+ return nil, err
+ end
+ if ignoreresponse then return nil,nil end
+
+ local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
+ return response,nil
+end
+
+
+local library = {
+ -- This function does a connect.
+ -- @param dont_disconnect - if true, does not disable the field
+ read1443a = function(dont_disconnect)
+
+ local command, result, info, err, data
+
+ command = Command:new{cmd = cmds.CMD_READER_ISO_14443a,
+ arg1 = ISO14A_COMMAND.ISO14A_CONNECT}
+ if dont_disconnect then
+ command.arg1 = command.arg1 + ISO14A_COMMAND.ISO14A_NO_DISCONNECT
+ end
+ local result,err = sendToDevice(command)
+ if result then
+ local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',result)
+ if arg0 == 0 then
+ print("iso14443a card select failed");
+ return nil, "iso14443a card select failed"
+ end
+ data = string.sub(result,count)
+ info, err = parse1443a(data)
+ else
+ err ="No response from card"
+ end
+
+ if err then
+ print(err)
+ return nil, err
+ end
+ return info
+ end,
+ parse1443a = parse1443a,
+ sendToDevice = sendToDevice,
+ ISO14A_COMMAND = ISO14A_COMMAND,
+}
+
+return library
\ No newline at end of file
+++ /dev/null
-
-
-local _keys = {
-
- --[[
-
- These keys are from the pm3 c-codebase.
-
- --]]
- 'ffffffffffff', -- Default key (first key used by program if no user defined key)
- '000000000000', -- Blank key
- 'a0a1a2a3a4a5', -- NFCForum MAD key
- 'b0b1b2b3b4b5',
- 'aabbccddeeff',
- '4d3a99c351dd',
- '1a982c7e459a',
- 'd3f7d3f7d3f7',
- '714c5c886e97',
- '587ee5f9350f',
- 'a0478cc39091',
- '533cb6c723f6',
- '8fd0a4f256e9',
-
-
- --[[
- The data below is taken form the Slurp project,
- https://github.com/4ZM/slurp/blob/master/res/xml/mifare_default_keys.xml
- released as GPLV3.
-
- --]]
-
- '000000000000', -- Default key
- 'ffffffffffff', -- Default key
- 'b0b1b2b3b4b5', -- Key from mfoc
- '4d3a99c351dd', -- Key from mfoc
- '1a982c7e459a', -- Key from mfoc
- 'aabbccddeeff', -- Key from mfoc
- '714c5c886e97', -- Key from mfoc
- '587ee5f9350f', -- Key from mfoc
- 'a0478cc39091', -- Key from mfoc
- '533cb6c723f6', -- Key from mfoc
- '8fd0a4f256e9', -- Key from mfoc
- -- Data from: http://pastebin.com/wcTHXLZZ
- 'a64598a77478', -- RKF SL Key A
- '26940b21ff5d', -- RKF SL Key A
- 'fc00018778f7', -- RKF SL Key A
- '00000ffe2488', -- RKF SL Key B
- '5c598c9c58b5', -- RKF SL Key B
- 'e4d2770a89be', -- RKF SL Key B
- -- Data from: http://pastebin.com/svGjN30Q
- '434f4d4d4f41', -- RKF JOJO GROUP Key A
- '434f4d4d4f42', -- RKF JOJO GROUP Key B
- '47524f555041', -- RKF JOJO GROUP Key A
- '47524f555042', -- RKF JOJO GROUP Key B
- '505249564141', -- RKF JOJO PRIVA Key A
- '505249564142', -- RKF JOJO PRIVA Key B
- -- Data from: http://pastebin.com/d7sSetef
- 'fc00018778f7', -- RKF Rejskort Danmark Key A
- '00000ffe2488', -- RKF Rejskort Danmark Key B
- '0297927c0f77', -- RKF Rejskort Danmark Key A
- 'ee0042f88840', -- RKF Rejskort Danmark Key B
- '722bfcc5375f', -- RKF Rejskort Danmark Key A
- 'f1d83f964314', -- RKF Rejskort Danmark Key B
- -- Data from: http://pastebin.com/pvJX0xVS
- '54726176656C', -- Transport Key A
- '776974687573', -- Transport Key B
- '4AF9D7ADEBE4', -- Directory and event log Key A
- '2BA9621E0A36', -- Directory and event log Key B
- -- Data from: http://pastebin.com/Dnnc5dFC
- -- New cards are not encrypted (MF Ultralight)
- 'fc00018778f7', -- Västtrafiken Key A
- '00000ffe2488', -- Västtrafiken Key B
- '0297927c0f77', -- Västtrafiken Key A
- 'ee0042f88840', -- Västtrafiken Key B
- '54726176656c', -- Västtrafiken Key A
- '776974687573', -- Västtrafiken Key B
- -- Data from: http://pastebin.com/y3PDBWR1
- '000000000001',
- 'a0a1a2a3a4a5',
- '123456789abc',
- 'b127c6f41436',
- '12f2ee3478c1',
- '34d1df9934c5',
- '55f5a5dd38c9',
- 'f1a97341a9fc',
- '33f974b42769',
- '14d446e33363',
- 'c934fe34d934',
- '1999a3554a55',
- '27dd91f1fcf1',
- 'a94133013401',
- '99c636334433',
- '43ab19ef5c31',
- 'a053a292a4af',
- '434f4d4d4f41',
- '434f4d4d4f42',
- '505249565441',
- '505249565442',
- -- Data from,:, http://pastebin.com/TUXj17K3
- 'fc0001877bf7', -- RKF ÖstgötaTrafiken Key A
- '00000ffe2488', -- RKF ÖstgötaTrafiken Key B
- '0297927c0f77', -- RKF ÖstgötaTrafiken Key A
- 'ee0042f88840', -- RKF ÖstgötaTrafiken Key B
- '54726176656c', -- RKF ÖstgötaTrafiken Key A
- '776974687573', -- RKF ÖstgötaTrafiken Key B
-
- --[[
- The keys below are taken from from https://code.google.com/p/mifare-key-cracker/downloads/list
- --]]
-
- 'bd493a3962b6',
- '010203040506',
- '111111111111',
- '222222222222',
- '333333333333',
- '444444444444',
- '555555555555',
- '666666666666',
- '777777777777',
- '888888888888',
- '999999999999',
- 'aaaaaaaaaaaa',
- 'bbbbbbbbbbbb',
- 'cccccccccccc',
- 'dddddddddddd',
- 'eeeeeeeeeeee',
- '0123456789ab',
- '123456789abc',
- }
-
----
--- The keys above have just been pasted in, for completeness sake. They contain duplicates.
--- We need to weed the duplicates out before we expose the list to someone who actually wants to use them
--- @param list a list to do 'uniq' on
-
-local function uniq(list)
-
- local foobar = {}
- --print("list length ", #list)
- for _, value in pairs(list) do
- value = value:lower()
- if not foobar[value] then
- foobar[value] = true
- table.insert(foobar, value);
- end
- end
- --print("final list length length ", #foobar)
- return foobar
-end
-
-return uniq(_keys)
\ No newline at end of file
+++ /dev/null
---[[
- This is a library to read 14443a tags. It can be used something like this
-
- local reader = require('read14a')
- result, err = reader.read1443a()
- if not result then
- print(err)
- return
- end
- print(result.name)
-
---]]
--- Loads the commands-library
-local cmds = require('commands')
-local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
-local ISO14A_COMMAND = {
- ISO14A_CONNECT = 1,
- ISO14A_NO_DISCONNECT = 2,
- ISO14A_APDU = 4,
- ISO14A_RAW = 8,
- ISO14A_REQUEST_TRIGGER = 0x10,
- ISO14A_APPEND_CRC = 0x20,
- ISO14A_SET_TIMEOUT = 0x40
-}
-
-local ISO14443a_TYPES = {}
-ISO14443a_TYPES[0x00] = "NXP MIFARE Ultralight | Ultralight C"
-ISO14443a_TYPES[0x04] = "NXP MIFARE (various !DESFire !DESFire EV1)"
-ISO14443a_TYPES[0x08] = "NXP MIFARE CLASSIC 1k | Plus 2k"
-ISO14443a_TYPES[0x09] = "NXP MIFARE Mini 0.3k"
-ISO14443a_TYPES[0x10] = "NXP MIFARE Plus 2k"
-ISO14443a_TYPES[0x11] = "NXP MIFARE Plus 4k"
-ISO14443a_TYPES[0x18] = "NXP MIFARE Classic 4k | Plus 4k"
-ISO14443a_TYPES[0x20] = "NXP MIFARE DESFire 4k | DESFire EV1 2k/4k/8k | Plus 2k/4k | JCOP 31/41"
-ISO14443a_TYPES[0x24] = "NXP MIFARE DESFire | DESFire EV1"
-ISO14443a_TYPES[0x28] = "JCOP31 or JCOP41 v2.3.1"
-ISO14443a_TYPES[0x38] = "Nokia 6212 or 6131 MIFARE CLASSIC 4K"
-ISO14443a_TYPES[0x88] = "Infineon MIFARE CLASSIC 1K"
-ISO14443a_TYPES[0x98] = "Gemplus MPCOS"
-
-
-local function tostring_1443a(sak)
- return ISO14443a_TYPES[sak] or ("Unknown (SAK=%x)"):format(sak)
-end
-
-local function parse1443a(data)
- --[[
-
- Based on this struct :
-
- typedef struct {
- byte_t uid[10];
- byte_t uidlen;
- byte_t atqa[2];
- byte_t sak;
- byte_t ats_len;
- byte_t ats[256];
- } __attribute__((__packed__)) iso14a_card_select_t;
-
- --]]
-
- local count,uid,uidlen, atqa, sak, ats_len, ats= bin.unpack('H10CH2CC',data)
- uid = uid:sub(1,2*uidlen)
- --print("uid, atqa, sak: ",uid, atqa, sak)
- --print("TYPE: ", tostring_1443a(sak))
- return { uid = uid, atqa = atqa, sak = sak, name = tostring_1443a(sak)}
-end
-
---- Sends a USBpacket to the device
--- @param command - the usb packet to send
--- @param ignoreresponse - if set to true, we don't read the device answer packet
--- which is usually recipe for fail. If not sent, the host will wait 2s for a
--- response of type CMD_ACK
--- @return packet,nil if successfull
--- nil, errormessage if unsuccessfull
-
-local function sendToDevice(command, ignoreresponse)
- core.clearCommandBuffer()
- local err = core.SendCommand(command:getBytes())
- if err then
- print(err)
- return nil, err
- end
- if ignoreresponse then return nil,nil end
-
- local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
- return response,nil
-end
-
-
-local library = {
- -- This function does a connect.
- -- @param dont_disconnect - if true, does not disable the field
- read1443a = function(dont_disconnect)
-
- local command, result, info, err, data
-
- command = Command:new{cmd = cmds.CMD_READER_ISO_14443a,
- arg1 = ISO14A_COMMAND.ISO14A_CONNECT}
- if dont_disconnect then
- command.arg1 = command.arg1 + ISO14A_COMMAND.ISO14A_NO_DISCONNECT
- end
- local result,err = sendToDevice(command)
- if result then
- local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',result)
- if arg0 == 0 then
- print("iso14443a card select failed");
- return nil, "iso14443a card select failed"
- end
- data = string.sub(result,count)
- info, err = parse1443a(data)
- else
- err ="No response from card"
- end
-
- if err then
- print(err)
- return nil, err
- end
- return info
- end,
- parse1443a = parse1443a,
- sendToDevice = sendToDevice,
- ISO14A_COMMAND = ISO14A_COMMAND,
-}
-
-return library
\ No newline at end of file
return 1;
}
+/**
+ * @brief Sets the lua path to include "./lualibs/?.lua", in order for a script to be
+ * able to do "require('foobar')" if foobar.lua is within lualibs folder.
+ * Taken from http://stackoverflow.com/questions/4125971/setting-the-global-lua-path-variable-from-c-c
+ * @param L
+ * @param path
+ * @return
+ */
+int setLuaPath( lua_State* L, const char* path )
+{
+ lua_getglobal( L, "package" );
+ lua_getfield( L, -1, "path" ); // get field "path" from table at top of stack (-1)
+ const char* cur_path = lua_tostring( L, -1 ); // grab path string from top of stack
+ int requiredLength = strlen(cur_path)+ strlen(path)+10; //A few bytes too many, whatever we can afford it
+ char * buf = malloc(requiredLength);
+ snprintf(buf, requiredLength, "%s;%s", cur_path, path);
+ lua_pop( L, 1 ); // get rid of the string on the stack we just pushed on line 5
+ lua_pushstring( L, buf ); // push the new one
+ lua_setfield( L, -2, "path" ); // set the field "path" in table at -2 with value at top of stack
+ lua_pop( L, 1 ); // get rid of package table from top of stack
+ return 0; // all done!
+}
+
+
int set_pm3_libraries(lua_State *L)
{
+
static const luaL_Reg libs[] = {
{"SendCommand", l_SendCommand},
{"WaitForResponseTimeout", l_WaitForResponseTimeout},
//-- remove the global environment table from the stack
lua_pop(L, 1);
+
+ //-- Last but not least, add to the LUA_PATH (package.path in lua)
+ // so we can load libraries from the ./lualib/ - directory
+ setLuaPath(L,"./lualibs/?.lua");
+
return 1;
}