]> cvs.zerfleddert.de Git - proxmark3-svn/blame_incremental - client/scripts/formatMifare.lua
fix/add support for 4K (and other non 1K) card sizes in hf mf commands
[proxmark3-svn] / client / scripts / formatMifare.lua
... / ...
CommitLineData
1local cmds = require('commands')\r
2local getopt = require('getopt')\r
3local bin = require('bin')\r
4local lib14a = require('read14a')\r
5local utils = require('utils')\r
6\r
7example =[[\r
8 1. script run formatMifare\r
9 2. script run formatMifare -k aabbccddeeff -n 112233445566 -a FF0780\r
10]]\r
11author = "Iceman"\r
12usage = "script run formatMifare -k <key>"\r
13desc =[[\r
14This script will generate 'hf mf wrbl' commands for each block to format a Mifare card.\r
15\r
16Alla datablocks gets 0x00\r
17As default the script sets the keys A/B to 0xFFFFFFFFFFFF\r
18and the access bytes will become 0x78,0x77,0x88\r
19The GDB will become 0x00\r
20\r
21The script will skip the manufactoring block 0.\r
22\r
23Arguments:\r
24 -h - this help\r
25 -k <key> - the current six byte key with write access\r
26 -n <key> - the new key that will be written to the card\r
27 -a <access> - the new access bytes that will be written to the card\r
28]]\r
29local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds\r
30local DEBUG = true -- the debug flag\r
31local CmdString = 'hf mf wrbl %d B %s %s'\r
32local numBlocks = 64\r
33local numSectors = 16\r
34--- \r
35-- A debug printout-function\r
36function dbg(args)\r
37 if not DEBUG then\r
38 return\r
39 end\r
40 \r
41 if type(args) == "table" then\r
42 local i = 1\r
43 while result[i] do\r
44 dbg(result[i])\r
45 i = i+1\r
46 end\r
47 else\r
48 print("###", args)\r
49 end \r
50end \r
51--- \r
52-- This is only meant to be used when errors occur\r
53function oops(err)\r
54 print("ERROR: ",err)\r
55end\r
56--- \r
57-- Usage help\r
58function help()\r
59 print(desc)\r
60 print("Example usage")\r
61 print(example)\r
62end\r
63--\r
64-- Exit message\r
65function ExitMsg(msg)\r
66 print( string.rep('--',20) )\r
67 print( string.rep('--',20) )\r
68 print(msg)\r
69 print()\r
70end\r
71--\r
72-- Read information from a card\r
73function GetCardInfo()\r
74 result, err = lib14a.read1443a(false)\r
75 if not result then\r
76 print(err)\r
77 return\r
78 end\r
79 print(("Found: %s"):format(result.name))\r
80\r
81 core.clearCommandBuffer()\r
82 \r
83 if 0x18 == result.sak then --NXP MIFARE Classic 4k | Plus 4k\r
84 -- IFARE Classic 4K offers 4096 bytes split into forty sectors, \r
85 -- of which 32 are same size as in the 1K with eight more that are quadruple size sectors. \r
86 numSectors = 40\r
87 elseif 0x08 == result.sak then -- NXP MIFARE CLASSIC 1k | Plus 2k\r
88 -- 1K offers 1024 bytes of data storage, split into 16 sector\r
89 numSectors = 16\r
90 elseif 0x09 == result.sak then -- NXP MIFARE Mini 0.3k\r
91 -- MIFARE Classic mini offers 320 bytes split into five sectors.\r
92 numSectors = 5\r
93 elseif 0x10 == result.sak then-- "NXP MIFARE Plus 2k"\r
94 numSectors = 32\r
95 else\r
96 print("I don't know how many sectors there are on this type of card, defaulting to 16")\r
97 end \r
98 --[[\r
99 The mifare Classic 1k card has 16 sectors of 4 data blocks each. \r
100 The first 32 sectors of a mifare Classic 4k card consists of 4 data blocks and the remaining\r
101 8 sectors consist of 16 data blocks. \r
102 --]]\r
103 \r
104 -- Defaults to 16 * 4 = 64 - 1 = 63\r
105 numBlocks = numSectors * 4 - 1 \r
106 \r
107 if numSectors > 32 then\r
108 numBlocks = 32*4+ (numSectors-32)*16 -1\r
109 end\r
110 \r
111end\r
112\r
113local function main(args)\r
114\r
115 print( string.rep('--',20) )\r
116 print( string.rep('--',20) )\r
117 print()\r
118 \r
119 local OldKey \r
120 local NewKey\r
121 local Accessbytes\r
122 \r
123 -- Arguments for the script\r
124 for o, a in getopt.getopt(args, 'hk:n:a:') do\r
125 if o == "h" then return help() end \r
126 if o == "k" then OldKey = a end\r
127 if o == "n" then NewKey = a end\r
128 if o == "a" then Accessbytes = a end\r
129 end\r
130\r
131 -- validate input args.\r
132 OldKey = OldKey or 'FFFFFFFFFFFF'\r
133 if #(OldKey) ~= 12 then\r
134 return oops( string.format('Wrong length of write key (was %d) expected 12', #OldKey))\r
135 end\r
136 \r
137 NewKey = NewKey or 'FFFFFFFFFFFF'\r
138 if #(NewKey) ~= 12 then\r
139 return oops( string.format('Wrong length of new key (was %d) expected 12', #NewKey))\r
140 end\r
141\r
142 --Accessbytes = Accessbytes or '787788'\r
143 Accessbytes = Accessbytes or 'FF0780'\r
144 if #(Accessbytes) ~= 6 then\r
145 return oops( string.format('Wrong length of accessbytes (was %d) expected 12', #Accessbytes))\r
146 end\r
147\r
148 GetCardInfo()\r
149 \r
150 -- Show info\r
151 print( string.format('Estimating number of blocks: %d', numBlocks))\r
152 print( string.format('Old key: %s', OldKey))\r
153 print( string.format('New key: %s', NewKey))\r
154 print( string.format('New Access: %s', Accessbytes))\r
155 print( string.rep('--',20) )\r
156\r
157 -- Set new block data\r
158 local EMPTY_BL = string.rep('00',16)\r
159 local EMPTY_SECTORTRAIL = string.format('%s%s%s%s',NewKey,Accessbytes,'00',NewKey)\r
160 \r
161 dbg( string.format('New sector-trailer : %s',EMPTY_SECTORTRAIL))\r
162 dbg( string.format('New emptyblock: %s',EMPTY_BL))\r
163 dbg('')\r
164 \r
165 -- Ask\r
166 local dialogResult = utils.confirm("Do you want to erase this card")\r
167 if dialogResult == false then \r
168 return ExitMsg('Quiting it is then. Your wish is my command...')\r
169 end \r
170\r
171 print( string.rep('--',20) )\r
172 \r
173 -- main loop\r
174 for block=0,numBlocks,1 do\r
175\r
176 local reminder = (block+1) % 4\r
177 local cmd\r
178 if reminder == 0 then\r
179 cmd = CmdString:format(block, OldKey , EMPTY_SECTORTRAIL)\r
180 else\r
181 cmd = CmdString:format(block, OldKey , EMPTY_BL) \r
182 end \r
183 \r
184 if block ~= 0 then\r
185 print(cmd)\r
186 --core.console(cmd)\r
187 end\r
188 \r
189 if core.ukbhit() then\r
190 print("aborted by user")\r
191 break\r
192 end\r
193 end\r
194end\r
195\r
196main(args)
Impressum, Datenschutz