mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-22 06:13:51 -07:00
fix tear off to work with topaz wrbl. fix topas wrbl to handle LOCK/OTP block 13,14, which needs write_nonerase command, fixed output for rdbl
This commit is contained in:
parent
c6e9f9781c
commit
c937e3b760
2 changed files with 143 additions and 29 deletions
|
@ -3094,6 +3094,9 @@ void ReaderIso14443a(PacketCommandNG *c) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((param & ISO14A_TOPAZMODE)) {
|
||||||
|
|
||||||
|
if (cmd[0] == TOPAZ_WRITE_E8 || cmd[0] == TOPAZ_WRITE_NE8) {
|
||||||
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred
|
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred
|
||||||
FpgaDisableTracing();
|
FpgaDisableTracing();
|
||||||
reply_mix(CMD_ACK, 0, 0, 0, NULL, 0);
|
reply_mix(CMD_ACK, 0, 0, 0, NULL, 0);
|
||||||
|
@ -3102,6 +3105,23 @@ void ReaderIso14443a(PacketCommandNG *c) {
|
||||||
FpgaDisableTracing();
|
FpgaDisableTracing();
|
||||||
reply_old(CMD_ACK, arg0, 0, 0, buf, sizeof(buf));
|
reply_old(CMD_ACK, arg0, 0, 0, buf, sizeof(buf));
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
arg0 = ReaderReceive(buf, par);
|
||||||
|
FpgaDisableTracing();
|
||||||
|
reply_old(CMD_ACK, arg0, 0, 0, buf, sizeof(buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred
|
||||||
|
FpgaDisableTracing();
|
||||||
|
reply_mix(CMD_ACK, 0, 0, 0, NULL, 0);
|
||||||
|
} else {
|
||||||
|
arg0 = ReaderReceive(buf, par);
|
||||||
|
FpgaDisableTracing();
|
||||||
|
reply_old(CMD_ACK, arg0, 0, 0, buf, sizeof(buf));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((param & ISO14A_REQUEST_TRIGGER))
|
if ((param & ISO14A_REQUEST_TRIGGER))
|
||||||
|
|
|
@ -224,6 +224,8 @@ static int topaz_write_erase8_block(uint8_t blockno, uint8_t *block_data) {
|
||||||
uint16_t resp_len = 11;
|
uint16_t resp_len = 11;
|
||||||
uint8_t response[11] = {0};
|
uint8_t response[11] = {0};
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
if (topaz_send_cmd(wr8_cmd, sizeof(wr8_cmd), response, &resp_len, true) == PM3_ETIMEOUT) {
|
if (topaz_send_cmd(wr8_cmd, sizeof(wr8_cmd), response, &resp_len, true) == PM3_ETIMEOUT) {
|
||||||
topaz_switch_off_field();
|
topaz_switch_off_field();
|
||||||
return PM3_ESOFT; // WriteErase 8bytes failed
|
return PM3_ESOFT; // WriteErase 8bytes failed
|
||||||
|
@ -243,6 +245,61 @@ static int topaz_write_erase8_block(uint8_t blockno, uint8_t *block_data) {
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// write a block (8 Bytes) of a selected Topaz tag.
|
||||||
|
static int topaz_write_nonerase8_block(uint8_t blockno, uint8_t *block_data) {
|
||||||
|
|
||||||
|
uint8_t atqa[2] = {0};
|
||||||
|
uint8_t rid_response[8] = {0};
|
||||||
|
int res = topaz_select(atqa, sizeof(atqa), rid_response, sizeof(rid_response), true);
|
||||||
|
if (res != PM3_SUCCESS) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (atqa[1] != 0x0c && atqa[0] != 0x00) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *uid_echo = &rid_response[2];
|
||||||
|
uint8_t rall_response[124] = {0};
|
||||||
|
|
||||||
|
res = topaz_rall(uid_echo, rall_response);
|
||||||
|
if (res == PM3_ESOFT) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ADD
|
||||||
|
// 7 6 5 4 3 2 1 0
|
||||||
|
// b b b --- Byte 0 - 7
|
||||||
|
// B B B B --------- BLOCK
|
||||||
|
// r ----------------- 0
|
||||||
|
//
|
||||||
|
|
||||||
|
uint8_t wr8_cmd[] = {TOPAZ_WRITE_NE8, blockno, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||||
|
memcpy(wr8_cmd + 10, uid_echo, 4);
|
||||||
|
memcpy(wr8_cmd + 2, block_data, 8);
|
||||||
|
|
||||||
|
uint16_t resp_len = 11;
|
||||||
|
uint8_t response[11] = {0};
|
||||||
|
|
||||||
|
//
|
||||||
|
if (topaz_send_cmd(wr8_cmd, sizeof(wr8_cmd), response, &resp_len, true) == PM3_ETIMEOUT) {
|
||||||
|
topaz_switch_off_field();
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resp_len != 11) {
|
||||||
|
return PM3_EFAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockno != response[0]) {
|
||||||
|
return PM3_EFAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp(block_data, response + 1, 8) == 0) {
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
// search for the lock area descriptor for the lockable area including byteno
|
// search for the lock area descriptor for the lockable area including byteno
|
||||||
static dynamic_lock_area_t *get_dynamic_lock_area(uint16_t byteno) {
|
static dynamic_lock_area_t *get_dynamic_lock_area(uint16_t byteno) {
|
||||||
|
@ -402,6 +459,12 @@ static int topaz_print_CC(uint8_t *data) {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void topaz_print_hdr(uint8_t blockno) {
|
||||||
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
PrintAndLogEx(INFO, " # | block " _GREEN_("0x%02X") " | ascii", blockno);
|
||||||
|
PrintAndLogEx(INFO, "----+-------------------------+---------");
|
||||||
|
}
|
||||||
|
|
||||||
// return type, length and value of a TLV, starting at memory position *TLV_ptr
|
// return type, length and value of a TLV, starting at memory position *TLV_ptr
|
||||||
static void get_TLV(uint8_t **TLV_ptr, uint8_t *TLV_type, uint16_t *TLV_length, uint8_t **TLV_value) {
|
static void get_TLV(uint8_t **TLV_ptr, uint8_t *TLV_type, uint16_t *TLV_length, uint8_t **TLV_value) {
|
||||||
*TLV_length = 0;
|
*TLV_length = 0;
|
||||||
|
@ -782,6 +845,7 @@ static int CmdHFTopazDump(const char *Cmd) {
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_str0("f", "file", "<fn>", "filename of dump"),
|
arg_str0("f", "file", "<fn>", "filename of dump"),
|
||||||
|
arg_lit0(NULL, "ns", "no save to file"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
@ -789,6 +853,8 @@ static int CmdHFTopazDump(const char *Cmd) {
|
||||||
int fnlen = 0;
|
int fnlen = 0;
|
||||||
char filename[FILE_PATH_SIZE] = {0};
|
char filename[FILE_PATH_SIZE] = {0};
|
||||||
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
|
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
|
||||||
|
bool nosave = arg_get_lit(ctx, 2);
|
||||||
|
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
int status = readTopazUid(false, false);
|
int status = readTopazUid(false, false);
|
||||||
|
@ -811,9 +877,18 @@ static int CmdHFTopazDump(const char *Cmd) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "-------------------------------------------------------------");
|
|
||||||
topaz_switch_off_field();
|
topaz_switch_off_field();
|
||||||
|
|
||||||
|
// Skip saving card data to file
|
||||||
|
if (nosave) {
|
||||||
|
PrintAndLogEx(INFO, "Called with no save option");
|
||||||
|
if (set_dynamic) {
|
||||||
|
free(topaz_tag.dynamic_memory);
|
||||||
|
}
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// user supplied filename?
|
// user supplied filename?
|
||||||
if (fnlen < 1) {
|
if (fnlen < 1) {
|
||||||
PrintAndLogEx(INFO, "Using UID as filename");
|
PrintAndLogEx(INFO, "Using UID as filename");
|
||||||
|
@ -888,13 +963,13 @@ static int CmdHFTopazRdBl(const char *Cmd) {
|
||||||
|
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "hf topaz rdbl",
|
CLIParserInit(&ctx, "hf topaz rdbl",
|
||||||
"Read a block",
|
"Read Topaz block",
|
||||||
"hf topaz rdbl -b 7\n"
|
"hf topaz rdbl --blk 7\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_int1("b", "block", "<dec>", "Block number to write"),
|
arg_int1(NULL, "blk", "<dec>", "Block number"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
@ -910,7 +985,11 @@ static int CmdHFTopazRdBl(const char *Cmd) {
|
||||||
uint8_t data[8] = {0};
|
uint8_t data[8] = {0};
|
||||||
int res = topaz_read_block(blockno, data);
|
int res = topaz_read_block(blockno, data);
|
||||||
if (res == PM3_SUCCESS) {
|
if (res == PM3_SUCCESS) {
|
||||||
PrintAndLogEx(SUCCESS, "Block: %0d (0x%02X) [ %s]", blockno, blockno, sprint_hex(data, sizeof(data)));
|
|
||||||
|
topaz_print_hdr(blockno);
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, " %2d | %s", blockno, sprint_hex_ascii(data, sizeof(data)));
|
||||||
|
PrintAndLogEx(NORMAL, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
topaz_switch_off_field();
|
topaz_switch_off_field();
|
||||||
|
@ -922,13 +1001,13 @@ static int CmdHFTopazWrBl(const char *Cmd) {
|
||||||
|
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "hf topaz wrbl",
|
CLIParserInit(&ctx, "hf topaz wrbl",
|
||||||
"Write a block",
|
"Write Topaz block with 8 hex bytes of data",
|
||||||
"hf topaz wrbl -b 7 -d 1122334455667788\n"
|
"hf topaz wrbl --blk 7 -d 1122334455667788\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_int1("b", "block", "<dec>", "Block number to write"),
|
arg_int1(NULL, "blk", "<dec>", "Block number"),
|
||||||
arg_str1("d", "data", "<hex>", "Block data (8 hex bytes)"),
|
arg_str1("d", "data", "<hex>", "Block data (8 hex bytes)"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
|
@ -954,14 +1033,23 @@ static int CmdHFTopazWrBl(const char *Cmd) {
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "Block: %0d (0x%02X) [ %s]", blockno, blockno, sprint_hex(data, dlen));
|
PrintAndLogEx(INFO, "Block: %0d (0x%02X) [ %s]", blockno, blockno, sprint_hex(data, dlen));
|
||||||
|
|
||||||
// send write Block
|
int res;
|
||||||
int res = topaz_write_erase8_block(blockno, data);
|
if (blockno != 13 && blockno != 14) {
|
||||||
|
// send write/erase block
|
||||||
|
res = topaz_write_erase8_block(blockno, data);
|
||||||
|
} else {
|
||||||
|
// send write/non erase block
|
||||||
|
res = topaz_write_nonerase8_block(blockno, data);
|
||||||
|
}
|
||||||
|
|
||||||
if (res == PM3_SUCCESS) {
|
if (res == PM3_SUCCESS) {
|
||||||
PrintAndLogEx(SUCCESS, "Write ( " _GREEN_("ok") " )");
|
PrintAndLogEx(SUCCESS, "Write ( " _GREEN_("ok") " )");
|
||||||
|
PrintAndLogEx(HINT, "try `" _YELLOW_("hf topaz rdbl --blk %u") "` to verify", blockno);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(WARNING, "Write ( " _RED_("fail") " )");
|
PrintAndLogEx(WARNING, "Write ( " _RED_("fail") " )");
|
||||||
}
|
}
|
||||||
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
|
||||||
topaz_switch_off_field();
|
topaz_switch_off_field();
|
||||||
return res;
|
return res;
|
||||||
|
@ -971,16 +1059,22 @@ static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
static command_t CommandTable[] = {
|
static command_t CommandTable[] = {
|
||||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||||
{"dump", CmdHFTopazDump, IfPm3Iso14443a, "Dump TOPAZ family tag to file"},
|
|
||||||
{"list", CmdHFTopazList, AlwaysAvailable, "List Topaz history"},
|
{"list", CmdHFTopazList, AlwaysAvailable, "List Topaz history"},
|
||||||
|
{"-----------", CmdHelp, IfPm3Iso14443a, "------------------- " _CYAN_("operations") " ---------------------"},
|
||||||
|
{"dump", CmdHFTopazDump, IfPm3Iso14443a, "Dump TOPAZ family tag to file"},
|
||||||
{"info", CmdHFTopazInfo, IfPm3Iso14443a, "Tag information"},
|
{"info", CmdHFTopazInfo, IfPm3Iso14443a, "Tag information"},
|
||||||
|
{"raw", CmdHFTopazRaw, IfPm3Iso14443a, "Send raw hex data to tag"},
|
||||||
|
{"rdbl", CmdHFTopazRdBl, IfPm3Iso14443a, "Read block"},
|
||||||
{"reader", CmdHFTopazReader, IfPm3Iso14443a, "Act like a Topaz reader"},
|
{"reader", CmdHFTopazReader, IfPm3Iso14443a, "Act like a Topaz reader"},
|
||||||
{"sim", CmdHFTopazSim, IfPm3Iso14443a, "Simulate Topaz tag"},
|
{"sim", CmdHFTopazSim, IfPm3Iso14443a, "Simulate Topaz tag"},
|
||||||
{"sniff", CmdHFTopazSniff, IfPm3Iso14443a, "Sniff Topaz reader-tag communication"},
|
{"sniff", CmdHFTopazSniff, IfPm3Iso14443a, "Sniff Topaz reader-tag communication"},
|
||||||
{"raw", CmdHFTopazRaw, IfPm3Iso14443a, "Send raw hex data to tag"},
|
|
||||||
{"rdbl", CmdHFTopazRdBl, IfPm3Iso14443a, "Read block"},
|
|
||||||
{"view", CmdHFTopazView, AlwaysAvailable, "Display content from tag dump file"},
|
{"view", CmdHFTopazView, AlwaysAvailable, "Display content from tag dump file"},
|
||||||
{"wrbl", CmdHFTopazWrBl, IfPm3Iso14443a, "Write block"},
|
{"wrbl", CmdHFTopazWrBl, IfPm3Iso14443a, "Write block"},
|
||||||
|
{"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("ndef") " -----------------------"},
|
||||||
|
// {"ndefformat", CmdHFTopazNDEFFormat, IfPm3Iso14443a, "Format Topaz Tag as NFC Tag"},
|
||||||
|
// {"ndefread", CmdHFTopazNDEFRead, IfPm3Iso14443a, "Read and print NDEF records from card"},
|
||||||
|
// {"ndefwrite", CmdHFTopazNDEFWrite, IfPm3Iso14443a, "Write NDEF records to card"},
|
||||||
|
|
||||||
{NULL, NULL, 0, NULL}
|
{NULL, NULL, 0, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue