1 local cmds = require('commands')
2 local getopt = require('getopt')
3 local bin = require('bin')
4 local lib14a = require('read14a')
5 local utils = require('utils')
8 1. script run formatMifare
9 2. script run formatMifare -k aabbccddeeff -n 112233445566 -a FF0780
12 usage = "script run formatMifare -k <key>"
14 This script will generate 'hf mf wrbl' commands for each block to format a Mifare card.
16 Alla datablocks gets 0x00
17 As default the script sets the keys A/B to 0xFFFFFFFFFFFF
18 and the access bytes will become 0x78,0x77,0x88
19 The GDB will become 0x00
21 The script will skip the manufactoring block 0.
25 -k <key> - the current six byte key with write access
26 -n <key> - the new key that will be written to the card
27 -a <access> - the new access bytes that will be written to the card
29 local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
30 local DEBUG = true -- the debug flag
31 local CmdString = 'hf mf wrbl %d B %s %s'
35 -- A debug printout-function
41 if type(args) == "table" then
52 -- This is only meant to be used when errors occur
60 print("Example usage")
66 print( string.rep('--',20) )
67 print( string.rep('--',20) )
72 -- Read information from a card
73 function GetCardInfo()
74 result, err = lib14a.read14443a(false, true)
79 print(("Found: %s"):format(result.name))
81 core.clearCommandBuffer()
83 if 0x18 == result.sak then -- NXP MIFARE Classic 4k | Plus 4k
84 -- IFARE Classic 4K offers 4096 bytes split into forty sectors,
85 -- of which 32 are same size as in the 1K with eight more that are quadruple size sectors.
87 elseif 0x08 == result.sak then -- NXP MIFARE CLASSIC 1k | Plus 2k
88 -- 1K offers 1024 bytes of data storage, split into 16 sector
90 elseif 0x09 == result.sak then -- NXP MIFARE Mini 0.3k
91 -- MIFARE Classic mini offers 320 bytes split into five sectors.
93 elseif 0x10 == result.sak then -- NXP MIFARE Plus 2k
95 elseif 0x01 == result.sak then -- NXP MIFARE TNP3xxx 1K
98 print("I don't know how many sectors there are on this type of card, defaulting to 16")
101 The mifare Classic 1k card has 16 sectors of 4 data blocks each.
102 The first 32 sectors of a mifare Classic 4k card consists of 4 data blocks and the remaining
103 8 sectors consist of 16 data blocks.
106 -- Defaults to 16 * 4 = 64 - 1 = 63
107 numBlocks = numSectors * 4 - 1
109 if numSectors > 32 then
110 numBlocks = 32*4+ (numSectors-32)*16 -1
115 local function main(args)
117 print( string.rep('--',20) )
118 print( string.rep('--',20) )
125 -- Arguments for the script
126 for o, a in getopt.getopt(args, 'hk:n:a:') do
127 if o == "h" then return help() end
128 if o == "k" then OldKey = a end
129 if o == "n" then NewKey = a end
130 if o == "a" then Accessbytes = a end
133 -- validate input args.
134 OldKey = OldKey or 'FFFFFFFFFFFF'
135 if #(OldKey) ~= 12 then
136 return oops( string.format('Wrong length of write key (was %d) expected 12', #OldKey))
139 NewKey = NewKey or 'FFFFFFFFFFFF'
140 if #(NewKey) ~= 12 then
141 return oops( string.format('Wrong length of new key (was %d) expected 12', #NewKey))
144 --Accessbytes = Accessbytes or '787788'
145 Accessbytes = Accessbytes or 'FF0780'
146 if #(Accessbytes) ~= 6 then
147 return oops( string.format('Wrong length of accessbytes (was %d) expected 12', #Accessbytes))
153 print( string.format('Estimating number of blocks: %d', numBlocks))
154 print( string.format('Old key: %s', OldKey))
155 print( string.format('New key: %s', NewKey))
156 print( string.format('New Access: %s', Accessbytes))
157 print( string.rep('--',20) )
159 -- Set new block data
160 local EMPTY_BL = string.rep('00',16)
161 local EMPTY_SECTORTRAIL = string.format('%s%s%s%s',NewKey,Accessbytes,'00',NewKey)
163 dbg( string.format('New sector-trailer : %s',EMPTY_SECTORTRAIL))
164 dbg( string.format('New emptyblock: %s',EMPTY_BL))
168 local dialogResult = utils.confirm("Do you want to erase this card")
169 if dialogResult == false then
170 return ExitMsg('Quiting it is then. Your wish is my command...')
173 print( string.rep('--',20) )
176 for block=0,numBlocks,1 do
178 local reminder = (block+1) % 4
180 if reminder == 0 then
181 cmd = CmdString:format(block, OldKey , EMPTY_SECTORTRAIL)
183 cmd = CmdString:format(block, OldKey , EMPTY_BL)
191 if core.ukbhit() then
192 print("aborted by user")