This commit is contained in:
iceman1001 2022-02-12 17:46:34 +01:00
parent f1d45b491c
commit ec59acf64c
9 changed files with 961 additions and 886 deletions

View file

@ -15,7 +15,7 @@
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Modes of operation: // Modes of operation:
// //
// --- Read --- // --- Read ---
// Proxmark reads an EM4100 tag. LED A is turned on. When the tag is detected, it is saved to flash (RDV4 only) and proxmark enters the emulation mode. // Proxmark reads an EM4100 tag. LED A is turned on. When the tag is detected, it is saved to flash (RDV4 only) and proxmark enters the emulation mode.
// It's the default mode for non-RDV4 devices, and if no previous read is present in the flash it's the default mode for RDV4 devices. // It's the default mode for non-RDV4 devices, and if no previous read is present in the flash it's the default mode for RDV4 devices.
@ -28,17 +28,17 @@
// Pressing the button enters writing mode and clones the emulated tag. // Pressing the button enters writing mode and clones the emulated tag.
// Double pressing the button enters the validation mode. // Double pressing the button enters the validation mode.
// Holding the button enters the reading mode. // Holding the button enters the reading mode.
// //
// --- Write --- // --- Write ---
// Proxmarks writes the last read tag. LEDs A and B are turned on. // Proxmarks writes the last read tag. LEDs A and B are turned on.
// When writing is complete LEDs A and B blink three times and proxmark enters the emulation mode. // When writing is complete LEDs A and B blink three times and proxmark enters the emulation mode.
// //
// --- Validate --- // --- Validate ---
// Proxmark reads an EM4100 tag. LED C is turned on. // Proxmark reads an EM4100 tag. LED C is turned on.
// If tag matches the last saved tag, LED C blinks three times. If it doesn't all LEDs blink three times. Proxmark enters the emulation mode afterwards. // If tag matches the last saved tag, LED C blinks three times. If it doesn't all LEDs blink three times. Proxmark enters the emulation mode afterwards.
// The result of the read is DISCARDED. // The result of the read is DISCARDED.
// Pressing the button enters the emulation mode. // Pressing the button enters the emulation mode.
// //
// --- Wipe --- // --- Wipe ---
// Proxmark continously wipes all approached T55xx tags. LED D is turned on, LEDs A-C are blinking. // Proxmark continously wipes all approached T55xx tags. LED D is turned on, LEDs A-C are blinking.
// Pressing the button enters the default mode (reading or emulation). // Pressing the button enters the default mode (reading or emulation).
@ -129,235 +129,232 @@ static void SaveIDtoFlash(uint64_t id) {
bt[4 - i] = (uint8_t)(id >> 8 * i & 0xff); bt[4 - i] = (uint8_t)(id >> 8 * i & 0xff);
} }
if (exists_in_spiffs(filename)) if (exists_in_spiffs(filename))
rdv40_spiffs_append(filename, &bt[0], 5, RDV40_SPIFFS_SAFETY_NORMAL); rdv40_spiffs_append(filename, &bt[0], 5, RDV40_SPIFFS_SAFETY_NORMAL);
else else
rdv40_spiffs_write(filename, &bt[0], 5, RDV40_SPIFFS_SAFETY_NORMAL); rdv40_spiffs_write(filename, &bt[0], 5, RDV40_SPIFFS_SAFETY_NORMAL);
if (exists_in_spiffs(filenameLast)) if (exists_in_spiffs(filenameLast))
rdv40_spiffs_remove(filenameLast, RDV40_SPIFFS_SAFETY_NORMAL); rdv40_spiffs_remove(filenameLast, RDV40_SPIFFS_SAFETY_NORMAL);
rdv40_spiffs_write(filenameLast, &bt[0], 5, RDV40_SPIFFS_SAFETY_NORMAL); rdv40_spiffs_write(filenameLast, &bt[0], 5, RDV40_SPIFFS_SAFETY_NORMAL);
} }
static bool ReadFlash(void) { static bool ReadFlash(void) {
if (exists_in_spiffs(filenameLast) == false) if (exists_in_spiffs(filenameLast) == false)
return false; return false;
uint8_t bt[5]; uint8_t bt[5];
if (rdv40_spiffs_read(filenameLast, (uint8_t *) &bt, 5, RDV40_SPIFFS_SAFETY_NORMAL) < 0) if (rdv40_spiffs_read(filenameLast, (uint8_t *) &bt, 5, RDV40_SPIFFS_SAFETY_NORMAL) < 0)
return false; return false;
low = bt[0]; low = bt[0];
low <<= 32; low <<= 32;
low |= (bt[1] << 24) | (bt[2] << 16) | (bt[3] << 8) | bt[4]; low |= (bt[1] << 24) | (bt[2] << 16) | (bt[3] << 8) | bt[4];
low2 = low; low2 = low;
high = 0; high = 0;
high2 = 0; high2 = 0;
return true; return true;
} }
#endif #endif
static void Wipe(void) { static void Wipe(void) {
DbpString("Wipe mode"); DbpString("Wipe mode");
LEDsoff(); LEDsoff();
for (;;) {
LED_A_ON();
LED_B_ON();
LED_C_ON();
LED_D_ON();
copy_em410x_to_t55xx(LF_RWSB_T55XX_TYPE, LF_CLOCK, (uint32_t) 0, (uint32_t) 0, false);
SpinDelay(60);
LEDsoff();
LED_D_ON();
int b = BUTTON_HELD(100);
if (b != BUTTON_NO_CLICK || data_available())
return;
SpinDelay(100);
b = BUTTON_HELD(100); for (;;) {
if (b != BUTTON_NO_CLICK || data_available()) LED_A_ON();
return; LED_B_ON();
} LED_C_ON();
LED_D_ON();
copy_em410x_to_t55xx(LF_RWSB_T55XX_TYPE, LF_CLOCK, (uint32_t) 0, (uint32_t) 0, false);
SpinDelay(60);
LEDsoff();
LED_D_ON();
int b = BUTTON_HELD(100);
if (b != BUTTON_NO_CLICK || data_available())
return;
SpinDelay(100);
b = BUTTON_HELD(100);
if (b != BUTTON_NO_CLICK || data_available())
return;
}
} }
static void Read(void) { static void Read(void) {
mode = 0; mode = 0;
while (low2 == 0 || mode == 0)
{
DbpString("Read");
LEDsoff();
LED_A_ON();
low2 = 0;
high2 = 0;
lf_em410x_watch(1, &high2, &low2, false);
if (low2 != 0) {
LED_B_ON();
low = low2;
high = high2;
mode = 1;
#ifdef WITH_FLASH while (low2 == 0 || mode == 0) {
SaveIDtoFlash(low2); DbpString("Read");
#endif LEDsoff();
LED_A_ON();
SpinDelay(50);
LED_C_ON();
SpinDelay(50);
LED_D_ON();
SpinDelay(50);
LEDsoff();
return;
}
if (data_available())
return;
int b = BUTTON_CLICKED(1000); low2 = 0;
high2 = 0;
lf_em410x_watch(1, &high2, &low2, false);
if ((b == BUTTON_SINGLE_CLICK || b == BUTTON_HOLD) && low != 0) { if (low2 != 0) {
mode = 1; LED_B_ON();
return; low = low2;
} high = high2;
mode = 1;
if (b == BUTTON_DOUBLE_CLICK) { #ifdef WITH_FLASH
Wipe(); SaveIDtoFlash(low2);
#endif
if (low != 0) { SpinDelay(50);
mode = 1; LED_C_ON();
return; SpinDelay(50);
} LED_D_ON();
} SpinDelay(50);
} LEDsoff();
return;
}
if (data_available())
return;
int b = BUTTON_CLICKED(1000);
if ((b == BUTTON_SINGLE_CLICK || b == BUTTON_HOLD) && low != 0) {
mode = 1;
return;
}
if (b == BUTTON_DOUBLE_CLICK) {
Wipe();
if (low != 0) {
mode = 1;
return;
}
}
}
} }
static void Validate(void) { static void Validate(void) {
DbpString("Validate"); DbpString("Validate");
LEDsoff(); LEDsoff();
LED_C_ON(); LED_C_ON();
for (;;) { for (;;) {
low2 = 0; low2 = 0;
high2 = 0; high2 = 0;
lf_em410x_watch(1, &high2, &low2, false); lf_em410x_watch(1, &high2, &low2, false);
if (low == low2 && high == high2) { if (low == low2 && high == high2) {
LED_C_OFF(); LED_C_OFF();
SpinDelay(150); SpinDelay(150);
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
LED_C_ON(); LED_C_ON();
SpinDelay(150); SpinDelay(150);
LED_C_OFF(); LED_C_OFF();
SpinDelay(150); SpinDelay(150);
} }
return; return;
} } else if (low2 != 0 || high2 != 0) {
else if (low2 != 0 || high2 != 0) { LEDsoff();
LEDsoff(); for (int i = 0; i < 3; i++) {
for (int i = 0; i < 3; i++) { LED_A_ON();
LED_A_ON(); LED_B_ON();
LED_B_ON(); LED_C_ON();
LED_C_ON(); LED_D_ON();
LED_D_ON(); SpinDelay(250);
SpinDelay(250); LEDsoff();
LEDsoff(); SpinDelay(150);
SpinDelay(150); }
}
return; return;
} } else
else SpinDelay(200);
SpinDelay(200);
int b = BUTTON_HELD(200); int b = BUTTON_HELD(200);
if (b != BUTTON_NO_CLICK || data_available()) if (b != BUTTON_NO_CLICK || data_available())
return; return;
} }
} }
static void Write(void) { static void Write(void) {
DbpString("Write"); DbpString("Write");
LED_A_ON(); LED_A_ON();
LED_B_ON(); LED_B_ON();
copy_em410x_to_t55xx(LF_RWSB_T55XX_TYPE, LF_CLOCK, (uint32_t)(low >> 32), (uint32_t)(low & 0xffffffff), false); copy_em410x_to_t55xx(LF_RWSB_T55XX_TYPE, LF_CLOCK, (uint32_t)(low >> 32), (uint32_t)(low & 0xffffffff), false);
SpinDelay(75); SpinDelay(75);
LEDsoff(); LEDsoff();
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
LED_A_ON(); LED_A_ON();
LED_B_ON(); LED_B_ON();
SpinDelay(75); SpinDelay(75);
LED_A_OFF(); LED_A_OFF();
LED_B_OFF(); LED_B_OFF();
SpinDelay(75); SpinDelay(75);
} }
} }
static void Emulate(void) { static void Emulate(void) {
DbpString("Emulate"); DbpString("Emulate");
LEDsoff(); LEDsoff();
for (;;) { for (;;) {
int bx = BUTTON_HELD(50); int bx = BUTTON_HELD(50);
if (bx == BUTTON_NO_CLICK) if (bx == BUTTON_NO_CLICK)
break; break;
SpinDelay(50); SpinDelay(50);
} }
LED_B_ON(); LED_B_ON();
construct_EM410x_emul(rev_quads(low)); construct_EM410x_emul(rev_quads(low));
SimulateTagLowFrequencyEx(buflen, 0, false, -1); SimulateTagLowFrequencyEx(buflen, 0, false, -1);
int b = BUTTON_CLICKED(800); int b = BUTTON_CLICKED(800);
if (b == BUTTON_NO_CLICK) if (b == BUTTON_NO_CLICK)
return; return;
for (;;) { for (;;) {
int bx = BUTTON_HELD(50); int bx = BUTTON_HELD(50);
if (bx == BUTTON_NO_CLICK) if (bx == BUTTON_NO_CLICK)
break; break;
SpinDelay(50); SpinDelay(50);
} }
if (b == BUTTON_SINGLE_CLICK) if (b == BUTTON_SINGLE_CLICK)
Write(); Write();
else if (b == BUTTON_HOLD) else if (b == BUTTON_HOLD)
mode = 0; mode = 0;
else if (b == BUTTON_DOUBLE_CLICK) else if (b == BUTTON_DOUBLE_CLICK)
Validate(); Validate();
} }
void RunMod() { void RunMod() {
StandAloneMode(); StandAloneMode();
LEDsoff(); LEDsoff();
LED_D_ON(); LED_D_ON();
FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
WDT_HIT(); WDT_HIT();
#ifdef WITH_FLASH #ifdef WITH_FLASH
if (ReadFlash()) if (ReadFlash())
mode = 1; mode = 1;
else Read(); else Read();
#else #else
Read(); Read();
#endif #endif
for (;;) { for (;;) {
WDT_HIT(); WDT_HIT();
LEDsoff(); LEDsoff();
if (data_available()) return; if (data_available()) return;
if (mode == 0) if (mode == 0)
Read(); Read();
else Emulate(); else Emulate();
} }
} }

View file

@ -233,7 +233,7 @@ static int CLIParseCommandParametersEx(CLIParserContext *ctx, size_t keyid, size
if (CLIParamHexToBuf(arg_get_str(ctx, aidid), hdata, hdatalen, &hdatalen)) { if (CLIParamHexToBuf(arg_get_str(ctx, aidid), hdata, hdatalen, &hdatalen)) {
return PM3_ESOFT; return PM3_ESOFT;
} }
if (hdatalen && (hdatalen < 1 || hdatalen > 16)) { if (hdatalen && (hdatalen < 1 || hdatalen > 16)) {
PrintAndLogEx(ERR, _RED_("ERROR:") " application id length must be 1-16 bytes only"); PrintAndLogEx(ERR, _RED_("ERROR:") " application id length must be 1-16 bytes only");
return PM3_EINVARG; return PM3_EINVARG;
@ -1466,7 +1466,7 @@ static int CmdHFCipurseUpdateKey(const char *Cmd) {
arg_int0(NULL, "newkeyn", "<dec>", "target key ID"), arg_int0(NULL, "newkeyn", "<dec>", "target key ID"),
arg_str0(NULL, "newkey", "<hex 16 byte>", "new key"), arg_str0(NULL, "newkey", "<hex 16 byte>", "new key"),
arg_str0(NULL, "newkeya", "<hex 1 byte>", "new key additional info. 0x00 by default"), arg_str0(NULL, "newkeya", "<hex 1 byte>", "new key additional info. 0x00 by default"),
arg_int0(NULL, "enckeyn", "<dec>", "encrypt key ID (must be equal to the key on the card)"), arg_int0(NULL, "enckeyn", "<dec>", "encrypt key ID (must be equal to the key on the card)"),
arg_str0(NULL, "enckey", "<hex 16 byte>", "encrypt key (must be equal to the key on the card)"), arg_str0(NULL, "enckey", "<hex 16 byte>", "encrypt key (must be equal to the key on the card)"),
@ -1541,7 +1541,7 @@ static int CmdHFCipurseUpdateKey(const char *Cmd) {
uint8_t encKey[CIPURSE_AES_KEY_LENGTH] = CIPURSE_DEFAULT_KEY; uint8_t encKey[CIPURSE_AES_KEY_LENGTH] = CIPURSE_DEFAULT_KEY;
if (hdatalen) if (hdatalen)
memcpy(encKey, hdata, CIPURSE_AES_KEY_LENGTH); memcpy(encKey, hdata, CIPURSE_AES_KEY_LENGTH);
bool noauth = arg_get_lit(ctx, 15); bool noauth = arg_get_lit(ctx, 15);
bool needCommit = arg_get_lit(ctx, 16); bool needCommit = arg_get_lit(ctx, 16);

View file

@ -4998,7 +4998,7 @@ static int CmdHF14ADesWriteData(const char *Cmd) {
arg_lit0(NULL, "debit", "use for value file debit operation instead of credit"), arg_lit0(NULL, "debit", "use for value file debit operation instead of credit"),
arg_lit0(NULL, "commit", "commit needs for backup file only. For the other file types and in the `auto` mode - command set it automatically"), arg_lit0(NULL, "commit", "commit needs for backup file only. For the other file types and in the `auto` mode - command set it automatically"),
arg_int0(NULL, "updaterec", "<dec>", "Record number for update record command. Updates record instead of write. Lastest record - 0"), arg_int0(NULL, "updaterec", "<dec>", "Record number for update record command. Updates record instead of write. Lastest record - 0"),
arg_str0(NULL, "isoid" , "<hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)"), arg_str0(NULL, "isoid", "<hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)"),
arg_str0(NULL, "fileisoid", "<hex>", "File ISO ID (ISO DF ID) (2 hex bytes, big endian). Works only for ISO write commands"), arg_str0(NULL, "fileisoid", "<hex>", "File ISO ID (ISO DF ID) (2 hex bytes, big endian). Works only for ISO write commands"),
arg_str0(NULL, "readerid", "<hex>", "reader id for CommitReaderID command. If present - the command issued before write command"), arg_str0(NULL, "readerid", "<hex>", "reader id for CommitReaderID command. If present - the command issued before write command"),
arg_str0(NULL, "trkey", "<hex>", "key for decode previous reader id"), arg_str0(NULL, "trkey", "<hex>", "key for decode previous reader id"),

View file

@ -893,7 +893,7 @@ static int CmdHFMFPWrbl(const char *Cmd) {
void *argtable[] = { void *argtable[] = {
arg_param_begin, arg_param_begin,
arg_lit0("v", "verbose", "Verbose mode"), arg_lit0("v", "verbose", "Verbose mode"),
arg_lit0("b", "keyb", "Use key B (def: keyA)"), arg_lit0("b", "keyb", "Use key B (def: keyA)"),
arg_int1(NULL, "blk", "<0..255>", "Block number"), arg_int1(NULL, "blk", "<0..255>", "Block number"),
arg_str1("d", "data", "<hex>", "Data, 16 hex bytes"), arg_str1("d", "data", "<hex>", "Data, 16 hex bytes"),

View file

@ -135,22 +135,22 @@ static int ul_print_nxp_silicon_info(uint8_t *card_uid) {
uint16_t waferCoordX = ((uid[6] & 3) << 8) | uid[1]; uint16_t waferCoordX = ((uid[6] & 3) << 8) | uid[1];
uint16_t waferCoordY = ((uid[6] & 12) << 6) | uid[2]; uint16_t waferCoordY = ((uid[6] & 12) << 6) | uid[2];
uint32_t waferCounter = ( uint32_t waferCounter = (
(uid[4] << 5) | (uid[4] << 5) |
((uid[6] & 0xF0) << 17) | ((uid[6] & 0xF0) << 17) |
(uid[5] << 13) | (uid[5] << 13) |
(uid[3] >> 3) (uid[3] >> 3)
); );
uint8_t testSite = uid[3] & 7; uint8_t testSite = uid[3] & 7;
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Silicon Information")); PrintAndLogEx(INFO, "--- " _CYAN_("Tag Silicon Information"));
PrintAndLogEx(INFO, " Wafer Counter: %" PRId32 " ( 0x%02" PRIX32 " )", waferCounter, waferCounter); PrintAndLogEx(INFO, " Wafer Counter: %" PRId32 " ( 0x%02" PRIX32 " )", waferCounter, waferCounter);
PrintAndLogEx(INFO, " Wafer Coordinates: x %" PRId16 ", y %" PRId16 " (0x%02" PRIX16 ", 0x%02" PRIX16 ")" PrintAndLogEx(INFO, " Wafer Coordinates: x %" PRId16 ", y %" PRId16 " (0x%02" PRIX16 ", 0x%02" PRIX16 ")"
, waferCoordX , waferCoordX
, waferCoordY , waferCoordY
, waferCoordX , waferCoordX
, waferCoordY , waferCoordY
); );
PrintAndLogEx(INFO, " Test Site: %u", testSite); PrintAndLogEx(INFO, " Test Site: %u", testSite);
return PM3_SUCCESS; return PM3_SUCCESS;
} }
@ -2063,7 +2063,7 @@ void printMFUdumpEx(mfu_dump_t *card, uint16_t pages, uint8_t startpage) {
PrintAndLogEx(INFO, "Version..... " _YELLOW_("%s"), sprint_hex(card->version, sizeof(card->version))); PrintAndLogEx(INFO, "Version..... " _YELLOW_("%s"), sprint_hex(card->version, sizeof(card->version)));
PrintAndLogEx(INFO, "TBD 0....... %s", sprint_hex(card->tbo, sizeof(card->tbo))); PrintAndLogEx(INFO, "TBD 0....... %s", sprint_hex(card->tbo, sizeof(card->tbo)));
PrintAndLogEx(INFO, "TBD 1....... %s", sprint_hex(card->tbo1, sizeof(card->tbo1))); PrintAndLogEx(INFO, "TBD 1....... %s", sprint_hex(card->tbo1, sizeof(card->tbo1)));
PrintAndLogEx(INFO, "Signature... %s", sprint_hex(card->signature, 16 )); PrintAndLogEx(INFO, "Signature... %s", sprint_hex(card->signature, 16));
PrintAndLogEx(INFO, " %s", sprint_hex(card->signature + 16, sizeof(card->signature) - 16)); PrintAndLogEx(INFO, " %s", sprint_hex(card->signature + 16, sizeof(card->signature) - 16));
for (uint8_t i = 0; i < 3; i ++) { for (uint8_t i = 0; i < 3; i ++) {
PrintAndLogEx(INFO, "Counter %d... %s", i, sprint_hex(card->counter_tearing[i], 3)); PrintAndLogEx(INFO, "Counter %d... %s", i, sprint_hex(card->counter_tearing[i], 3));
@ -2535,7 +2535,7 @@ static int CmdHF14AMfURestore(const char *Cmd) {
free(fptr); free(fptr);
} }
// reserve memory // reserve memory
uint8_t *dump = NULL; uint8_t *dump = NULL;
size_t bytes_read = 0; size_t bytes_read = 0;
int res = 0; int res = 0;
@ -2589,7 +2589,7 @@ static int CmdHF14AMfURestore(const char *Cmd) {
if (pages - 1 != mem->pages) { if (pages - 1 != mem->pages) {
PrintAndLogEx(ERR, "Error, invalid dump, wrong page count"); PrintAndLogEx(ERR, "Error, invalid dump, wrong page count");
PrintAndLogEx(INFO, " %u vs mempg %u", pages -1 , mem->pages); PrintAndLogEx(INFO, " %u vs mempg %u", pages - 1, mem->pages);
free(dump); free(dump);
return PM3_ESOFT; return PM3_ESOFT;
} }
@ -4152,7 +4152,7 @@ static int CmdHF14AMfuEView(const char *Cmd) {
return PM3_ETIMEOUT; return PM3_ETIMEOUT;
} }
printMFUdumpEx( (mfu_dump_t *)dump, blocks, 0); printMFUdumpEx((mfu_dump_t *)dump, blocks, 0);
free(dump); free(dump);
return PM3_SUCCESS; return PM3_SUCCESS;
} }
@ -4225,14 +4225,14 @@ static int CmdHF14AMfuView(const char *Cmd) {
return res; return res;
} }
uint16_t block_cnt = ((bytes_read - MFU_DUMP_PREFIX_LENGTH) / MFU_BLOCK_SIZE); uint16_t block_cnt = ((bytes_read - MFU_DUMP_PREFIX_LENGTH) / MFU_BLOCK_SIZE);
if (verbose) { if (verbose) {
PrintAndLogEx(INFO, "File: " _YELLOW_("%s"), filename); PrintAndLogEx(INFO, "File: " _YELLOW_("%s"), filename);
PrintAndLogEx(INFO, "File size %zu bytes, file blocks %d (0x%x)", bytes_read, block_cnt, block_cnt); PrintAndLogEx(INFO, "File size %zu bytes, file blocks %d (0x%x)", bytes_read, block_cnt, block_cnt);
} }
printMFUdumpEx( (mfu_dump_t *)dump, block_cnt, 0); printMFUdumpEx((mfu_dump_t *)dump, block_cnt, 0);
free(dump); free(dump);
return PM3_SUCCESS; return PM3_SUCCESS;
} }

View file

@ -1112,7 +1112,7 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz
if (!strcmp(ctype, "mfu")) { if (!strcmp(ctype, "mfu")) {
mfu_dump_t* mem = (mfu_dump_t *)udata; mfu_dump_t *mem = (mfu_dump_t *)udata;
JsonLoadBufAsHex(root, "$.Card.Version", mem->version, sizeof(mem->version), datalen); JsonLoadBufAsHex(root, "$.Card.Version", mem->version, sizeof(mem->version), datalen);
JsonLoadBufAsHex(root, "$.Card.TBO_0", mem->tbo, sizeof(mem->tbo), datalen); JsonLoadBufAsHex(root, "$.Card.TBO_0", mem->tbo, sizeof(mem->tbo), datalen);
@ -1124,7 +1124,7 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz
JsonLoadBufAsHex(root, "$.Card.Tearing1", &mem->counter_tearing[1][3], 1, datalen); JsonLoadBufAsHex(root, "$.Card.Tearing1", &mem->counter_tearing[1][3], 1, datalen);
JsonLoadBufAsHex(root, "$.Card.Counter2", &mem->counter_tearing[2][0], 3, datalen); JsonLoadBufAsHex(root, "$.Card.Counter2", &mem->counter_tearing[2][0], 3, datalen);
JsonLoadBufAsHex(root, "$.Card.Tearing2", &mem->counter_tearing[2][3], 1, datalen); JsonLoadBufAsHex(root, "$.Card.Tearing2", &mem->counter_tearing[2][3], 1, datalen);
*datalen = MFU_DUMP_PREFIX_LENGTH; *datalen = MFU_DUMP_PREFIX_LENGTH;
size_t sptr = 0; size_t sptr = 0;
for (int i = 0; i < 256; i++) { for (int i = 0; i < 256; i++) {
@ -1146,7 +1146,7 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz
} }
// remove one, since pages indicates a index rather than number of available pages // remove one, since pages indicates a index rather than number of available pages
--mem->pages; --mem->pages;
*datalen += sptr; *datalen += sptr;
} }

View file

@ -185,6 +185,8 @@ const static vocabulory_t vocabulory[] = {
{ 0, "hf cipurse formatall" }, { 0, "hf cipurse formatall" },
{ 0, "hf cipurse create" }, { 0, "hf cipurse create" },
{ 0, "hf cipurse delete" }, { 0, "hf cipurse delete" },
{ 0, "hf cipurse updkey" },
{ 0, "hf cipurse updakey" },
{ 0, "hf cipurse default" }, { 0, "hf cipurse default" },
{ 1, "hf cipurse test" }, { 1, "hf cipurse test" },
{ 1, "hf epa help" }, { 1, "hf epa help" },
@ -348,6 +350,7 @@ const static vocabulory_t vocabulory[] = {
{ 0, "hf mfu ndefread" }, { 0, "hf mfu ndefread" },
{ 0, "hf mfu rdbl" }, { 0, "hf mfu rdbl" },
{ 0, "hf mfu restore" }, { 0, "hf mfu restore" },
{ 1, "hf mfu view" },
{ 0, "hf mfu wrbl" }, { 0, "hf mfu wrbl" },
{ 0, "hf mfu eload" }, { 0, "hf mfu eload" },
{ 0, "hf mfu eview" }, { 0, "hf mfu eview" },

File diff suppressed because it is too large Load diff

View file

@ -137,17 +137,17 @@ Check column "offline" for their availability.
|command |offline |description |command |offline |description
|------- |------- |----------- |------- |------- |-----------
|`emv help `|Y |`This help` |`emv help `|Y |`This help`
|`emv exec `|N |`Executes EMV contactless transaction.` |`emv exec `|N |`Executes EMV contactless transaction`
|`emv pse `|N |`Execute PPSE. It selects 2PAY.SYS.DDF01 or 1PAY.SYS.DDF01 directory.` |`emv pse `|N |`Execute PPSE. It selects 2PAY.SYS.DDF01 or 1PAY.SYS.DDF01 directory`
|`emv search `|N |`Try to select all applets from applets list and print installed applets.` |`emv search `|N |`Try to select all applets from applets list and print installed applets`
|`emv select `|N |`Select applet.` |`emv select `|N |`Select applet`
|`emv gpo `|N |`Execute GetProcessingOptions.` |`emv gpo `|N |`Execute GetProcessingOptions`
|`emv readrec `|N |`Read files from card.` |`emv readrec `|N |`Read files from card`
|`emv genac `|N |`Generate ApplicationCryptogram.` |`emv genac `|N |`Generate ApplicationCryptogram`
|`emv challenge `|N |`Generate challenge.` |`emv challenge `|N |`Generate challenge`
|`emv intauth `|N |`Internal authentication.` |`emv intauth `|N |`Internal authentication`
|`emv scan `|N |`Scan EMV card and save it contents to json file for emulator.` |`emv scan `|N |`Scan EMV card and save it contents to json file for emulator`
|`emv test `|Y |`Crypto logic test.` |`emv test `|Y |`Crypto logic test`
|`emv list `|Y |`List ISO7816 history` |`emv list `|Y |`List ISO7816 history`
|`emv roca `|N |`Extract public keys and run ROCA test` |`emv roca `|N |`Extract public keys and run ROCA test`
@ -252,6 +252,8 @@ Check column "offline" for their availability.
|`hf cipurse formatall `|N |`Erase all the data from chip` |`hf cipurse formatall `|N |`Erase all the data from chip`
|`hf cipurse create `|N |`Create file, application, key via DGI record` |`hf cipurse create `|N |`Create file, application, key via DGI record`
|`hf cipurse delete `|N |`Delete file` |`hf cipurse delete `|N |`Delete file`
|`hf cipurse updkey `|N |`Update key`
|`hf cipurse updakey `|N |`Update key attributes`
|`hf cipurse default `|N |`Set default key and file id for all the other commands` |`hf cipurse default `|N |`Set default key and file id for all the other commands`
|`hf cipurse test `|Y |`Tests` |`hf cipurse test `|Y |`Tests`
@ -519,8 +521,9 @@ Check column "offline" for their availability.
|`hf mfu ndefread `|N |`Prints NDEF records from card` |`hf mfu ndefread `|N |`Prints NDEF records from card`
|`hf mfu rdbl `|N |`Read block` |`hf mfu rdbl `|N |`Read block`
|`hf mfu restore `|N |`Restore a dump onto a MFU MAGIC tag` |`hf mfu restore `|N |`Restore a dump onto a MFU MAGIC tag`
|`hf mfu view `|Y |`Display content from tag dump file`
|`hf mfu wrbl `|N |`Write block` |`hf mfu wrbl `|N |`Write block`
|`hf mfu eload `|N |`load Ultralight .eml dump file into emulator memory` |`hf mfu eload `|N |`Load Ultralight .eml dump file into emulator memory`
|`hf mfu eview `|N |`View emulator memory` |`hf mfu eview `|N |`View emulator memory`
|`hf mfu sim `|N |`Simulate MIFARE Ultralight from emulator memory` |`hf mfu sim `|N |`Simulate MIFARE Ultralight from emulator memory`
|`hf mfu setpwd `|N |`Set 3DES key - Ultralight-C` |`hf mfu setpwd `|N |`Set 3DES key - Ultralight-C`