--- /dev/null
+--[[\r
+ This may be moved to a separate library at some point (Holiman)\r
+--]]\r
+local Utils = \r
+{\r
+ -- Asks the user for Yes or No\r
+ confirm = function(message, ...)\r
+ local answer\r
+ message = message .. " [y/n] ?"\r
+ repeat\r
+ io.write(message)\r
+ io.flush()\r
+ answer=io.read()\r
+ if answer == 'Y' or answer == "y" then\r
+ return true\r
+ elseif answer == 'N' or answer == 'n' then \r
+ return false\r
+ end\r
+ until false\r
+ end,\r
+ ---\r
+ -- Asks the user for input\r
+ input = function (message , default)\r
+ local answer\r
+ if default ~= nil then\r
+ message = message .. " (default: ".. default.. " )"\r
+ end\r
+ message = message .." \n > "\r
+ io.write(message)\r
+ io.flush()\r
+ answer=io.read()\r
+ if answer == '' then answer = default end\r
+\r
+ return answer\r
+ end,\r
+ --\r
+ -- Converts DECIMAL to HEX\r
+ ConvertDec2Hex = function(IN)\r
+ local B,K,OUT,I,D=16,"0123456789ABCDEF","",0\r
+ while IN>0 do\r
+ I=I+1\r
+ IN,D=math.floor(IN/B),math.mod(IN,B)+1\r
+ OUT=string.sub(K,D,D)..OUT\r
+ end\r
+ return OUT\r
+ end,\r
+ ---\r
+ -- Convert Byte array to string of hex\r
+ ConvertBytes2String = function(bytes)\r
+ s = {}\r
+ for i = 1, #(bytes) do\r
+ s[i] = string.format("%02X",bytes[i]) \r
+ end\r
+ return table.concat(s)\r
+ end, \r
+}\r
+return Utils
\ No newline at end of file
--- /dev/null
+local getopt = require('getopt')\r
+local bin = require('bin')\r
+local dumplib = require('html_dumplib')\r
+\r
+example =[[\r
+ 1. script run emul2dump\r
+ 2. script run emul2dump -i myfile.eml\r
+ 3. script run emul2dump -i myfile.eml -o myfile.bin\r
+]]\r
+author = "Iceman"\r
+usage = "script run emul2dump [-i <file>] [-o <file>]"\r
+desc =[[\r
+This script takes an dumpfile on EML (ASCII) format and converts it to the PM3 dumpbin file to be used with "hf mf restore"\r
+\r
+Arguments:\r
+ -h This help\r
+ -i <filename> Specifies the dump-file (input). If omitted, 'dumpdata.eml' is used \r
+ -o <filename> Specifies the output file. If omitted, <currdate>.bin is used. \r
+]]\r
+\r
+--- \r
+-- This is only meant to be used when errors occur\r
+function oops(err)\r
+ print("ERROR: ",err)\r
+end\r
+--- \r
+-- Usage help\r
+function help()\r
+ print(desc)\r
+ print("Example usage")\r
+ print(example)\r
+end\r
+--\r
+-- Exit message\r
+function ExitMsg(msg)\r
+ print( string.rep('--',20) )\r
+ print( string.rep('--',20) )\r
+ print(msg)\r
+ print()\r
+end\r
+\r
+local function main(args)\r
+ \r
+ local input = "dumpdata.eml"\r
+ local output = os.date("%Y-%m-%d_%H%M%S.bin");\r
+ \r
+ -- Arguments for the script\r
+ for o, a in getopt.getopt(args, 'hi:o:') do\r
+ if o == "h" then return help() end \r
+ if o == "i" then input = a end\r
+ if o == "o" then output = a end\r
+ end\r
+\r
+ local filename, err = dumplib.convert_eml_to_bin(input,output)\r
+ if err then return oops(err) end\r
+\r
+ ExitMsg(("Wrote a BIN dump to the file %s"):format(filename))\r
+end\r
+\r
+main(args)
\ No newline at end of file
--- /dev/null
+local cmds = require('commands')\r
+local getopt = require('getopt')\r
+local bin = require('bin')\r
+local lib14a = require('read14a')\r
+local utils = require('utils')\r
+\r
+example =[[\r
+ 1. script run formatMifare\r
+ 2. script run formatMifare -k aabbccddeeff -n 112233445566 -a FF0780\r
+]]\r
+author = "Iceman"\r
+usage = "script run formatMifare -k <key>"\r
+desc =[[\r
+This script will generate 'hf mf wrbl' commands for each block to format a Mifare card.\r
+\r
+Alla datablocks gets 0x00\r
+As default the script sets the keys A/B to 0xFFFFFFFFFFFF\r
+and the access bytes will become 0x78,0x77,0x88\r
+The GDB will become 0x00\r
+\r
+The script will skip the manufactoring block 0.\r
+\r
+Arguments:\r
+ -h - this help\r
+ -k <key> - the current six byte key with write access\r
+ -n <key> - the new key that will be written to the card\r
+ -a <access> - the new access bytes that will be written to the card\r
+]]\r
+local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds\r
+local DEBUG = true -- the debug flag\r
+local CmdString = 'hf mf wrbl %d B %s %s'\r
+local numBlocks = 64\r
+local numSectors = 16\r
+--- \r
+-- A debug printout-function\r
+function dbg(args)\r
+ if not DEBUG then\r
+ return\r
+ end\r
+ \r
+ if type(args) == "table" then\r
+ local i = 1\r
+ while result[i] do\r
+ dbg(result[i])\r
+ i = i+1\r
+ end\r
+ else\r
+ print("###", args)\r
+ end \r
+end \r
+--- \r
+-- This is only meant to be used when errors occur\r
+function oops(err)\r
+ print("ERROR: ",err)\r
+end\r
+--- \r
+-- Usage help\r
+function help()\r
+ print(desc)\r
+ print("Example usage")\r
+ print(example)\r
+end\r
+--\r
+-- Exit message\r
+function ExitMsg(msg)\r
+ print( string.rep('--',20) )\r
+ print( string.rep('--',20) )\r
+ print(msg)\r
+ print()\r
+end\r
+--\r
+-- Read information from a card\r
+function GetCardInfo()\r
+ result, err = lib14a.read1443a(false)\r
+ if not result then\r
+ print(err)\r
+ return\r
+ end\r
+ print(("Found: %s"):format(result.name))\r
+\r
+ core.clearCommandBuffer()\r
+ \r
+ if 0x18 == result.sak then --NXP MIFARE Classic 4k | Plus 4k\r
+ -- IFARE Classic 4K offers 4096 bytes split into forty sectors, \r
+ -- of which 32 are same size as in the 1K with eight more that are quadruple size sectors. \r
+ numSectors = 40\r
+ elseif 0x08 == result.sak then -- NXP MIFARE CLASSIC 1k | Plus 2k\r
+ -- 1K offers 1024 bytes of data storage, split into 16 sector\r
+ numSectors = 16\r
+ elseif 0x09 == result.sak then -- NXP MIFARE Mini 0.3k\r
+ -- MIFARE Classic mini offers 320 bytes split into five sectors.\r
+ numSectors = 5\r
+ elseif 0x10 == result.sak then-- "NXP MIFARE Plus 2k"\r
+ numSectors = 32\r
+ else\r
+ print("I don't know how many sectors there are on this type of card, defaulting to 16")\r
+ end \r
+ --[[\r
+ The mifare Classic 1k card has 16 sectors of 4 data blocks each. \r
+ The first 32 sectors of a mifare Classic 4k card consists of 4 data blocks and the remaining\r
+ 8 sectors consist of 16 data blocks. \r
+ --]]\r
+ \r
+ -- Defaults to 16 * 4 = 64 - 1 = 63\r
+ numBlocks = numSectors * 4 - 1 \r
+ \r
+ if numSectors > 32 then\r
+ numBlocks = 32*4+ (numSectors-32)*16 -1\r
+ end\r
+ \r
+end\r
+\r
+local function main(args)\r
+\r
+ print( string.rep('--',20) )\r
+ print( string.rep('--',20) )\r
+ print()\r
+ \r
+ local OldKey \r
+ local NewKey\r
+ local Accessbytes\r
+ \r
+ -- Arguments for the script\r
+ for o, a in getopt.getopt(args, 'hk:n:a:') do\r
+ if o == "h" then return help() end \r
+ if o == "k" then OldKey = a end\r
+ if o == "n" then NewKey = a end\r
+ if o == "a" then Accessbytes = a end\r
+ end\r
+\r
+ -- validate input args.\r
+ OldKey = OldKey or 'FFFFFFFFFFFF'\r
+ if #(OldKey) ~= 12 then\r
+ return oops( string.format('Wrong length of write key (was %d) expected 12', #OldKey))\r
+ end\r
+ \r
+ NewKey = NewKey or 'FFFFFFFFFFFF'\r
+ if #(NewKey) ~= 12 then\r
+ return oops( string.format('Wrong length of new key (was %d) expected 12', #NewKey))\r
+ end\r
+\r
+ --Accessbytes = Accessbytes or '787788'\r
+ Accessbytes = Accessbytes or 'FF0780'\r
+ if #(Accessbytes) ~= 6 then\r
+ return oops( string.format('Wrong length of accessbytes (was %d) expected 12', #Accessbytes))\r
+ end\r
+\r
+ GetCardInfo()\r
+ \r
+ -- Show info\r
+ print( string.format('Estimating number of blocks: %d', numBlocks))\r
+ print( string.format('Old key: %s', OldKey))\r
+ print( string.format('New key: %s', NewKey))\r
+ print( string.format('New Access: %s', Accessbytes))\r
+ print( string.rep('--',20) )\r
+\r
+ -- Set new block data\r
+ local EMPTY_BL = string.rep('00',16)\r
+ local EMPTY_SECTORTRAIL = string.format('%s%s%s%s',NewKey,Accessbytes,'00',NewKey)\r
+ \r
+ dbg( string.format('New sector-trailer : %s',EMPTY_SECTORTRAIL))\r
+ dbg( string.format('New emptyblock: %s',EMPTY_BL))\r
+ dbg('')\r
+ \r
+ -- Ask\r
+ local dialogResult = utils.confirm("Do you want to erase this card")\r
+ if dialogResult == false then \r
+ return ExitMsg('Quiting it is then. Your wish is my command...')\r
+ end \r
+\r
+ print( string.rep('--',20) )\r
+ \r
+ -- main loop\r
+ for block=0,numBlocks,1 do\r
+\r
+ local reminder = (block+1) % 4\r
+ local cmd\r
+ if reminder == 0 then\r
+ cmd = CmdString:format(block, OldKey , EMPTY_SECTORTRAIL)\r
+ else\r
+ cmd = CmdString:format(block, OldKey , EMPTY_BL) \r
+ end \r
+ \r
+ if block ~= 0 then\r
+ print(cmd)\r
+ --core.console(cmd)\r
+ end\r
+ \r
+ if core.ukbhit() then\r
+ print("aborted by user")\r
+ break\r
+ end\r
+ end\r
+end\r
+\r
+main(args)
\ No newline at end of file