mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-02-26 00:55:19 +08: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
|
@ -1291,7 +1291,7 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, tag_r
|
|||
{ .response = rPPS, .response_n = sizeof(rPPS) }, // PPS response
|
||||
{ .response = rPACK, .response_n = sizeof(rPACK) } // PACK response
|
||||
};
|
||||
|
||||
|
||||
// "precompile" responses. There are 12 predefined responses with a total of 84 bytes data to transmit.
|
||||
|
||||
// Coded responses need one byte per bit to transfer (data, parity, start, stop, correction)
|
||||
|
@ -3094,13 +3094,33 @@ void ReaderIso14443a(PacketCommandNG *c) {
|
|||
}
|
||||
}
|
||||
|
||||
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred
|
||||
FpgaDisableTracing();
|
||||
reply_mix(CMD_ACK, 0, 0, 0, NULL, 0);
|
||||
if ((param & ISO14A_TOPAZMODE)) {
|
||||
|
||||
if (cmd[0] == TOPAZ_WRITE_E8 || cmd[0] == TOPAZ_WRITE_NE8) {
|
||||
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));
|
||||
}
|
||||
} else {
|
||||
arg0 = ReaderReceive(buf, par);
|
||||
FpgaDisableTracing();
|
||||
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));
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -224,6 +224,8 @@ static int topaz_write_erase8_block(uint8_t blockno, uint8_t *block_data) {
|
|||
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; // WriteErase 8bytes failed
|
||||
|
@ -243,6 +245,61 @@ static int topaz_write_erase8_block(uint8_t blockno, uint8_t *block_data) {
|
|||
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
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
static void get_TLV(uint8_t **TLV_ptr, uint8_t *TLV_type, uint16_t *TLV_length, uint8_t **TLV_value) {
|
||||
*TLV_length = 0;
|
||||
|
@ -782,6 +845,7 @@ static int CmdHFTopazDump(const char *Cmd) {
|
|||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_str0("f", "file", "<fn>", "filename of dump"),
|
||||
arg_lit0(NULL, "ns", "no save to file"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
@ -789,6 +853,8 @@ static int CmdHFTopazDump(const char *Cmd) {
|
|||
int fnlen = 0;
|
||||
char filename[FILE_PATH_SIZE] = {0};
|
||||
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
|
||||
bool nosave = arg_get_lit(ctx, 2);
|
||||
|
||||
CLIParserFree(ctx);
|
||||
|
||||
int status = readTopazUid(false, false);
|
||||
|
@ -811,9 +877,18 @@ static int CmdHFTopazDump(const char *Cmd) {
|
|||
);
|
||||
}
|
||||
|
||||
PrintAndLogEx(INFO, "-------------------------------------------------------------");
|
||||
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?
|
||||
if (fnlen < 1) {
|
||||
PrintAndLogEx(INFO, "Using UID as filename");
|
||||
|
@ -888,13 +963,13 @@ static int CmdHFTopazRdBl(const char *Cmd) {
|
|||
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf topaz rdbl",
|
||||
"Read a block",
|
||||
"hf topaz rdbl -b 7\n"
|
||||
"Read Topaz block",
|
||||
"hf topaz rdbl --blk 7\n"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_int1("b", "block", "<dec>", "Block number to write"),
|
||||
arg_int1(NULL, "blk", "<dec>", "Block number"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
@ -910,7 +985,11 @@ static int CmdHFTopazRdBl(const char *Cmd) {
|
|||
uint8_t data[8] = {0};
|
||||
int res = topaz_read_block(blockno, data);
|
||||
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();
|
||||
|
@ -922,13 +1001,13 @@ static int CmdHFTopazWrBl(const char *Cmd) {
|
|||
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf topaz wrbl",
|
||||
"Write a block",
|
||||
"hf topaz wrbl -b 7 -d 1122334455667788\n"
|
||||
"Write Topaz block with 8 hex bytes of data",
|
||||
"hf topaz wrbl --blk 7 -d 1122334455667788\n"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
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_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));
|
||||
|
||||
// send write Block
|
||||
int res = topaz_write_erase8_block(blockno, data);
|
||||
int res;
|
||||
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) {
|
||||
PrintAndLogEx(SUCCESS, "Write ( " _GREEN_("ok") " )");
|
||||
PrintAndLogEx(HINT, "try `" _YELLOW_("hf topaz rdbl --blk %u") "` to verify", blockno);
|
||||
|
||||
} else {
|
||||
PrintAndLogEx(WARNING, "Write ( " _RED_("fail") " )");
|
||||
}
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
|
||||
topaz_switch_off_field();
|
||||
return res;
|
||||
|
@ -970,18 +1058,24 @@ static int CmdHFTopazWrBl(const char *Cmd) {
|
|||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||
{"dump", CmdHFTopazDump, IfPm3Iso14443a, "Dump TOPAZ family tag to file"},
|
||||
{"list", CmdHFTopazList, AlwaysAvailable, "List Topaz history"},
|
||||
{"info", CmdHFTopazInfo, IfPm3Iso14443a, "Tag information"},
|
||||
{"reader", CmdHFTopazReader, IfPm3Iso14443a, "Act like a Topaz reader"},
|
||||
{"sim", CmdHFTopazSim, IfPm3Iso14443a, "Simulate Topaz tag"},
|
||||
{"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"},
|
||||
{"wrbl", CmdHFTopazWrBl, IfPm3Iso14443a, "Write block"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||
{"list", CmdHFTopazList, AlwaysAvailable, "List Topaz history"},
|
||||
{"-----------", CmdHelp, IfPm3Iso14443a, "------------------- " _CYAN_("operations") " ---------------------"},
|
||||
{"dump", CmdHFTopazDump, IfPm3Iso14443a, "Dump TOPAZ family tag to file"},
|
||||
{"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"},
|
||||
{"sim", CmdHFTopazSim, IfPm3Iso14443a, "Simulate Topaz tag"},
|
||||
{"sniff", CmdHFTopazSniff, IfPm3Iso14443a, "Sniff Topaz reader-tag communication"},
|
||||
{"view", CmdHFTopazView, AlwaysAvailable, "Display content from tag dump file"},
|
||||
{"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}
|
||||
};
|
||||
|
||||
static int CmdHelp(const char *Cmd) {
|
||||
|
|
Loading…
Reference in a new issue