]> git.zerfleddert.de Git - proxmark3-svn/blob - client/cmdhfmfu.c
Minor bug fixes with help from Holiman.
[proxmark3-svn] / client / cmdhfmfu.c
1 //-----------------------------------------------------------------------------
2 // Ultralight Code (c) 2013,2014 Midnitesnake & Andy Davies of Pentura
3 //
4 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
5 // at your option, any later version. See the LICENSE.txt file for the text of
6 // the license.
7 //-----------------------------------------------------------------------------
8 // High frequency MIFARE ULTRALIGHT (C) commands
9 //-----------------------------------------------------------------------------
10 #include <openssl/des.h>
11 #include "cmdhfmf.h"
12
13 uint8_t MAX_ULTRA_BLOCKS= 0x0f;
14 uint8_t MAX_ULTRAC_BLOCKS= 0x2c;
15 uint8_t key1_blnk_data[16] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
16 uint8_t key2_defa_data[16] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
17 uint8_t key3_3des_data[16] = { 0x49,0x45,0x4D,0x4B,0x41,0x45,0x52,0x42,0x21,0x4E,0x41,0x43,0x55,0x4F,0x59,0x46 };
18 uint8_t key4_nfc_data[16] = { 0x42,0x52,0x45,0x41,0x4b,0x4d,0x45,0x49,0x46,0x59,0x4f,0x55,0x43,0x41,0x4e,0x21 };
19 uint8_t key5_ones_data[16] = { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 };
20
21 static int CmdHelp(const char *Cmd);
22
23 //
24 // Mifare Ultralight Write Single Block
25 //
26 int CmdHF14AMfUWrBl(const char *Cmd){
27 uint8_t blockNo = 0;
28 bool chinese_card = 0;
29 uint8_t bldata[16] = {0x00};
30 UsbCommand resp;
31
32 if (strlen(Cmd)<3) {
33 PrintAndLog("Usage: hf mfu uwrbl <block number> <block data (8 hex symbols)> [w]");
34 PrintAndLog(" sample: hf mfu uwrbl 0 01020304");
35 return 0;
36 }
37 blockNo = param_get8(Cmd, 0);
38 if (blockNo>MAX_ULTRA_BLOCKS){
39 PrintAndLog("Error: Maximum number of blocks is 15 for Ultralight Cards!");
40 return 1;
41 }
42 if (param_gethex(Cmd, 1, bldata, 8)) {
43 PrintAndLog("Block data must include 8 HEX symbols");
44 return 1;
45 }
46 if (strchr(Cmd,'w') != 0) {
47 chinese_card=1;
48 }
49 switch(blockNo){
50 case 0:
51 if (!chinese_card){
52 PrintAndLog("Access Denied");
53 }else{
54 PrintAndLog("--specialblock no:%02x", blockNo);
55 PrintAndLog("--data: %s", sprint_hex(bldata, 4));
56 UsbCommand d = {CMD_MIFAREU_WRITEBL, {blockNo}};
57 memcpy(d.d.asBytes,bldata, 4);
58 SendCommand(&d);
59 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
60 uint8_t isOK = resp.arg[0] & 0xff;
61 PrintAndLog("isOk:%02x", isOK);
62 } else {
63 PrintAndLog("Command execute timeout");
64 }
65 }
66 break;
67 case 1:
68 if (!chinese_card){
69 PrintAndLog("Access Denied");
70 }else{
71 PrintAndLog("--specialblock no:%02x", blockNo);
72 PrintAndLog("--data: %s", sprint_hex(bldata, 4));
73 UsbCommand d = {CMD_MIFAREU_WRITEBL, {blockNo}};
74 memcpy(d.d.asBytes,bldata, 4);
75 SendCommand(&d);
76 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
77 uint8_t isOK = resp.arg[0] & 0xff;
78 PrintAndLog("isOk:%02x", isOK);
79 } else {
80 PrintAndLog("Command execute timeout");
81 }
82 }
83 break;
84 case 2:
85 if (!chinese_card){
86 PrintAndLog("Access Denied");
87 }else{
88 PrintAndLog("--specialblock no:%02x", blockNo);
89 PrintAndLog("--data: %s", sprint_hex(bldata, 4));
90 UsbCommand c = {CMD_MIFAREU_WRITEBL, {blockNo}};
91 memcpy(c.d.asBytes, bldata, 4);
92 SendCommand(&c);
93 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
94 uint8_t isOK = resp.arg[0] & 0xff;
95 PrintAndLog("isOk:%02x", isOK);
96 } else {
97 PrintAndLog("Command execute timeout");
98 }
99 }
100 break;
101 case 3:
102 PrintAndLog("--specialblock no:%02x", blockNo);
103 PrintAndLog("--data: %s", sprint_hex(bldata, 4));
104 UsbCommand d = {CMD_MIFAREU_WRITEBL, {blockNo}};
105 memcpy(d.d.asBytes,bldata, 4);
106 SendCommand(&d);
107 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
108 uint8_t isOK = resp.arg[0] & 0xff;
109 PrintAndLog("isOk:%02x", isOK);
110 } else {
111 PrintAndLog("Command execute timeout");
112 }
113 break;
114 default:
115 PrintAndLog("--block no:%02x", blockNo);
116 PrintAndLog("--data: %s", sprint_hex(bldata, 4));
117 UsbCommand e = {CMD_MIFAREU_WRITEBL, {blockNo}};
118 memcpy(e.d.asBytes,bldata, 4);
119 SendCommand(&e);
120 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
121 uint8_t isOK = resp.arg[0] & 0xff;
122 PrintAndLog("isOk:%02x", isOK);
123 } else {
124 PrintAndLog("Command execute timeout");
125 }
126 break;
127 }
128 return 0;
129 }
130
131 //
132 // Mifare Ultralight Read Single Block
133 //
134 int CmdHF14AMfURdBl(const char *Cmd){
135
136 uint8_t blockNo = 0;
137
138 if (strlen(Cmd)<1) {
139 PrintAndLog("Usage: hf mfu urdbl <block number>");
140 PrintAndLog(" sample: hfu mfu urdbl 0");
141 return 0;
142 }
143
144 blockNo = param_get8(Cmd, 0);
145 // if (blockNo>MAX_ULTRA_BLOCKS){
146 // PrintAndLog("Error: Maximum number of blocks is 15 for Ultralight Cards!");
147 // return 1;
148 // }
149 PrintAndLog("--block no:%02x", (int)blockNo);
150 UsbCommand c = {CMD_MIFAREU_READBL, {blockNo}};
151 SendCommand(&c);
152
153 UsbCommand resp;
154 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
155 uint8_t isOK = resp.arg[0] & 0xff;
156 uint8_t * data = resp.d.asBytes;
157
158 if (isOK)
159 PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 4));
160 else
161 PrintAndLog("isOk:%02x", isOK);
162 } else {
163 PrintAndLog("Command execute timeout");
164 }
165 return 0;
166 }
167
168 //
169 // Mifare Ultralight Read (Dump) Card Contents
170 //
171 int CmdHF14AMfURdCard(const char *Cmd){
172 int i;
173 uint8_t BlockNo = 0;
174 int Pages=16;
175 uint8_t *lockbytes_t=NULL;
176 uint8_t lockbytes[2]={0x00};
177 bool bit[16]={0x00};
178 bool dump=false;
179 uint8_t datatemp[7]= {0x00};
180
181 uint8_t isOK = 0;
182 uint8_t * data = NULL;
183 FILE *fout = NULL;
184
185 if (strchr(Cmd,'x') != 0){
186 dump=true;
187 if ((fout = fopen("dump_ultralight_data.bin","wb")) == NULL) {
188 PrintAndLog("Could not create file name dumpdata.bin");
189 return 1;
190 }
191 PrintAndLog("Dumping Ultralight Card Data...");
192 }
193 PrintAndLog("Attempting to Read Ultralight... ");
194 UsbCommand c = {CMD_MIFAREU_READCARD, {BlockNo, Pages}};
195 SendCommand(&c);
196 UsbCommand resp;
197
198 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
199 isOK = resp.arg[0] & 0xff;
200 data = resp.d.asBytes;
201 PrintAndLog("isOk:%02x", isOK);
202 if (isOK) {
203
204 // UID
205 memcpy( datatemp, data,3);
206 memcpy( datatemp+3, data+4, 4);
207 PrintAndLog(" UID :%s ", sprint_hex(datatemp, 7));
208 // BBC
209 // CT (cascade tag byte) 0x88 xor SN0 xor SN1 xor SN2
210 int crc0 = 0x88 ^ data[0] ^ data[1] ^data[2];
211 if ( data[3] == crc0 ) {
212 PrintAndLog(" BCC0 :%02x - Ok", data[3]);
213 }
214 else{
215 PrintAndLog(" BCC0 :%02x - crc should be %02x", data[3], crc0);
216 }
217
218 int crc1 = data[4] ^ data[5] ^ data[6] ^data[7];
219 if ( data[8] == crc1 ){
220 PrintAndLog(" BCC1 :%02x - Ok", data[8]);
221 }
222 else{
223 PrintAndLog(" BCC1 :%02x - crc should be %02x", data[8], crc1 );
224 }
225
226 PrintAndLog(" Internal :%s ", sprint_hex(data + 9, 1));
227
228 memcpy(datatemp, data+10, 2);
229 PrintAndLog(" Lock :%s - %s", sprint_hex(datatemp, 2),printBits( 2, &datatemp) );
230
231 PrintAndLog(" OneTimePad :%s ", sprint_hex(data + 3*4, 4));
232 PrintAndLog("");
233
234 for (i = 0; i < Pages; i++) {
235 switch(i){
236 case 2:
237 //process lock bytes
238 lockbytes_t=data+(i*4);
239 lockbytes[0]=lockbytes_t[2];
240 lockbytes[1]=lockbytes_t[3];
241 for(int j=0; j<16; j++){
242 bit[j]=lockbytes[j/8] & ( 1 <<(7-j%8));
243 }
244 PrintAndLog("Block %02x:%s ", i,sprint_hex(data + i * 4, 4));
245 memcpy(datatemp,data + i * 4,4);
246 if (dump) fwrite ( datatemp, 1, 4, fout );
247 break;
248 case 3:
249 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[4]);
250 memcpy(datatemp,data + i * 4,4);
251 if (dump) fwrite ( datatemp, 1, 4, fout );
252 break;
253 case 4:
254 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[3]);
255 memcpy(datatemp,data + i * 4,4);
256 if (dump) fwrite ( datatemp, 1, 4, fout );
257 break;
258 case 5:
259 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[2]);
260 memcpy(datatemp,data + i * 4,4);
261 if (dump) fwrite ( datatemp, 1, 4, fout );
262 break;
263 case 6:
264 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[1]);
265 memcpy(datatemp,data + i * 4,4);
266 if (dump) fwrite ( datatemp, 1, 4, fout );
267 break;
268 case 7:
269 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[0]);
270 memcpy(datatemp,data + i * 4,4);
271 if (dump) fwrite ( datatemp, 1, 4, fout );
272 break;
273 case 8:
274 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[15]);
275 memcpy(datatemp,data + i * 4,4);
276 if (dump) fwrite ( datatemp, 1, 4, fout );
277 break;
278 case 9:
279 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[14]);
280 memcpy(datatemp,data + i * 4,4);
281 if (dump) fwrite ( datatemp, 1, 4, fout );
282 break;
283 case 10:
284 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[13]);
285 memcpy(datatemp,data + i * 4,4);
286 if (dump) fwrite ( datatemp, 1, 4, fout );
287 break;
288 case 11:
289 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[12]);
290 memcpy(datatemp,data + i * 4,4);
291 if (dump) fwrite ( datatemp, 1, 4, fout );
292 break;
293 case 12:
294 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[11]);
295 memcpy(datatemp,data + i * 4,4);
296 if (dump) fwrite ( datatemp, 1, 4, fout );
297 break;
298 case 13:
299 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[10]);
300 memcpy(datatemp,data + i * 4,4);
301 if (dump) fwrite ( datatemp, 1, 4, fout );
302 break;
303 case 14:
304 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[9]);
305 memcpy(datatemp,data + i * 4,4);
306 if (dump) fwrite ( datatemp, 1, 4, fout );
307 break;
308 case 15:
309 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[8]);
310 memcpy(datatemp,data + i * 4,4);
311 if (dump) fwrite ( datatemp, 1, 4, fout );
312 break;
313 default:
314 PrintAndLog("Block %02x:%s ", i,sprint_hex(data + i * 4, 4));
315 memcpy(datatemp,data + i * 4,4);
316 if (dump) fwrite ( datatemp, 1, 4, fout );
317 break;
318 }
319 }
320 }
321 } else {
322 PrintAndLog("Command1 execute timeout");
323 }
324 if (dump) fclose(fout);
325 return 0;
326 }
327
328 int CmdHF14AMfUDump(const char *Cmd){
329 int i;
330 uint8_t BlockNo = 0;
331 int Pages = 16;
332 uint8_t *lockbytes_t = NULL;
333 uint8_t lockbytes[2] = {0x00};
334 bool bit[16] = {0x00};
335 uint8_t datatemp[5] = {0x00};
336 bool dump = true;
337 uint8_t isOK = 0;
338 uint8_t * data = NULL;
339 FILE *fout;
340
341 if ((fout = fopen("dump_ultralight_data.bin","wb")) == NULL) {
342 PrintAndLog("Could not create file name dumpdata.bin");
343 return 1;
344 }
345 PrintAndLog("Dumping Ultralight Card Data...");
346
347 PrintAndLog("Attempting to Read Ultralight... ");
348 UsbCommand c = {CMD_MIFAREU_READCARD, {BlockNo,Pages}};
349 SendCommand(&c);
350 UsbCommand resp;
351
352 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
353 isOK = resp.arg[0] & 0xff;
354 data = resp.d.asBytes;
355 PrintAndLog("isOk:%02x", isOK);
356 if (isOK)
357 for (i = 0; i < Pages; i++) {
358 switch(i){
359 case 2:
360 //process lock bytes
361 lockbytes_t=data+(i*4);
362 lockbytes[0]=lockbytes_t[2];
363 lockbytes[1]=lockbytes_t[3];
364 for(int j=0; j<16; j++){
365 bit[j]=lockbytes[j/8] & ( 1 <<(7-j%8));
366 }
367 PrintAndLog("Block %02x:%s ", i,sprint_hex(data + i * 4, 4));
368 memcpy(datatemp,data + i * 4,4);
369 if (dump) fwrite ( datatemp, 1, 4, fout );
370 break;
371 case 3:
372 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[4]);
373 memcpy(datatemp,data + i * 4,4);
374 if (dump) fwrite ( datatemp, 1, 4, fout );
375 break;
376 case 4:
377 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[3]);
378 memcpy(datatemp,data + i * 4,4);
379 if (dump) fwrite ( datatemp, 1, 4, fout );
380 break;
381 case 5:
382 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[2]);
383 memcpy(datatemp,data + i * 4,4);
384 if (dump) fwrite ( datatemp, 1, 4, fout );
385 break;
386 case 6:
387 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[1]);
388 memcpy(datatemp,data + i * 4,4);
389 if (dump) fwrite ( datatemp, 1, 4, fout );
390 break;
391 case 7:
392 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[0]);
393 memcpy(datatemp,data + i * 4,4);
394 if (dump) fwrite ( datatemp, 1, 4, fout );
395 break;
396 case 8:
397 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[15]);
398 memcpy(datatemp,data + i * 4,4);
399 if (dump) fwrite ( datatemp, 1, 4, fout );
400 break;
401 case 9:
402 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[14]);
403 memcpy(datatemp,data + i * 4,4);
404 if (dump) fwrite ( datatemp, 1, 4, fout );
405 break;
406 case 10:
407 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[13]);
408 memcpy(datatemp,data + i * 4,4);
409 if (dump) fwrite ( datatemp, 1, 4, fout );
410 break;
411 case 11:
412 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[12]);
413 memcpy(datatemp,data + i * 4,4);
414 if (dump) fwrite ( datatemp, 1, 4, fout );
415 break;
416 case 12:
417 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[11]);
418 memcpy(datatemp,data + i * 4,4);
419 if (dump) fwrite ( datatemp, 1, 4, fout );
420 break;
421 case 13:
422 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[10]);
423 memcpy(datatemp,data + i * 4,4);
424 if (dump) fwrite ( datatemp, 1, 4, fout );
425 break;
426 case 14:
427 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[9]);
428 memcpy(datatemp,data + i * 4,4);
429 if (dump) fwrite ( datatemp, 1, 4, fout );
430 break;
431 case 15:
432 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[8]);
433 memcpy(datatemp,data + i * 4,4);
434 if (dump) fwrite ( datatemp, 1, 4, fout );
435 break;
436 default:
437 PrintAndLog("Block %02x:%s ", i,sprint_hex(data + i * 4, 4));
438 memcpy(datatemp,data + i * 4,4);
439 if (dump) fwrite ( datatemp, 1, 4, fout );
440 break;
441 }
442 }
443 } else {
444 PrintAndLog("Command1 execute timeout");
445 }
446 if (dump) fclose(fout);
447 return 0;
448 }
449
450 // Needed to Authenticate to Ultralight C tags
451 void rol (uint8_t *data, const size_t len){
452 uint8_t first = data[0];
453 for (size_t i = 0; i < len-1; i++) {
454 data[i] = data[i+1];
455 }
456 data[len-1] = first;
457 }
458
459 //-------------------------------------------------------------------------------
460 // Ultralight C Methods
461 //-------------------------------------------------------------------------------
462
463 //
464 // Ultralight C Authentication Demo {currently uses hard-coded key}
465 //
466 int CmdHF14AMfucAuth(const char *Cmd){
467
468 uint8_t blockNo = 0, keyNo=0;
469 uint8_t e_RndB[8] = {0x00};
470 uint32_t cuid=0;
471 unsigned char RndARndB[16] = {0x00};
472 uint8_t key[16] = {0x00};
473 DES_cblock RndA, RndB;
474 DES_cblock iv[8] = {0x00};
475 DES_key_schedule ks1,ks2;
476 DES_cblock key1,key2;
477
478 if (strlen(Cmd)<1) {
479 PrintAndLog("Usage: hf mfu auth k <key number>");
480 PrintAndLog(" sample: hf mfu auth k 0");
481 return 0;
482 }
483
484 //Change key to user defined one
485 if (strchr(Cmd,'k') != 0){
486 //choose a key
487 keyNo = param_get8(Cmd, 1);
488 switch(keyNo){
489 case 0:
490 memcpy(key,key1_blnk_data,16);
491 break;
492 case 1:
493 memcpy(key,key2_defa_data,16);
494 break;
495 case 2:
496 memcpy(key,key4_nfc_data,16);
497 break;
498 case 3:
499 memcpy(key,key5_ones_data,16);
500 break;
501 default:
502 memcpy(key,key3_3des_data,16);
503 break;
504 }
505 }else{
506 memcpy(key,key3_3des_data,16);
507 }
508 memcpy(key1,key,8);
509 memcpy(key2,key+8,8);
510 DES_set_key((DES_cblock *)key1,&ks1);
511 DES_set_key((DES_cblock *)key2,&ks2);
512
513 //Auth1
514 UsbCommand c = {CMD_MIFAREUC_AUTH1, {blockNo}};
515 SendCommand(&c);
516 UsbCommand resp;
517 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
518 uint8_t isOK = resp.arg[0] & 0xff;
519 cuid = resp.arg[1];
520 uint8_t * data= resp.d.asBytes;
521
522 if (isOK){
523 PrintAndLog("enc(RndB):%s", sprint_hex(data+1, 8));
524 memcpy(e_RndB,data+1,8);
525 }
526 } else {
527 PrintAndLog("Command execute timeout");
528 }
529
530 //Do crypto magic
531 DES_random_key(&RndA);
532 DES_ede2_cbc_encrypt(e_RndB,RndB,sizeof(e_RndB),&ks1,&ks2,&iv,0);
533 PrintAndLog(" RndB:%s",sprint_hex(RndB, 8));
534 PrintAndLog(" RndA:%s",sprint_hex(RndA, 8));
535 rol(RndB,8);
536 memcpy(RndARndB,RndA,8);
537 memcpy(RndARndB+8,RndB,8);
538 PrintAndLog(" RA+B:%s",sprint_hex(RndARndB, 16));
539 DES_ede2_cbc_encrypt(RndARndB,RndARndB,sizeof(RndARndB),&ks1,&ks2,&e_RndB,1);
540 PrintAndLog("enc(RA+B):%s",sprint_hex(RndARndB, 16));
541
542 //Auth2
543 UsbCommand d = {CMD_MIFAREUC_AUTH2, {cuid}};
544 memcpy(d.d.asBytes,RndARndB, 16);
545 SendCommand(&d);
546
547 UsbCommand respb;
548 if (WaitForResponseTimeout(CMD_ACK,&respb,1500)) {
549 uint8_t isOK = respb.arg[0] & 0xff;
550 uint8_t * data2= respb.d.asBytes;
551
552 if (isOK){
553 PrintAndLog("enc(RndA'):%s", sprint_hex(data2+1, 8));
554 }
555
556 } else {
557 PrintAndLog("Command execute timeout");
558 }
559 return 1;
560 }
561
562 //
563 // Ultralight C Read Single Block
564 //
565 int CmdHF14AMfUCRdBl(const char *Cmd)
566 {
567 uint8_t blockNo = 0;
568
569 if (strlen(Cmd)<1) {
570 PrintAndLog("Usage: hf mfu ucrdbl <block number>");
571 PrintAndLog(" sample: hf mfu ucrdbl 0");
572 return 0;
573 }
574
575 blockNo = param_get8(Cmd, 0);
576 if (blockNo>MAX_ULTRAC_BLOCKS){
577 PrintAndLog("Error: Maximum number of readable blocks is 44 for Ultralight Cards!");
578 return 1;
579 }
580 PrintAndLog("--block no:%02x", (int)blockNo);
581
582 //Read Block
583 UsbCommand e = {CMD_MIFAREU_READBL, {blockNo}};
584 SendCommand(&e);
585 UsbCommand resp_c;
586 if (WaitForResponseTimeout(CMD_ACK,&resp_c,1500)) {
587 uint8_t isOK = resp_c.arg[0] & 0xff;
588 uint8_t * data = resp_c.d.asBytes;
589 if (isOK)
590 PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 4));
591 else
592 PrintAndLog("isOk:%02x", isOK);
593 } else {
594 PrintAndLog("Command execute timeout");
595 }
596 return 0;
597 }
598
599 //
600 // Ultralight C Read (or Dump) Card Contents
601 //
602 int CmdHF14AMfUCRdCard(const char *Cmd){
603 int i;
604 uint8_t BlockNo = 0;
605 int Pages=44;
606 uint8_t *lockbytes_t=NULL;
607 uint8_t lockbytes[2]={0x00};
608 uint8_t *lockbytes_t2=NULL;
609 uint8_t lockbytes2[2]={0x00};
610 bool bit[16]={0x00};
611 bool bit2[16]={0x00};
612 bool dump=false;
613 uint8_t datatemp[5]={0x00};
614 uint8_t isOK = 0;
615 uint8_t * data = NULL;
616 FILE *fout = NULL;
617
618 if (strchr(Cmd,'x') != 0){
619 dump=true;
620 if ((fout = fopen("dump_ultralightc_data.bin","wb")) == NULL) {
621 PrintAndLog("Could not create file name dumpdata.bin");
622 return 1;
623 }
624 PrintAndLog("Dumping Ultralight C Card Data...");
625 }
626 PrintAndLog("Attempting to Read Ultralight C... ");
627 UsbCommand c = {CMD_MIFAREUC_READCARD, {BlockNo, Pages}};
628 SendCommand(&c);
629 UsbCommand resp;
630
631 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
632 isOK = resp.arg[0] & 0xff;
633 data = resp.d.asBytes;
634 //Pages=sizeof(data)/sizeof(data[0]);
635 PrintAndLog("isOk:%02x", isOK);
636 if (isOK)
637 for (i = 0; i < Pages; i++) {
638 switch(i){
639 case 2:
640 //process lock bytes
641 lockbytes_t=data+(i*4);
642 lockbytes[0]=lockbytes_t[2];
643 lockbytes[1]=lockbytes_t[3];
644 for(int j=0; j<16; j++){
645 bit[j]=lockbytes[j/8] & ( 1 <<(7-j%8));
646 }
647 //might as well read bottom lockbytes too
648 lockbytes_t2=data+(40*4);
649 lockbytes2[0]=lockbytes_t2[2];
650 lockbytes2[1]=lockbytes_t2[3];
651 for(int j=0; j<16; j++){
652 bit2[j]=lockbytes2[j/8] & ( 1 <<(7-j%8));
653 }
654 PrintAndLog("Block %02x:%s ", i,sprint_hex(data + i * 4, 4));
655 memcpy(datatemp,data + i * 4,4);
656 if (dump) fwrite ( datatemp, 1, 4, fout );
657 break;
658 case 3:
659 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[4]);
660 memcpy(datatemp,data + i * 4,4);
661 if (dump) fwrite ( datatemp, 1, 4, fout );
662 break;
663 case 4:
664 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[3]);
665 memcpy(datatemp,data + i * 4,4);
666 if (dump) fwrite ( datatemp, 1, 4, fout );
667 break;
668 case 5:
669 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[2]);
670 memcpy(datatemp,data + i * 4,4);
671 if (dump) fwrite ( datatemp, 1, 4, fout );
672 break;
673 case 6:
674 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[1]);
675 memcpy(datatemp,data + i * 4,4);
676 if (dump) fwrite ( datatemp, 1, 4, fout );
677 break;
678 case 7:
679 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[0]);
680 memcpy(datatemp,data + i * 4,4);
681 if (dump) fwrite ( datatemp, 1, 4, fout );
682 break;
683 case 8:
684 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[15]);
685 memcpy(datatemp,data + i * 4,4);
686 if (dump) fwrite ( datatemp, 1, 4, fout );
687 break;
688 case 9:
689 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[14]);
690 memcpy(datatemp,data + i * 4,4);
691 if (dump) fwrite ( datatemp, 1, 4, fout );
692 break;
693 case 10:
694 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[13]);
695 memcpy(datatemp,data + i * 4,4);
696 if (dump) fwrite ( datatemp, 1, 4, fout );
697 break;
698 case 11:
699 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[12]);
700 memcpy(datatemp,data + i * 4,4);
701 if (dump) fwrite ( datatemp, 1, 4, fout );
702 break;
703 case 12:
704 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[11]);
705 memcpy(datatemp,data + i * 4,4);
706 if (dump) fwrite ( datatemp, 1, 4, fout );
707 break;
708 case 13:
709 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[10]);
710 memcpy(datatemp,data + i * 4,4);
711 if (dump) fwrite ( datatemp, 1, 4, fout );
712 break;
713 case 14:
714 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[9]);
715 memcpy(datatemp,data + i * 4,4);
716 if (dump) fwrite ( datatemp, 1, 4, fout );
717 break;
718 case 15:
719 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[8]);
720 memcpy(datatemp,data + i * 4,4);
721 if (dump) fwrite ( datatemp, 1, 4, fout );
722 break;
723 case 16:
724 case 17:
725 case 18:
726 case 19:
727 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[6]);
728 memcpy(datatemp,data + i * 4,4);
729 if (dump) fwrite ( datatemp, 1, 4, fout );
730 break;
731 case 20:
732 case 21:
733 case 22:
734 case 23:
735 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[5]);
736 memcpy(datatemp,data + i * 4,4);
737 if (dump) fwrite ( datatemp, 1, 4, fout );
738 break;
739 case 24:
740 case 25:
741 case 26:
742 case 27:
743 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[4]);
744 memcpy(datatemp,data + i * 4,4);
745 if (dump) fwrite ( datatemp, 1, 4, fout );
746 break;
747 case 28:
748 case 29:
749 case 30:
750 case 31:
751 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[2]);
752 memcpy(datatemp,data + i * 4,4);
753 if (dump) fwrite ( datatemp, 1, 4, fout );
754 break;
755 case 32:
756 case 33:
757 case 34:
758 case 35:
759 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[1]);
760 memcpy(datatemp,data + i * 4,4);
761 if (dump) fwrite ( datatemp, 1, 4, fout );
762 break;
763 case 36:
764 case 37:
765 case 38:
766 case 39:
767 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[0]);
768 memcpy(datatemp,data + i * 4,4);
769 if (dump) fwrite ( datatemp, 1, 4, fout );
770 break;
771 case 40:
772 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[12]);
773 memcpy(datatemp,data + i * 4,4);
774 if (dump) fwrite ( datatemp, 1, 4, fout );
775 break;
776 case 41:
777 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[11]);
778 memcpy(datatemp,data + i * 4,4);
779 if (dump) fwrite ( datatemp, 1, 4, fout );
780 break;
781 case 42:
782 //auth0
783 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[10]);
784 memcpy(datatemp,data + i * 4,4);
785 if (dump) fwrite ( datatemp, 1, 4, fout );
786 break;
787 case 43:
788 //auth1
789 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[9]);
790 memcpy(datatemp,data + i * 4,4);
791 if (dump) fwrite ( datatemp, 1, 4, fout );
792 break;
793 default:
794 PrintAndLog("Block %02x:%s ", i,sprint_hex(data + i * 4, 4));
795 memcpy(datatemp,data + i * 4,4);
796 if (dump) fwrite ( datatemp, 1, 4, fout );
797 break;
798 }
799 }
800
801 } else {
802 PrintAndLog("Command1 execute timeout");
803 }
804 if (dump) fclose(fout);
805 return 0;
806 }
807
808 //
809 // Ultralight C Dump Card Contents to file
810 //
811 int CmdHF14AMfUCDump(const char *Cmd){
812 int i;
813 uint8_t BlockNo = 0;
814 int Pages=44;
815 uint8_t *lockbytes_t=NULL;
816 uint8_t lockbytes[2]={0x00};
817 uint8_t *lockbytes_t2=NULL;
818 uint8_t lockbytes2[2]={0x00};
819 bool bit[16]={0x00};
820 bool bit2[16]={0x00};
821 bool dump=true;
822 uint8_t datatemp[5]={0x00};
823
824 uint8_t isOK = 0;
825 uint8_t * data = NULL;
826 FILE *fout;
827
828 if ((fout = fopen("dump_ultralightc_data.bin","wb")) == NULL) {
829 PrintAndLog("Could not create file name dumpdata.bin");
830 return 1;
831 }
832 PrintAndLog("Dumping Ultralight C Card Data...");
833 PrintAndLog("Attempting to Read Ultralight C... ");
834 UsbCommand c = {CMD_MIFAREU_READCARD, {BlockNo,Pages}};
835 SendCommand(&c);
836 UsbCommand resp;
837
838 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
839 isOK = resp.arg[0] & 0xff;
840 data = resp.d.asBytes;
841 PrintAndLog("isOk:%02x", isOK);
842 if (isOK)
843 for (i = 0; i < Pages; i++) {
844 switch(i){
845 case 2:
846 //process lock bytes
847 lockbytes_t=data+(i*4);
848 lockbytes[0]=lockbytes_t[2];
849 lockbytes[1]=lockbytes_t[3];
850 for(int j=0; j<16; j++){
851 bit[j]=lockbytes[j/8] & ( 1 <<(7-j%8));
852
853 }
854 //might as well read bottom lockbytes too
855 lockbytes_t2=data+(40*4);
856 lockbytes2[0]=lockbytes_t2[2];
857 lockbytes2[1]=lockbytes_t2[3];
858 for(int j=0; j<16; j++){
859 bit2[j]=lockbytes2[j/8] & ( 1 <<(7-j%8));
860 }
861
862 PrintAndLog("Block %02x:%s ", i,sprint_hex(data + i * 4, 4));
863 memcpy(datatemp,data + i * 4,4);
864 if (dump) fwrite ( datatemp, 1, 4, fout );
865 break;
866 case 3:
867 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[4]);
868 memcpy(datatemp,data + i * 4,4);
869 if (dump) fwrite ( datatemp, 1, 4, fout );
870 break;
871 case 4:
872 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[3]);
873 memcpy(datatemp,data + i * 4,4);
874 if (dump) fwrite ( datatemp, 1, 4, fout );
875 break;
876 case 5:
877 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[2]);
878 memcpy(datatemp,data + i * 4,4);
879 if (dump) fwrite ( datatemp, 1, 4, fout );
880 break;
881 case 6:
882 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[1]);
883 memcpy(datatemp,data + i * 4,4);
884 if (dump) fwrite ( datatemp, 1, 4, fout );
885 break;
886 case 7:
887 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[0]);
888 memcpy(datatemp,data + i * 4,4);
889 if (dump) fwrite ( datatemp, 1, 4, fout );
890 break;
891 case 8:
892 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[15]);
893 memcpy(datatemp,data + i * 4,4);
894 if (dump) fwrite ( datatemp, 1, 4, fout );
895 break;
896 case 9:
897 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[14]);
898 memcpy(datatemp,data + i * 4,4);
899 if (dump) fwrite ( datatemp, 1, 4, fout );
900 break;
901 case 10:
902 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[13]);
903 memcpy(datatemp,data + i * 4,4);
904 if (dump) fwrite ( datatemp, 1, 4, fout );
905 break;
906 case 11:
907 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[12]);
908 memcpy(datatemp,data + i * 4,4);
909 if (dump) fwrite ( datatemp, 1, 4, fout );
910 break;
911 case 12:
912 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[11]);
913 memcpy(datatemp,data + i * 4,4);
914 if (dump) fwrite ( datatemp, 1, 4, fout );
915 break;
916 case 13:
917 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[10]);
918 memcpy(datatemp,data + i * 4,4);
919 if (dump) fwrite ( datatemp, 1, 4, fout );
920 break;
921 case 14:
922 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[9]);
923 memcpy(datatemp,data + i * 4,4);
924 if (dump) fwrite ( datatemp, 1, 4, fout );
925 break;
926 case 15:
927 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[8]);
928 memcpy(datatemp,data + i * 4,4);
929 if (dump) fwrite ( datatemp, 1, 4, fout );
930 break;
931 case 16:
932 case 17:
933 case 18:
934 case 19:
935 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[6]);
936 memcpy(datatemp,data + i * 4,4);
937 if (dump) fwrite ( datatemp, 1, 4, fout );
938 break;
939 case 20:
940 case 21:
941 case 22:
942 case 23:
943 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[5]);
944 memcpy(datatemp,data + i * 4,4);
945 if (dump) fwrite ( datatemp, 1, 4, fout );
946 break;
947 case 24:
948 case 25:
949 case 26:
950 case 27:
951 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[4]);
952 memcpy(datatemp,data + i * 4,4);
953 if (dump) fwrite ( datatemp, 1, 4, fout );
954 break;
955 case 28:
956 case 29:
957 case 30:
958 case 31:
959 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[2]);
960 memcpy(datatemp,data + i * 4,4);
961 if (dump) fwrite ( datatemp, 1, 4, fout );
962 break;
963 case 32:
964 case 33:
965 case 34:
966 case 35:
967 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[1]);
968 memcpy(datatemp,data + i * 4,4);
969 if (dump) fwrite ( datatemp, 1, 4, fout );
970 break;
971 case 36:
972 case 37:
973 case 38:
974 case 39:
975 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[0]);
976 memcpy(datatemp,data + i * 4,4);
977 if (dump) fwrite ( datatemp, 1, 4, fout );
978 break;
979 case 40:
980 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[12]);
981 memcpy(datatemp,data + i * 4,4);
982 if (dump) fwrite ( datatemp, 1, 4, fout );
983 break;
984 case 41:
985 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[11]);
986 memcpy(datatemp,data + i * 4,4);
987 if (dump) fwrite ( datatemp, 1, 4, fout );
988 break;
989 case 42:
990 //auth0
991 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[10]);
992 memcpy(datatemp,data + i * 4,4);
993 if (dump) fwrite ( datatemp, 1, 4, fout );
994 break;
995 case 43:
996 //auth1
997 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[9]);
998 memcpy(datatemp,data + i * 4,4);
999 if (dump) fwrite ( datatemp, 1, 4, fout );
1000 break;
1001 default:
1002 PrintAndLog("Block %02x:%s ", i,sprint_hex(data + i * 4, 4));
1003 memcpy(datatemp,data + i * 4,4);
1004 if (dump) fwrite ( datatemp, 1, 4, fout );
1005 break;
1006 }
1007 }
1008
1009 } else {
1010 PrintAndLog("Command1 execute timeout");
1011 }
1012 if (dump) fclose(fout);
1013 return 0;
1014 }
1015
1016 //
1017 // Mifare Ultralight C Write Single Block
1018 //
1019 int CmdHF14AMfUCWrBl(const char *Cmd){
1020
1021 uint8_t blockNo = 0;
1022 bool chinese_card = 0;
1023 uint8_t bldata[16] = {0x00};
1024 UsbCommand resp;
1025
1026 if (strlen(Cmd)<3) {
1027 PrintAndLog("Usage: hf mfu ucwrbl <block number> <block data (8 hex symbols)> [w]");
1028 PrintAndLog(" sample: hf mfu uwrbl 0 01020304");
1029 return 0;
1030 }
1031 blockNo = param_get8(Cmd, 0);
1032 if (blockNo>(MAX_ULTRAC_BLOCKS+4)){
1033 PrintAndLog("Error: Maximum number of blocks is 47 for Ultralight Cards!");
1034 return 1;
1035 }
1036 if (param_gethex(Cmd, 1, bldata, 8)) {
1037 PrintAndLog("Block data must include 8 HEX symbols");
1038 return 1;
1039 }
1040 if (strchr(Cmd,'w') != 0) {
1041 chinese_card=1;
1042 }
1043 switch(blockNo){
1044 case 0:
1045 if (!chinese_card){
1046 PrintAndLog("Access Denied");
1047 }else{
1048 PrintAndLog("--specialblock no:%02x", blockNo);
1049 PrintAndLog("--data: %s", sprint_hex(bldata, 4));
1050 UsbCommand d = {CMD_MIFAREU_WRITEBL, {blockNo}};
1051 memcpy(d.d.asBytes,bldata, 4);
1052 SendCommand(&d);
1053 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
1054 uint8_t isOK = resp.arg[0] & 0xff;
1055 PrintAndLog("isOk:%02x", isOK);
1056 } else {
1057 PrintAndLog("Command execute timeout");
1058 }
1059 }
1060 break;
1061 case 1:
1062 if (!chinese_card){
1063 PrintAndLog("Access Denied");
1064 }else{
1065 PrintAndLog("--specialblock no:%02x", blockNo);
1066 PrintAndLog("--data: %s", sprint_hex(bldata, 4));
1067 UsbCommand d = {CMD_MIFAREU_WRITEBL, {blockNo}};
1068 memcpy(d.d.asBytes,bldata, 4);
1069 SendCommand(&d);
1070 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
1071 uint8_t isOK = resp.arg[0] & 0xff;
1072 PrintAndLog("isOk:%02x", isOK);
1073 } else {
1074 PrintAndLog("Command execute timeout");
1075 }
1076 }
1077 break;
1078 case 2:
1079 if (!chinese_card){
1080 PrintAndLog("Access Denied");
1081 }else{
1082 PrintAndLog("--specialblock no:%02x", blockNo);
1083 PrintAndLog("--data: %s", sprint_hex(bldata, 4));
1084 UsbCommand c = {CMD_MIFAREU_WRITEBL, {blockNo}};
1085 memcpy(c.d.asBytes, bldata, 4);
1086 SendCommand(&c);
1087 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
1088 uint8_t isOK = resp.arg[0] & 0xff;
1089 PrintAndLog("isOk:%02x", isOK);
1090 } else {
1091 PrintAndLog("Command execute timeout");
1092 }
1093 }
1094 break;
1095 case 3:
1096 PrintAndLog("--specialblock no:%02x", blockNo);
1097 PrintAndLog("--data: %s", sprint_hex(bldata, 4));
1098 UsbCommand d = {CMD_MIFAREU_WRITEBL, {blockNo}};
1099 memcpy(d.d.asBytes,bldata, 4);
1100 SendCommand(&d);
1101 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
1102 uint8_t isOK = resp.arg[0] & 0xff;
1103 PrintAndLog("isOk:%02x", isOK);
1104 } else {
1105 PrintAndLog("Command execute timeout");
1106 }
1107 break;
1108 default:
1109 PrintAndLog("--block no:%02x", blockNo);
1110 PrintAndLog("--data: %s", sprint_hex(bldata, 4));
1111 UsbCommand e = {CMD_MIFAREU_WRITEBL, {blockNo}};
1112 memcpy(e.d.asBytes,bldata, 4);
1113 SendCommand(&e);
1114 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
1115 uint8_t isOK = resp.arg[0] & 0xff;
1116 PrintAndLog("isOk:%02x", isOK);
1117 } else {
1118 PrintAndLog("Command execute timeout");
1119 }
1120 break;
1121 }
1122 return 0;
1123 }
1124
1125 //------------------------------------
1126 // Menu Stuff
1127 //------------------------------------
1128 static command_t CommandTable[] =
1129 {
1130 {"help", CmdHelp, 1,"This help"},
1131 {"dbg", CmdHF14AMfDbg, 0,"Set default debug mode"},
1132 {"urdbl", CmdHF14AMfURdBl, 0,"Read MIFARE Ultralight block"},
1133 {"urdcard", CmdHF14AMfURdCard, 0,"Read MIFARE Ultralight Card"},
1134 {"udump", CmdHF14AMfUDump, 0,"Dump MIFARE Ultralight tag to binary file"},
1135 {"uwrbl", CmdHF14AMfUWrBl, 0,"Write MIFARE Ultralight block"},
1136 {"ucrdbl", CmdHF14AMfUCRdBl, 0,"Read MIFARE Ultralight C block"},
1137 {"ucrdcard",CmdHF14AMfUCRdCard, 0,"Read MIFARE Ultralight C Card"},
1138 {"ucdump", CmdHF14AMfUCDump, 0,"Dump MIFARE Ultralight C tag to binary file"},
1139 {"ucwrbl", CmdHF14AMfUCWrBl, 0,"Write MIFARE Ultralight C block"},
1140 {"auth", CmdHF14AMfucAuth, 0,"Ultralight C Authentication"},
1141 {NULL, NULL, 0, NULL}
1142 };
1143
1144 int CmdHFMFUltra(const char *Cmd){
1145 // flush
1146 WaitForResponseTimeout(CMD_ACK,NULL,100);
1147 CmdsParse(CommandTable, Cmd);
1148 return 0;
1149 }
1150
1151 int CmdHelp(const char *Cmd){
1152 CmdsHelp(CommandTable);
1153 return 0;
1154 }
Impressum, Datenschutz