]> git.zerfleddert.de Git - proxmark3-svn/blame - client/scripts/formatMifare.lua
fix uint8 vs uint32 and use sprint_hex
[proxmark3-svn] / client / scripts / formatMifare.lua
CommitLineData
5b1311fb
MHS
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
ab7fdfcb 83 if 0x18 == result.sak then -- NXP MIFARE Classic 4k | Plus 4k\r
5b1311fb
MHS
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
ab7fdfcb 87 elseif 0x08 == result.sak then -- NXP MIFARE CLASSIC 1k | Plus 2k\r
5b1311fb
MHS
88 -- 1K offers 1024 bytes of data storage, split into 16 sector\r
89 numSectors = 16\r
ab7fdfcb 90 elseif 0x09 == result.sak then -- NXP MIFARE Mini 0.3k\r
5b1311fb
MHS
91 -- MIFARE Classic mini offers 320 bytes split into five sectors.\r
92 numSectors = 5\r
9484ff3d 93 elseif 0x10 == result.sak then -- NXP MIFARE Plus 2k\r
5b1311fb 94 numSectors = 32\r
9484ff3d 95 elseif 0x01 == sak then -- NXP MIFARE TNP3xxx 1K\r
96 numSectors = 16\r
5b1311fb
MHS
97 else\r
98 print("I don't know how many sectors there are on this type of card, defaulting to 16")\r
99 end \r
100 --[[\r
101 The mifare Classic 1k card has 16 sectors of 4 data blocks each. \r
102 The first 32 sectors of a mifare Classic 4k card consists of 4 data blocks and the remaining\r
103 8 sectors consist of 16 data blocks. \r
104 --]]\r
105 \r
106 -- Defaults to 16 * 4 = 64 - 1 = 63\r
107 numBlocks = numSectors * 4 - 1 \r
108 \r
109 if numSectors > 32 then\r
110 numBlocks = 32*4+ (numSectors-32)*16 -1\r
111 end\r
112 \r
113end\r
114\r
115local function main(args)\r
116\r
117 print( string.rep('--',20) )\r
118 print( string.rep('--',20) )\r
119 print()\r
120 \r
121 local OldKey \r
122 local NewKey\r
123 local Accessbytes\r
124 \r
125 -- Arguments for the script\r
126 for o, a in getopt.getopt(args, 'hk:n:a:') do\r
127 if o == "h" then return help() end \r
128 if o == "k" then OldKey = a end\r
129 if o == "n" then NewKey = a end\r
130 if o == "a" then Accessbytes = a end\r
131 end\r
132\r
133 -- validate input args.\r
134 OldKey = OldKey or 'FFFFFFFFFFFF'\r
135 if #(OldKey) ~= 12 then\r
136 return oops( string.format('Wrong length of write key (was %d) expected 12', #OldKey))\r
137 end\r
138 \r
139 NewKey = NewKey or 'FFFFFFFFFFFF'\r
140 if #(NewKey) ~= 12 then\r
141 return oops( string.format('Wrong length of new key (was %d) expected 12', #NewKey))\r
142 end\r
143\r
144 --Accessbytes = Accessbytes or '787788'\r
145 Accessbytes = Accessbytes or 'FF0780'\r
146 if #(Accessbytes) ~= 6 then\r
147 return oops( string.format('Wrong length of accessbytes (was %d) expected 12', #Accessbytes))\r
148 end\r
149\r
150 GetCardInfo()\r
151 \r
152 -- Show info\r
153 print( string.format('Estimating number of blocks: %d', numBlocks))\r
154 print( string.format('Old key: %s', OldKey))\r
155 print( string.format('New key: %s', NewKey))\r
156 print( string.format('New Access: %s', Accessbytes))\r
157 print( string.rep('--',20) )\r
158\r
159 -- Set new block data\r
160 local EMPTY_BL = string.rep('00',16)\r
161 local EMPTY_SECTORTRAIL = string.format('%s%s%s%s',NewKey,Accessbytes,'00',NewKey)\r
162 \r
163 dbg( string.format('New sector-trailer : %s',EMPTY_SECTORTRAIL))\r
164 dbg( string.format('New emptyblock: %s',EMPTY_BL))\r
165 dbg('')\r
166 \r
167 -- Ask\r
168 local dialogResult = utils.confirm("Do you want to erase this card")\r
169 if dialogResult == false then \r
170 return ExitMsg('Quiting it is then. Your wish is my command...')\r
171 end \r
172\r
173 print( string.rep('--',20) )\r
174 \r
175 -- main loop\r
176 for block=0,numBlocks,1 do\r
177\r
178 local reminder = (block+1) % 4\r
179 local cmd\r
180 if reminder == 0 then\r
181 cmd = CmdString:format(block, OldKey , EMPTY_SECTORTRAIL)\r
182 else\r
183 cmd = CmdString:format(block, OldKey , EMPTY_BL) \r
184 end \r
185 \r
186 if block ~= 0 then\r
187 print(cmd)\r
188 --core.console(cmd)\r
189 end\r
190 \r
191 if core.ukbhit() then\r
192 print("aborted by user")\r
193 break\r
194 end\r
195 end\r
196end\r
197\r
198main(args)
Impressum, Datenschutz