mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 05:43:48 -07:00
added hf 14b view
and modified dump command to be prepared to handle the different tags
This commit is contained in:
parent
45ea60c92b
commit
7b732e152e
2 changed files with 291 additions and 151 deletions
|
@ -42,6 +42,9 @@
|
|||
// client side time out, waiting for device to ask tag a APDU to answer
|
||||
#define APDU_TIMEOUT 2000
|
||||
|
||||
// for static arrays
|
||||
#define ST25TB_SR_BLOCK_SIZE 4
|
||||
|
||||
// iso14b apdu input frame length
|
||||
static uint16_t apdu_frame_length = 0;
|
||||
//static uint16_t ats_fsc[] = {16, 24, 32, 40, 48, 64, 96, 128, 256};
|
||||
|
@ -415,10 +418,14 @@ static int CmdHF14BCmdRaw(const char *Cmd) {
|
|||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static bool get_14b_UID(iso14b_card_select_t *card) {
|
||||
static bool get_14b_UID(uint8_t *d, iso14b_type_t *found_type) {
|
||||
|
||||
if (card == NULL)
|
||||
// sanity checks
|
||||
if (d == NULL || found_type == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*found_type = ISO14B_NONE;
|
||||
|
||||
iso14b_raw_cmd_t packet = {
|
||||
.flags = (ISO14B_CONNECT | ISO14B_SELECT_SR | ISO14B_DISCONNECT),
|
||||
|
@ -429,11 +436,11 @@ static bool get_14b_UID(iso14b_card_select_t *card) {
|
|||
PacketResponseNG resp;
|
||||
clearCommandBuffer();
|
||||
SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t *)&packet, sizeof(iso14b_raw_cmd_t));
|
||||
|
||||
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT)) {
|
||||
|
||||
if (resp.oldarg[0] == 0) {
|
||||
memcpy(card, (iso14b_card_select_t *)resp.data.asBytes, sizeof(iso14b_card_select_t));
|
||||
memcpy(d, resp.data.asBytes, sizeof(iso14b_card_select_t));
|
||||
*found_type = ISO14B_SELECT_SR;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -445,7 +452,21 @@ static bool get_14b_UID(iso14b_card_select_t *card) {
|
|||
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT)) {
|
||||
|
||||
if (resp.oldarg[0] == 0) {
|
||||
memcpy(card, (iso14b_card_select_t *)resp.data.asBytes, sizeof(iso14b_card_select_t));
|
||||
memcpy(d, resp.data.asBytes, sizeof(iso14b_card_select_t));
|
||||
*found_type = ISO14B_STANDARD;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// test CT
|
||||
packet.flags = (ISO14B_CONNECT | ISO14B_SELECT_CTS | ISO14B_DISCONNECT);
|
||||
clearCommandBuffer();
|
||||
SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t *)&packet, sizeof(iso14b_raw_cmd_t));
|
||||
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT)) {
|
||||
|
||||
if (resp.oldarg[0] == 0) {
|
||||
memcpy(d, resp.data.asBytes, sizeof(iso14b_cts_card_select_t));
|
||||
*found_type = ISO14B_CT;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -726,7 +747,7 @@ static void print_ct_general_info(void *vcard) {
|
|||
iso14b_cts_card_select_t card;
|
||||
memcpy(&card, (iso14b_cts_card_select_t *)vcard, sizeof(iso14b_cts_card_select_t));
|
||||
|
||||
uint32_t uid32 = (card.uid[0] | card.uid[1] << 8 | card.uid[2] << 16 | card.uid[3] << 24);
|
||||
uint32_t uid32 = MemLeToUint4byte(card.uid);
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(SUCCESS, "ASK C-Ticket");
|
||||
PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s") " ( " _YELLOW_("%010u") " )", sprint_hex(card.uid, sizeof(card.uid)), uid32);
|
||||
|
@ -735,6 +756,71 @@ static void print_ct_general_info(void *vcard) {
|
|||
PrintAndLogEx(NORMAL, "");
|
||||
}
|
||||
|
||||
static void print_hdr(void) {
|
||||
PrintAndLogEx(INFO, " block# | data |lck| ascii");
|
||||
PrintAndLogEx(INFO, "---------+--------------+---+----------");
|
||||
}
|
||||
|
||||
static void print_footer(void) {
|
||||
PrintAndLogEx(INFO, "---------+--------------+---+----------");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
}
|
||||
|
||||
/*
|
||||
static void print_ct_blocks(uint8_t *data, size_t len) {
|
||||
|
||||
size_t blocks = len / ST25TB_SR_BLOCK_SIZE;
|
||||
|
||||
print_hdr();
|
||||
|
||||
for (int i = 0; i <= blocks; i++) {
|
||||
PrintAndLogEx(INFO,
|
||||
"%3d/0x%02X | %s | %s | %s",
|
||||
i,
|
||||
i,
|
||||
sprint_hex(data + (i * 4), 4),
|
||||
" ",
|
||||
sprint_ascii(data + (i * 4), 4)
|
||||
);
|
||||
}
|
||||
print_footer();
|
||||
}
|
||||
*/
|
||||
|
||||
static void print_sr_blocks(uint8_t *data, size_t len) {
|
||||
|
||||
size_t blocks = len / ST25TB_SR_BLOCK_SIZE;
|
||||
uint8_t chipid = get_st_chipid(data);
|
||||
PrintAndLogEx(SUCCESS, _GREEN_("%s") " tag", get_st_chip_model(chipid));
|
||||
|
||||
PrintAndLogEx(DEBUG, "systemblock : %s", sprint_hex(data + (blocks * 4), 4));
|
||||
PrintAndLogEx(DEBUG, " otp lock : %02x %02x", data[(blocks * 4)], data[(blocks * 4) + 1]);
|
||||
|
||||
print_hdr();
|
||||
|
||||
for (int i = 0; i <= blocks; i++) {
|
||||
PrintAndLogEx(INFO,
|
||||
"%3d/0x%02X | %s | %s | %s",
|
||||
i,
|
||||
i,
|
||||
sprint_hex(data + (i * 4), 4),
|
||||
get_st_lock_info(chipid, data + (blocks * 4), i),
|
||||
sprint_ascii(data + (i * 4), 4)
|
||||
);
|
||||
}
|
||||
|
||||
PrintAndLogEx(INFO,
|
||||
"%3d/0x%02X | %s | %s | %s",
|
||||
0xFF,
|
||||
0xFF,
|
||||
sprint_hex(data + (0xFF * 4), 4),
|
||||
get_st_lock_info(chipid, data + (blocks * 4), 0xFF),
|
||||
sprint_ascii(data + (0xFF * 4), 4)
|
||||
);
|
||||
|
||||
print_footer();
|
||||
}
|
||||
|
||||
// iceman, calypso?
|
||||
// 05 00 00 = find one tag in field
|
||||
// 1d xx xx xx xx 00 08 01 00 = attrib xx=UID (resp 10 [f9 e0])
|
||||
|
@ -1280,17 +1366,40 @@ static int CmdHF14BDump(const char *Cmd) {
|
|||
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
iso14b_card_select_t card;
|
||||
if (get_14b_UID(&card) == false) {
|
||||
|
||||
uint8_t select[sizeof(iso14b_card_select_t)] = {0};
|
||||
iso14b_type_t select_cardtype = ISO14B_NONE;
|
||||
if (get_14b_UID(select, &select_cardtype) == false) {
|
||||
PrintAndLogEx(WARNING, "no tag found");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
if (card.uidlen != 8) {
|
||||
PrintAndLogEx(FAILED, "current dump command only work with SRI4K / SRI512 tags");
|
||||
return PM3_SUCCESS;
|
||||
if (select_cardtype == ISO14B_CT) {
|
||||
iso14b_cts_card_select_t ct_card;
|
||||
memcpy(&ct_card, (iso14b_cts_card_select_t *)&select, sizeof(iso14b_cts_card_select_t));
|
||||
|
||||
uint32_t uid32 = MemLeToUint4byte(ct_card.uid);
|
||||
PrintAndLogEx(SUCCESS, "UID: " _GREEN_("%s") " ( " _YELLOW_("%010u") " )", sprint_hex(ct_card.uid, 4), uid32);
|
||||
|
||||
// Have to figure out how large one of these are..
|
||||
PrintAndLogEx(FAILED, "Dumping CT tags is not implemented yet.");
|
||||
|
||||
// print_ct_blocks(data, cardsize);
|
||||
return switch_off_field_14b();
|
||||
}
|
||||
|
||||
if (select_cardtype == ISO14B_CT) {
|
||||
// Have to figure out how large one of these are..
|
||||
PrintAndLogEx(FAILED, "Dumping Standard ISO14443-B tags is not implemented yet.");
|
||||
// print_std_blocks(data, cardsize);
|
||||
return switch_off_field_14b();
|
||||
}
|
||||
|
||||
|
||||
if (select_cardtype == ISO14B_SR) {
|
||||
iso14b_card_select_t card;
|
||||
memcpy(&card, (iso14b_card_select_t *)&select, sizeof(iso14b_card_select_t));
|
||||
|
||||
// detect cardsize
|
||||
// 1 = 4096
|
||||
// 2 = 512
|
||||
|
@ -1329,7 +1438,7 @@ static int CmdHF14BDump(const char *Cmd) {
|
|||
SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t *)packet, sizeof(iso14b_raw_cmd_t));
|
||||
PacketResponseNG resp;
|
||||
|
||||
// select
|
||||
// select SR tag
|
||||
int status;
|
||||
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, 2000)) {
|
||||
status = resp.oldarg[0];
|
||||
|
@ -1402,34 +1511,7 @@ static int CmdHF14BDump(const char *Cmd) {
|
|||
return switch_off_field_14b();
|
||||
}
|
||||
|
||||
PrintAndLogEx(DEBUG, "systemblock : %s", sprint_hex(data + (blocks * 4), 4));
|
||||
PrintAndLogEx(DEBUG, " otp lock : %02x %02x", data[(blocks * 4)], data[(blocks * 4) + 1]);
|
||||
|
||||
|
||||
PrintAndLogEx(INFO, " block# | data |lck| ascii");
|
||||
PrintAndLogEx(INFO, "---------+--------------+---+----------");
|
||||
|
||||
for (int i = 0; i <= blocks; i++) {
|
||||
PrintAndLogEx(INFO,
|
||||
"%3d/0x%02X | %s | %s | %s",
|
||||
i,
|
||||
i,
|
||||
sprint_hex(data + (i * 4), 4),
|
||||
get_st_lock_info(chipid, data + (blocks * 4), i),
|
||||
sprint_ascii(data + (i * 4), 4)
|
||||
);
|
||||
}
|
||||
|
||||
PrintAndLogEx(INFO,
|
||||
"%3d/0x%02X | %s | %s | %s",
|
||||
0xFF,
|
||||
0xFF,
|
||||
sprint_hex(data + (0xFF * 4), 4),
|
||||
get_st_lock_info(chipid, data + (blocks * 4), 0xFF),
|
||||
sprint_ascii(data + (0xFF * 4), 4)
|
||||
);
|
||||
PrintAndLogEx(INFO, "---------+--------------+---+----------");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
print_sr_blocks(data, cardsize);
|
||||
|
||||
// save to file
|
||||
if (fnlen < 1) {
|
||||
|
@ -1440,6 +1522,8 @@ static int CmdHF14BDump(const char *Cmd) {
|
|||
|
||||
size_t datalen = (blocks + 1) * 4;
|
||||
pm3_save_dump(filename, data, datalen, jsf14b, 4);
|
||||
}
|
||||
|
||||
return switch_off_field_14b();
|
||||
}
|
||||
/*
|
||||
|
@ -2018,6 +2102,54 @@ out:
|
|||
return res;
|
||||
}
|
||||
|
||||
|
||||
static int CmdHF14BView(const char *Cmd) {
|
||||
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf 14b view",
|
||||
"Print a ISO14443-B dump file (bin/eml/json)",
|
||||
"hf 14b view -f hf-14b-01020304-dump.bin"
|
||||
);
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_str1("f", "file", "<fn>", "filename of dump"),
|
||||
arg_lit0("v", "verbose", "verbose output"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
int fnlen = 0;
|
||||
char filename[FILE_PATH_SIZE];
|
||||
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
|
||||
bool verbose = arg_get_lit(ctx, 2);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
// read dump file
|
||||
uint8_t *dump = NULL;
|
||||
size_t bytes_read = 0;
|
||||
int res = pm3_load_dump(filename, (void **)&dump, &bytes_read, (ST25TB_SR_BLOCK_SIZE * 0xFF));
|
||||
if (res != PM3_SUCCESS) {
|
||||
return res;
|
||||
}
|
||||
|
||||
uint16_t block_cnt = bytes_read / ST25TB_SR_BLOCK_SIZE;
|
||||
|
||||
if (verbose) {
|
||||
PrintAndLogEx(INFO, "File: " _YELLOW_("%s"), filename);
|
||||
PrintAndLogEx(INFO, "File size %zu bytes, file blocks %d (0x%x)", bytes_read, block_cnt, block_cnt);
|
||||
}
|
||||
|
||||
// figure out a way to identify the different dump files.
|
||||
// STD/SR/CT is difference
|
||||
|
||||
print_sr_blocks(dump, bytes_read);
|
||||
//print_std_blocks(dump, bytes_read);
|
||||
//print_ct_blocks(dump, bytes_read);
|
||||
|
||||
free(dump);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||
{"apdu", CmdHF14BAPDU, IfPm3Iso14443b, "Send ISO 14443-4 APDU to tag"},
|
||||
|
@ -2032,6 +2164,7 @@ static command_t CommandTable[] = {
|
|||
{"sniff", CmdHF14BSniff, IfPm3Iso14443b, "Eavesdrop ISO-14443-B"},
|
||||
{"rdbl", CmdHF14BSriRdBl, IfPm3Iso14443b, "Read SRI512/SRIX4x block"},
|
||||
{"sriwrite", CmdHF14BWriteSri, IfPm3Iso14443b, "Write data to a SRI512 or SRIX4K tag"},
|
||||
{"view", CmdHF14BView, AlwaysAvailable, "Display content from tag dump file"},
|
||||
// {"valid", srix4kValid, AlwaysAvailable, "srix4k checksum test"},
|
||||
{NULL, NULL, NULL, NULL}
|
||||
};
|
||||
|
|
|
@ -50,6 +50,13 @@ typedef enum ISO14B_COMMAND {
|
|||
ISO14B_SELECT_XRX = (1 << 12),
|
||||
} iso14b_command_t;
|
||||
|
||||
typedef enum ISO14B_TYPE {
|
||||
ISO14B_NONE = 0,
|
||||
ISO14B_STANDARD = 1,
|
||||
ISO14B_SR = 2,
|
||||
ISO14B_CT = 4,
|
||||
} iso14b_type_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t flags; // the ISO14B_COMMAND enum
|
||||
uint32_t timeout;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue