mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 05:43:48 -07:00
commit
1614d920b2
13 changed files with 143 additions and 140 deletions
|
@ -73,8 +73,8 @@ extern uint32_t _stack_start, _stack_end;
|
|||
struct common_area common_area __attribute__((section(".commonarea")));
|
||||
static int button_status = BUTTON_NO_CLICK;
|
||||
static bool allow_send_wtx = false;
|
||||
static uint16_t tearoff_delay_us = 0;
|
||||
static bool tearoff_enabled = false;
|
||||
uint16_t tearoff_delay_us = 0;
|
||||
bool tearoff_enabled = false;
|
||||
|
||||
int tearoff_hook(void) {
|
||||
if (tearoff_enabled) {
|
||||
|
|
|
@ -1881,7 +1881,7 @@ void iClass_WriteBlock(uint8_t *msg) {
|
|||
|
||||
iclass_send_as_reader(write, write_len, &start_time, &eof_time);
|
||||
|
||||
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured
|
||||
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred
|
||||
res = false;
|
||||
switch_off();
|
||||
if (payload->req.send_reply)
|
||||
|
|
|
@ -2972,7 +2972,7 @@ void ReaderIso14443a(PacketCommandNG *c) {
|
|||
}
|
||||
}
|
||||
|
||||
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured
|
||||
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred
|
||||
FpgaDisableTracing();
|
||||
reply_mix(CMD_ACK, 0, 0, 0, NULL, 0);
|
||||
} else {
|
||||
|
|
|
@ -2092,7 +2092,7 @@ void SendRawCommand14443B_Ex(PacketCommandNG *c) {
|
|||
uint32_t eof_time = 0;
|
||||
CodeAndTransmit14443bAsReader(cmd, len, &start_time, &eof_time);
|
||||
|
||||
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured
|
||||
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred
|
||||
FpgaDisableTracing();
|
||||
reply_mix(CMD_HF_ISO14443B_COMMAND, -2, 0, 0, NULL, 0);
|
||||
} else {
|
||||
|
|
|
@ -1477,7 +1477,7 @@ int SendDataTag(uint8_t *send, int sendlen, bool init, bool speed_fast, uint8_t
|
|||
tosend_t *ts = get_tosend();
|
||||
TransmitTo15693Tag(ts->buf, ts->max, &start_time);
|
||||
|
||||
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured
|
||||
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred
|
||||
|
||||
res = PM3_ETEAROFF;
|
||||
|
||||
|
@ -1598,7 +1598,7 @@ void ReaderIso15693(uint32_t parameter) {
|
|||
uint32_t eof_time;
|
||||
int recvlen = SendDataTag(cmd, sizeof(cmd), true, true, answer, ISO15693_MAX_RESPONSE_LENGTH, start_time, ISO15693_READER_TIMEOUT, &eof_time);
|
||||
|
||||
if (recvlen == PM3_ETEAROFF) { // tearoff occured
|
||||
if (recvlen == PM3_ETEAROFF) { // tearoff occurred
|
||||
reply_mix(CMD_ACK, recvlen, 0, 0, NULL, 0);
|
||||
} else {
|
||||
|
||||
|
@ -1928,7 +1928,7 @@ void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint
|
|||
uint32_t start_time = 0;
|
||||
int recvlen = SendDataTag(data, datalen, true, speed, (recv ? recvbuf : NULL), sizeof(recvbuf), start_time, timeout, &eof_time);
|
||||
|
||||
if (recvlen == PM3_ETEAROFF) { // tearoff occured
|
||||
if (recvlen == PM3_ETEAROFF) { // tearoff occurred
|
||||
reply_mix(CMD_ACK, recvlen, 0, 0, NULL, 0);
|
||||
} else {
|
||||
|
||||
|
|
|
@ -2639,7 +2639,7 @@ void EM4xWriteWord(uint8_t addr, uint32_t data, uint32_t pwd, uint8_t usepwd) {
|
|||
|
||||
SendForward(len, false);
|
||||
|
||||
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured
|
||||
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred
|
||||
StopTicks();
|
||||
reply_ng(CMD_LF_EM4X_WRITEWORD, PM3_ETEAROFF, NULL, 0);
|
||||
} else {
|
||||
|
@ -2681,7 +2681,7 @@ void EM4xProtectWord(uint32_t data, uint32_t pwd, uint8_t usepwd) {
|
|||
|
||||
SendForward(len, false);
|
||||
|
||||
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured
|
||||
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred
|
||||
StopTicks();
|
||||
reply_ng(CMD_LF_EM4X_PROTECTWORD, PM3_ETEAROFF, NULL, 0);
|
||||
} else {
|
||||
|
|
|
@ -2713,20 +2713,15 @@ void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain) {
|
|||
//
|
||||
// Tear-off attack against MFU.
|
||||
// - Moebius et al
|
||||
void MifareU_Otp_Tearoff(uint8_t blno, uint32_t tearoff_time, uint8_t *datain) {
|
||||
void MifareU_Otp_Tearoff(uint8_t blno, uint32_t tearoff_time, uint8_t *data_testwrite) {
|
||||
uint8_t blockNo = blno;
|
||||
uint8_t data_fullwrite[4] = {0x00};
|
||||
uint8_t data_testwrite[4] = {0x00};
|
||||
memcpy(data_fullwrite, datain, 4);
|
||||
memcpy(data_testwrite, datain + 4, 4);
|
||||
|
||||
if (DBGLEVEL >= DBG_DEBUG) DbpString("Preparing OTP tear-off");
|
||||
|
||||
if (tearoff_time > 43000)
|
||||
tearoff_time = 43000;
|
||||
|
||||
MifareUWriteBlockEx(blockNo, 0, data_fullwrite, false);
|
||||
|
||||
tearoff_delay_us = tearoff_time;
|
||||
tearoff_enabled = true;
|
||||
|
||||
LEDsoff();
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
|
@ -2750,15 +2745,9 @@ void MifareU_Otp_Tearoff(uint8_t blno, uint32_t tearoff_time, uint8_t *datain) {
|
|||
return;
|
||||
};
|
||||
// send
|
||||
ReaderTransmit(cmd, sizeof(cmd), NULL);
|
||||
|
||||
// Wait before cutting power. aka tear-off
|
||||
LED_D_ON();
|
||||
|
||||
SpinDelayUsPrecision(tearoff_time);
|
||||
if (DBGLEVEL >= DBG_DEBUG) Dbprintf(_YELLOW_("OTP tear-off triggered!"));
|
||||
switch_off();
|
||||
|
||||
ReaderTransmit(cmd, sizeof(cmd), NULL);
|
||||
tearoff_hook();
|
||||
reply_ng(CMD_HF_MFU_OTP_TEAROFF, PM3_SUCCESS, NULL, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -103,14 +103,6 @@ static inline uint32_t leadingzeros(uint64_t a) {
|
|||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
static inline uint32_t countones(uint64_t a) {
|
||||
#if defined __GNUC__
|
||||
return __builtin_popcountll(a);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
const char *card_types[] = {
|
||||
|
@ -2034,7 +2026,7 @@ static int CmdHFiClass_ReadBlock(const char *Cmd) {
|
|||
|
||||
uint64_t a = bytes_to_num(data, 8);
|
||||
bool starts = (leadingzeros(a) < 12);
|
||||
bool ones = (countones(a) > 16 && countones(a) < 48);
|
||||
bool ones = (bitcount64(a) > 16 && bitcount64(a) < 48);
|
||||
|
||||
if (starts && ones) {
|
||||
PrintAndLogEx(INFO, "data looks encrypted, False Positives " _YELLOW_("ARE") " possible");
|
||||
|
|
|
@ -3102,7 +3102,7 @@ static int CmdHF14AMfuOtpTearoff(const char *Cmd) {
|
|||
"hf mfu otptear -b 3 -i 100 -s 1000\n"
|
||||
"hf mfu otptear -b 3 -i 1 -e 200\n"
|
||||
"hf mfu otptear -b 3 -i 100 -s 200 -e 2500 -d FFFFFFFF -t EEEEEEEE\n"
|
||||
"hf mfu otptear -b 3 -i 100 -s 200 -e 2500 -d FFFFFFFF -t EEEEEEEE -m 00000000 -> quite when OTP is reset"
|
||||
"hf mfu otptear -b 3 -i 100 -s 200 -e 2500 -d FFFFFFFF -t EEEEEEEE -m 00000000 -> quit when OTP is reset"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
|
@ -3112,7 +3112,7 @@ static int CmdHF14AMfuOtpTearoff(const char *Cmd) {
|
|||
arg_u64_0("e", "end", "<dec>", "end time (def 3000 us)"),
|
||||
arg_u64_0("s", "start", "<dec>", "start time (def 0 us)"),
|
||||
arg_str0("d", "data", "<hex>", "initialise data before run (4 bytes)"),
|
||||
arg_str0("t", "test", "<hex>", "test write data (4 bytes)"),
|
||||
arg_str0("t", "test", "<hex>", "test write data (4 bytes, 00000000 by default)"),
|
||||
arg_str0("m", "match", "<hex>", "exit criteria, if block matches this value (4 bytes)"),
|
||||
arg_param_end
|
||||
};
|
||||
|
@ -3126,6 +3126,7 @@ static int CmdHF14AMfuOtpTearoff(const char *Cmd) {
|
|||
int d_len = 0;
|
||||
uint8_t data[4] = {0x00};
|
||||
CLIGetHexWithReturn(ctx, 5, data, &d_len);
|
||||
bool use_data = (d_len > 0);
|
||||
|
||||
int t_len = 0;
|
||||
uint8_t test[4] = {0x00};
|
||||
|
@ -3150,7 +3151,7 @@ static int CmdHF14AMfuOtpTearoff(const char *Cmd) {
|
|||
return PM3_EINVARG;
|
||||
}
|
||||
if (start > (end - steps)) {
|
||||
PrintAndLogEx(WARNING, "Start time larger then (end time + steps)");
|
||||
PrintAndLogEx(WARNING, "Start time larger than (end time + steps)");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
|
@ -3169,26 +3170,34 @@ static int CmdHF14AMfuOtpTearoff(const char *Cmd) {
|
|||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
uint8_t teardata[8] = {0x00};
|
||||
memcpy(teardata, data, sizeof(data));
|
||||
memcpy(teardata + sizeof(data), test, sizeof(test));
|
||||
uint8_t teardata[4] = {0x00};
|
||||
memcpy(teardata, test, sizeof(test));
|
||||
|
||||
PrintAndLogEx(INFO, "----------------- " _CYAN_("MFU Tear off") " ---------------------");
|
||||
PrintAndLogEx(INFO, "Starting Tear-off test");
|
||||
PrintAndLogEx(INFO, "Target block no: %u", blockno);
|
||||
PrintAndLogEx(INFO, "Target inital block data : %s", sprint_hex_inrow(teardata, 4));
|
||||
PrintAndLogEx(INFO, "Target write block data : %s", sprint_hex_inrow(teardata + 4, 4));
|
||||
if (use_data) {
|
||||
PrintAndLogEx(INFO, "Target inital block data : %s", sprint_hex_inrow(data, 4));
|
||||
}
|
||||
PrintAndLogEx(INFO, "Target write block data : %s", sprint_hex_inrow(teardata, 4));
|
||||
if (use_match) {
|
||||
PrintAndLogEx(INFO, "Target match block data : %s", sprint_hex_inrow(match, 4));
|
||||
}
|
||||
PrintAndLogEx(INFO, "----------------------------------------------------");
|
||||
uint8_t isOK;
|
||||
bool got_pre = false, got_post = false, lock_on = false;
|
||||
bool lock_on = false;
|
||||
uint8_t pre[4] = {0};
|
||||
uint8_t post[4] = {0};
|
||||
uint32_t current = start;
|
||||
int phase_clear = -1;
|
||||
int phase_newwr = -1;
|
||||
int phase_begin_clear = -1;
|
||||
int phase_end_clear = -1;
|
||||
int phase_begin_newwr = -1;
|
||||
int phase_end_newwr = -1;
|
||||
bool skip_phase1 = false;
|
||||
uint8_t retries = 0;
|
||||
uint8_t error_retries = 0;
|
||||
|
||||
while (current <= (end - steps)) {
|
||||
while ((current <= (end - steps)) && (error_retries < 10)) {
|
||||
|
||||
if (kbd_enter_pressed()) {
|
||||
PrintAndLogEx(INFO, "\naborted via keyboard!\n");
|
||||
|
@ -3198,10 +3207,27 @@ static int CmdHF14AMfuOtpTearoff(const char *Cmd) {
|
|||
PrintAndLogEx(INFO, "Using tear-off delay " _GREEN_("%" PRIu32) " us", current);
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandMIX(CMD_HF_MIFAREU_READBL, blockno, 0, 0, NULL, 0);
|
||||
PacketResponseNG resp;
|
||||
|
||||
got_pre = false;
|
||||
if (use_data) {
|
||||
SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, blockno, 0, 0, data, d_len);
|
||||
bool got_written = false;
|
||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||
isOK = resp.oldarg[0] & 0xff;
|
||||
if (isOK) {
|
||||
got_written = true;
|
||||
}
|
||||
}
|
||||
if (! got_written) {
|
||||
PrintAndLogEx(FAILED, "Failed to write block BEFORE");
|
||||
error_retries++;
|
||||
continue; // try again
|
||||
}
|
||||
}
|
||||
|
||||
SendCommandMIX(CMD_HF_MIFAREU_READBL, blockno, 0, 0, NULL, 0);
|
||||
|
||||
bool got_pre = false;
|
||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||
isOK = resp.oldarg[0] & 0xFF;
|
||||
if (isOK) {
|
||||
|
@ -3209,9 +3235,13 @@ static int CmdHF14AMfuOtpTearoff(const char *Cmd) {
|
|||
got_pre = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (! got_pre) {
|
||||
PrintAndLogEx(FAILED, "Failed to read block BEFORE");
|
||||
error_retries++;
|
||||
continue; // try again
|
||||
}
|
||||
clearCommandBuffer();
|
||||
SendCommandMIX(CMD_HF_MFU_OTP_TEAROFF, blockno, current, 0, teardata, 8);
|
||||
SendCommandMIX(CMD_HF_MFU_OTP_TEAROFF, blockno, current, 0, teardata, sizeof(teardata));
|
||||
|
||||
// we be getting ACK that we are silently ignoring here..
|
||||
|
||||
|
@ -3222,10 +3252,11 @@ static int CmdHF14AMfuOtpTearoff(const char *Cmd) {
|
|||
|
||||
if (resp.status != PM3_SUCCESS) {
|
||||
PrintAndLogEx(WARNING, "Tear off reporting failure to select tag");
|
||||
error_retries++;
|
||||
continue;
|
||||
}
|
||||
|
||||
got_post = false;
|
||||
bool got_post = false;
|
||||
clearCommandBuffer();
|
||||
SendCommandMIX(CMD_HF_MIFAREU_READBL, blockno, 0, 0, NULL, 0);
|
||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||
|
@ -3235,55 +3266,53 @@ static int CmdHF14AMfuOtpTearoff(const char *Cmd) {
|
|||
got_post = true;
|
||||
}
|
||||
}
|
||||
if (! got_post) {
|
||||
PrintAndLogEx(FAILED, "Failed to read block BEFORE");
|
||||
error_retries++;
|
||||
continue; // try again
|
||||
}
|
||||
error_retries = 0;
|
||||
char prestr[20] = {0};
|
||||
snprintf(prestr, sizeof(prestr), "%s", sprint_hex_inrow(pre, sizeof(pre)));
|
||||
char poststr[20] = {0};
|
||||
snprintf(poststr, sizeof(poststr), "%s", sprint_hex_inrow(post, sizeof(post)));
|
||||
|
||||
if (got_pre && got_post) {
|
||||
|
||||
char prestr[20] = {0};
|
||||
snprintf(prestr, sizeof(prestr), "%s", sprint_hex_inrow(pre, sizeof(pre)));
|
||||
char poststr[20] = {0};
|
||||
snprintf(poststr, sizeof(poststr), "%s", sprint_hex_inrow(post, sizeof(post)));
|
||||
|
||||
if (memcmp(pre, post, sizeof(pre)) == 0) {
|
||||
|
||||
PrintAndLogEx(INFO, "Current %02d (0x%02X) %s"
|
||||
, blockno
|
||||
, blockno
|
||||
, poststr
|
||||
);
|
||||
} else {
|
||||
|
||||
// skip first message, since its the reset write.
|
||||
if (current == start) {
|
||||
PrintAndLogEx(INFO, "Inital write");
|
||||
} else {
|
||||
PrintAndLogEx(INFO, _CYAN_("Tear off occured") " : %02d (0x%02X) %s vs " _RED_("%s")
|
||||
, blockno
|
||||
, blockno
|
||||
, prestr
|
||||
, poststr
|
||||
);
|
||||
|
||||
lock_on = true;
|
||||
|
||||
if (phase_clear == -1)
|
||||
phase_clear = current;
|
||||
|
||||
// new write phase must be atleast 100us later..
|
||||
if (phase_clear > -1 && phase_newwr == -1 && current > (phase_clear + 100))
|
||||
phase_newwr = current;
|
||||
}
|
||||
}
|
||||
|
||||
if (use_match && memcmp(pre, match, sizeof(pre)) == 0) {
|
||||
PrintAndLogEx(SUCCESS, "Block matches!\n");
|
||||
break;
|
||||
}
|
||||
if (memcmp(pre, post, sizeof(pre)) == 0) {
|
||||
|
||||
PrintAndLogEx(INFO, "Current : %02d (0x%02X) %s"
|
||||
, blockno
|
||||
, blockno
|
||||
, poststr
|
||||
);
|
||||
} else {
|
||||
if (got_pre == false)
|
||||
PrintAndLogEx(FAILED, "Failed to read block BEFORE");
|
||||
if (got_post == false)
|
||||
PrintAndLogEx(FAILED, "Failed to read block AFTER");
|
||||
PrintAndLogEx(INFO, _CYAN_("Tear off occurred") " : %02d (0x%02X) %s => " _RED_("%s")
|
||||
, blockno
|
||||
, blockno
|
||||
, prestr
|
||||
, poststr
|
||||
);
|
||||
|
||||
lock_on = true;
|
||||
|
||||
if ((phase_begin_clear == -1) && (bitcount32(*(uint32_t*)pre) > bitcount32(*(uint32_t*)post)))
|
||||
phase_begin_clear = current;
|
||||
|
||||
if ((phase_begin_clear > -1) && (phase_end_clear == -1) && (bitcount32(*(uint32_t*)post) == 0))
|
||||
phase_end_clear = current;
|
||||
|
||||
if ((current == start) && (phase_end_clear > -1))
|
||||
skip_phase1 = true;
|
||||
// new write phase must be atleast 100us later..
|
||||
if (((bitcount32(*(uint32_t*)pre) == 0) || (phase_end_clear > -1)) && (phase_begin_newwr == -1) && (bitcount32(*(uint32_t*)post) != 0) && (skip_phase1 || (current > (phase_end_clear + 100))))
|
||||
phase_begin_newwr = current;
|
||||
|
||||
if ((phase_begin_newwr > -1) && (phase_end_newwr == -1) && (memcmp(post, teardata, sizeof(teardata)) == 0))
|
||||
phase_end_newwr = current;
|
||||
}
|
||||
|
||||
if (use_match && memcmp(post, match, sizeof(post)) == 0) {
|
||||
PrintAndLogEx(SUCCESS, "Block matches stop condition!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/* TEMPORALLY DISABLED
|
||||
|
@ -3314,11 +3343,17 @@ static int CmdHF14AMfuOtpTearoff(const char *Cmd) {
|
|||
}
|
||||
|
||||
PrintAndLogEx(INFO, "----------------------------------------------------");
|
||||
if (phase_clear > - 1) {
|
||||
PrintAndLogEx(INFO, "New phase boundary around " _YELLOW_("%d") " us", phase_clear);
|
||||
if ((phase_begin_clear > - 1) && (phase_begin_clear != start)) {
|
||||
PrintAndLogEx(INFO, "Erase phase start boundary around " _YELLOW_("%5d") " us", phase_begin_clear);
|
||||
}
|
||||
if (phase_newwr > - 1) {
|
||||
PrintAndLogEx(INFO, "New phase boundary around " _YELLOW_("%d") " us", phase_newwr);
|
||||
if ((phase_end_clear > - 1) && (phase_end_clear != start)){
|
||||
PrintAndLogEx(INFO, "Erase phase end boundary around " _YELLOW_("%5d") " us", phase_end_clear);
|
||||
}
|
||||
if (phase_begin_newwr > - 1) {
|
||||
PrintAndLogEx(INFO, "Write phase start boundary around " _YELLOW_("%5d") " us", phase_begin_newwr);
|
||||
}
|
||||
if (phase_end_newwr > - 1) {
|
||||
PrintAndLogEx(INFO, "Write phase end boundary around " _YELLOW_("%5d") " us", phase_end_newwr);
|
||||
}
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
return PM3_SUCCESS;
|
||||
|
|
|
@ -118,16 +118,6 @@ static void verify_values(uint64_t *animalid, uint32_t *countryid, uint32_t *ext
|
|||
}
|
||||
}
|
||||
|
||||
static inline uint32_t bitcount(uint32_t a) {
|
||||
#if defined __GNUC__
|
||||
return __builtin_popcountl(a);
|
||||
#else
|
||||
a = a - ((a >> 1) & 0x55555555);
|
||||
a = (a & 0x33333333) + ((a >> 2) & 0x33333333);
|
||||
return (((a + (a >> 4)) & 0x0f0f0f0f) * 0x01010101) >> 24;
|
||||
#endif
|
||||
}
|
||||
|
||||
// FDX-B ISO11784/85 demod (aka animal tag) BIPHASE, inverted, rf/32, with preamble of 00000000001 (128bits)
|
||||
// 8 databits + 1 parity (1)
|
||||
// CIITT 16 chksum
|
||||
|
@ -594,7 +584,7 @@ int demodFDXB(bool verbose) {
|
|||
|
||||
uint8_t bt_par = (extended & 0x100) >> 8;
|
||||
uint8_t bt_temperature = extended & 0xff;
|
||||
uint8_t bt_calc_parity = (bitcount(bt_temperature) & 0x1) ? 0 : 1;
|
||||
uint8_t bt_calc_parity = (bitcount32(bt_temperature) & 0x1) ? 0 : 1;
|
||||
uint8_t is_bt_temperature = (bt_calc_parity == bt_par) && !(extended & 0xe00) ;
|
||||
|
||||
if (is_bt_temperature) {
|
||||
|
|
|
@ -37,20 +37,10 @@ const uint8_t translateTable[10] = {8, 2, 1, 12, 4, 5, 10, 13, 0, 9};
|
|||
const uint8_t invTranslateTable[16] = {8, 2, 1, 0xff, 4, 5, 0xff, 0xff, 0, 9, 6, 0xff, 3, 7, 0xff, 0xff};
|
||||
const uint8_t preamble[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}; // zero inside
|
||||
|
||||
static inline uint32_t bitcount(uint32_t a) {
|
||||
#if defined __GNUC__
|
||||
return __builtin_popcountl(a);
|
||||
#else
|
||||
a = a - ((a >> 1) & 0x55555555);
|
||||
a = (a & 0x33333333) + ((a >> 2) & 0x33333333);
|
||||
return (((a + (a >> 4)) & 0x0f0f0f0f) * 0x01010101) >> 24;
|
||||
#endif
|
||||
}
|
||||
|
||||
static uint8_t isEven_64_63(const uint8_t *data) { // 8
|
||||
uint32_t tmp[2];
|
||||
memcpy(tmp, data, 8);
|
||||
return (bitcount(tmp[0]) + (bitcount(tmp[1] & 0xfeffffff))) & 1;
|
||||
return (bitcount32(tmp[0]) + (bitcount32(tmp[1] & 0xfeffffff))) & 1;
|
||||
}
|
||||
|
||||
//NEDAP demod - ASK/Biphase (or Diphase), RF/64 with preamble of 1111111110 (always a 128 bit data stream)
|
||||
|
|
|
@ -447,7 +447,7 @@ static int CmdT55xxSetConfig(const char *Cmd) {
|
|||
arg_lit0(NULL, "st", "set/reset Sequence Terminator on"),
|
||||
arg_int0(NULL, "rate", "<dec>", "set bitrate <8|16|32|40|50|64|100|128>"),
|
||||
arg_str0("c", "blk0", "<hex>", "set configuration from a block0 (4 hex bytes)"),
|
||||
arg_int0("o", "offset", "<dec>", "set offset, where data should start decode in bitstream"),
|
||||
arg_int0("o", "offset", "<0-255>", "set offset, where data should start decode in bitstream "),
|
||||
};
|
||||
|
||||
uint8_t idx = 19;
|
||||
|
@ -467,7 +467,8 @@ static int CmdT55xxSetConfig(const char *Cmd) {
|
|||
bool use_q5 = arg_get_lit(ctx, idx++);
|
||||
bool use_st = arg_get_lit(ctx, idx++);
|
||||
|
||||
int bitrate = arg_get_int_def(ctx, idx++, -1);
|
||||
int bitrate = arg_get_int_def(ctx, idx, -1);
|
||||
idx++;
|
||||
|
||||
bool gotconf = false;
|
||||
uint32_t block0 = 0;
|
||||
|
@ -481,7 +482,8 @@ static int CmdT55xxSetConfig(const char *Cmd) {
|
|||
gotconf = true;
|
||||
}
|
||||
|
||||
int offset = arg_get_int_def(ctx, idx++, -1);
|
||||
int offset = arg_get_int_def(ctx, idx, -1);
|
||||
idx++;
|
||||
|
||||
bool r0 = arg_get_lit(ctx, idx++);
|
||||
bool r1 = arg_get_lit(ctx, idx++);
|
||||
|
@ -519,7 +521,7 @@ static int CmdT55xxSetConfig(const char *Cmd) {
|
|||
}
|
||||
|
||||
// validate user specified offset
|
||||
if (offset > -1) {
|
||||
if (offset > -1 && offset < 0x100) {
|
||||
config.offset = offset;
|
||||
}
|
||||
|
||||
|
@ -2939,35 +2941,36 @@ static int CmdT55xxWipe(const char *Cmd) {
|
|||
PrintAndLogEx(INFO, "Begin wiping...");
|
||||
|
||||
// Creating cmd string for write block :)
|
||||
char writeData[36] = {0};
|
||||
char *ptrData = writeData;
|
||||
snprintf(ptrData, sizeof(writeData), "-b 0 ");
|
||||
char wcmd[36] = {0};
|
||||
char *pwcmd = wcmd;
|
||||
|
||||
snprintf(pwcmd, sizeof(wcmd), "-b 0 ");
|
||||
|
||||
if (usepwd) {
|
||||
snprintf(ptrData + strlen(writeData), sizeof(writeData) - strlen(writeData), "p %08x ", password);
|
||||
snprintf(pwcmd + strlen(wcmd), sizeof(wcmd) - strlen(wcmd), "-p %08x ", password);
|
||||
}
|
||||
snprintf(ptrData + strlen(writeData), sizeof(writeData) - strlen(writeData), "d %08X", block0);
|
||||
snprintf(pwcmd + strlen(wcmd), sizeof(wcmd) - strlen(wcmd), "-d %08X", block0);
|
||||
|
||||
if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS)
|
||||
if (CmdT55xxWriteBlock(pwcmd) != PM3_SUCCESS)
|
||||
PrintAndLogEx(WARNING, "Warning: error writing blk 0");
|
||||
|
||||
for (uint8_t blk = 1; blk < 8; blk++) {
|
||||
|
||||
snprintf(ptrData, sizeof(writeData), "-b %d -d 0", blk);
|
||||
snprintf(pwcmd, sizeof(wcmd), "-b %d -d 00000000", blk);
|
||||
|
||||
if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS)
|
||||
if (CmdT55xxWriteBlock(pwcmd) != PM3_SUCCESS)
|
||||
PrintAndLogEx(WARNING, "Warning: error writing blk %d", blk);
|
||||
|
||||
memset(writeData, 0x00, sizeof(writeData));
|
||||
memset(wcmd, 0x00, sizeof(wcmd));
|
||||
}
|
||||
|
||||
// Check and rest t55xx downlink mode.
|
||||
if (config.downlink_mode != T55XX_DLMODE_FIXED) { // Detect found a different mode so card must support
|
||||
snprintf(ptrData, sizeof(writeData), "-b 3 --pg1 -d 00000000");
|
||||
if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS) {
|
||||
snprintf(pwcmd, sizeof(wcmd), "-b 3 --pg1 -d 00000000");
|
||||
if (CmdT55xxWriteBlock(pwcmd) != PM3_SUCCESS) {
|
||||
PrintAndLogEx(WARNING, "Warning: failed writing block 3 page 1 (config)");
|
||||
}
|
||||
memset(writeData, 0x00, sizeof(writeData));
|
||||
memset(wcmd, 0x00, sizeof(wcmd));
|
||||
}
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -56,6 +56,10 @@ struct version_information {
|
|||
#define DBG_EXTENDED 4 // errors + info + debug + breaking debug messages
|
||||
extern int DBGLEVEL;
|
||||
|
||||
// tear-off
|
||||
extern uint16_t tearoff_delay_us;
|
||||
extern bool tearoff_enabled;
|
||||
|
||||
// reader voltage field detector
|
||||
#define MF_MINFIELDV 4000
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue