textual
[RRG-proxmark3.git] / client / src / cmdlfhid.c
blob50a0d5aecde247bf2921a1a0f05870fb673b30db
1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
3 // 2016,2017, marshmellow, iceman
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 // Low frequency HID commands (known)
9 //
10 // Useful resources:
11 // RF interface, programming a T55x7 clone, 26-bit HID H10301 encoding:
12 // http://www.proxmark.org/files/Documents/125%20kHz%20-%20HID/HID_format_example.pdf
14 // "Understanding Card Data Formats"
15 // https://www.hidglobal.com/sites/default/files/hid-understanding_card_data_formats-wp-en.pdf
17 // "What Format Do You Need?"
18 // https://www.hidglobal.com/sites/default/files/resource_files/hid-prox-br-en.pdf
19 //-----------------------------------------------------------------------------
21 #include "cmdlfhid.h"
22 #include <stdio.h>
23 #include <string.h>
24 #include <ctype.h>
25 #include <inttypes.h>
26 #include "cmdparser.h" // command_t
27 #include "comms.h"
28 #include "commonutil.h" // ARRAYLEN
29 #include "cliparser.h"
30 #include "ui.h"
31 #include "graph.h"
32 #include "cmddata.h" // g_debugMode, demodbuff cmds
33 #include "cmdlf.h" // lf_read, lfsim_wait_check
34 #include "util_posix.h"
35 #include "lfdemod.h"
36 #include "wiegand_formats.h"
37 #include "wiegand_formatutils.h"
38 #include "cmdlfem4x05.h" // EM defines
40 #ifndef BITS
41 # define BITS 96
42 #endif
44 static int CmdHelp(const char *Cmd);
46 // sending three times. Didn't seem to break the previous sim?
47 static int sendPing(void) {
48 SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
49 SendCommandNG(CMD_PING, NULL, 0);
50 clearCommandBuffer();
51 PacketResponseNG resp;
52 if (!WaitForResponseTimeout(CMD_PING, &resp, 1000))
53 return PM3_ETIMEOUT;
54 return PM3_SUCCESS;
56 static int sendTry(uint8_t format_idx, wiegand_card_t *card, uint32_t delay, bool verbose) {
58 wiegand_message_t packed;
59 memset(&packed, 0, sizeof(wiegand_message_t));
61 if (HIDPack(format_idx, card, &packed, true) == false) {
62 PrintAndLogEx(WARNING, "The card data could not be encoded in the selected format.");
63 return PM3_ESOFT;
66 if (verbose) {
67 PrintAndLogEx(INFO, "Trying FC: " _YELLOW_("%u") " CN: " _YELLOW_("%"PRIu64) " Issue level: " _YELLOW_("%u") " OEM: " _YELLOW_("%u")
68 , card->FacilityCode
69 , card->CardNumber
70 , card->IssueLevel
71 , card->OEM
75 lf_hidsim_t payload;
76 payload.hi2 = packed.Top;
77 payload.hi = packed.Mid;
78 payload.lo = packed.Bot;
79 payload.longFMT = (packed.Mid > 0xFFF);
81 clearCommandBuffer();
83 SendCommandNG(CMD_LF_HID_SIMULATE, (uint8_t *)&payload, sizeof(payload));
85 PacketResponseNG resp;
86 WaitForResponse(CMD_LF_HID_SIMULATE, &resp);
87 if (resp.status == PM3_EOPABORTED)
88 return resp.status;
90 msleep(delay);
91 return sendPing();
94 //by marshmellow (based on existing demod + holiman's refactor)
95 //HID Prox demod - FSK RF/50 with preamble of 00011101 (then manchester encoded)
96 //print full HID Prox ID and some bit format details if found
97 int demodHID(bool verbose) {
98 (void) verbose; // unused so far
100 // HID simulation etc uses 0/1 as signal data. This must be converted in order to demod it back again
101 if (isGraphBitstream()) {
102 convertGraphFromBitstream();
105 //raw fsk demod no manchester decoding no start bit finding just get binary from wave
106 uint32_t hi2 = 0, hi = 0, lo = 0;
108 uint8_t bits[GraphTraceLen];
109 size_t size = getFromGraphBuf(bits);
110 if (size == 0) {
111 PrintAndLogEx(DEBUG, "DEBUG: Error - " _RED_("HID not enough samples"));
112 return PM3_ESOFT;
114 //get binary from fsk wave
115 int waveIdx = 0;
116 int idx = HIDdemodFSK(bits, &size, &hi2, &hi, &lo, &waveIdx);
117 if (idx < 0) {
119 if (idx == -1)
120 PrintAndLogEx(DEBUG, "DEBUG: Error - " _RED_("HID not enough samples"));
121 else if (idx == -2)
122 PrintAndLogEx(DEBUG, "DEBUG: Error - " _RED_("HID just noise detected"));
123 else if (idx == -3)
124 PrintAndLogEx(DEBUG, "DEBUG: Error - " _RED_("HID problem during FSK demod"));
125 else if (idx == -4)
126 PrintAndLogEx(DEBUG, "DEBUG: Error - " _RED_("HID preamble not found"));
127 else if (idx == -5)
128 PrintAndLogEx(DEBUG, "DEBUG: Error - " _RED_("HID error in Manchester data, size %zu"), size);
129 else
130 PrintAndLogEx(DEBUG, "DEBUG: Error - " _RED_("HID error demoding fsk %d"), idx);
132 return PM3_ESOFT;
135 setDemodBuff(bits, size, idx);
136 setClockGrid(50, waveIdx + (idx * 50));
138 if (hi2 == 0 && hi == 0 && lo == 0) {
139 PrintAndLogEx(DEBUG, "DEBUG: Error - " _RED_("HID no values found"));
140 return PM3_ESOFT;
143 wiegand_message_t packed = initialize_message_object(hi2, hi, lo, 0);
144 if (HIDTryUnpack(&packed) == false) {
145 printDemodBuff(0, false, false, true);
147 PrintAndLogEx(INFO, "raw: " _GREEN_("%08x%08x%08x"), hi2, hi, lo);
149 PrintAndLogEx(DEBUG, "DEBUG: HID idx: %d, Len: %zu, Printing Demod Buffer: ", idx, size);
150 if (g_debugMode) {
151 PrintAndLogEx(DEBUG, "raw: " _GREEN_("%08x%08x%08x"), hi2, hi, lo);
153 printDemodBuff(0, false, false, false);
156 return PM3_SUCCESS;
159 static int CmdHIDDemod(const char *Cmd) {
160 CLIParserContext *ctx;
161 CLIParserInit(&ctx, "lf hid demod",
162 "Try to find HID Prox preamble, if found decode / descramble data",
163 "lf hid demod"
166 void *argtable[] = {
167 arg_param_begin,
168 arg_param_end
170 CLIExecWithReturn(ctx, Cmd, argtable, true);
171 CLIParserFree(ctx);
172 return demodHID(true);
175 // this read is the "normal" read, which download lf signal and tries to demod here.
176 static int CmdHIDReader(const char *Cmd) {
177 CLIParserContext *ctx;
178 CLIParserInit(&ctx, "lf hid reader",
179 "read a HID Prox tag",
180 "lf hid reader -@ -> continuous reader mode"
183 void *argtable[] = {
184 arg_param_begin,
185 arg_lit0("@", NULL, "optional - continuous reader mode"),
186 arg_param_end
188 CLIExecWithReturn(ctx, Cmd, argtable, true);
189 bool cm = arg_get_lit(ctx, 1);
190 CLIParserFree(ctx);
192 if (cm) {
193 PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " to exit");
196 do {
197 lf_read(false, 16000);
198 demodHID(!cm);
199 } while (cm && !kbd_enter_pressed());
201 return PM3_SUCCESS;
204 // this read loops on device side.
205 // uses the demod in lfops.c
206 static int CmdHIDWatch(const char *Cmd) {
207 CLIParserContext *ctx;
209 CLIParserInit(&ctx, "lf hid watch",
210 "Enables HID compatible reader mode printing details.\n"
211 "By default, values are printed and logged until the button is pressed or another USB command is issued.\n",
212 "lf hid watch"
215 void *argtable[] = {
216 arg_param_begin,
217 arg_param_end
219 CLIExecWithReturn(ctx, Cmd, argtable, true);
220 CLIParserFree(ctx);
222 PrintAndLogEx(SUCCESS, "Watching for HID Prox cards - place tag on antenna");
223 PrintAndLogEx(INFO, "Press pm3-button to stop reading cards");
224 clearCommandBuffer();
225 SendCommandNG(CMD_LF_HID_WATCH, NULL, 0);
226 return lfsim_wait_check(CMD_LF_HID_WATCH);
229 static int CmdHIDSim(const char *Cmd) {
231 CLIParserContext *ctx;
232 CLIParserInit(&ctx, "lf hid sim",
233 "Enables simulation of HID card with card number.\n"
234 "Simulation runs until the button is pressed or another USB command is issued.",
235 "lf hid sim -r 2006ec0c86 -> HID 10301 26 bit\n"
236 "lf hid sim -r 2e0ec00c87 -> HID Corporate 35 bit\n"
237 "lf hid sim -r 01f0760643c3 -> HID P10001 40 bit\n"
238 "lf hid sim -r 01400076000c86 -> HID Corporate 48 bit\n"
239 "lf hid sim -w H10301 --fc 118 --cn 1603 -> HID 10301 26 bit\n"
242 void *argtable[] = {
243 arg_param_begin,
244 arg_str0("w", "wiegand", "<format>", "see " _YELLOW_("`wiegand list`") " for available formats"),
245 arg_u64_0(NULL, "fc", "<dec>", "facility code"),
246 arg_u64_0(NULL, "cn", "<dec>", "card number"),
247 arg_u64_0("i", NULL, "<dec>", "issue level"),
248 arg_u64_0("o", "oem", "<dec>", "OEM code"),
249 arg_strx0("r", "raw", "<hex>", "raw bytes"),
250 arg_param_end
252 CLIExecWithReturn(ctx, Cmd, argtable, false);
254 char format[16] = {0};
255 int format_len = 0;
256 CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)format, sizeof(format), &format_len);
258 wiegand_card_t card;
259 memset(&card, 0, sizeof(wiegand_card_t));
260 card.FacilityCode = arg_get_u32_def(ctx, 2, 0);
261 card.CardNumber = arg_get_u32_def(ctx, 3, 0);
262 card.IssueLevel = arg_get_u32_def(ctx, 4, 0);
263 card.OEM = arg_get_u32_def(ctx, 5, 0);
265 int raw_len = 0;
266 char raw[40] = {0};
267 CLIParamStrToBuf(arg_get_str(ctx, 6), (uint8_t *)raw, sizeof(raw), &raw_len);
268 CLIParserFree(ctx);
270 wiegand_message_t packed;
271 memset(&packed, 0, sizeof(wiegand_message_t));
273 // format validation
274 int format_idx = HIDFindCardFormat((char *)format);
275 if (format_idx == -1 && raw_len == 0) {
276 PrintAndLogEx(WARNING, "Unknown format: " _YELLOW_("%s"), format);
277 return PM3_EINVARG;
280 if (raw_len) {
281 uint32_t top = 0, mid = 0, bot = 0;
282 hexstring_to_u96(&top, &mid, &bot, raw);
283 packed.Top = top;
284 packed.Mid = mid;
285 packed.Bot = bot;
286 } else {
287 if (HIDPack(format_idx, &card, &packed, true) == false) {
288 PrintAndLogEx(WARNING, "The card data could not be encoded in the selected format.");
289 return PM3_ESOFT;
293 if (raw_len == 0) {
294 PrintAndLogEx(INFO, "Simulating HID tag");
295 HIDTryUnpack(&packed);
296 } else {
297 PrintAndLogEx(INFO, "Simulating HID tag using raw " _GREEN_("%s"), raw);
300 lf_hidsim_t payload;
301 payload.hi2 = packed.Top;
302 payload.hi = packed.Mid;
303 payload.lo = packed.Bot;
304 payload.longFMT = (packed.Mid > 0xFFF);
306 clearCommandBuffer();
307 SendCommandNG(CMD_LF_HID_SIMULATE, (uint8_t *)&payload, sizeof(payload));
308 return lfsim_wait_check(CMD_LF_HID_SIMULATE);
311 static int CmdHIDClone(const char *Cmd) {
313 CLIParserContext *ctx;
314 CLIParserInit(&ctx, "lf hid clone",
315 "clone a HID Prox tag to a T55x7, Q5/T5555 or EM4305/4469 tag.\n"
316 "Tag must be on the antenna when issuing this command.",
317 "lf hid clone -r 2006ec0c86 -> write raw value (HID 10301 26 bit)\n"
318 "lf hid clone -r 2e0ec00c87 -> write raw value (HID Corporate 35 bit)\n"
319 "lf hid clone -r 01f0760643c3 -> write raw value (HID P10001 40 bit)\n"
320 "lf hid clone -r 01400076000c86 -> write raw value (HID Corporate 48 bit)\n"
321 "lf hid clone -w H10301 --fc 118 --cn 1603 -> write raw value (HID 10301 26 bit)\n"
322 "lf hid clone -w H10301 --fc 118 --cn 1603 --q5 -> HID 10301 26 bit, encode for Q5/T5555 tag\n"
323 "lf hid clone -w H10301 --fc 118 --cn 1603 --em -> HID 10301 26 bit, encode for EM4305/4469"
326 void *argtable[] = {
327 arg_param_begin,
328 arg_str0("w", "wiegand", "<format>", "see " _YELLOW_("`wiegand list`") " for available formats"),
329 arg_u64_0(NULL, "fc", "<dec>", "facility code"),
330 arg_u64_0(NULL, "cn", "<dec>", "card number"),
331 arg_int0("i", NULL, "<dec>", "issue level"),
332 arg_int0("o", "oem", "<dec>", "OEM code"),
333 arg_strx0("r", "raw", "<hex>", "raw bytes"),
334 arg_lit0(NULL, "q5", "optional - specify writing to Q5/T5555 tag"),
335 arg_lit0(NULL, "em", "optional - specify writing to EM4305/4469 tag"),
336 arg_str0(NULL, "bin", "<bin>", "Binary string i.e 0001001001"),
337 arg_param_end
339 CLIExecWithReturn(ctx, Cmd, argtable, false);
341 char format[16] = {0};
342 int format_len = 0;
343 CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)format, sizeof(format), &format_len);
345 wiegand_card_t card;
346 memset(&card, 0, sizeof(wiegand_card_t));
347 card.FacilityCode = arg_get_u32_def(ctx, 2, 0);
348 card.CardNumber = arg_get_u32_def(ctx, 3, 0);
349 card.IssueLevel = arg_get_u32_def(ctx, 4, 0);
350 card.OEM = arg_get_u32_def(ctx, 5, 0);
352 int raw_len = 0;
353 char raw[40] = {0};
354 CLIParamStrToBuf(arg_get_str(ctx, 6), (uint8_t *)raw, sizeof(raw), &raw_len);
356 bool q5 = arg_get_lit(ctx, 7);
357 bool em = arg_get_lit(ctx, 8);
359 int bin_len = 63;
360 uint8_t bin[70] = {0};
361 CLIGetStrWithReturn(ctx, 9, bin, &bin_len);
362 CLIParserFree(ctx);
364 if (q5 && em) {
365 PrintAndLogEx(FAILED, "Can't specify both Q5 and EM4305 at the same time");
366 return PM3_EINVARG;
369 if (bin_len > 127) {
370 PrintAndLogEx(ERR, "Binary wiegand string must be less than 128 bits");
371 return PM3_EINVARG;
374 wiegand_message_t packed;
375 memset(&packed, 0, sizeof(wiegand_message_t));
377 // format validation
378 int format_idx = HIDFindCardFormat((char *)format);
379 if (format_idx == -1 && raw_len == 0) {
380 PrintAndLogEx(WARNING, "Unknown format: " _YELLOW_("%s"), format);
381 return PM3_EINVARG;
384 uint32_t top = 0, mid = 0, bot = 0;
385 if (raw_len) {
386 hexstring_to_u96(&top, &mid, &bot, raw);
387 packed.Top = top;
388 packed.Mid = mid;
389 packed.Bot = bot;
390 } else if (bin_len) {
391 int res = binstring_to_u96(&top, &mid, &bot, (const char *)bin);
392 if (res != bin_len) {
393 PrintAndLogEx(ERR, "Binary string contains none <0|1> chars");
394 return PM3_EINVARG;
396 packed.Top = top;
397 packed.Mid = mid;
398 packed.Bot = bot;
399 } else {
400 if (HIDPack(format_idx, &card, &packed, true) == false) {
401 PrintAndLogEx(WARNING, "The card data could not be encoded in the selected format.");
402 return PM3_ESOFT;
406 char cardtype[16] = {"T55x7"};
407 // Q5
408 if (q5) {
409 snprintf(cardtype, sizeof(cardtype), "Q5/T5555");
412 // EM4305
413 if (em) {
414 snprintf(cardtype, sizeof(cardtype), "EM4305/4469");
417 if (raw_len == 0) {
418 PrintAndLogEx(INFO, "Preparing to clone HID tag");
419 HIDUnpack(format_idx, &packed);
420 } else {
421 PrintAndLogEx(INFO, "Preparing to clone HID tag using raw " _YELLOW_("%s"), raw);
424 lf_hidsim_t payload;
425 payload.hi2 = packed.Top;
426 payload.hi = packed.Mid;
427 payload.lo = packed.Bot;
428 payload.longFMT = (packed.Mid > 0xFFF);
429 payload.Q5 = q5;
430 payload.EM = em;
432 clearCommandBuffer();
433 SendCommandNG(CMD_LF_HID_CLONE, (uint8_t *)&payload, sizeof(payload));
435 PacketResponseNG resp;
436 WaitForResponse(CMD_LF_HID_CLONE, &resp);
437 if (resp.status == PM3_SUCCESS) {
438 PrintAndLogEx(INFO, "Done");
439 } else {
440 PrintAndLogEx(FAILED, "Failed cloning");
441 return resp.status;
444 PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf hid reader`") " to verify");
445 return PM3_SUCCESS;
449 PrintAndLogEx(NORMAL, "HID | OEM | FC | CN | Wiegand | HID Formatted");
450 PrintAndLogEx(NORMAL, "----+-----+------+---------+-----------+--------------------");
451 PrintAndLogEx(NORMAL, " %u | %03u | %03u | %" PRIu64 " | %" PRIX64 " | %" PRIX64,
452 fmtlen[i],
453 oem,
455 cardnum,
456 wiegand,
457 blocks
460 PrintAndLogEx(NORMAL, "----+-----+-----+-------+-----------+--------------------");
463 static int CmdHIDBrute(const char *Cmd) {
465 uint32_t delay = 1000;
466 int format_idx = -1;
467 int direction = 0;
468 uint8_t format[16] = {0};
469 int formatLen;
471 wiegand_card_t cn_hi, cn_low;
472 memset(&cn_hi, 0, sizeof(wiegand_card_t));
474 CLIParserContext *ctx;
475 CLIParserInit(&ctx, "lf hid brute",
476 "Enables bruteforce of HID readers with specified facility code.\n"
477 "This is a attack against reader. if cardnumber is given, it starts with it and goes up / down one step\n"
478 "if cardnumber is not given, it starts with 1 and goes up to 65535",
479 "lf hid brute -w H10301 --fc 224\n"
480 "lf hid brute -w H10301 --fc 21 -d 2000\n"
481 "lf hid brute -v -w H10301 --fc 21 --cn 200 -d 2000\n"
482 "lf hid brute -v -w H10301 --fc 21 --cn 200 -d 2000 --up\n"
485 void *argtable[] = {
486 arg_param_begin,
487 arg_lit0("v", "verbose", "verbose logging, show all tries"),
488 arg_str1("w", "wiegand", "<format>", "see " _YELLOW_("`wiegand list`") " for available formats"),
489 arg_u64_0(NULL, "fc", "<dec>", "facility code"),
490 arg_u64_0(NULL, "cn", "<dec>", "card number to start with"),
491 arg_u64_0("i", "issue", "<dec>", "issue level"),
492 arg_u64_0("o", "oem", "<dec>", "OEM code"),
493 arg_u64_0("d", "delay", "<dec>", "delay betweens attempts in ms. Default 1000ms"),
494 arg_lit0(NULL, "up", "direction to increment card number. (default is both directions)"),
495 arg_lit0(NULL, "down", "direction to decrement card number. (default is both directions)"),
496 arg_param_end
498 CLIExecWithReturn(ctx, Cmd, argtable, false);
500 bool verbose = arg_get_lit(ctx, 1);
501 formatLen = sizeof(format);
502 CLIGetStrWithReturn(ctx, 2, format, &formatLen);
504 format_idx = HIDFindCardFormat((char *) format);
505 if (format_idx == -1) {
506 PrintAndLogEx(WARNING, "Unknown format: " _YELLOW_("%s"), format);
507 CLIParserFree(ctx);
508 return PM3_EINVARG;
511 cn_hi.FacilityCode = arg_get_u32_def(ctx, 3, 0);
512 cn_hi.CardNumber = arg_get_u32_def(ctx, 4, 0);
513 cn_hi.IssueLevel = arg_get_u32_def(ctx, 5, 0);
514 cn_hi.OEM = arg_get_u32_def(ctx, 6, 0);
515 delay = arg_get_u32_def(ctx, 7, 1000);
517 if (arg_get_lit(ctx, 8) && arg_get_lit(ctx, 9)) {
518 direction = 0;
519 } else if (arg_get_lit(ctx, 8)) {
520 direction = 1;
521 } else if (arg_get_lit(ctx, 9)) {
522 direction = 2;
525 CLIParserFree(ctx);
527 if (verbose) {
528 PrintAndLogEx(INFO, "Wiegand format#.. %i", format_idx);
529 PrintAndLogEx(INFO, "OEM#............. %u", cn_hi.OEM);
530 PrintAndLogEx(INFO, "ISSUE#........... %u", cn_hi.IssueLevel);
531 PrintAndLogEx(INFO, "Facility#........ %u", cn_hi.FacilityCode);
532 PrintAndLogEx(INFO, "Card#............ %" PRIu64, cn_hi.CardNumber);
533 switch (direction) {
534 case 0:
535 PrintAndLogEx(INFO, "Brute-forcing direction: " _YELLOW_("BOTH") " delay " _YELLOW_("%d"), delay);
536 break;
537 case 1:
538 PrintAndLogEx(INFO, "Brute-forcing direction: " _YELLOW_("UP") " delay " _YELLOW_("%d"), delay);
539 break;
540 case 2:
541 PrintAndLogEx(INFO, "Brute-forcing direction: " _YELLOW_("DOWN") " delay " _YELLOW_("%d"), delay);
542 break;
543 default:
544 break;
547 PrintAndLogEx(INFO, "Started brute-forcing HID Prox reader");
548 PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " or pm3-button to abort simulation");
549 // copy values to low.
550 cn_low = cn_hi;
552 // main loop
553 // iceman: could add options for bruteforcing OEM, ISSUE or FC as well..
554 bool exitloop = false;
555 bool fin_hi, fin_low;
556 fin_hi = fin_low = false;
557 do {
559 if (!session.pm3_present) {
560 PrintAndLogEx(WARNING, "Device offline\n");
561 return PM3_ENODATA;
564 if (kbd_enter_pressed()) {
565 PrintAndLogEx(WARNING, "aborted via keyboard!");
566 return sendPing();
569 // do one up
570 if (direction != 2) {
571 if (cn_hi.CardNumber < 0xFFFF) {
572 cn_hi.CardNumber++;
573 if (sendTry(format_idx, &cn_hi, delay, verbose) != PM3_SUCCESS) {
574 return PM3_ESOFT;
576 } else {
577 fin_hi = true;
581 // do one down
582 if (direction != 1) {
583 if (cn_low.CardNumber > 0) {
584 cn_low.CardNumber--;
585 if (sendTry(format_idx, &cn_low, delay, verbose) != PM3_SUCCESS) {
586 return PM3_ESOFT;
588 } else {
589 fin_low = true;
593 switch (direction) {
594 case 0:
595 if (fin_hi && fin_low) {
596 exitloop = true;
598 break;
599 case 1:
600 exitloop = fin_hi;
601 break;
602 case 2:
603 exitloop = fin_low;
604 break;
605 default:
606 break;
609 } while (exitloop == false);
611 PrintAndLogEx(INFO, "Brute forcing finished");
612 return PM3_SUCCESS;
615 static command_t CommandTable[] = {
616 {"help", CmdHelp, AlwaysAvailable, "this help"},
617 {"demod", CmdHIDDemod, AlwaysAvailable, "demodulate HID Prox tag from the GraphBuffer"},
618 {"reader", CmdHIDReader, IfPm3Lf, "attempt to read and extract tag data"},
619 {"clone", CmdHIDClone, IfPm3Lf, "clone HID tag to T55x7"},
620 {"sim", CmdHIDSim, IfPm3Lf, "simulate HID tag"},
621 {"brute", CmdHIDBrute, IfPm3Lf, "bruteforce card number against reader"},
622 {"watch", CmdHIDWatch, IfPm3Lf, "continuously watch for cards. Reader mode"},
623 {NULL, NULL, NULL, NULL}
626 static int CmdHelp(const char *Cmd) {
627 (void)Cmd; // Cmd is not used so far
628 CmdsHelp(CommandTable);
629 return PM3_SUCCESS;
632 int CmdLFHID(const char *Cmd) {
633 clearCommandBuffer();
634 return CmdsParse(CommandTable, Cmd);