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