]> git.zerfleddert.de Git - proxmark3-svn/blob - client/cmdhfmfu.c
Fixed build environment
[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;
475 DES_key_schedule ks1,ks2;
476 DES_cblock key1,key2;
477
478 //
479 memset(iv, 0, 8);
480
481 if (strlen(Cmd)<1) {
482 PrintAndLog("Usage: hf mfu auth k <key number>");
483 PrintAndLog(" sample: hf mfu auth k 0");
484 return 0;
485 }
486
487 //Change key to user defined one
488 if (strchr(Cmd,'k') != 0){
489 //choose a key
490 keyNo = param_get8(Cmd, 1);
491 switch(keyNo){
492 case 0:
493 memcpy(key,key1_blnk_data,16);
494 break;
495 case 1:
496 memcpy(key,key2_defa_data,16);
497 break;
498 case 2:
499 memcpy(key,key4_nfc_data,16);
500 break;
501 case 3:
502 memcpy(key,key5_ones_data,16);
503 break;
504 default:
505 memcpy(key,key3_3des_data,16);
506 break;
507 }
508 }else{
509 memcpy(key,key3_3des_data,16);
510 }
511 memcpy(key1,key,8);
512 memcpy(key2,key+8,8);
513 DES_set_key((DES_cblock *)key1,&ks1);
514 DES_set_key((DES_cblock *)key2,&ks2);
515
516 //Auth1
517 UsbCommand c = {CMD_MIFAREUC_AUTH1, {blockNo}};
518 SendCommand(&c);
519 UsbCommand resp;
520 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
521 uint8_t isOK = resp.arg[0] & 0xff;
522 cuid = resp.arg[1];
523 uint8_t * data= resp.d.asBytes;
524
525 if (isOK){
526 PrintAndLog("enc(RndB):%s", sprint_hex(data+1, 8));
527 memcpy(e_RndB,data+1,8);
528 }
529 } else {
530 PrintAndLog("Command execute timeout");
531 }
532
533 //Do crypto magic
534 DES_random_key(&RndA);
535 DES_ede2_cbc_encrypt(e_RndB,RndB,sizeof(e_RndB),&ks1,&ks2,&iv,0);
536 PrintAndLog(" RndB:%s",sprint_hex(RndB, 8));
537 PrintAndLog(" RndA:%s",sprint_hex(RndA, 8));
538 rol(RndB,8);
539 memcpy(RndARndB,RndA,8);
540 memcpy(RndARndB+8,RndB,8);
541 PrintAndLog(" RA+B:%s",sprint_hex(RndARndB, 16));
542 DES_ede2_cbc_encrypt(RndARndB,RndARndB,sizeof(RndARndB),&ks1,&ks2,&e_RndB,1);
543 PrintAndLog("enc(RA+B):%s",sprint_hex(RndARndB, 16));
544
545 //Auth2
546 UsbCommand d = {CMD_MIFAREUC_AUTH2, {cuid}};
547 memcpy(d.d.asBytes,RndARndB, 16);
548 SendCommand(&d);
549
550 UsbCommand respb;
551 if (WaitForResponseTimeout(CMD_ACK,&respb,1500)) {
552 uint8_t isOK = respb.arg[0] & 0xff;
553 uint8_t * data2= respb.d.asBytes;
554
555 if (isOK){
556 PrintAndLog("enc(RndA'):%s", sprint_hex(data2+1, 8));
557 }
558
559 } else {
560 PrintAndLog("Command execute timeout");
561 }
562 return 1;
563 }
564
565 //
566 // Ultralight C Read Single Block
567 //
568 int CmdHF14AMfUCRdBl(const char *Cmd)
569 {
570 uint8_t blockNo = 0;
571
572 if (strlen(Cmd)<1) {
573 PrintAndLog("Usage: hf mfu ucrdbl <block number>");
574 PrintAndLog(" sample: hf mfu ucrdbl 0");
575 return 0;
576 }
577
578 blockNo = param_get8(Cmd, 0);
579 if (blockNo>MAX_ULTRAC_BLOCKS){
580 PrintAndLog("Error: Maximum number of readable blocks is 44 for Ultralight Cards!");
581 return 1;
582 }
583 PrintAndLog("--block no:%02x", (int)blockNo);
584
585 //Read Block
586 UsbCommand e = {CMD_MIFAREU_READBL, {blockNo}};
587 SendCommand(&e);
588 UsbCommand resp_c;
589 if (WaitForResponseTimeout(CMD_ACK,&resp_c,1500)) {
590 uint8_t isOK = resp_c.arg[0] & 0xff;
591 uint8_t * data = resp_c.d.asBytes;
592 if (isOK)
593 PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 4));
594 else
595 PrintAndLog("isOk:%02x", isOK);
596 } else {
597 PrintAndLog("Command execute timeout");
598 }
599 return 0;
600 }
601
602 //
603 // Ultralight C Read (or Dump) Card Contents
604 //
605 int CmdHF14AMfUCRdCard(const char *Cmd){
606 int i;
607 uint8_t BlockNo = 0;
608 int Pages=44;
609 uint8_t *lockbytes_t=NULL;
610 uint8_t lockbytes[2]={0x00};
611 uint8_t *lockbytes_t2=NULL;
612 uint8_t lockbytes2[2]={0x00};
613 bool bit[16]={0x00};
614 bool bit2[16]={0x00};
615 bool dump=false;
616 uint8_t datatemp[5]={0x00};
617 uint8_t isOK = 0;
618 uint8_t * data = NULL;
619 FILE *fout = NULL;
620
621 if (strchr(Cmd,'x') != 0){
622 dump=true;
623 if ((fout = fopen("dump_ultralightc_data.bin","wb")) == NULL) {
624 PrintAndLog("Could not create file name dumpdata.bin");
625 return 1;
626 }
627 PrintAndLog("Dumping Ultralight C Card Data...");
628 }
629 PrintAndLog("Attempting to Read Ultralight C... ");
630 UsbCommand c = {CMD_MIFAREUC_READCARD, {BlockNo, Pages}};
631 SendCommand(&c);
632 UsbCommand resp;
633
634 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
635 isOK = resp.arg[0] & 0xff;
636 data = resp.d.asBytes;
637 //Pages=sizeof(data)/sizeof(data[0]);
638 PrintAndLog("isOk:%02x", isOK);
639 if (isOK)
640 for (i = 0; i < Pages; i++) {
641 switch(i){
642 case 2:
643 //process lock bytes
644 lockbytes_t=data+(i*4);
645 lockbytes[0]=lockbytes_t[2];
646 lockbytes[1]=lockbytes_t[3];
647 for(int j=0; j<16; j++){
648 bit[j]=lockbytes[j/8] & ( 1 <<(7-j%8));
649 }
650 //might as well read bottom lockbytes too
651 lockbytes_t2=data+(40*4);
652 lockbytes2[0]=lockbytes_t2[2];
653 lockbytes2[1]=lockbytes_t2[3];
654 for(int j=0; j<16; j++){
655 bit2[j]=lockbytes2[j/8] & ( 1 <<(7-j%8));
656 }
657 PrintAndLog("Block %02x:%s ", i,sprint_hex(data + i * 4, 4));
658 memcpy(datatemp,data + i * 4,4);
659 if (dump) fwrite ( datatemp, 1, 4, fout );
660 break;
661 case 3:
662 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[4]);
663 memcpy(datatemp,data + i * 4,4);
664 if (dump) fwrite ( datatemp, 1, 4, fout );
665 break;
666 case 4:
667 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[3]);
668 memcpy(datatemp,data + i * 4,4);
669 if (dump) fwrite ( datatemp, 1, 4, fout );
670 break;
671 case 5:
672 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[2]);
673 memcpy(datatemp,data + i * 4,4);
674 if (dump) fwrite ( datatemp, 1, 4, fout );
675 break;
676 case 6:
677 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[1]);
678 memcpy(datatemp,data + i * 4,4);
679 if (dump) fwrite ( datatemp, 1, 4, fout );
680 break;
681 case 7:
682 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[0]);
683 memcpy(datatemp,data + i * 4,4);
684 if (dump) fwrite ( datatemp, 1, 4, fout );
685 break;
686 case 8:
687 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[15]);
688 memcpy(datatemp,data + i * 4,4);
689 if (dump) fwrite ( datatemp, 1, 4, fout );
690 break;
691 case 9:
692 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[14]);
693 memcpy(datatemp,data + i * 4,4);
694 if (dump) fwrite ( datatemp, 1, 4, fout );
695 break;
696 case 10:
697 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[13]);
698 memcpy(datatemp,data + i * 4,4);
699 if (dump) fwrite ( datatemp, 1, 4, fout );
700 break;
701 case 11:
702 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[12]);
703 memcpy(datatemp,data + i * 4,4);
704 if (dump) fwrite ( datatemp, 1, 4, fout );
705 break;
706 case 12:
707 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[11]);
708 memcpy(datatemp,data + i * 4,4);
709 if (dump) fwrite ( datatemp, 1, 4, fout );
710 break;
711 case 13:
712 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[10]);
713 memcpy(datatemp,data + i * 4,4);
714 if (dump) fwrite ( datatemp, 1, 4, fout );
715 break;
716 case 14:
717 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[9]);
718 memcpy(datatemp,data + i * 4,4);
719 if (dump) fwrite ( datatemp, 1, 4, fout );
720 break;
721 case 15:
722 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[8]);
723 memcpy(datatemp,data + i * 4,4);
724 if (dump) fwrite ( datatemp, 1, 4, fout );
725 break;
726 case 16:
727 case 17:
728 case 18:
729 case 19:
730 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[6]);
731 memcpy(datatemp,data + i * 4,4);
732 if (dump) fwrite ( datatemp, 1, 4, fout );
733 break;
734 case 20:
735 case 21:
736 case 22:
737 case 23:
738 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[5]);
739 memcpy(datatemp,data + i * 4,4);
740 if (dump) fwrite ( datatemp, 1, 4, fout );
741 break;
742 case 24:
743 case 25:
744 case 26:
745 case 27:
746 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[4]);
747 memcpy(datatemp,data + i * 4,4);
748 if (dump) fwrite ( datatemp, 1, 4, fout );
749 break;
750 case 28:
751 case 29:
752 case 30:
753 case 31:
754 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[2]);
755 memcpy(datatemp,data + i * 4,4);
756 if (dump) fwrite ( datatemp, 1, 4, fout );
757 break;
758 case 32:
759 case 33:
760 case 34:
761 case 35:
762 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[1]);
763 memcpy(datatemp,data + i * 4,4);
764 if (dump) fwrite ( datatemp, 1, 4, fout );
765 break;
766 case 36:
767 case 37:
768 case 38:
769 case 39:
770 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[0]);
771 memcpy(datatemp,data + i * 4,4);
772 if (dump) fwrite ( datatemp, 1, 4, fout );
773 break;
774 case 40:
775 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[12]);
776 memcpy(datatemp,data + i * 4,4);
777 if (dump) fwrite ( datatemp, 1, 4, fout );
778 break;
779 case 41:
780 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[11]);
781 memcpy(datatemp,data + i * 4,4);
782 if (dump) fwrite ( datatemp, 1, 4, fout );
783 break;
784 case 42:
785 //auth0
786 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[10]);
787 memcpy(datatemp,data + i * 4,4);
788 if (dump) fwrite ( datatemp, 1, 4, fout );
789 break;
790 case 43:
791 //auth1
792 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[9]);
793 memcpy(datatemp,data + i * 4,4);
794 if (dump) fwrite ( datatemp, 1, 4, fout );
795 break;
796 default:
797 PrintAndLog("Block %02x:%s ", i,sprint_hex(data + i * 4, 4));
798 memcpy(datatemp,data + i * 4,4);
799 if (dump) fwrite ( datatemp, 1, 4, fout );
800 break;
801 }
802 }
803
804 } else {
805 PrintAndLog("Command1 execute timeout");
806 }
807 if (dump) fclose(fout);
808 return 0;
809 }
810
811 //
812 // Ultralight C Dump Card Contents to file
813 //
814 int CmdHF14AMfUCDump(const char *Cmd){
815 int i;
816 uint8_t BlockNo = 0;
817 int Pages=44;
818 uint8_t *lockbytes_t=NULL;
819 uint8_t lockbytes[2]={0x00};
820 uint8_t *lockbytes_t2=NULL;
821 uint8_t lockbytes2[2]={0x00};
822 bool bit[16]={0x00};
823 bool bit2[16]={0x00};
824 bool dump=true;
825 uint8_t datatemp[5]={0x00};
826
827 uint8_t isOK = 0;
828 uint8_t * data = NULL;
829 FILE *fout;
830
831 if ((fout = fopen("dump_ultralightc_data.bin","wb")) == NULL) {
832 PrintAndLog("Could not create file name dumpdata.bin");
833 return 1;
834 }
835 PrintAndLog("Dumping Ultralight C Card Data...");
836 PrintAndLog("Attempting to Read Ultralight C... ");
837 UsbCommand c = {CMD_MIFAREU_READCARD, {BlockNo,Pages}};
838 SendCommand(&c);
839 UsbCommand resp;
840
841 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
842 isOK = resp.arg[0] & 0xff;
843 data = resp.d.asBytes;
844 PrintAndLog("isOk:%02x", isOK);
845 if (isOK)
846 for (i = 0; i < Pages; i++) {
847 switch(i){
848 case 2:
849 //process lock bytes
850 lockbytes_t=data+(i*4);
851 lockbytes[0]=lockbytes_t[2];
852 lockbytes[1]=lockbytes_t[3];
853 for(int j=0; j<16; j++){
854 bit[j]=lockbytes[j/8] & ( 1 <<(7-j%8));
855
856 }
857 //might as well read bottom lockbytes too
858 lockbytes_t2=data+(40*4);
859 lockbytes2[0]=lockbytes_t2[2];
860 lockbytes2[1]=lockbytes_t2[3];
861 for(int j=0; j<16; j++){
862 bit2[j]=lockbytes2[j/8] & ( 1 <<(7-j%8));
863 }
864
865 PrintAndLog("Block %02x:%s ", i,sprint_hex(data + i * 4, 4));
866 memcpy(datatemp,data + i * 4,4);
867 if (dump) fwrite ( datatemp, 1, 4, fout );
868 break;
869 case 3:
870 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[4]);
871 memcpy(datatemp,data + i * 4,4);
872 if (dump) fwrite ( datatemp, 1, 4, fout );
873 break;
874 case 4:
875 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[3]);
876 memcpy(datatemp,data + i * 4,4);
877 if (dump) fwrite ( datatemp, 1, 4, fout );
878 break;
879 case 5:
880 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[2]);
881 memcpy(datatemp,data + i * 4,4);
882 if (dump) fwrite ( datatemp, 1, 4, fout );
883 break;
884 case 6:
885 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[1]);
886 memcpy(datatemp,data + i * 4,4);
887 if (dump) fwrite ( datatemp, 1, 4, fout );
888 break;
889 case 7:
890 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[0]);
891 memcpy(datatemp,data + i * 4,4);
892 if (dump) fwrite ( datatemp, 1, 4, fout );
893 break;
894 case 8:
895 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[15]);
896 memcpy(datatemp,data + i * 4,4);
897 if (dump) fwrite ( datatemp, 1, 4, fout );
898 break;
899 case 9:
900 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[14]);
901 memcpy(datatemp,data + i * 4,4);
902 if (dump) fwrite ( datatemp, 1, 4, fout );
903 break;
904 case 10:
905 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[13]);
906 memcpy(datatemp,data + i * 4,4);
907 if (dump) fwrite ( datatemp, 1, 4, fout );
908 break;
909 case 11:
910 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[12]);
911 memcpy(datatemp,data + i * 4,4);
912 if (dump) fwrite ( datatemp, 1, 4, fout );
913 break;
914 case 12:
915 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[11]);
916 memcpy(datatemp,data + i * 4,4);
917 if (dump) fwrite ( datatemp, 1, 4, fout );
918 break;
919 case 13:
920 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[10]);
921 memcpy(datatemp,data + i * 4,4);
922 if (dump) fwrite ( datatemp, 1, 4, fout );
923 break;
924 case 14:
925 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[9]);
926 memcpy(datatemp,data + i * 4,4);
927 if (dump) fwrite ( datatemp, 1, 4, fout );
928 break;
929 case 15:
930 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[8]);
931 memcpy(datatemp,data + i * 4,4);
932 if (dump) fwrite ( datatemp, 1, 4, fout );
933 break;
934 case 16:
935 case 17:
936 case 18:
937 case 19:
938 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[6]);
939 memcpy(datatemp,data + i * 4,4);
940 if (dump) fwrite ( datatemp, 1, 4, fout );
941 break;
942 case 20:
943 case 21:
944 case 22:
945 case 23:
946 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[5]);
947 memcpy(datatemp,data + i * 4,4);
948 if (dump) fwrite ( datatemp, 1, 4, fout );
949 break;
950 case 24:
951 case 25:
952 case 26:
953 case 27:
954 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[4]);
955 memcpy(datatemp,data + i * 4,4);
956 if (dump) fwrite ( datatemp, 1, 4, fout );
957 break;
958 case 28:
959 case 29:
960 case 30:
961 case 31:
962 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[2]);
963 memcpy(datatemp,data + i * 4,4);
964 if (dump) fwrite ( datatemp, 1, 4, fout );
965 break;
966 case 32:
967 case 33:
968 case 34:
969 case 35:
970 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[1]);
971 memcpy(datatemp,data + i * 4,4);
972 if (dump) fwrite ( datatemp, 1, 4, fout );
973 break;
974 case 36:
975 case 37:
976 case 38:
977 case 39:
978 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[0]);
979 memcpy(datatemp,data + i * 4,4);
980 if (dump) fwrite ( datatemp, 1, 4, fout );
981 break;
982 case 40:
983 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[12]);
984 memcpy(datatemp,data + i * 4,4);
985 if (dump) fwrite ( datatemp, 1, 4, fout );
986 break;
987 case 41:
988 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[11]);
989 memcpy(datatemp,data + i * 4,4);
990 if (dump) fwrite ( datatemp, 1, 4, fout );
991 break;
992 case 42:
993 //auth0
994 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[10]);
995 memcpy(datatemp,data + i * 4,4);
996 if (dump) fwrite ( datatemp, 1, 4, fout );
997 break;
998 case 43:
999 //auth1
1000 PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[9]);
1001 memcpy(datatemp,data + i * 4,4);
1002 if (dump) fwrite ( datatemp, 1, 4, fout );
1003 break;
1004 default:
1005 PrintAndLog("Block %02x:%s ", i,sprint_hex(data + i * 4, 4));
1006 memcpy(datatemp,data + i * 4,4);
1007 if (dump) fwrite ( datatemp, 1, 4, fout );
1008 break;
1009 }
1010 }
1011
1012 } else {
1013 PrintAndLog("Command1 execute timeout");
1014 }
1015 if (dump) fclose(fout);
1016 return 0;
1017 }
1018
1019 //
1020 // Mifare Ultralight C Write Single Block
1021 //
1022 int CmdHF14AMfUCWrBl(const char *Cmd){
1023
1024 uint8_t blockNo = 0;
1025 bool chinese_card = 0;
1026 uint8_t bldata[16] = {0x00};
1027 UsbCommand resp;
1028
1029 if (strlen(Cmd)<3) {
1030 PrintAndLog("Usage: hf mfu ucwrbl <block number> <block data (8 hex symbols)> [w]");
1031 PrintAndLog(" sample: hf mfu uwrbl 0 01020304");
1032 return 0;
1033 }
1034 blockNo = param_get8(Cmd, 0);
1035 if (blockNo>(MAX_ULTRAC_BLOCKS+4)){
1036 PrintAndLog("Error: Maximum number of blocks is 47 for Ultralight Cards!");
1037 return 1;
1038 }
1039 if (param_gethex(Cmd, 1, bldata, 8)) {
1040 PrintAndLog("Block data must include 8 HEX symbols");
1041 return 1;
1042 }
1043 if (strchr(Cmd,'w') != 0) {
1044 chinese_card=1;
1045 }
1046 switch(blockNo){
1047 case 0:
1048 if (!chinese_card){
1049 PrintAndLog("Access Denied");
1050 }else{
1051 PrintAndLog("--specialblock no:%02x", blockNo);
1052 PrintAndLog("--data: %s", sprint_hex(bldata, 4));
1053 UsbCommand d = {CMD_MIFAREU_WRITEBL, {blockNo}};
1054 memcpy(d.d.asBytes,bldata, 4);
1055 SendCommand(&d);
1056 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
1057 uint8_t isOK = resp.arg[0] & 0xff;
1058 PrintAndLog("isOk:%02x", isOK);
1059 } else {
1060 PrintAndLog("Command execute timeout");
1061 }
1062 }
1063 break;
1064 case 1:
1065 if (!chinese_card){
1066 PrintAndLog("Access Denied");
1067 }else{
1068 PrintAndLog("--specialblock no:%02x", blockNo);
1069 PrintAndLog("--data: %s", sprint_hex(bldata, 4));
1070 UsbCommand d = {CMD_MIFAREU_WRITEBL, {blockNo}};
1071 memcpy(d.d.asBytes,bldata, 4);
1072 SendCommand(&d);
1073 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
1074 uint8_t isOK = resp.arg[0] & 0xff;
1075 PrintAndLog("isOk:%02x", isOK);
1076 } else {
1077 PrintAndLog("Command execute timeout");
1078 }
1079 }
1080 break;
1081 case 2:
1082 if (!chinese_card){
1083 PrintAndLog("Access Denied");
1084 }else{
1085 PrintAndLog("--specialblock no:%02x", blockNo);
1086 PrintAndLog("--data: %s", sprint_hex(bldata, 4));
1087 UsbCommand c = {CMD_MIFAREU_WRITEBL, {blockNo}};
1088 memcpy(c.d.asBytes, bldata, 4);
1089 SendCommand(&c);
1090 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
1091 uint8_t isOK = resp.arg[0] & 0xff;
1092 PrintAndLog("isOk:%02x", isOK);
1093 } else {
1094 PrintAndLog("Command execute timeout");
1095 }
1096 }
1097 break;
1098 case 3:
1099 PrintAndLog("--specialblock no:%02x", blockNo);
1100 PrintAndLog("--data: %s", sprint_hex(bldata, 4));
1101 UsbCommand d = {CMD_MIFAREU_WRITEBL, {blockNo}};
1102 memcpy(d.d.asBytes,bldata, 4);
1103 SendCommand(&d);
1104 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
1105 uint8_t isOK = resp.arg[0] & 0xff;
1106 PrintAndLog("isOk:%02x", isOK);
1107 } else {
1108 PrintAndLog("Command execute timeout");
1109 }
1110 break;
1111 default:
1112 PrintAndLog("--block no:%02x", blockNo);
1113 PrintAndLog("--data: %s", sprint_hex(bldata, 4));
1114 UsbCommand e = {CMD_MIFAREU_WRITEBL, {blockNo}};
1115 memcpy(e.d.asBytes,bldata, 4);
1116 SendCommand(&e);
1117 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
1118 uint8_t isOK = resp.arg[0] & 0xff;
1119 PrintAndLog("isOk:%02x", isOK);
1120 } else {
1121 PrintAndLog("Command execute timeout");
1122 }
1123 break;
1124 }
1125 return 0;
1126 }
1127
1128 //------------------------------------
1129 // Menu Stuff
1130 //------------------------------------
1131 static command_t CommandTable[] =
1132 {
1133 {"help", CmdHelp, 1,"This help"},
1134 {"dbg", CmdHF14AMfDbg, 0,"Set default debug mode"},
1135 {"urdbl", CmdHF14AMfURdBl, 0,"Read MIFARE Ultralight block"},
1136 {"urdcard", CmdHF14AMfURdCard, 0,"Read MIFARE Ultralight Card"},
1137 {"udump", CmdHF14AMfUDump, 0,"Dump MIFARE Ultralight tag to binary file"},
1138 {"uwrbl", CmdHF14AMfUWrBl, 0,"Write MIFARE Ultralight block"},
1139 {"ucrdbl", CmdHF14AMfUCRdBl, 0,"Read MIFARE Ultralight C block"},
1140 {"ucrdcard",CmdHF14AMfUCRdCard, 0,"Read MIFARE Ultralight C Card"},
1141 {"ucdump", CmdHF14AMfUCDump, 0,"Dump MIFARE Ultralight C tag to binary file"},
1142 {"ucwrbl", CmdHF14AMfUCWrBl, 0,"Write MIFARE Ultralight C block"},
1143 {"auth", CmdHF14AMfucAuth, 0,"Ultralight C Authentication"},
1144 {NULL, NULL, 0, NULL}
1145 };
1146
1147 int CmdHFMFUltra(const char *Cmd){
1148 // flush
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