mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2024-09-22 16:26:14 +08:00
commit
de4ad7e9fc
|
@ -3,6 +3,8 @@ All notable changes to this project will be documented in this file.
|
||||||
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
||||||
|
|
||||||
## [unreleased][unreleased]
|
## [unreleased][unreleased]
|
||||||
|
- Add `lf t55xx protect` - sets password and enables password protection on t55x7 tag (@iceman1001)
|
||||||
|
- Chg `lf t55xx wipe` - now accepts user provided configuration block (@iceman1001)
|
||||||
- Chg proxmark3-flasher is now merged into proxmark3 client. Add pm3-flash (@doegox)
|
- Chg proxmark3-flasher is now merged into proxmark3 client. Add pm3-flash (@doegox)
|
||||||
- Chg `hf iclass clone\dump\rdbl\wrbl` - now uses NG (@iceman1001)
|
- Chg `hf iclass clone\dump\rdbl\wrbl` - now uses NG (@iceman1001)
|
||||||
- Fix `hf iclass clone` - last block always fails (@iceman1001)
|
- Fix `hf iclass clone` - last block always fails (@iceman1001)
|
||||||
|
|
|
@ -195,7 +195,7 @@ void RunMod() {
|
||||||
MifareCGetBlock(params, 0, testBlock0);
|
MifareCGetBlock(params, 0, testBlock0);
|
||||||
|
|
||||||
if (memcmp(testBlock0, newBlock0, 16) == 0) {
|
if (memcmp(testBlock0, newBlock0, 16) == 0) {
|
||||||
DbpString("Cloned successfull!");
|
DbpString("Cloned successful!");
|
||||||
cardRead[selected] = 0; // Only if the card was cloned successfully should we clear it
|
cardRead[selected] = 0; // Only if the card was cloned successfully should we clear it
|
||||||
playing = 0;
|
playing = 0;
|
||||||
iGotoRecord = 1;
|
iGotoRecord = 1;
|
||||||
|
|
|
@ -128,7 +128,7 @@ void RunMod() {
|
||||||
WAIT_BUTTON_RELEASED();
|
WAIT_BUTTON_RELEASED();
|
||||||
|
|
||||||
Dbprintf("[=] %x %x %08x", selected, high[selected], low[selected]);
|
Dbprintf("[=] %x %x %08x", selected, high[selected], low[selected]);
|
||||||
CmdHIDsimTAG(high[selected], low[selected], 0);
|
CmdHIDsimTAG(0, high[selected], low[selected], 0, 0);
|
||||||
DbpString("[=] done playing");
|
DbpString("[=] done playing");
|
||||||
|
|
||||||
if (BUTTON_HELD(1000) > 0)
|
if (BUTTON_HELD(1000) > 0)
|
||||||
|
@ -188,7 +188,7 @@ void RunMod() {
|
||||||
// Print actual code to brute
|
// Print actual code to brute
|
||||||
Dbprintf("[=] TAG ID: %x%08x (%d) - FC: %u - Card: %u", high[selected], low[selected], (low[selected] >> 1) & 0xFFFF, fc, cardnum);
|
Dbprintf("[=] TAG ID: %x%08x (%d) - FC: %u - Card: %u", high[selected], low[selected], (low[selected] >> 1) & 0xFFFF, fc, cardnum);
|
||||||
|
|
||||||
CmdHIDsimTAGEx(high[selected], low[selected], 1, 50000);
|
CmdHIDsimTAGEx(0, high[selected], low[selected], 0, 1, 50000);
|
||||||
}
|
}
|
||||||
|
|
||||||
cardnum = original_cardnum;
|
cardnum = original_cardnum;
|
||||||
|
@ -216,7 +216,7 @@ void RunMod() {
|
||||||
// Print actual code to brute
|
// Print actual code to brute
|
||||||
Dbprintf("[=] TAG ID: %x%08x (%d) - FC: %u - Card: %u", high[selected], low[selected], (low[selected] >> 1) & 0xFFFF, fc, cardnum);
|
Dbprintf("[=] TAG ID: %x%08x (%d) - FC: %u - Card: %u", high[selected], low[selected], (low[selected] >> 1) & 0xFFFF, fc, cardnum);
|
||||||
|
|
||||||
CmdHIDsimTAGEx(high[selected], low[selected], 1, 50000);
|
CmdHIDsimTAGEx(0, high[selected], low[selected], 0, 1, 50000);
|
||||||
}
|
}
|
||||||
|
|
||||||
DbpString("[=] done bruteforcing");
|
DbpString("[=] done bruteforcing");
|
||||||
|
|
|
@ -102,7 +102,7 @@ void RunMod() {
|
||||||
Dbprintf("[=] trying Facility = %08x ID %08x", high, i);
|
Dbprintf("[=] trying Facility = %08x ID %08x", high, i);
|
||||||
|
|
||||||
// high, i, ledcontrol, timelimit 20000
|
// high, i, ledcontrol, timelimit 20000
|
||||||
CmdHIDsimTAGEx(high, i, false, 20000);
|
CmdHIDsimTAGEx(0, high, i, 0, false, 20000);
|
||||||
|
|
||||||
SpinDelay(100);
|
SpinDelay(100);
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,7 @@ void RunMod() {
|
||||||
Dbprintf("[=] simulating %x | %x%08x", selected, high[selected], low[selected]);
|
Dbprintf("[=] simulating %x | %x%08x", selected, high[selected], low[selected]);
|
||||||
|
|
||||||
// high, low, no led control(A) no time limit
|
// high, low, no led control(A) no time limit
|
||||||
CmdHIDsimTAGEx(high[selected], low[selected], false, -1);
|
CmdHIDsimTAGEx(0, high[selected], low[selected], 0, false, -1);
|
||||||
|
|
||||||
DbpString("[=] simulating done");
|
DbpString("[=] simulating done");
|
||||||
|
|
||||||
|
|
|
@ -702,7 +702,8 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_LF_HID_SIMULATE: {
|
case CMD_LF_HID_SIMULATE: {
|
||||||
CmdHIDsimTAG(packet->oldarg[0], packet->oldarg[1], 1);
|
lf_hidsim_t *payload = (lf_hidsim_t *)packet->data.asBytes;
|
||||||
|
CmdHIDsimTAG(payload->hi2, payload->hi, payload->lo, payload->longFMT, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_LF_FSK_SIMULATE: {
|
case CMD_LF_FSK_SIMULATE: {
|
||||||
|
@ -856,7 +857,12 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_LF_VIKING_CLONE: {
|
case CMD_LF_VIKING_CLONE: {
|
||||||
CopyVikingtoT55xx(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2]);
|
struct p {
|
||||||
|
bool Q5;
|
||||||
|
uint8_t blocks[8];
|
||||||
|
} PACKED;
|
||||||
|
struct p *payload = (struct p*)packet->data.asBytes;
|
||||||
|
CopyVikingtoT55xx(payload->blocks, payload->Q5);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_LF_COTAG_READ: {
|
case CMD_LF_COTAG_READ: {
|
||||||
|
|
|
@ -139,8 +139,8 @@ void EPA_Finish() {
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Parses DER encoded data, e.g. from EF.CardAccess and fills out the given
|
// Parses DER encoded data, e.g. from EF.CardAccess and fills out the given
|
||||||
// structs. If a pointer is 0, it is ignored.
|
// structs. If a pointer is 0, it is ignored.
|
||||||
// The function returns 0 on success and if an error occured, it returns the
|
// The function returns 0 on success and if an error occurred, it returns the
|
||||||
// offset where it occured.
|
// offset where it occurred.
|
||||||
//
|
//
|
||||||
// TODO: This function can access memory outside of the given data if the DER
|
// TODO: This function can access memory outside of the given data if the DER
|
||||||
// encoding is broken
|
// encoding is broken
|
||||||
|
@ -274,7 +274,7 @@ void EPA_PACE_Collect_Nonce(PacketCommandNG *c) {
|
||||||
* ack layout:
|
* ack layout:
|
||||||
* arg:
|
* arg:
|
||||||
* 1. element
|
* 1. element
|
||||||
* step where the error occured or 0 if no error occured
|
* step where the error occurred or 0 if no error occurred
|
||||||
* 2. element
|
* 2. element
|
||||||
* return code of the last executed function
|
* return code of the last executed function
|
||||||
* d:
|
* d:
|
||||||
|
|
|
@ -427,7 +427,7 @@ static bool hitag2_password(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blocknr > 7) {
|
if (blocknr > 7) {
|
||||||
DbpString("Read succesful!");
|
DbpString("Read successful!");
|
||||||
bSuccessful = true;
|
bSuccessful = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -440,7 +440,7 @@ static bool hitag2_password(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t
|
||||||
|
|
||||||
// Unexpected response
|
// Unexpected response
|
||||||
default: {
|
default: {
|
||||||
Dbprintf("Uknown frame length: %d", rxlen);
|
Dbprintf("Unknown frame length: %d", rxlen);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -532,7 +532,7 @@ static bool hitag2_crypto(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *
|
||||||
blocknr++;
|
blocknr++;
|
||||||
}
|
}
|
||||||
if (blocknr > 7) {
|
if (blocknr > 7) {
|
||||||
DbpString("Read succesful!");
|
DbpString("Read successful!");
|
||||||
bSuccessful = true;
|
bSuccessful = true;
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -546,7 +546,7 @@ static bool hitag2_crypto(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *
|
||||||
|
|
||||||
// Unexpected response
|
// Unexpected response
|
||||||
default: {
|
default: {
|
||||||
Dbprintf("Uknown frame length: %d", rxlen);
|
Dbprintf("Unknown frame length: %d", rxlen);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -588,7 +588,7 @@ static bool hitag2_authenticate(uint8_t *rx, const size_t rxlen, uint8_t *tx, si
|
||||||
memcpy(tx, NrAr, 8);
|
memcpy(tx, NrAr, 8);
|
||||||
bCrypto = true;
|
bCrypto = true;
|
||||||
} else {
|
} else {
|
||||||
DbpString("Authentication succesful!");
|
DbpString("Authentication successful!");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -596,7 +596,7 @@ static bool hitag2_authenticate(uint8_t *rx, const size_t rxlen, uint8_t *tx, si
|
||||||
|
|
||||||
// Unexpected response
|
// Unexpected response
|
||||||
default: {
|
default: {
|
||||||
Dbprintf("Uknown frame length: %d", rxlen);
|
Dbprintf("Unknown frame length: %d", rxlen);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -655,7 +655,7 @@ static bool hitag2_test_auth_attempts(uint8_t *rx, const size_t rxlen, uint8_t *
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
Dbprintf("Uknown frame length: %d", rxlen);
|
Dbprintf("Unknown frame length: %d", rxlen);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -696,7 +696,7 @@ static bool hitag2_read_uid(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t
|
||||||
break;
|
break;
|
||||||
// Unexpected response
|
// Unexpected response
|
||||||
default: {
|
default: {
|
||||||
Dbprintf("Uknown frame length: %d", rxlen);
|
Dbprintf("Unknown frame length: %d", rxlen);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1277,7 +1277,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
|
||||||
|
|
||||||
// Wait for HITAG_T_WAIT_2 carrier periods after the last tag bit before transmitting,
|
// Wait for HITAG_T_WAIT_2 carrier periods after the last tag bit before transmitting,
|
||||||
// Since the clock counts since the last falling edge, a 'one' means that the
|
// Since the clock counts since the last falling edge, a 'one' means that the
|
||||||
// falling edge occured halfway the period. with respect to this falling edge,
|
// falling edge occurred halfway the period. with respect to this falling edge,
|
||||||
// we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'.
|
// we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'.
|
||||||
// All timer values are in terms of T0 units
|
// All timer values are in terms of T0 units
|
||||||
while (AT91C_BASE_TC0->TC_CV < T0 * (t_wait + (HITAG_T_TAG_HALF_PERIOD * lastbit)));
|
while (AT91C_BASE_TC0->TC_CV < T0 * (t_wait + (HITAG_T_TAG_HALF_PERIOD * lastbit)));
|
||||||
|
@ -1533,7 +1533,7 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) {
|
||||||
|
|
||||||
// Wait for HITAG_T_WAIT_2 carrier periods after the last tag bit before transmitting,
|
// Wait for HITAG_T_WAIT_2 carrier periods after the last tag bit before transmitting,
|
||||||
// Since the clock counts since the last falling edge, a 'one' means that the
|
// Since the clock counts since the last falling edge, a 'one' means that the
|
||||||
// falling edge occured halfway the period. with respect to this falling edge,
|
// falling edge occurred halfway the period. with respect to this falling edge,
|
||||||
// we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'.
|
// we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'.
|
||||||
// All timer values are in terms of T0 units
|
// All timer values are in terms of T0 units
|
||||||
while (AT91C_BASE_TC0->TC_CV < T0 * (t_wait + (HITAG_T_TAG_HALF_PERIOD * lastbit))) {};
|
while (AT91C_BASE_TC0->TC_CV < T0 * (t_wait + (HITAG_T_TAG_HALF_PERIOD * lastbit))) {};
|
||||||
|
|
|
@ -1354,7 +1354,7 @@ void ReadHitagS(hitag_function htf, hitag_data *htd) {
|
||||||
|
|
||||||
// Wait for HITAG_T_WAIT_2 carrier periods after the last tag bit before transmitting,
|
// Wait for HITAG_T_WAIT_2 carrier periods after the last tag bit before transmitting,
|
||||||
// Since the clock counts since the last falling edge, a 'one' means that the
|
// Since the clock counts since the last falling edge, a 'one' means that the
|
||||||
// falling edge occured halfway the period. with respect to this falling edge,
|
// falling edge occurred halfway the period. with respect to this falling edge,
|
||||||
// we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'.
|
// we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'.
|
||||||
// All timer values are in terms of T0 units
|
// All timer values are in terms of T0 units
|
||||||
|
|
||||||
|
@ -1643,7 +1643,7 @@ void WritePageHitagS(hitag_function htf, hitag_data *htd, int page) {
|
||||||
|
|
||||||
// Wait for HITAG_T_WAIT_2 carrier periods after the last tag bit before transmitting,
|
// Wait for HITAG_T_WAIT_2 carrier periods after the last tag bit before transmitting,
|
||||||
// Since the clock counts since the last falling edge, a 'one' means that the
|
// Since the clock counts since the last falling edge, a 'one' means that the
|
||||||
// falling edge occured halfway the period. with respect to this falling edge,
|
// falling edge occurred halfway the period. with respect to this falling edge,
|
||||||
// we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'.
|
// we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'.
|
||||||
// All timer values are in terms of T0 units
|
// All timer values are in terms of T0 units
|
||||||
|
|
||||||
|
@ -1952,7 +1952,7 @@ void check_challenges(bool file_given, uint8_t *data) {
|
||||||
|
|
||||||
// Wait for HITAG_T_WAIT_2 carrier periods after the last tag bit before transmitting,
|
// Wait for HITAG_T_WAIT_2 carrier periods after the last tag bit before transmitting,
|
||||||
// Since the clock counts since the last falling edge, a 'one' means that the
|
// Since the clock counts since the last falling edge, a 'one' means that the
|
||||||
// falling edge occured halfway the period. with respect to this falling edge,
|
// falling edge occurred halfway the period. with respect to this falling edge,
|
||||||
// we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'.
|
// we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'.
|
||||||
// All timer values are in terms of T0 units
|
// All timer values are in terms of T0 units
|
||||||
|
|
||||||
|
|
|
@ -1005,7 +1005,7 @@ static bool SimulateIso14443aInit(int tagType, int flags, uint8_t *data, tag_res
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default: {
|
default: {
|
||||||
if (DBGLEVEL >= DBG_ERROR) Dbprintf("Error: unkown tagtype (%d)", tagType);
|
if (DBGLEVEL >= DBG_ERROR) Dbprintf("Error: unknown tagtype (%d)", tagType);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2999,7 +2999,7 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
|
||||||
|
|
||||||
mf_nr_ar[3] &= 0x1F;
|
mf_nr_ar[3] &= 0x1F;
|
||||||
|
|
||||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("Number of sent auth requestes: %u", i);
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("Number of sent auth requests: %u", i);
|
||||||
|
|
||||||
uint8_t buf[32] = {0x00};
|
uint8_t buf[32] = {0x00};
|
||||||
memset(buf, 0x00, sizeof(buf));
|
memset(buf, 0x00, sizeof(buf));
|
||||||
|
|
|
@ -766,7 +766,7 @@ void DbdecodeIso15693Answer(int len, uint8_t *d) {
|
||||||
strncat(status, "0F: no info", DBD15STATLEN - strlen(status));
|
strncat(status, "0F: no info", DBD15STATLEN - strlen(status));
|
||||||
break;
|
break;
|
||||||
case 0x10:
|
case 0x10:
|
||||||
strncat(status, "10: dont exist", DBD15STATLEN - strlen(status));
|
strncat(status, "10: don't exist", DBD15STATLEN - strlen(status));
|
||||||
break;
|
break;
|
||||||
case 0x11:
|
case 0x11:
|
||||||
strncat(status, "11: lock again", DBD15STATLEN - strlen(status));
|
strncat(status, "11: lock again", DBD15STATLEN - strlen(status));
|
||||||
|
|
156
armsrc/lfops.c
156
armsrc/lfops.c
|
@ -876,69 +876,6 @@ void SimulateTagLowFrequency(int period, int gap, bool ledcontrol) {
|
||||||
#define DEBUG_FRAME_CONTENTS 1
|
#define DEBUG_FRAME_CONTENTS 1
|
||||||
void SimulateTagLowFrequencyBidir(int divisor, int max_bitlen) {
|
void SimulateTagLowFrequencyBidir(int divisor, int max_bitlen) {
|
||||||
}
|
}
|
||||||
// compose fc/5 fc/8 waveform (FSK1)
|
|
||||||
|
|
||||||
// compose fc/8 fc/10 waveform (FSK2)
|
|
||||||
// also manchester,
|
|
||||||
static void fc(int c, int *n) {
|
|
||||||
uint8_t *dest = BigBuf_get_addr();
|
|
||||||
int idx;
|
|
||||||
|
|
||||||
// for when we want an fc8 pattern every 4 logical bits
|
|
||||||
if (c == 0) {
|
|
||||||
dest[((*n)++)] = 1;
|
|
||||||
dest[((*n)++)] = 1;
|
|
||||||
dest[((*n)++)] = 1;
|
|
||||||
dest[((*n)++)] = 1;
|
|
||||||
dest[((*n)++)] = 0;
|
|
||||||
dest[((*n)++)] = 0;
|
|
||||||
dest[((*n)++)] = 0;
|
|
||||||
dest[((*n)++)] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// an fc/8 encoded bit is a bit pattern of 11110000 x6 = 48 samples
|
|
||||||
if (c == 8) {
|
|
||||||
for (idx = 0; idx < 6; idx++) {
|
|
||||||
dest[((*n)++)] = 1;
|
|
||||||
dest[((*n)++)] = 1;
|
|
||||||
dest[((*n)++)] = 1;
|
|
||||||
dest[((*n)++)] = 1;
|
|
||||||
dest[((*n)++)] = 0;
|
|
||||||
dest[((*n)++)] = 0;
|
|
||||||
dest[((*n)++)] = 0;
|
|
||||||
dest[((*n)++)] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// an fc/10 encoded bit is a bit pattern of 1111100000 x5 = 50 samples
|
|
||||||
if (c == 10) {
|
|
||||||
for (idx = 0; idx < 5; idx++) {
|
|
||||||
dest[((*n)++)] = 1;
|
|
||||||
dest[((*n)++)] = 1;
|
|
||||||
dest[((*n)++)] = 1;
|
|
||||||
dest[((*n)++)] = 1;
|
|
||||||
dest[((*n)++)] = 1;
|
|
||||||
dest[((*n)++)] = 0;
|
|
||||||
dest[((*n)++)] = 0;
|
|
||||||
dest[((*n)++)] = 0;
|
|
||||||
dest[((*n)++)] = 0;
|
|
||||||
dest[((*n)++)] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// special start of frame marker containing invalid bit sequences
|
|
||||||
// this one is focused on HID, with manchester encoding.
|
|
||||||
static void fcSTT(int *n) {
|
|
||||||
fc(8, n);
|
|
||||||
fc(8, n); // invalid
|
|
||||||
fc(8, n);
|
|
||||||
fc(10, n); // logical 0
|
|
||||||
fc(10, n);
|
|
||||||
fc(10, n); // invalid
|
|
||||||
fc(8, n);
|
|
||||||
fc(10, n); // logical 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// compose fc/X fc/Y waveform (FSKx)
|
// compose fc/X fc/Y waveform (FSKx)
|
||||||
static void fcAll(uint8_t fc, int *n, uint8_t clock, int16_t *remainder) {
|
static void fcAll(uint8_t fc, int *n, uint8_t clock, int16_t *remainder) {
|
||||||
|
@ -964,17 +901,8 @@ static void fcAll(uint8_t fc, int *n, uint8_t clock, int16_t *remainder) {
|
||||||
|
|
||||||
// prepare a waveform pattern in the buffer based on the ID given then
|
// prepare a waveform pattern in the buffer based on the ID given then
|
||||||
// simulate a HID tag until the button is pressed
|
// simulate a HID tag until the button is pressed
|
||||||
void CmdHIDsimTAGEx(uint32_t hi, uint32_t lo, bool ledcontrol, int numcycles) {
|
void CmdHIDsimTAGEx(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT, bool ledcontrol, int numcycles) {
|
||||||
|
|
||||||
if (hi > 0xFFF) {
|
|
||||||
DbpString("[!] tags can only have 44 bits. - USE lf simfsk for larger tags");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
|
||||||
set_tracing(false);
|
|
||||||
|
|
||||||
int n = 0, i = 0;
|
|
||||||
/*
|
/*
|
||||||
HID tag bitstream format
|
HID tag bitstream format
|
||||||
The tag contains a 44bit unique code. This is sent out MSB first in sets of 4 bits
|
The tag contains a 44bit unique code. This is sent out MSB first in sets of 4 bits
|
||||||
|
@ -989,53 +917,44 @@ void CmdHIDsimTAGEx(uint32_t hi, uint32_t lo, bool ledcontrol, int numcycles) {
|
||||||
bit 0 = fc8
|
bit 0 = fc8
|
||||||
*/
|
*/
|
||||||
|
|
||||||
fc(0, &n);
|
// special start of frame marker containing invalid Manchester bit sequences
|
||||||
|
uint8_t bits[8+8*2+84*2] = { 0, 0, 0, 1, 1, 1, 0, 1 };
|
||||||
|
uint8_t bitlen = 0;
|
||||||
|
uint16_t n = 8;
|
||||||
|
|
||||||
// special start of frame marker containing invalid bit sequences
|
if (longFMT) {
|
||||||
fcSTT(&n);
|
// Ensure no more than 84 bits supplied
|
||||||
|
if (hi2 > 0xFFFFF) {
|
||||||
// manchester encode bits 43 to 32
|
DbpString("Tags can only have 84 bits.");
|
||||||
for (i = 11; i >= 0; i--) {
|
return;
|
||||||
|
|
||||||
if ((i % 4) == 3) fc(0, &n);
|
|
||||||
|
|
||||||
if ((hi >> i) & 1) {
|
|
||||||
fc(10, &n);
|
|
||||||
fc(8, &n); // low-high transition
|
|
||||||
} else {
|
|
||||||
fc(8, &n);
|
|
||||||
fc(10, &n); // high-low transition
|
|
||||||
}
|
}
|
||||||
}
|
bitlen = 8+8*2+84*2;
|
||||||
|
hi2 |= 0x9E00000; // 9E: long format identifier
|
||||||
|
manchesterEncodeUint32(hi2, 16+12, bits, &n);
|
||||||
|
manchesterEncodeUint32(hi, 32, bits, &n);
|
||||||
|
manchesterEncodeUint32(lo, 32, bits, &n);
|
||||||
|
} else {
|
||||||
|
|
||||||
// manchester encode bits 31 to 0
|
if (hi > 0xFFF) {
|
||||||
for (i = 31; i >= 0; i--) {
|
DbpString("[!] tags can only have 44 bits. - USE lf simfsk for larger tags");
|
||||||
|
return;
|
||||||
if ((i % 4) == 3) fc(0, &n);
|
|
||||||
|
|
||||||
if ((lo >> i) & 1) {
|
|
||||||
fc(10, &n);
|
|
||||||
fc(8, &n); // low-high transition
|
|
||||||
} else {
|
|
||||||
fc(8, &n);
|
|
||||||
fc(10, &n); // high-low transition
|
|
||||||
}
|
}
|
||||||
|
bitlen = 8+44*2;
|
||||||
|
manchesterEncodeUint32(hi, 12, bits, &n);
|
||||||
|
manchesterEncodeUint32(lo, 32, bits, &n);
|
||||||
}
|
}
|
||||||
|
CmdFSKsimTAGEx(10, 8, 0, 50, bitlen, bits, ledcontrol, numcycles);
|
||||||
if (ledcontrol) LED_A_ON();
|
|
||||||
SimulateTagLowFrequencyEx(n, 0, ledcontrol, numcycles);
|
|
||||||
if (ledcontrol) LED_A_OFF();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmdHIDsimTAG(uint32_t hi, uint32_t lo, bool ledcontrol) {
|
void CmdHIDsimTAG(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT, bool ledcontrol) {
|
||||||
CmdHIDsimTAGEx(hi, lo, ledcontrol, -1);
|
CmdHIDsimTAGEx(hi2, hi, lo, longFMT, ledcontrol, -1);
|
||||||
reply_ng(CMD_LF_HID_SIMULATE, PM3_EOPABORTED, NULL, 0);
|
reply_ng(CMD_LF_HID_SIMULATE, PM3_EOPABORTED, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// prepare a waveform pattern in the buffer based on the ID given then
|
// prepare a waveform pattern in the buffer based on the ID given then
|
||||||
// simulate a FSK tag until the button is pressed
|
// simulate a FSK tag until the button is pressed
|
||||||
// arg1 contains fcHigh and fcLow, arg2 contains STT marker and clock
|
// arg1 contains fcHigh and fcLow, arg2 contains STT marker and clock
|
||||||
void CmdFSKsimTAG(uint8_t fchigh, uint8_t fclow, uint8_t separator, uint8_t clk, uint16_t bitslen, uint8_t *bits, bool ledcontrol) {
|
void CmdFSKsimTAGEx(uint8_t fchigh, uint8_t fclow, uint8_t separator, uint8_t clk, uint16_t bitslen, uint8_t *bits, bool ledcontrol, int numcycles) {
|
||||||
|
|
||||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||||
|
|
||||||
|
@ -1064,8 +983,15 @@ void CmdFSKsimTAG(uint8_t fchigh, uint8_t fclow, uint8_t separator, uint8_t clk,
|
||||||
Dbprintf("Simulating with fcHigh: %d, fcLow: %d, clk: %d, STT: %d, n: %d", fchigh, fclow, clk, separator, n);
|
Dbprintf("Simulating with fcHigh: %d, fcLow: %d, clk: %d, STT: %d, n: %d", fchigh, fclow, clk, separator, n);
|
||||||
|
|
||||||
if (ledcontrol) LED_A_ON();
|
if (ledcontrol) LED_A_ON();
|
||||||
SimulateTagLowFrequency(n, 0, ledcontrol);
|
SimulateTagLowFrequencyEx(n, 0, ledcontrol, numcycles);
|
||||||
if (ledcontrol) LED_A_OFF();
|
if (ledcontrol) LED_A_OFF();
|
||||||
|
}
|
||||||
|
|
||||||
|
// prepare a waveform pattern in the buffer based on the ID given then
|
||||||
|
// simulate a FSK tag until the button is pressed
|
||||||
|
// arg1 contains fcHigh and fcLow, arg2 contains STT marker and clock
|
||||||
|
void CmdFSKsimTAG(uint8_t fchigh, uint8_t fclow, uint8_t separator, uint8_t clk, uint16_t bitslen, uint8_t *bits, bool ledcontrol) {
|
||||||
|
CmdFSKsimTAGEx(fchigh, fclow, separator, clk, bitslen, bits, ledcontrol, -1);
|
||||||
reply_ng(CMD_LF_FSK_SIMULATE, PM3_EOPABORTED, NULL, 0);
|
reply_ng(CMD_LF_FSK_SIMULATE, PM3_EOPABORTED, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2152,13 +2078,19 @@ void CopyIndala224toT55x7(uint32_t uid1, uint32_t uid2, uint32_t uid3, uint32_t
|
||||||
LED_D_OFF();
|
LED_D_OFF();
|
||||||
}
|
}
|
||||||
// clone viking tag to T55xx
|
// clone viking tag to T55xx
|
||||||
void CopyVikingtoT55xx(uint32_t block1, uint32_t block2, uint8_t Q5) {
|
void CopyVikingtoT55xx(uint8_t *blocks, uint8_t Q5) {
|
||||||
uint32_t data[] = {T55x7_BITRATE_RF_32 | T55x7_MODULATION_MANCHESTER | (2 << T55x7_MAXBLOCK_SHIFT), block1, block2};
|
|
||||||
if (Q5) data[0] = T5555_SET_BITRATE(32) | T5555_MODULATION_MANCHESTER | 2 << T5555_MAXBLOCK_SHIFT;
|
uint32_t data[] = {T55x7_BITRATE_RF_32 | T55x7_MODULATION_MANCHESTER | (2 << T55x7_MAXBLOCK_SHIFT), 0, 0};
|
||||||
|
if (Q5)
|
||||||
|
data[0] = T5555_SET_BITRATE(32) | T5555_MODULATION_MANCHESTER | 2 << T5555_MAXBLOCK_SHIFT;
|
||||||
|
|
||||||
|
data[1] = bytes_to_num(blocks, 4);
|
||||||
|
data[2] = bytes_to_num(blocks +4, 4);
|
||||||
|
|
||||||
// Program the data blocks for supplied ID and the block 0 config
|
// Program the data blocks for supplied ID and the block 0 config
|
||||||
WriteT55xx(data, 0, 3);
|
WriteT55xx(data, 0, 3);
|
||||||
LED_D_OFF();
|
LED_D_OFF();
|
||||||
reply_mix(CMD_ACK, 0, 0, 0, 0, 0);
|
reply_ng(CMD_LF_VIKING_CLONE, PM3_SUCCESS, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define 9bit header for EM410x tags
|
// Define 9bit header for EM410x tags
|
||||||
|
|
|
@ -30,9 +30,10 @@ void SimulateTagLowFrequencyEx(int period, int gap, bool ledcontrol, int numcycl
|
||||||
void SimulateTagLowFrequency(int period, int gap, bool ledcontrol);
|
void SimulateTagLowFrequency(int period, int gap, bool ledcontrol);
|
||||||
void SimulateTagLowFrequencyBidir(int divisor, int max_bitlen);
|
void SimulateTagLowFrequencyBidir(int divisor, int max_bitlen);
|
||||||
|
|
||||||
void CmdHIDsimTAGEx(uint32_t hi, uint32_t lo, bool ledcontrol, int numcycles);
|
void CmdHIDsimTAGEx(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT, bool ledcontrol, int numcycles);
|
||||||
void CmdHIDsimTAG(uint32_t hi, uint32_t lo, bool ledcontrol);
|
void CmdHIDsimTAG(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT, bool ledcontrol);
|
||||||
|
|
||||||
|
void CmdFSKsimTAGEx(uint8_t fchigh, uint8_t fclow, uint8_t separator, uint8_t clk, uint16_t bitslen, uint8_t *bits, bool ledcontrol, int numcycles);
|
||||||
void CmdFSKsimTAG(uint8_t fchigh, uint8_t fclow, uint8_t separator, uint8_t clk, uint16_t bitslen, uint8_t *bits, bool ledcontrol);
|
void CmdFSKsimTAG(uint8_t fchigh, uint8_t fclow, uint8_t separator, uint8_t clk, uint16_t bitslen, uint8_t *bits, bool ledcontrol);
|
||||||
void CmdASKsimTAG(uint8_t encoding, uint8_t invert, uint8_t separator, uint8_t clk, uint16_t size, uint8_t *bits, bool ledcontrol);
|
void CmdASKsimTAG(uint8_t encoding, uint8_t invert, uint8_t separator, uint8_t clk, uint16_t size, uint8_t *bits, bool ledcontrol);
|
||||||
void CmdPSKsimTag(uint8_t carrier, uint8_t invert, uint8_t clk, uint16_t size, uint8_t *bits, bool ledcontrol);
|
void CmdPSKsimTag(uint8_t carrier, uint8_t invert, uint8_t clk, uint16_t size, uint8_t *bits, bool ledcontrol);
|
||||||
|
@ -43,7 +44,7 @@ void CmdEM410xdemod(int findone, uint32_t *high, uint64_t *low, int ledcontrol);
|
||||||
void CmdIOdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol);
|
void CmdIOdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol);
|
||||||
void CopyIOtoT55x7(uint32_t hi, uint32_t lo); // Clone an ioProx card to T5557/T5567
|
void CopyIOtoT55x7(uint32_t hi, uint32_t lo); // Clone an ioProx card to T5557/T5567
|
||||||
void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT); // Clone an HID card to T5557/T5567
|
void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT); // Clone an HID card to T5557/T5567
|
||||||
void CopyVikingtoT55xx(uint32_t block1, uint32_t block2, uint8_t Q5);
|
void CopyVikingtoT55xx(uint8_t *blocks, uint8_t Q5);
|
||||||
void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo);
|
void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo);
|
||||||
void CopyIndala64toT55x7(uint32_t hi, uint32_t lo); // Clone Indala 64-bit tag by UID to T55x7
|
void CopyIndala64toT55x7(uint32_t hi, uint32_t lo); // Clone Indala 64-bit tag by UID to T55x7
|
||||||
void CopyIndala224toT55x7(uint32_t uid1, uint32_t uid2, uint32_t uid3, uint32_t uid4, uint32_t uid5, uint32_t uid6, uint32_t uid7); // Clone Indala 224-bit tag by UID to T55x7
|
void CopyIndala224toT55x7(uint32_t uid1, uint32_t uid2, uint32_t uid3, uint32_t uid4, uint32_t uid5, uint32_t uid6, uint32_t uid7); // Clone Indala 224-bit tag by UID to T55x7
|
||||||
|
|
|
@ -913,7 +913,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
uint16_t unsuccessfull_tries = 0;
|
uint16_t unsuccessful_tries = 0;
|
||||||
uint16_t davg = 0;
|
uint16_t davg = 0;
|
||||||
dmax = 0;
|
dmax = 0;
|
||||||
dmin = 2000;
|
dmin = 2000;
|
||||||
|
@ -970,8 +970,8 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)
|
||||||
}
|
}
|
||||||
if (DBGLEVEL >= 3) Dbprintf("Nested: calibrating... ntdist=%d", i);
|
if (DBGLEVEL >= 3) Dbprintf("Nested: calibrating... ntdist=%d", i);
|
||||||
} else {
|
} else {
|
||||||
unsuccessfull_tries++;
|
unsuccessful_tries++;
|
||||||
if (unsuccessfull_tries > NESTED_MAX_TRIES) { // card isn't vulnerable to nested attack (random numbers are not predictable)
|
if (unsuccessful_tries > NESTED_MAX_TRIES) { // card isn't vulnerable to nested attack (random numbers are not predictable)
|
||||||
isOK = -3;
|
isOK = -3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1038,7 +1038,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)
|
||||||
|
|
||||||
if (valid_nonce(nttest, nt2, ks1, par_array)) {
|
if (valid_nonce(nttest, nt2, ks1, par_array)) {
|
||||||
if (ncount > 0) { // we are only interested in disambiguous nonces, try again
|
if (ncount > 0) { // we are only interested in disambiguous nonces, try again
|
||||||
if (DBGLEVEL >= 3) Dbprintf("Nonce#%d: dismissed (ambigous), ntdist=%d", i + 1, j);
|
if (DBGLEVEL >= 3) Dbprintf("Nonce#%d: dismissed (ambiguous), ntdist=%d", i + 1, j);
|
||||||
target_nt[i] = 0;
|
target_nt[i] = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1118,7 +1118,7 @@ uint8_t chkKey(struct chk_t *c) {
|
||||||
|
|
||||||
CHK_TIMEOUT();
|
CHK_TIMEOUT();
|
||||||
|
|
||||||
// if successfull auth, send HALT
|
// if successful auth, send HALT
|
||||||
// if ( !res )
|
// if ( !res )
|
||||||
// mifare_classic_halt_ex(c->pcs);
|
// mifare_classic_halt_ex(c->pcs);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -302,7 +302,7 @@ int rdv40_spiffs_lazy_mount() {
|
||||||
if (!rdv40_spiffs_mounted()) {
|
if (!rdv40_spiffs_mounted()) {
|
||||||
changed = rdv40_spiffs_mount();
|
changed = rdv40_spiffs_mount();
|
||||||
/* if changed = 0 = SPIFFS_OK then all went well then the change
|
/* if changed = 0 = SPIFFS_OK then all went well then the change
|
||||||
* actually occured :)*/
|
* actually occurred :)*/
|
||||||
changed = !changed;
|
changed = !changed;
|
||||||
}
|
}
|
||||||
return changed;
|
return changed;
|
||||||
|
@ -371,7 +371,7 @@ just get back to this state. If not, just don't.
|
||||||
[...]
|
[...]
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
// Again : This will "toggle" spiffs mount status only if a "change" occured
|
// Again : This will "toggle" spiffs mount status only if a "change" occurred
|
||||||
// (and should be fed by the result of a spiffs_lazy* function) If everything
|
// (and should be fed by the result of a spiffs_lazy* function) If everything
|
||||||
// went well, it will return SPIFFS_OK if everything went well, and a report
|
// went well, it will return SPIFFS_OK if everything went well, and a report
|
||||||
// back the chain a SPI_ERRNO if not.
|
// back the chain a SPI_ERRNO if not.
|
||||||
|
|
|
@ -45,7 +45,7 @@ static int usage_analyse_checksum(void) {
|
||||||
PrintAndLogEx(NORMAL, "Usage: analyse chksum [h] [v] b <bytes> m <mask>");
|
PrintAndLogEx(NORMAL, "Usage: analyse chksum [h] [v] b <bytes> m <mask>");
|
||||||
PrintAndLogEx(NORMAL, "Options:");
|
PrintAndLogEx(NORMAL, "Options:");
|
||||||
PrintAndLogEx(NORMAL, " h This help");
|
PrintAndLogEx(NORMAL, " h This help");
|
||||||
PrintAndLogEx(NORMAL, " v supress header");
|
PrintAndLogEx(NORMAL, " v suppress header");
|
||||||
PrintAndLogEx(NORMAL, " b <bytes> bytes to calc missing XOR in a LCR");
|
PrintAndLogEx(NORMAL, " b <bytes> bytes to calc missing XOR in a LCR");
|
||||||
PrintAndLogEx(NORMAL, " m <mask> bit mask to limit the outpuyt");
|
PrintAndLogEx(NORMAL, " m <mask> bit mask to limit the outpuyt");
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
|
|
@ -164,7 +164,7 @@ static int CmdHFEPAPACEReplay(const char *Cmd) {
|
||||||
PrintAndLogEx(NORMAL, "GA Perform Key Agreement: %u us", resp.data.asDwords[3]);
|
PrintAndLogEx(NORMAL, "GA Perform Key Agreement: %u us", resp.data.asDwords[3]);
|
||||||
PrintAndLogEx(NORMAL, "GA Mutual Authenticate: %u us", resp.data.asDwords[4]);
|
PrintAndLogEx(NORMAL, "GA Mutual Authenticate: %u us", resp.data.asDwords[4]);
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(NORMAL, "PACE replay successfull!");
|
PrintAndLogEx(NORMAL, "PACE replay successful!");
|
||||||
PrintAndLogEx(NORMAL, "MSE Set AT: %u us", resp.data.asDwords[0]);
|
PrintAndLogEx(NORMAL, "MSE Set AT: %u us", resp.data.asDwords[0]);
|
||||||
PrintAndLogEx(NORMAL, "GA Get Nonce: %u us", resp.data.asDwords[1]);
|
PrintAndLogEx(NORMAL, "GA Get Nonce: %u us", resp.data.asDwords[1]);
|
||||||
PrintAndLogEx(NORMAL, "GA Map Nonce: %u us", resp.data.asDwords[2]);
|
PrintAndLogEx(NORMAL, "GA Map Nonce: %u us", resp.data.asDwords[2]);
|
||||||
|
|
|
@ -1006,7 +1006,7 @@ static int CmdHF14AMfDump(const char *Cmd) {
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "time: %" PRIu64 " seconds\n", (msclock() - t1) / 1000);
|
PrintAndLogEx(SUCCESS, "time: %" PRIu64 " seconds\n", (msclock() - t1) / 1000);
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "\nSucceded in dumping all blocks");
|
PrintAndLogEx(SUCCESS, "\nSucceeded in dumping all blocks");
|
||||||
|
|
||||||
if (strlen(dataFilename) < 1) {
|
if (strlen(dataFilename) < 1) {
|
||||||
fptr = GenerateFilename("hf-mf-", "-data");
|
fptr = GenerateFilename("hf-mf-", "-data");
|
||||||
|
@ -1422,14 +1422,14 @@ jumptoend:
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "saving keys to binary file " _YELLOW_("%s"), fptr);
|
PrintAndLogEx(SUCCESS, "saving keys to binary file " _YELLOW_("%s"), fptr);
|
||||||
uint8_t standart[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
uint8_t standard[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||||
uint8_t tempkey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
uint8_t tempkey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||||
for (int i = 0; i < SectorsCnt; i++) {
|
for (int i = 0; i < SectorsCnt; i++) {
|
||||||
if (e_sector[i].foundKey[0]) {
|
if (e_sector[i].foundKey[0]) {
|
||||||
num_to_bytes(e_sector[i].Key[0], 6, tempkey);
|
num_to_bytes(e_sector[i].Key[0], 6, tempkey);
|
||||||
fwrite(tempkey, 1, 6, fkeys);
|
fwrite(tempkey, 1, 6, fkeys);
|
||||||
} else {
|
} else {
|
||||||
fwrite(&standart, 1, 6, fkeys);
|
fwrite(&standard, 1, 6, fkeys);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int i = 0; i < SectorsCnt; i++) {
|
for (int i = 0; i < SectorsCnt; i++) {
|
||||||
|
@ -1437,7 +1437,7 @@ jumptoend:
|
||||||
num_to_bytes(e_sector[i].Key[1], 6, tempkey);
|
num_to_bytes(e_sector[i].Key[1], 6, tempkey);
|
||||||
fwrite(tempkey, 1, 6, fkeys);
|
fwrite(tempkey, 1, 6, fkeys);
|
||||||
} else {
|
} else {
|
||||||
fwrite(&standart, 1, 6, fkeys);
|
fwrite(&standard, 1, 6, fkeys);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fflush(fkeys);
|
fflush(fkeys);
|
||||||
|
|
|
@ -76,14 +76,14 @@ static int usage_lf_hid_sim(void) {
|
||||||
static int usage_lf_hid_clone(void) {
|
static int usage_lf_hid_clone(void) {
|
||||||
PrintAndLogEx(NORMAL, "Clone HID to T55x7. Tag must be on antenna. ");
|
PrintAndLogEx(NORMAL, "Clone HID to T55x7. Tag must be on antenna. ");
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(NORMAL, "Usage: lf hid clone [h] [ID] <L>");
|
PrintAndLogEx(NORMAL, "Usage: lf hid clone [h] [l] ID");
|
||||||
PrintAndLogEx(NORMAL, "Options:");
|
PrintAndLogEx(NORMAL, "Options:");
|
||||||
PrintAndLogEx(NORMAL, " h - This help");
|
PrintAndLogEx(NORMAL, " h - This help");
|
||||||
|
PrintAndLogEx(NORMAL, " l - 84bit ID");
|
||||||
PrintAndLogEx(NORMAL, " ID - HID id");
|
PrintAndLogEx(NORMAL, " ID - HID id");
|
||||||
PrintAndLogEx(NORMAL, " L - 84bit ID");
|
|
||||||
PrintAndLogEx(NORMAL, "Examples:");
|
PrintAndLogEx(NORMAL, "Examples:");
|
||||||
PrintAndLogEx(NORMAL, " lf hid clone 2006ec0c86");
|
PrintAndLogEx(NORMAL, " lf hid clone 2006ec0c86");
|
||||||
PrintAndLogEx(NORMAL, " lf hid clone 2006ec0c86 L");
|
PrintAndLogEx(NORMAL, " lf hid clone l 2006ec0c86");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
static int usage_lf_hid_brute(void) {
|
static int usage_lf_hid_brute(void) {
|
||||||
|
@ -261,22 +261,41 @@ static int CmdHIDRead_device(const char *Cmd) {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
static int CmdHIDSim(const char *Cmd) {
|
static int CmdHIDSim(const char *Cmd) {
|
||||||
uint32_t hi = 0, lo = 0;
|
lf_hidsim_t payload;
|
||||||
|
payload.longFMT = 0;
|
||||||
|
uint32_t hi2 = 0, hi = 0, lo = 0;
|
||||||
uint32_t n = 0, i = 0;
|
uint32_t n = 0, i = 0;
|
||||||
|
|
||||||
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
|
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
|
||||||
if (strlen(Cmd) == 0 || ctmp == 'h') return usage_lf_hid_sim();
|
if (strlen(Cmd) == 0 || ctmp == 'h') return usage_lf_hid_sim();
|
||||||
|
|
||||||
while (sscanf(&Cmd[i++], "%1x", &n) == 1) {
|
if (strchr(Cmd, 'l') != 0) {
|
||||||
hi = (hi << 4) | (lo >> 28);
|
i++;
|
||||||
lo = (lo << 4) | (n & 0xf);
|
while (sscanf(&Cmd[i++], "%1x", &n) == 1) {
|
||||||
|
hi2 = (hi2 << 4) | (hi >> 28);
|
||||||
|
hi = (hi << 4) | (lo >> 28);
|
||||||
|
lo = (lo << 4) | (n & 0xf);
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, "Simulating HID tag with long ID %x%08x%08x", hi2, hi, lo);
|
||||||
|
payload.longFMT = 1;
|
||||||
|
} else {
|
||||||
|
while (sscanf(&Cmd[i++], "%1x", &n) == 1) {
|
||||||
|
hi = (hi << 4) | (lo >> 28);
|
||||||
|
lo = (lo << 4) | (n & 0xf);
|
||||||
|
}
|
||||||
|
PrintAndLogEx(SUCCESS, "Simulating HID tag with ID %x%08x", hi, lo);
|
||||||
|
hi2 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "Simulating HID tag with ID %x%08x", hi, lo);
|
|
||||||
PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation");
|
PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation");
|
||||||
|
|
||||||
|
payload.hi2 = hi2;
|
||||||
|
payload.hi = hi;
|
||||||
|
payload.lo = lo;
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandMIX(CMD_LF_HID_SIMULATE, hi, lo, 0, NULL, 0);
|
SendCommandNG(CMD_LF_HID_SIMULATE, (uint8_t *)&payload, sizeof(payload));
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
WaitForResponse(CMD_LF_HID_SIMULATE, &resp);
|
WaitForResponse(CMD_LF_HID_SIMULATE, &resp);
|
||||||
PrintAndLogEx(INFO, "Done");
|
PrintAndLogEx(INFO, "Done");
|
||||||
|
@ -294,6 +313,7 @@ static int CmdHIDClone(const char *Cmd) {
|
||||||
if (strlen(Cmd) == 0 || ctmp == 'H' || ctmp == 'h') return usage_lf_hid_clone();
|
if (strlen(Cmd) == 0 || ctmp == 'H' || ctmp == 'h') return usage_lf_hid_clone();
|
||||||
uint8_t longid[1] = {0};
|
uint8_t longid[1] = {0};
|
||||||
if (strchr(Cmd, 'l') != 0) {
|
if (strchr(Cmd, 'l') != 0) {
|
||||||
|
i++;
|
||||||
while (sscanf(&Cmd[i++], "%1x", &n) == 1) {
|
while (sscanf(&Cmd[i++], "%1x", &n) == 1) {
|
||||||
hi2 = (hi2 << 4) | (hi >> 28);
|
hi2 = (hi2 << 4) | (hi >> 28);
|
||||||
hi = (hi << 4) | (lo >> 28);
|
hi = (hi << 4) | (lo >> 28);
|
||||||
|
|
|
@ -245,7 +245,7 @@ static int CmdLFHitagList(const char *Cmd) {
|
||||||
|
|
||||||
if (f) {
|
if (f) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
PrintAndLogEx(NORMAL, "Recorded activity succesfully written to file: %s", filename);
|
PrintAndLogEx(NORMAL, "Recorded activity successfully written to file: %s", filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(got);
|
free(got);
|
||||||
|
|
|
@ -81,10 +81,25 @@ static int CmdNexWatchRead(const char *Cmd) {
|
||||||
return CmdNexWatchDemod(Cmd);
|
return CmdNexWatchDemod(Cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int CmdNexWatchClone(const char *Cmd) {
|
||||||
|
|
||||||
|
// should be able to clone the raw hex.
|
||||||
|
PrintAndLogEx(INFO, " To be implemented, feel free to contribute!");
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CmdNexWatchSim(const char *Cmd) {
|
||||||
|
PrintAndLogEx(INFO, " To be implemented, feel free to contribute!");
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static command_t CommandTable[] = {
|
static command_t CommandTable[] = {
|
||||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||||
{"demod", CmdNexWatchDemod, AlwaysAvailable, "Demodulate a NexWatch tag (nexkey, quadrakey) from the GraphBuffer"},
|
{"demod", CmdNexWatchDemod, AlwaysAvailable, "Demodulate a NexWatch tag (nexkey, quadrakey) from the GraphBuffer"},
|
||||||
{"read", CmdNexWatchRead, IfPm3Lf, "Attempt to Read and Extract tag data from the antenna"},
|
{"read", CmdNexWatchRead, IfPm3Lf, "Attempt to Read and Extract tag data from the antenna"},
|
||||||
|
{"clone", CmdNexWatchClone, IfPm3Lf, "clone NexWatch tag"},
|
||||||
|
{"sim", CmdNexWatchSim, IfPm3Lf, "simulate NexWatch tag"},
|
||||||
{NULL, NULL, NULL, NULL}
|
{NULL, NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,18 +9,6 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
#include "cmdlfnoralsy.h"
|
#include "cmdlfnoralsy.h"
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#include "cmdparser.h" // command_t
|
|
||||||
#include "comms.h"
|
|
||||||
#include "ui.h"
|
|
||||||
#include "cmddata.h"
|
|
||||||
#include "cmdlf.h"
|
|
||||||
#include "protocols.h" // for T55xx config register definitions
|
|
||||||
#include "lfdemod.h" // parityTest
|
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
static int usage_lf_noralsy_clone(void) {
|
static int usage_lf_noralsy_clone(void) {
|
||||||
|
@ -150,7 +138,7 @@ static int CmdNoralsyClone(const char *Cmd) {
|
||||||
year = param_get32ex(Cmd, 1, 2000, 10);
|
year = param_get32ex(Cmd, 1, 2000, 10);
|
||||||
|
|
||||||
//Q5
|
//Q5
|
||||||
if (param_getchar(Cmd, 2) == 'Q' || param_getchar(Cmd, 2) == 'q')
|
if (tolower(param_getchar(Cmd, 2) == 'q'))
|
||||||
blocks[0] = T5555_MODULATION_MANCHESTER | T5555_SET_BITRATE(32) | T5555_ST_TERMINATOR | 3 << T5555_MAXBLOCK_SHIFT;
|
blocks[0] = T5555_MODULATION_MANCHESTER | T5555_SET_BITRATE(32) | T5555_ST_TERMINATOR | 3 << T5555_MAXBLOCK_SHIFT;
|
||||||
|
|
||||||
if (getnoralsyBits(id, year, bits) != PM3_SUCCESS) {
|
if (getnoralsyBits(id, year, bits) != PM3_SUCCESS) {
|
||||||
|
@ -166,6 +154,7 @@ static int CmdNoralsyClone(const char *Cmd) {
|
||||||
PrintAndLogEx(INFO, "Preparing to clone Noralsy to T55x7 with CardId: %u", id);
|
PrintAndLogEx(INFO, "Preparing to clone Noralsy to T55x7 with CardId: %u", id);
|
||||||
print_blocks(blocks, 4);
|
print_blocks(blocks, 4);
|
||||||
|
|
||||||
|
uint8_t res = 0;
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
|
|
||||||
// fast push mode
|
// fast push mode
|
||||||
|
@ -187,7 +176,19 @@ static int CmdNoralsyClone(const char *Cmd) {
|
||||||
PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
|
PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// write block0, needs a detect.
|
||||||
|
if (i == 0)
|
||||||
|
t55xxAquireAndDetect(false, 0, blocks[i], false);
|
||||||
|
|
||||||
|
if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false)
|
||||||
|
res++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( res == 0 )
|
||||||
|
PrintAndLogEx(SUCCESS, "Success writing to tag");
|
||||||
|
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,19 @@
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "cmdparser.h" // command_t
|
||||||
|
#include "comms.h"
|
||||||
|
#include "ui.h"
|
||||||
|
#include "cmddata.h"
|
||||||
|
#include "cmdlf.h"
|
||||||
|
#include "protocols.h" // for T55xx config register definitions
|
||||||
|
#include "lfdemod.h" // parityTest
|
||||||
|
#include "cmdlft55xx.h" // verifywrite
|
||||||
|
|
||||||
int CmdLFNoralsy(const char *Cmd);
|
int CmdLFNoralsy(const char *Cmd);
|
||||||
|
|
||||||
int demodNoralsy(void);
|
int demodNoralsy(void);
|
||||||
|
|
|
@ -9,13 +9,6 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
#include "cmdlfpac.h"
|
#include "cmdlfpac.h"
|
||||||
|
|
||||||
#include "cmdparser.h" // command_t
|
|
||||||
#include "comms.h"
|
|
||||||
#include "ui.h"
|
|
||||||
#include "cmddata.h"
|
|
||||||
#include "cmdlf.h"
|
|
||||||
#include "lfdemod.h" // preamble test
|
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
//see NRZDemod for what args are accepted
|
//see NRZDemod for what args are accepted
|
||||||
|
@ -63,10 +56,25 @@ static int CmdPacRead(const char *Cmd) {
|
||||||
return CmdPacDemod(Cmd);
|
return CmdPacDemod(Cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int CmdPacClone(const char *Cmd) {
|
||||||
|
// possible to raw hex and clone
|
||||||
|
PrintAndLogEx(INFO, " To be implemented, feel free to contribute!");
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CmdPacSim(const char *Cmd) {
|
||||||
|
|
||||||
|
// NRZ sim.
|
||||||
|
PrintAndLogEx(INFO, " To be implemented, feel free to contribute!");
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static command_t CommandTable[] = {
|
static command_t CommandTable[] = {
|
||||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||||
{"demod", CmdPacDemod, AlwaysAvailable, "Demodulate an PAC tag from the GraphBuffer"},
|
{"demod", CmdPacDemod, AlwaysAvailable, "Demodulate an PAC tag from the GraphBuffer"},
|
||||||
{"read", CmdPacRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"},
|
{"read", CmdPacRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"},
|
||||||
|
{"clone", CmdPacClone, IfPm3Lf, "clone PAC tag"},
|
||||||
|
{"sim", CmdPacSim, IfPm3Lf, "simulate PAC tag"},
|
||||||
{NULL, NULL, NULL, NULL}
|
{NULL, NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,12 @@
|
||||||
#define CMDLFPAC_H__
|
#define CMDLFPAC_H__
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "cmdparser.h" // command_t
|
||||||
|
#include "comms.h"
|
||||||
|
#include "ui.h"
|
||||||
|
#include "cmddata.h"
|
||||||
|
#include "cmdlf.h"
|
||||||
|
#include "lfdemod.h" // preamble test
|
||||||
|
|
||||||
int CmdLFPac(const char *Cmd);
|
int CmdLFPac(const char *Cmd);
|
||||||
|
|
||||||
|
|
|
@ -112,6 +112,10 @@ static int CmdParadoxRead(const char *Cmd) {
|
||||||
return CmdParadoxDemod(Cmd);
|
return CmdParadoxDemod(Cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int CmdParadoxClone(const char *Cmd) {
|
||||||
|
PrintAndLogEx(INFO, " To be implemented, feel free to contribute!");
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static int CmdParadoxSim(const char *Cmd) {
|
static int CmdParadoxSim(const char *Cmd) {
|
||||||
PrintAndLogEx(INFO, " To be implemented, feel free to contribute!");
|
PrintAndLogEx(INFO, " To be implemented, feel free to contribute!");
|
||||||
|
@ -165,7 +169,7 @@ static command_t CommandTable[] = {
|
||||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||||
{"demod", CmdParadoxDemod, AlwaysAvailable, "Demodulate a Paradox FSK tag from the GraphBuffer"},
|
{"demod", CmdParadoxDemod, AlwaysAvailable, "Demodulate a Paradox FSK tag from the GraphBuffer"},
|
||||||
{"read", CmdParadoxRead, IfPm3Lf, "Attempt to read and Extract tag data from the antenna"},
|
{"read", CmdParadoxRead, IfPm3Lf, "Attempt to read and Extract tag data from the antenna"},
|
||||||
// {"clone", CmdParadoxClone, IfPm3Lf, "clone paradox tag"},
|
{"clone", CmdParadoxClone, IfPm3Lf, "clone paradox tag"},
|
||||||
{"sim", CmdParadoxSim, IfPm3Lf, "simulate paradox tag"},
|
{"sim", CmdParadoxSim, IfPm3Lf, "simulate paradox tag"},
|
||||||
{NULL, NULL, NULL, NULL}
|
{NULL, NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,19 +9,6 @@
|
||||||
|
|
||||||
#include "cmdlfpresco.h"
|
#include "cmdlfpresco.h"
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#include "cmdparser.h" // command_t
|
|
||||||
#include "comms.h"
|
|
||||||
#include "ui.h"
|
|
||||||
#include "cmddata.h"
|
|
||||||
#include "cmdlf.h"
|
|
||||||
#include "protocols.h" // for T55xx config register definitions
|
|
||||||
#include "lfdemod.h" // parityTest
|
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
static int usage_lf_presco_clone(void) {
|
static int usage_lf_presco_clone(void) {
|
||||||
|
@ -134,6 +121,7 @@ static int CmdPrescoClone(const char *Cmd) {
|
||||||
PrintAndLogEx(INFO, "Preparing to clone Presco to T55x7 with SiteCode: %u, UserCode: %u, FullCode: %08x", sitecode, usercode, fullcode);
|
PrintAndLogEx(INFO, "Preparing to clone Presco to T55x7 with SiteCode: %u, UserCode: %u, FullCode: %08x", sitecode, usercode, fullcode);
|
||||||
print_blocks(blocks, 5);
|
print_blocks(blocks, 5);
|
||||||
|
|
||||||
|
uint8_t res = 0;
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
|
|
||||||
// fast push mode
|
// fast push mode
|
||||||
|
@ -155,7 +143,22 @@ static int CmdPrescoClone(const char *Cmd) {
|
||||||
PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
|
PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// write block0, needs a detect.
|
||||||
|
if (i == 0) {
|
||||||
|
printf("enter detect ");
|
||||||
|
bool ok = t55xxAquireAndDetect(false, 0, blocks[i], false);
|
||||||
|
printf(" b0 = '%c' \n", (ok) ? 'Y':'N');
|
||||||
|
}
|
||||||
|
if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) {
|
||||||
|
res++;
|
||||||
|
printf(" i = %d \n", i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( res == 0 )
|
||||||
|
PrintAndLogEx(SUCCESS, "Success writing to tag");
|
||||||
|
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,20 @@
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "cmdparser.h" // command_t
|
||||||
|
#include "comms.h"
|
||||||
|
#include "ui.h"
|
||||||
|
#include "cmddata.h"
|
||||||
|
#include "cmdlf.h"
|
||||||
|
#include "protocols.h" // for T55xx config register definitions
|
||||||
|
#include "lfdemod.h" // parityTest
|
||||||
|
#include "cmdlft55xx.h" // verifywrite
|
||||||
|
|
||||||
int CmdLFPresco(const char *Cmd);
|
int CmdLFPresco(const char *Cmd);
|
||||||
|
|
||||||
int demodPresco(void);
|
int demodPresco(void);
|
||||||
|
|
|
@ -9,21 +9,6 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
#include "cmdlfpyramid.h"
|
#include "cmdlfpyramid.h"
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#include "cmdparser.h" // command_t
|
|
||||||
#include "comms.h"
|
|
||||||
#include "ui.h"
|
|
||||||
#include "graph.h"
|
|
||||||
#include "cmddata.h"
|
|
||||||
#include "cmdlf.h"
|
|
||||||
#include "protocols.h" // for T55xx config register definitions
|
|
||||||
#include "lfdemod.h" // parityTest
|
|
||||||
#include "crc.h"
|
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
static int usage_lf_pyramid_clone(void) {
|
static int usage_lf_pyramid_clone(void) {
|
||||||
|
@ -246,11 +231,12 @@ static int CmdPyramidClone(const char *Cmd) {
|
||||||
PrintAndLogEx(INFO, "Preparing to clone Farpointe/Pyramid to T55x7 with Facility Code: %u, Card Number: %u", facilitycode, cardnumber);
|
PrintAndLogEx(INFO, "Preparing to clone Farpointe/Pyramid to T55x7 with Facility Code: %u, Card Number: %u", facilitycode, cardnumber);
|
||||||
print_blocks(blocks, 5);
|
print_blocks(blocks, 5);
|
||||||
|
|
||||||
|
uint8_t res = 0;
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
|
|
||||||
// fast push mode
|
// fast push mode
|
||||||
conn.block_after_ACK = true;
|
conn.block_after_ACK = true;
|
||||||
for (uint8_t i = 0; i < 5; i++) {
|
for (int8_t i = 0; i < 5; i++) {
|
||||||
if (i == 4) {
|
if (i == 4) {
|
||||||
// Disable fast mode on last packet
|
// Disable fast mode on last packet
|
||||||
conn.block_after_ACK = false;
|
conn.block_after_ACK = false;
|
||||||
|
@ -267,7 +253,19 @@ static int CmdPyramidClone(const char *Cmd) {
|
||||||
PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
|
PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// write block0, needs a detect.
|
||||||
|
if (i == 0)
|
||||||
|
t55xxAquireAndDetect(false, 0, blocks[i], false);
|
||||||
|
|
||||||
|
if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false)
|
||||||
|
res++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( res == 0 )
|
||||||
|
PrintAndLogEx(SUCCESS, "Success writing to tag");
|
||||||
|
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,21 @@
|
||||||
#define CMDLFPYRAMID_H__
|
#define CMDLFPYRAMID_H__
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "cmdparser.h" // command_t
|
||||||
|
#include "comms.h"
|
||||||
|
#include "ui.h"
|
||||||
|
#include "graph.h"
|
||||||
|
#include "cmddata.h"
|
||||||
|
#include "cmdlf.h"
|
||||||
|
#include "protocols.h" // for T55xx config register definitions
|
||||||
|
#include "lfdemod.h" // parityTest
|
||||||
|
#include "crc.h"
|
||||||
|
#include "cmdlft55xx.h" // verifywrite
|
||||||
|
|
||||||
int CmdLFPyramid(const char *Cmd);
|
int CmdLFPyramid(const char *Cmd);
|
||||||
|
|
||||||
|
|
|
@ -111,12 +111,22 @@ static int CmdSecurakeyRead(const char *Cmd) {
|
||||||
return CmdSecurakeyDemod(Cmd);
|
return CmdSecurakeyDemod(Cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int CmdSecurakeyClone(const char *Cmd) {
|
||||||
|
PrintAndLogEx(INFO, " To be implemented, feel free to contribute!");
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CmdSecurakeySim(const char *Cmd) {
|
||||||
|
PrintAndLogEx(INFO, " To be implemented, feel free to contribute!");
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static command_t CommandTable[] = {
|
static command_t CommandTable[] = {
|
||||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||||
{"demod", CmdSecurakeyDemod, AlwaysAvailable, "Demodulate an Securakey tag from the GraphBuffer"},
|
{"demod", CmdSecurakeyDemod, AlwaysAvailable, "Demodulate an Securakey tag from the GraphBuffer"},
|
||||||
{"read", CmdSecurakeyRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"},
|
{"read", CmdSecurakeyRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"},
|
||||||
//{"clone", CmdSecurakeyClone, IfPm3Lf, "clone Securakey tag"},
|
{"clone", CmdSecurakeyClone, IfPm3Lf, "clone Securakey tag"},
|
||||||
//{"sim", CmdSecurakeydSim, IfPm3Lf, "simulate Securakey tag"},
|
{"sim", CmdSecurakeySim, IfPm3Lf, "simulate Securakey tag"},
|
||||||
{NULL, NULL, NULL, NULL}
|
{NULL, NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,6 @@ static int usage_t55xx_config() {
|
||||||
PrintAndLogEx(NORMAL, " ST [0/1] - Set/reset Sequence Terminator on");
|
PrintAndLogEx(NORMAL, " ST [0/1] - Set/reset Sequence Terminator on");
|
||||||
PrintAndLogEx(NORMAL, ""); // layout is a little differnet, so seperate until a better fix
|
PrintAndLogEx(NORMAL, ""); // layout is a little differnet, so seperate until a better fix
|
||||||
print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE);
|
print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE);
|
||||||
PrintAndLogEx(NORMAL, "fix this code....");
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(NORMAL, "Examples:");
|
PrintAndLogEx(NORMAL, "Examples:");
|
||||||
PrintAndLogEx(NORMAL, " lf t55xx config d FSK - FSK demodulation");
|
PrintAndLogEx(NORMAL, " lf t55xx config d FSK - FSK demodulation");
|
||||||
|
@ -97,7 +96,7 @@ static int usage_t55xx_config() {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
static int usage_t55xx_read() {
|
static int usage_t55xx_read() {
|
||||||
PrintAndLogEx(NORMAL, "Usage: lf t55xx read [r <mode>] b <block> [p <password>] <override_safety> <page1>");
|
PrintAndLogEx(NORMAL, "Usage: lf t55xx read [r <mode>] b <block> [p <password>] [o] <page1>");
|
||||||
PrintAndLogEx(NORMAL, "Options:");
|
PrintAndLogEx(NORMAL, "Options:");
|
||||||
PrintAndLogEx(NORMAL, " b <block> - block number to read. Between 0-7");
|
PrintAndLogEx(NORMAL, " b <block> - block number to read. Between 0-7");
|
||||||
PrintAndLogEx(NORMAL, " p <password> - OPTIONAL password (8 hex characters)");
|
PrintAndLogEx(NORMAL, " p <password> - OPTIONAL password (8 hex characters)");
|
||||||
|
@ -271,33 +270,36 @@ static int usage_t55xx_recoverpw() {
|
||||||
PrintAndLogEx(NORMAL, "press " _YELLOW_("'enter'") " to cancel the command");
|
PrintAndLogEx(NORMAL, "press " _YELLOW_("'enter'") " to cancel the command");
|
||||||
PrintAndLogEx(NORMAL, "WARNING: this may brick non-password protected chips!");
|
PrintAndLogEx(NORMAL, "WARNING: this may brick non-password protected chips!");
|
||||||
PrintAndLogEx(NORMAL, "Try reading block 7 before\n");
|
PrintAndLogEx(NORMAL, "Try reading block 7 before\n");
|
||||||
PrintAndLogEx(NORMAL, "Usage: lf t55xx recoverpw [r <mode>] [p password]");
|
PrintAndLogEx(NORMAL, "Usage: lf t55xx recoverpw [r <mode>] [p <password>]");
|
||||||
PrintAndLogEx(NORMAL, " password must be 4 bytes (8 hex symbols)");
|
PrintAndLogEx(NORMAL, " password must be 4 bytes (8 hex symbols)");
|
||||||
PrintAndLogEx(NORMAL, " default password is 51243648, used by many cloners");
|
PrintAndLogEx(NORMAL, " default password is 51243648, used by many cloners");
|
||||||
PrintAndLogEx(NORMAL, "Options:");
|
PrintAndLogEx(NORMAL, "Options:");
|
||||||
PrintAndLogEx(NORMAL, " h - this help");
|
PrintAndLogEx(NORMAL, " h - this help");
|
||||||
print_usage_t55xx_downloadlink(T55XX_DLMODE_ALL);
|
print_usage_t55xx_downloadlink(T55XX_DLMODE_ALL);
|
||||||
PrintAndLogEx(NORMAL, " [password] - 4 byte hex value of password written by cloner");
|
PrintAndLogEx(NORMAL, " p <password> - 4 byte hex value of password written by cloner");
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(NORMAL, "Examples:");
|
PrintAndLogEx(NORMAL, "Examples:");
|
||||||
PrintAndLogEx(NORMAL, " lf t55xx recoverpw");
|
PrintAndLogEx(NORMAL, " lf t55xx recoverpw");
|
||||||
|
PrintAndLogEx(NORMAL, " lf t55xx recoverpw p 51243648");
|
||||||
PrintAndLogEx(NORMAL, " lf t55xx recoverpw r 3 p 51243648");
|
PrintAndLogEx(NORMAL, " lf t55xx recoverpw r 3 p 51243648");
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
static int usage_t55xx_wipe() {
|
static int usage_t55xx_wipe() {
|
||||||
PrintAndLogEx(NORMAL, "Usage: lf t55xx wipe [h] [Q5] [p <password>]");
|
PrintAndLogEx(NORMAL, "Usage: lf t55xx wipe [h] [Q5] [p <password>] [c <blk0>]");
|
||||||
PrintAndLogEx(NORMAL, "This commands wipes a tag, fills blocks 1-7 with zeros and a default configuration block");
|
PrintAndLogEx(NORMAL, "This commands wipes a tag, fills blocks 1-7 with zeros and a default configuration block");
|
||||||
PrintAndLogEx(NORMAL, "Options:");
|
PrintAndLogEx(NORMAL, "Options:");
|
||||||
PrintAndLogEx(NORMAL, " h - this help");
|
PrintAndLogEx(NORMAL, " h - this help");
|
||||||
PrintAndLogEx(NORMAL, " q - indicates to use the T5555 (Q5) default configuration block");
|
PrintAndLogEx(NORMAL, " c <block0> - set configuration from a block0");
|
||||||
|
PrintAndLogEx(NORMAL, " q - indicates to use the T5555 (Q5) default configuration block");
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(NORMAL, "Examples:");
|
PrintAndLogEx(NORMAL, "Examples:");
|
||||||
PrintAndLogEx(NORMAL, " lf t55xx wipe - wipes a t55x7 tag, config block 0x000880E0");
|
PrintAndLogEx(NORMAL, " lf t55xx wipe - wipes a t55x7 tag, config block 0x000880E0");
|
||||||
PrintAndLogEx(NORMAL, " lf t55xx wipe q - wipes a t5555 Q5 tag, config block 0x6001F004");
|
PrintAndLogEx(NORMAL, " lf t55xx wipe q - wipes a t5555 Q5 tag, config block 0x6001F004");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
static int usage_lf_deviceconfig() {
|
static int usage_t55xx_deviceconfig() {
|
||||||
PrintAndLogEx(NORMAL, "Sets t55x7 timings for direct commands. The timings are set here in Field Clocks (FC), \nwhich is converted to (US) on device");
|
PrintAndLogEx(NORMAL, "Sets t55x7 timings for direct commands. The timings are set here in Field Clocks (FC), \nwhich is converted to (US) on device");
|
||||||
PrintAndLogEx(NORMAL, "Usage: lf t55xx deviceconfig [r <mode>] a <gap> b <gap> c <gap> d <gap> e <gap> f <gap> g <gap> [p]");
|
PrintAndLogEx(NORMAL, "Usage: lf t55xx deviceconfig [r <mode>] a <gap> b <gap> c <gap> d <gap> e <gap> f <gap> g <gap> [p]");
|
||||||
PrintAndLogEx(NORMAL, "Options:");
|
PrintAndLogEx(NORMAL, "Options:");
|
||||||
|
@ -310,7 +312,6 @@ static int usage_lf_deviceconfig() {
|
||||||
PrintAndLogEx(NORMAL, " f <8..255> - Set write TWO gap (1 of 4 only)");
|
PrintAndLogEx(NORMAL, " f <8..255> - Set write TWO gap (1 of 4 only)");
|
||||||
PrintAndLogEx(NORMAL, " g <8..255> - Set write THREE gap (1 of 4 only)");
|
PrintAndLogEx(NORMAL, " g <8..255> - Set write THREE gap (1 of 4 only)");
|
||||||
PrintAndLogEx(NORMAL, " p - persist to flashmemory");
|
PrintAndLogEx(NORMAL, " p - persist to flashmemory");
|
||||||
// print_usage_t55xx_downloadlink(); // does not apply to config
|
|
||||||
PrintAndLogEx(NORMAL, " z - Set default t55x7 timings (use p to save if required)");
|
PrintAndLogEx(NORMAL, " z - Set default t55x7 timings (use p to save if required)");
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(NORMAL, "Examples:");
|
PrintAndLogEx(NORMAL, "Examples:");
|
||||||
|
@ -319,55 +320,175 @@ static int usage_lf_deviceconfig() {
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
static int usage_t55xx_protect() {
|
||||||
|
PrintAndLogEx(NORMAL, "This command set or unsets the pwd bit on T5577.");
|
||||||
|
PrintAndLogEx(NORMAL, "Usage: lf t55xx protect [r <mode>] [p <password>] [o] [n <new_password>]");
|
||||||
|
PrintAndLogEx(NORMAL, "Options:");
|
||||||
|
PrintAndLogEx(NORMAL, " p <password> - OPTIONAL password (8 hex characters)");
|
||||||
|
PrintAndLogEx(NORMAL, " o - OPTIONAL override safety check");
|
||||||
|
PrintAndLogEx(NORMAL, " n <new password> - new password");
|
||||||
|
print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE);
|
||||||
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
PrintAndLogEx(NORMAL, "Examples:");
|
||||||
|
PrintAndLogEx(NORMAL, " lf t55xx protect n 01020304 - sets new password to 01020304");
|
||||||
|
PrintAndLogEx(NORMAL, " lf t55xx protect p 11223344 - use pwd 11223344 to set newpwd to 00000000");
|
||||||
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
static bool t55xxVerifyWrite( uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, uint32_t data) {
|
static bool t55xxProtect(bool lock, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, uint32_t new_password ) {
|
||||||
|
|
||||||
//Password mode
|
|
||||||
if (usepwd) {
|
|
||||||
// try reading the config block and verify that PWD bit is set before doing this!
|
|
||||||
if (override == 0) {
|
|
||||||
if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0, downlink_mode) == false)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (tryDetectModulation(downlink_mode,T55XX_DontPrintConfig) == false) {
|
PrintAndLogEx(INFO, "Checking current configuration");
|
||||||
PrintAndLogEx(NORMAL, "Safety Check: Could not detect if PWD bit is set in config block. Exits.");
|
|
||||||
return false;
|
bool testmode = false;
|
||||||
} else {
|
uint32_t block0 = 0;
|
||||||
PrintAndLogEx(NORMAL, "Safety Check: PWD bit is NOT set in config block. Reading without password...");
|
|
||||||
usepwd = false;
|
int res = T55xxReadBlockEx(T55x7_CONFIGURATION_BLOCK, T55x7_PAGE0, usepwd, override, password, downlink_mode, false);
|
||||||
}
|
if (res != PM3_SUCCESS) {
|
||||||
} else if (override == 1) {
|
PrintAndLogEx(WARNING, "Failed to read block0, use `p` password parameter?");
|
||||||
PrintAndLogEx(NORMAL, "Safety Check Overriden - proceeding despite risk");
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AquireData(page1, block, usepwd, password, downlink_mode) == false)
|
if (GetT55xxBlockData(&block0) == false)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (block == 0 && page1 == false) {
|
bool isPwdBitAlreadySet = (block0 >> (32-28) & 1);
|
||||||
if (tryDetectModulation(downlink_mode,T55XX_DontPrintConfig) == false) {
|
if (isPwdBitAlreadySet) {
|
||||||
PrintAndLogEx(WARNING, "Could not detect modulation automatically. Try setting it manually with \'lf t55xx config\'");
|
PrintAndLogEx(INFO, "PWD bit is already set");
|
||||||
return false;
|
usepwd = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set / clear pwd bit
|
||||||
|
if (lock) {
|
||||||
|
block0 |= 1 << 4;
|
||||||
|
} else {
|
||||||
|
block0 &= ~(1 << 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// write new password
|
||||||
|
if ( t55xxWrite(T55x7_PWD_BLOCK, T55x7_PAGE0, usepwd, testmode, password, downlink_mode, new_password ) != PM3_SUCCESS ) {
|
||||||
|
PrintAndLogEx(ERR, "Failed to write new password");
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(SUCCESS, "Wrote new password");
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate new password
|
||||||
|
uint32_t curr_password = (isPwdBitAlreadySet) ? new_password : password;
|
||||||
|
|
||||||
|
if (t55xxVerifyWrite(T55x7_PWD_BLOCK, T55x7_PAGE0, usepwd, override, curr_password, downlink_mode, new_password) == false) {
|
||||||
|
PrintAndLogEx(WARNING, "Failed to validate the password write. aborting.");
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(SUCCESS, "Validated new password");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DecodeT55xxBlock() == false)
|
// write config
|
||||||
|
if ( t55xxWrite(T55x7_CONFIGURATION_BLOCK, T55x7_PAGE0, usepwd, testmode, curr_password, downlink_mode, block0 ) != PM3_SUCCESS ) {
|
||||||
|
PrintAndLogEx(ERR, "Failed to write modified configuration block %08X", block0);
|
||||||
return false;
|
return false;
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(SUCCESS, "Wrote modified configuration block");
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate new config. If all went well, card should now demand pwd, hence override = 0.
|
||||||
|
override = 0;
|
||||||
|
if (t55xxVerifyWrite(T55x7_CONFIGURATION_BLOCK, T55x7_PAGE0, true, override, new_password, downlink_mode, block0) == false) {
|
||||||
|
PrintAndLogEx(WARNING, "Failed to validate pwd bit set on configuration block. aborting.");
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(SUCCESS, "New configuration block " _YELLOW_("%08X")"password " _YELLOW_("%08X"), block0, new_password);
|
||||||
|
PrintAndLogEx(SUCCESS, "Success, tag is locked");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// compare...
|
bool t55xxAquireAndDetect(bool usepwd, uint32_t password, uint32_t known_block0, bool verbose) {
|
||||||
uint32_t readblock = 0;
|
|
||||||
if (GetT55xxBlockData(&readblock) == false)
|
if (verbose)
|
||||||
return false;
|
PrintAndLogEx(INFO, "Block0 write detected, running `detect` to see if validation is possible");
|
||||||
|
|
||||||
return (readblock == data);
|
for ( uint8_t m = 0; m < 4; m++) {
|
||||||
|
if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, m) == false)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (tryDetectModulationEx(m, verbose, known_block0) == false)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool t55xxVerifyWrite(uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, uint32_t data) {
|
||||||
|
|
||||||
|
uint32_t read_data = 0;
|
||||||
|
|
||||||
|
if (downlink_mode == 0xFF)
|
||||||
|
downlink_mode = config.downlink_mode;
|
||||||
|
|
||||||
|
int res = T55xxReadBlockEx(block, page1, usepwd, override, password, downlink_mode, false);
|
||||||
|
if (res == PM3_SUCCESS) {
|
||||||
|
|
||||||
|
if (GetT55xxBlockData(&read_data) == false)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
} else if ( res == PM3_EWRONGANSVER) {
|
||||||
|
|
||||||
|
// could't decode. Lets see if this was a block 0 write and try read/detect it auto.
|
||||||
|
// this messes up with ppls config..
|
||||||
|
if (block == 0 && page1 == false) {
|
||||||
|
|
||||||
|
if (t55xxAquireAndDetect(usepwd, password, data, true) == false)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return t55xxVerifyWrite(block, page1, usepwd, 2, password, config.downlink_mode, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (read_data == data);
|
||||||
|
}
|
||||||
|
|
||||||
|
int t55xxWrite(uint8_t block, bool page1, bool usepwd, bool testMode, uint32_t password, uint8_t downlink_mode, uint32_t data) {
|
||||||
|
|
||||||
|
uint8_t flags;
|
||||||
|
flags = (usepwd) ? 0x1 : 0;
|
||||||
|
flags |= (page1) ? 0x2 : 0;
|
||||||
|
flags |= (testMode) ? 0x4 : 0;
|
||||||
|
flags |= (downlink_mode << 3);
|
||||||
|
|
||||||
|
/*
|
||||||
|
OLD style
|
||||||
|
arg0 = data, (4 bytes)
|
||||||
|
arg1 = block (1 byte)
|
||||||
|
arg2 = password (4 bytes)
|
||||||
|
flags = data[0] (1 byte)
|
||||||
|
|
||||||
|
new style
|
||||||
|
uses struct in pm3_cmd.h
|
||||||
|
*/
|
||||||
|
t55xx_write_block_t ng;
|
||||||
|
ng.data = data;
|
||||||
|
ng.pwd = password;
|
||||||
|
ng.blockno = block;
|
||||||
|
ng.flags = flags;
|
||||||
|
|
||||||
|
PacketResponseNG resp;
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng));
|
||||||
|
if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, 2000)) {
|
||||||
|
PrintAndLogEx(ERR, "Error occurred, device did not ACK write operation.");
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
|
return resp.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
void printT5xxHeader(uint8_t page) {
|
void printT5xxHeader(uint8_t page) {
|
||||||
PrintAndLogEx(NORMAL, "Reading Page %d:", page);
|
PrintAndLogEx(SUCCESS, "Reading Page %d:", page);
|
||||||
PrintAndLogEx(NORMAL, "blk | hex data | binary | ascii");
|
PrintAndLogEx(SUCCESS, "blk | hex data | binary | ascii");
|
||||||
PrintAndLogEx(NORMAL, "----+----------+----------------------------------+-------");
|
PrintAndLogEx(SUCCESS, "----+----------+----------------------------------+-------");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CmdT55xxSetConfig(const char *Cmd) {
|
static int CmdT55xxSetConfig(const char *Cmd) {
|
||||||
|
@ -481,7 +602,7 @@ static int CmdT55xxSetConfig(const char *Cmd) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
errors = param_getdec(Cmd, cmdp + 1,&downlink_mode);
|
errors = param_getdec(Cmd, cmdp + 1, &downlink_mode);
|
||||||
if (downlink_mode > 3)
|
if (downlink_mode > 3)
|
||||||
downlink_mode = 0;
|
downlink_mode = 0;
|
||||||
if (!errors)
|
if (!errors)
|
||||||
|
@ -530,35 +651,42 @@ static int CmdT55xxSetConfig(const char *Cmd) {
|
||||||
|
|
||||||
return printConfiguration(config);
|
return printConfiguration(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode) {
|
int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode) {
|
||||||
|
return T55xxReadBlockEx(block, page1, usepwd, override, password, downlink_mode, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
int T55xxReadBlockEx(uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, bool verbose) {
|
||||||
//Password mode
|
//Password mode
|
||||||
if (usepwd) {
|
if (usepwd) {
|
||||||
// try reading the config block and verify that PWD bit is set before doing this!
|
// try reading the config block and verify that PWD bit is set before doing this!
|
||||||
|
// override = 1 (override and display)
|
||||||
|
// override = 2 (override and no display)
|
||||||
if (override == 0) {
|
if (override == 0) {
|
||||||
if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0, downlink_mode)) return PM3_ESOFT;
|
if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0, downlink_mode) == false)
|
||||||
|
return PM3_ERFTRANS;
|
||||||
|
|
||||||
if (!tryDetectModulation(downlink_mode,T55XX_DontPrintConfig)) {
|
if (tryDetectModulation(downlink_mode, false) == false) {
|
||||||
PrintAndLogEx(NORMAL, "Safety Check: Could not detect if PWD bit is set in config block. Exits.");
|
PrintAndLogEx(WARNING, "Safety check: Could not detect if PWD bit is set in config block. Exits.");
|
||||||
return PM3_ESOFT;
|
return PM3_EWRONGANSVER;
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(NORMAL, "Safety Check: PWD bit is NOT set in config block. Reading without password...");
|
PrintAndLogEx(WARNING, "Safety check: PWD bit is NOT set in config block. Reading without password...");
|
||||||
usepwd = false;
|
usepwd = false;
|
||||||
page1 = false; // ??
|
page1 = false; // ??
|
||||||
}
|
}
|
||||||
} else if (override == 1) {
|
} else if (override == 1) {
|
||||||
// Show only if first for command i.e. override = 1 (override and display) override = 2 (override and dont display)
|
PrintAndLogEx(INFO, "Safety check overridden - proceeding despite risk");
|
||||||
PrintAndLogEx(NORMAL, "Safety Check Overriden - proceeding despite risk");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!AquireData(page1, block, usepwd, password, downlink_mode))
|
if (AquireData(page1, block, usepwd, password, downlink_mode) == false)
|
||||||
return PM3_ESOFT;
|
return PM3_ERFTRANS;
|
||||||
|
|
||||||
if (!DecodeT55xxBlock())
|
if (DecodeT55xxBlock() == false)
|
||||||
return PM3_ESOFT;
|
return PM3_EWRONGANSVER;
|
||||||
|
|
||||||
|
if (verbose)
|
||||||
|
printT55xxBlock(block);
|
||||||
|
|
||||||
printT55xxBlock(block);
|
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -730,7 +858,6 @@ static int CmdT55xxDetect(const char *Cmd) {
|
||||||
uint32_t password = 0;
|
uint32_t password = 0;
|
||||||
uint8_t cmdp = 0;
|
uint8_t cmdp = 0;
|
||||||
uint8_t downlink_mode = 0;
|
uint8_t downlink_mode = 0;
|
||||||
uint8_t dl_mode = 0;
|
|
||||||
|
|
||||||
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||||
switch (tolower(param_getchar(Cmd, cmdp))) {
|
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||||
|
@ -765,22 +892,31 @@ static int CmdT55xxDetect(const char *Cmd) {
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
|
|
||||||
if (useGB == false) {
|
if (useGB == false) {
|
||||||
for (dl_mode = downlink_mode; dl_mode < 4; dl_mode++) {
|
|
||||||
found = AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, dl_mode);
|
if ( try_all_dl_modes ) {
|
||||||
|
|
||||||
|
for (uint8_t m = downlink_mode; m < 4; m++) {
|
||||||
|
if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, m) == false)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (tryDetectModulation(m, T55XX_PrintConfig) == false)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (tryDetectModulation(dl_mode,T55XX_PrintConfig)) {
|
|
||||||
dl_mode = 4;
|
|
||||||
found = true;
|
found = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else found = false;
|
} else {
|
||||||
|
|
||||||
if (!try_all_dl_modes) dl_mode = 4;
|
if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, downlink_mode)) {
|
||||||
|
found = tryDetectModulation(downlink_mode, T55XX_PrintConfig);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
found = tryDetectModulation(downlink_mode,T55XX_PrintConfig);
|
found = tryDetectModulation(downlink_mode, T55XX_PrintConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found)
|
if (found == false)
|
||||||
PrintAndLogEx(WARNING, "Could not detect modulation automatically. Try setting it manually with " _YELLOW_("\'lf t55xx config\'"));
|
PrintAndLogEx(WARNING, "Could not detect modulation automatically. Try setting it manually with " _YELLOW_("\'lf t55xx config\'"));
|
||||||
|
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
|
@ -788,6 +924,10 @@ static int CmdT55xxDetect(const char *Cmd) {
|
||||||
|
|
||||||
// detect configuration?
|
// detect configuration?
|
||||||
bool tryDetectModulation(uint8_t downlink_mode, bool print_config) {
|
bool tryDetectModulation(uint8_t downlink_mode, bool print_config) {
|
||||||
|
return tryDetectModulationEx(downlink_mode, print_config, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tryDetectModulationEx(uint8_t downlink_mode, bool print_config, uint32_t wanted_conf) {
|
||||||
|
|
||||||
t55xx_conf_block_t tests[15];
|
t55xx_conf_block_t tests[15];
|
||||||
int bitRate = 0, clk = 0, firstClockEdge = 0;
|
int bitRate = 0, clk = 0, firstClockEdge = 0;
|
||||||
|
@ -959,7 +1099,10 @@ bool tryDetectModulation(uint8_t downlink_mode, bool print_config) {
|
||||||
config.Q5 = tests[0].Q5;
|
config.Q5 = tests[0].Q5;
|
||||||
config.ST = tests[0].ST;
|
config.ST = tests[0].ST;
|
||||||
config.downlink_mode = downlink_mode;
|
config.downlink_mode = downlink_mode;
|
||||||
if (print_config) printConfiguration(config);
|
|
||||||
|
if (print_config)
|
||||||
|
printConfiguration(config);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -967,8 +1110,13 @@ bool tryDetectModulation(uint8_t downlink_mode, bool print_config) {
|
||||||
if (hits > 1) {
|
if (hits > 1) {
|
||||||
PrintAndLogEx(SUCCESS, "Found [%d] possible matches for modulation.", hits);
|
PrintAndLogEx(SUCCESS, "Found [%d] possible matches for modulation.", hits);
|
||||||
for (int i = 0; i < hits; ++i) {
|
for (int i = 0; i < hits; ++i) {
|
||||||
|
|
||||||
|
bool wanted = false;
|
||||||
|
if (wanted_conf > 0)
|
||||||
|
wanted = (wanted_conf == tests[i].block0);
|
||||||
|
|
||||||
retval = testKnownConfigBlock(tests[i].block0);
|
retval = testKnownConfigBlock(tests[i].block0);
|
||||||
if (retval) {
|
if (retval || wanted ) {
|
||||||
PrintAndLogEx(NORMAL, "--[%d]--------------- << selected this", i + 1);
|
PrintAndLogEx(NORMAL, "--[%d]--------------- << selected this", i + 1);
|
||||||
config.modulation = tests[i].modulation;
|
config.modulation = tests[i].modulation;
|
||||||
config.bitrate = tests[i].bitrate;
|
config.bitrate = tests[i].bitrate;
|
||||||
|
@ -981,7 +1129,9 @@ bool tryDetectModulation(uint8_t downlink_mode, bool print_config) {
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(NORMAL, "--[%d]---------------", i + 1);
|
PrintAndLogEx(NORMAL, "--[%d]---------------", i + 1);
|
||||||
}
|
}
|
||||||
if (print_config) printConfiguration(tests[i]);
|
|
||||||
|
if (print_config)
|
||||||
|
printConfiguration(tests[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
|
@ -1035,7 +1185,7 @@ void printT55xxBlock(uint8_t blockNum) {
|
||||||
|
|
||||||
num_to_bytes(blockData, 4, bytes);
|
num_to_bytes(blockData, 4, bytes);
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, " %02d | %08X | %s | %s", blockNum, blockData, sprint_bin(DemodBuffer + config.offset, 32), sprint_ascii(bytes, 4));
|
PrintAndLogEx(SUCCESS, " %02d | %08X | %s | %s", blockNum, blockData, sprint_bin(DemodBuffer + config.offset, 32), sprint_ascii(bytes, 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool testModulation(uint8_t mode, uint8_t modread) {
|
static bool testModulation(uint8_t mode, uint8_t modread) {
|
||||||
|
@ -1234,14 +1384,14 @@ int special(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int printConfiguration(t55xx_conf_block_t b) {
|
int printConfiguration(t55xx_conf_block_t b) {
|
||||||
PrintAndLogEx(NORMAL, " Chip Type : %s", (b.Q5) ? "T5555(Q5)" : "T55x7");
|
PrintAndLogEx(NORMAL, " Chip Type : %s", (b.Q5) ? "T5555(Q5)" : "T55x7");
|
||||||
PrintAndLogEx(NORMAL, " Modulation : %s", GetSelectedModulationStr(b.modulation));
|
PrintAndLogEx(NORMAL, " Modulation : %s", GetSelectedModulationStr(b.modulation));
|
||||||
PrintAndLogEx(NORMAL, " Bit Rate : %s", GetBitRateStr(b.bitrate, (b.block0 & T55x7_X_MODE && (b.block0 >> 28 == 6 || b.block0 >> 28 == 9))));
|
PrintAndLogEx(NORMAL, " Bit Rate : %s", GetBitRateStr(b.bitrate, (b.block0 & T55x7_X_MODE && (b.block0 >> 28 == 6 || b.block0 >> 28 == 9))));
|
||||||
PrintAndLogEx(NORMAL, " Inverted : %s", (b.inverted) ? _GREEN_("Yes") : "No");
|
PrintAndLogEx(NORMAL, " Inverted : %s", (b.inverted) ? _GREEN_("Yes") : "No");
|
||||||
PrintAndLogEx(NORMAL, " Offset : %d", b.offset);
|
PrintAndLogEx(NORMAL, " Offset : %d", b.offset);
|
||||||
PrintAndLogEx(NORMAL, " Seq. Term. : %s", (b.ST) ? _GREEN_("Yes") : "No");
|
PrintAndLogEx(NORMAL, " Seq. Term. : %s", (b.ST) ? _GREEN_("Yes") : "No");
|
||||||
PrintAndLogEx(NORMAL, " Block0 : 0x%08X", b.block0);
|
PrintAndLogEx(NORMAL, " Block0 : 0x%08X", b.block0);
|
||||||
PrintAndLogEx(NORMAL, " DL Mode : %s",GetDownlinkModeStr (b.downlink_mode));
|
PrintAndLogEx(NORMAL, " Downling Mode : %s", GetDownlinkModeStr (b.downlink_mode));
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1265,6 +1415,7 @@ static int CmdT55xxWakeUp(const char *Cmd) {
|
||||||
downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10);
|
downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10);
|
||||||
if (downlink_mode > 3)
|
if (downlink_mode > 3)
|
||||||
downlink_mode = 0;
|
downlink_mode = 0;
|
||||||
|
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -1358,46 +1509,20 @@ static int CmdT55xxWriteBlock(const char *Cmd) {
|
||||||
}
|
}
|
||||||
if (errors || !gotdata) return usage_t55xx_write();
|
if (errors || !gotdata) return usage_t55xx_write();
|
||||||
|
|
||||||
PacketResponseNG resp;
|
|
||||||
uint8_t flags;
|
|
||||||
flags = (usepwd) ? 0x1 : 0;
|
|
||||||
flags |= (page1) ? 0x2 : 0;
|
|
||||||
flags |= (testMode) ? 0x4 : 0;
|
|
||||||
flags |= (downlink_mode << 3);
|
|
||||||
|
|
||||||
char pwdStr[16] = {0};
|
char pwdStr[16] = {0};
|
||||||
snprintf(pwdStr, sizeof(pwdStr), "pwd: 0x%08X", password);
|
snprintf(pwdStr, sizeof(pwdStr), "pwd: 0x%08X", password);
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "Writing page %d block: %02d data: 0x%08X %s", page1, block, data, (usepwd) ? pwdStr : "");
|
PrintAndLogEx(INFO, "Writing page %d block: %02d data: 0x%08X %s", page1, block, data, (usepwd) ? pwdStr : "");
|
||||||
|
|
||||||
/*
|
if ( t55xxWrite(block, page1, usepwd, testMode, password, downlink_mode, data) != PM3_SUCCESS ) {
|
||||||
OLD style
|
PrintAndLogEx(ERR, "Write failed");
|
||||||
arg0 = data, (4 bytes)
|
return PM3_ESOFT;
|
||||||
arg1 = block (1 byte)
|
|
||||||
arg2 = password (4 bytes)
|
|
||||||
flags = data[0] (1 byte)
|
|
||||||
|
|
||||||
new style
|
|
||||||
uses struct in pm3_cmd.h
|
|
||||||
*/
|
|
||||||
t55xx_write_block_t ng;
|
|
||||||
ng.data = data;
|
|
||||||
ng.pwd = password;
|
|
||||||
ng.blockno = block;
|
|
||||||
ng.flags = flags;
|
|
||||||
|
|
||||||
clearCommandBuffer();
|
|
||||||
SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng));
|
|
||||||
if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, 2000)) {
|
|
||||||
PrintAndLogEx(ERR, "Error occurred, device did not ACK write operation. (May be due to old firmware)");
|
|
||||||
return PM3_ETIMEOUT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (validate) {
|
if (validate) {
|
||||||
//t55xxVerifyWrite( uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, uint32_t data) {
|
|
||||||
bool isOK = t55xxVerifyWrite(block, page1, usepwd, 1, password, downlink_mode, data);
|
bool isOK = t55xxVerifyWrite(block, page1, usepwd, 1, password, downlink_mode, data);
|
||||||
if (isOK)
|
if (isOK)
|
||||||
PrintAndLogEx(SUCCESS, "Write OK, validation succesful");
|
PrintAndLogEx(SUCCESS, "Write OK, validation successful");
|
||||||
else
|
else
|
||||||
PrintAndLogEx(WARNING, "Write could not validate the written data");
|
PrintAndLogEx(WARNING, "Write could not validate the written data");
|
||||||
}
|
}
|
||||||
|
@ -2047,16 +2172,16 @@ char *GetDownlinkModeStr (uint8_t downlink_mode)
|
||||||
|
|
||||||
switch (downlink_mode) {
|
switch (downlink_mode) {
|
||||||
case T55XX_DLMODE_FIXED :
|
case T55XX_DLMODE_FIXED :
|
||||||
snprintf (retStr,sizeof(buf),"default/fixed bit length");
|
snprintf(retStr, sizeof(buf),"default/fixed bit length");
|
||||||
break;
|
break;
|
||||||
case T55XX_DLMODE_LLR :
|
case T55XX_DLMODE_LLR :
|
||||||
snprintf (retStr,sizeof(buf),"long leading reference");
|
snprintf(retStr, sizeof(buf),"long leading reference");
|
||||||
break;
|
break;
|
||||||
case T55XX_DLMODE_LEADING_ZERO :
|
case T55XX_DLMODE_LEADING_ZERO :
|
||||||
snprintf (retStr,sizeof(buf),"leading zero reference");
|
snprintf(retStr, sizeof(buf),"leading zero reference");
|
||||||
break;
|
break;
|
||||||
case T55XX_DLMODE_1OF4 :
|
case T55XX_DLMODE_1OF4 :
|
||||||
snprintf (retStr,sizeof(buf),"1 of 4 coding reference");
|
snprintf(retStr, sizeof(buf),"1 of 4 coding reference");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
snprintf(retStr, sizeof(buf), _RED_("(Unknown)"));
|
snprintf(retStr, sizeof(buf), _RED_("(Unknown)"));
|
||||||
|
@ -2211,8 +2336,6 @@ static int CmdResetRead(const char *Cmd) {
|
||||||
|
|
||||||
if (errors) return usage_t55xx_resetread();
|
if (errors) return usage_t55xx_resetread();
|
||||||
|
|
||||||
// PrintAndLogEx(INFO, "DL : %d\n", downlink_mode); // no value outside of debug
|
|
||||||
|
|
||||||
flags = downlink_mode << 3;
|
flags = downlink_mode << 3;
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
|
@ -2232,11 +2355,11 @@ static int CmdResetRead(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CmdT55xxWipe(const char *Cmd) {
|
static int CmdT55xxWipe(const char *Cmd) {
|
||||||
|
|
||||||
char writeData[36] = {0};
|
char writeData[36] = {0};
|
||||||
char *ptrData = writeData;
|
char *ptrData = writeData;
|
||||||
uint32_t password = 0;
|
uint32_t password = 0, block0 = 0;
|
||||||
bool usepwd = false;
|
bool usepwd = false, Q5 = false, gotconf = false;
|
||||||
bool Q5 = false;
|
|
||||||
uint8_t cmdp = 0;
|
uint8_t cmdp = 0;
|
||||||
bool errors = false;
|
bool errors = false;
|
||||||
|
|
||||||
|
@ -2250,6 +2373,11 @@ static int CmdT55xxWipe(const char *Cmd) {
|
||||||
usepwd = true;
|
usepwd = true;
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
break;
|
break;
|
||||||
|
case 'c':
|
||||||
|
block0 = param_get32ex(Cmd, cmdp + 1, 0, 16);
|
||||||
|
gotconf = true;
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
case 'q':
|
case 'q':
|
||||||
Q5 = true;
|
Q5 = true;
|
||||||
cmdp++;
|
cmdp++;
|
||||||
|
@ -2263,22 +2391,31 @@ static int CmdT55xxWipe(const char *Cmd) {
|
||||||
|
|
||||||
if (errors) return usage_t55xx_wipe();
|
if (errors) return usage_t55xx_wipe();
|
||||||
|
|
||||||
// Try with the default password to reset block 0
|
|
||||||
// With a pwd should work even if pwd bit not set
|
|
||||||
PrintAndLogEx(INFO, "\nBeginning Wipe of a T55xx tag (assuming the tag is not password protected)\n");
|
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, "\nBegin wiping %s", (Q5)? "Q5 / T5555 tag" : "T55x7 tag");
|
||||||
|
|
||||||
if (usepwd) {
|
// default config blocks.
|
||||||
snprintf(ptrData, sizeof(writeData), "b 0 p %08x ", password);
|
if (gotconf == false) {
|
||||||
} else {
|
block0 = (Q5) ? 0x6001F004 : 0x000880E0;
|
||||||
snprintf(ptrData, sizeof(writeData), "b 0 ");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Q5)
|
char msg[80] = {0};
|
||||||
snprintf(ptrData + strlen(writeData), sizeof(writeData) - strlen(writeData), "d 6001F004");
|
|
||||||
else
|
|
||||||
snprintf(ptrData + strlen(writeData), sizeof(writeData) - strlen(writeData), "d 000880E0");
|
|
||||||
|
|
||||||
|
if (gotconf)
|
||||||
|
snprintf(msg, sizeof(msg), "User provided configuration block %08X", block0);
|
||||||
|
else
|
||||||
|
snprintf(msg, sizeof(msg), "Default configation block %08X", block0);
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, "%s", msg);
|
||||||
|
|
||||||
|
// Creating cmd string for write block :)
|
||||||
|
snprintf(ptrData, sizeof(writeData), "b 0 ");
|
||||||
|
|
||||||
|
if (usepwd) {
|
||||||
|
snprintf(ptrData + strlen(writeData), sizeof(writeData) - strlen(writeData), "p %08x ", password);
|
||||||
|
}
|
||||||
|
snprintf(ptrData + strlen(writeData), sizeof(writeData) - strlen(writeData), "d %08X", block0);
|
||||||
|
|
||||||
if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS)
|
if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS)
|
||||||
PrintAndLogEx(WARNING, "Warning: error writing blk 0");
|
PrintAndLogEx(WARNING, "Warning: error writing blk 0");
|
||||||
|
|
||||||
|
@ -2296,7 +2433,7 @@ static int CmdT55xxWipe(const char *Cmd) {
|
||||||
if (config.downlink_mode != T55XX_DLMODE_FIXED) { // Detect found a different mode so card must support
|
if (config.downlink_mode != T55XX_DLMODE_FIXED) { // Detect found a different mode so card must support
|
||||||
snprintf(ptrData, sizeof(writeData), "b 3 1 d 00000000");
|
snprintf(ptrData, sizeof(writeData), "b 3 1 d 00000000");
|
||||||
if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS)
|
if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS)
|
||||||
PrintAndLogEx(WARNING, "Warning: error writing blk 3 page 1 (config)");
|
PrintAndLogEx(WARNING, "Warning: failed writing block 3 page 1 (config)");
|
||||||
memset(writeData, 0x00, sizeof(writeData));
|
memset(writeData, 0x00, sizeof(writeData));
|
||||||
}
|
}
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
|
@ -2390,10 +2527,9 @@ static int CmdT55xxChkPwds(const char *Cmd) {
|
||||||
PrintAndLogEx(SUCCESS, "\nFound a candidate [ " _YELLOW_("%08X") " ]. Trying to validate", resp.oldarg[1]);
|
PrintAndLogEx(SUCCESS, "\nFound a candidate [ " _YELLOW_("%08X") " ]. Trying to validate", resp.oldarg[1]);
|
||||||
|
|
||||||
if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, resp.oldarg[1], downlink_mode)) {
|
if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, resp.oldarg[1], downlink_mode)) {
|
||||||
found = tryDetectModulation(downlink_mode,T55XX_PrintConfig);
|
found = tryDetectModulation(downlink_mode, T55XX_PrintConfig);
|
||||||
if (found) {
|
if (found) {
|
||||||
PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08X") " ]", resp.oldarg[1]);
|
PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08X") " ]", resp.oldarg[1]);
|
||||||
// T55xx_Print_DownlinkMode(downlink_mode);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(WARNING, "Check pwd failed");
|
PrintAndLogEx(WARNING, "Check pwd failed");
|
||||||
|
@ -2446,7 +2582,6 @@ static int CmdT55xxChkPwds(const char *Cmd) {
|
||||||
found = tryDetectModulation(dl_mode,T55XX_PrintConfig);
|
found = tryDetectModulation(dl_mode,T55XX_PrintConfig);
|
||||||
if (found) {
|
if (found) {
|
||||||
PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08X") " ]", curr_password);
|
PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08X") " ]", curr_password);
|
||||||
// T55xx_Print_DownlinkMode(dl_mode);
|
|
||||||
dl_mode = 4; // Exit other downlink mode checks
|
dl_mode = 4; // Exit other downlink mode checks
|
||||||
c = keycount; // Exit loop
|
c = keycount; // Exit loop
|
||||||
}
|
}
|
||||||
|
@ -2740,7 +2875,6 @@ bool tryDetectP1(bool getData) {
|
||||||
(DemodBufferLen == 32 || DemodBufferLen == 64)) {
|
(DemodBufferLen == 32 || DemodBufferLen == 64)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// try NRZ clock detect. it could be another type even if successful.
|
// try NRZ clock detect. it could be another type even if successful.
|
||||||
|
@ -2797,16 +2931,16 @@ bool tryDetectP1(bool getData) {
|
||||||
}
|
}
|
||||||
// does this need to be a callable command?
|
// does this need to be a callable command?
|
||||||
static int CmdT55xxDetectPage1(const char *Cmd) {
|
static int CmdT55xxDetectPage1(const char *Cmd) {
|
||||||
bool errors = false;
|
bool errors = false;
|
||||||
bool useGB = false;
|
bool useGB = false;
|
||||||
bool usepwd = false;
|
bool usepwd = false;
|
||||||
bool try_all_dl_modes = true;
|
bool try_all_dl_modes = true;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
uint8_t found_mode = 0;
|
uint8_t found_mode = 0;
|
||||||
uint32_t password = 0;
|
uint32_t password = 0;
|
||||||
uint8_t cmdp = 0;
|
uint8_t cmdp = 0;
|
||||||
uint8_t downlink_mode = 0;
|
uint8_t downlink_mode = config.downlink_mode;
|
||||||
uint8_t dl_mode = 0;
|
uint8_t dl_mode = 0;
|
||||||
|
|
||||||
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||||
switch (tolower(param_getchar(Cmd, cmdp))) {
|
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||||
|
@ -2822,7 +2956,8 @@ static int CmdT55xxDetectPage1(const char *Cmd) {
|
||||||
useGB = true;
|
useGB = true;
|
||||||
cmdp++;
|
cmdp++;
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
|
//ICEMAN STRANGE
|
||||||
downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10);
|
downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10);
|
||||||
if (downlink_mode == 4)
|
if (downlink_mode == 4)
|
||||||
try_all_dl_modes = true;
|
try_all_dl_modes = true;
|
||||||
|
@ -2876,7 +3011,7 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) {
|
||||||
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||||
switch (tolower(param_getchar(Cmd, cmdp))) {
|
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||||
case 'h':
|
case 'h':
|
||||||
return usage_lf_deviceconfig();
|
return usage_t55xx_deviceconfig();
|
||||||
case 'a':
|
case 'a':
|
||||||
errors |= param_getdec(Cmd, cmdp + 1, &startgap);
|
errors |= param_getdec(Cmd, cmdp + 1, &startgap);
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
|
@ -2928,7 +3063,7 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//Validations
|
//Validations
|
||||||
if (errors || cmdp == 0) return usage_lf_deviceconfig();
|
if (errors || cmdp == 0) return usage_t55xx_deviceconfig();
|
||||||
|
|
||||||
t55xx_configurations_t configurations = {{{0}, {0}, {0}, {0}}};
|
t55xx_configurations_t configurations = {{{0}, {0}, {0}, {0}}};
|
||||||
|
|
||||||
|
@ -2984,6 +3119,64 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int CmdT55xxProtect(const char *Cmd) {
|
||||||
|
bool errors = false, usepwd = false, gotnewpwd = false;
|
||||||
|
uint32_t password = 0, new_password = 0;
|
||||||
|
uint8_t override = 0;
|
||||||
|
uint8_t cmdp = 0;
|
||||||
|
uint8_t downlink_mode = config.downlink_mode;
|
||||||
|
|
||||||
|
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||||
|
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||||
|
case 'h':
|
||||||
|
return usage_t55xx_protect();
|
||||||
|
case 'o':
|
||||||
|
override = 2;
|
||||||
|
cmdp++;
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
new_password = param_get32ex(Cmd, cmdp + 1, 0, 16);
|
||||||
|
gotnewpwd = true;
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
password = param_get32ex(Cmd, cmdp + 1, 0, 16);
|
||||||
|
usepwd = true;
|
||||||
|
override = 1;
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
//ICEMAN STRANGE
|
||||||
|
downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10);
|
||||||
|
if (downlink_mode > 3)
|
||||||
|
downlink_mode = 0;
|
||||||
|
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||||
|
errors = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gotnewpwd == false)
|
||||||
|
return usage_t55xx_protect();
|
||||||
|
|
||||||
|
if (errors || cmdp == 0) return usage_t55xx_protect();
|
||||||
|
|
||||||
|
// sanity check.
|
||||||
|
if (SanityOfflineCheck(false) != PM3_SUCCESS)
|
||||||
|
return PM3_ESOFT;
|
||||||
|
|
||||||
|
// lock
|
||||||
|
if ( t55xxProtect(true, usepwd, override, password, downlink_mode, new_password) == false ) {
|
||||||
|
PrintAndLogEx(WARNING, "Command failed. Did you run `lf t55xx detect` before?");
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static command_t CommandTable[] = {
|
static command_t CommandTable[] = {
|
||||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||||
{"bruteforce", CmdT55xxBruteForce, IfPm3Lf, "<start password> <end password> Simple bruteforce attack to find password"},
|
{"bruteforce", CmdT55xxBruteForce, IfPm3Lf, "<start password> <end password> Simple bruteforce attack to find password"},
|
||||||
|
@ -2991,9 +3184,10 @@ static command_t CommandTable[] = {
|
||||||
{"chk", CmdT55xxChkPwds, IfPm3Lf, "Check passwords from dictionary/flash"},
|
{"chk", CmdT55xxChkPwds, IfPm3Lf, "Check passwords from dictionary/flash"},
|
||||||
{"detect", CmdT55xxDetect, AlwaysAvailable, "[1] Try detecting the tag modulation from reading the configuration block."},
|
{"detect", CmdT55xxDetect, AlwaysAvailable, "[1] Try detecting the tag modulation from reading the configuration block."},
|
||||||
{"deviceconfig", CmdT55xxSetDeviceConfig, IfPm3Lf, "Set/Get T55XX device configuration (startgap, writegap, write0, write1, readgap"},
|
{"deviceconfig", CmdT55xxSetDeviceConfig, IfPm3Lf, "Set/Get T55XX device configuration (startgap, writegap, write0, write1, readgap"},
|
||||||
{"p1detect", CmdT55xxDetectPage1, IfPm3Lf, "[1] Try detecting if this is a t55xx tag by reading page 1"},
|
|
||||||
{"dump", CmdT55xxDump, IfPm3Lf, "[password] [o] Dump T55xx card block 0-7. Optional [password], [override]"},
|
{"dump", CmdT55xxDump, IfPm3Lf, "[password] [o] Dump T55xx card block 0-7. Optional [password], [override]"},
|
||||||
{"info", CmdT55xxInfo, AlwaysAvailable, "[1] Show T55x7 configuration data (page 0/ blk 0)"},
|
{"info", CmdT55xxInfo, AlwaysAvailable, "[1] Show T55x7 configuration data (page 0/ blk 0)"},
|
||||||
|
{"p1detect", CmdT55xxDetectPage1, IfPm3Lf, "[1] Try detecting if this is a t55xx tag by reading page 1"},
|
||||||
|
{"protect", CmdT55xxProtect, IfPm3Lf, "Password protect tag"},
|
||||||
{"read", CmdT55xxReadBlock, IfPm3Lf, "b <block> p [password] [o] [1] -- Read T55xx block data. Optional [p password], [override], [page1]"},
|
{"read", CmdT55xxReadBlock, IfPm3Lf, "b <block> p [password] [o] [1] -- Read T55xx block data. Optional [p password], [override], [page1]"},
|
||||||
{"resetread", CmdResetRead, IfPm3Lf, "Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)"},
|
{"resetread", CmdResetRead, IfPm3Lf, "Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)"},
|
||||||
{"recoverpw", CmdT55xxRecoverPW, IfPm3Lf, "[password] Try to recover from bad password write from a cloner. Only use on PW protected chips!"},
|
{"recoverpw", CmdT55xxRecoverPW, IfPm3Lf, "[password] Try to recover from bad password write from a cloner. Only use on PW protected chips!"},
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#define T55x7_CONFIGURATION_BLOCK 0x00
|
#define T55x7_CONFIGURATION_BLOCK 0x00
|
||||||
|
#define T55x7_PWD_BLOCK 0x07
|
||||||
#define T55x7_TRACE_BLOCK1 0x01
|
#define T55x7_TRACE_BLOCK1 0x01
|
||||||
#define T55x7_TRACE_BLOCK2 0x02
|
#define T55x7_TRACE_BLOCK2 0x02
|
||||||
#define T55x7_PAGE0 0x00
|
#define T55x7_PAGE0 0x00
|
||||||
|
@ -142,10 +143,17 @@ void printT5xxHeader(uint8_t page);
|
||||||
void printT55xxBlock(uint8_t blockNum);
|
void printT55xxBlock(uint8_t blockNum);
|
||||||
int printConfiguration(t55xx_conf_block_t b);
|
int printConfiguration(t55xx_conf_block_t b);
|
||||||
|
|
||||||
int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode);
|
bool t55xxAquireAndDetect(bool usepwd, uint32_t password, uint32_t known_block0, bool verbose);
|
||||||
|
bool t55xxVerifyWrite( uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, uint32_t data);
|
||||||
|
int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode);
|
||||||
|
int T55xxReadBlockEx(uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, bool verbose);
|
||||||
|
|
||||||
|
int t55xxWrite(uint8_t block, bool page1, bool usepwd, bool testMode, uint32_t password, uint8_t downlink_mode, uint32_t data);
|
||||||
|
|
||||||
bool GetT55xxBlockData(uint32_t *blockdata);
|
bool GetT55xxBlockData(uint32_t *blockdata);
|
||||||
bool DecodeT55xxBlock(void);
|
bool DecodeT55xxBlock(void);
|
||||||
bool tryDetectModulation(uint8_t downlink_mode, bool print_config);
|
bool tryDetectModulation(uint8_t downlink_mode, bool print_config);
|
||||||
|
bool tryDetectModulationEx(uint8_t downlink_mode, bool print_config, uint32_t wanted_conf);
|
||||||
bool testKnownConfigBlock(uint32_t block0);
|
bool testKnownConfigBlock(uint32_t block0);
|
||||||
|
|
||||||
bool tryDetectP1(bool getData);
|
bool tryDetectP1(bool getData);
|
||||||
|
|
|
@ -9,17 +9,6 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
#include "cmdlfviking.h"
|
#include "cmdlfviking.h"
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#include "cmdparser.h" // command_t
|
|
||||||
#include "comms.h"
|
|
||||||
#include "ui.h"
|
|
||||||
#include "cmddata.h"
|
|
||||||
#include "cmdlf.h"
|
|
||||||
#include "lfdemod.h"
|
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
static int usage_lf_viking_clone(void) {
|
static int usage_lf_viking_clone(void) {
|
||||||
|
@ -90,22 +79,31 @@ static int CmdVikingClone(const char *Cmd) {
|
||||||
id = param_get32ex(Cmd, 0, 0, 16);
|
id = param_get32ex(Cmd, 0, 0, 16);
|
||||||
if (id == 0) return usage_lf_viking_clone();
|
if (id == 0) return usage_lf_viking_clone();
|
||||||
|
|
||||||
cmdp = param_getchar(Cmd, 1);
|
cmdp = tolower(param_getchar(Cmd, 1));
|
||||||
if (cmdp == 'Q' || cmdp == 'q')
|
if (cmdp == 'q')
|
||||||
Q5 = true;
|
Q5 = true;
|
||||||
|
|
||||||
rawID = getVikingBits(id);
|
rawID = getVikingBits(id);
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "Preparing to clone Viking tag - ID " _YELLOW_("%08X")" raw " _YELLOW_("%08X%08X"), id, (uint32_t)(rawID >> 32), (uint32_t)(rawID & 0xFFFFFFFF));
|
struct p {
|
||||||
|
bool Q5;
|
||||||
|
uint8_t blocks[8];
|
||||||
|
} PACKED payload;
|
||||||
|
payload.Q5 = Q5;
|
||||||
|
|
||||||
|
num_to_bytes(rawID, 8, &payload.blocks[0]);
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, "Preparing to clone Viking tag - ID " _YELLOW_("%08X")" raw " _YELLOW_("%s"), id, sprint_hex(payload.blocks, sizeof(payload.blocks)));
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandMIX(CMD_LF_VIKING_CLONE, rawID >> 32, rawID & 0xFFFFFFFF, Q5, NULL, 0);
|
|
||||||
|
SendCommandNG(CMD_LF_VIKING_CLONE, (uint8_t*)&payload, sizeof(payload));
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, T55XX_WRITE_TIMEOUT)) {
|
if (!WaitForResponseTimeout(CMD_LF_VIKING_CLONE, &resp, T55XX_WRITE_TIMEOUT)) {
|
||||||
PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
|
PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
return PM3_SUCCESS;
|
return resp.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CmdVikingSim(const char *Cmd) {
|
static int CmdVikingSim(const char *Cmd) {
|
||||||
|
|
|
@ -9,8 +9,21 @@
|
||||||
#ifndef CMDLFVIKING_H__
|
#ifndef CMDLFVIKING_H__
|
||||||
#define CMDLFVIKING_H__
|
#define CMDLFVIKING_H__
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
#include "cmdparser.h" // command_t
|
||||||
|
#include "comms.h"
|
||||||
|
#include "ui.h"
|
||||||
|
#include "cmddata.h"
|
||||||
|
#include "cmdlf.h"
|
||||||
|
#include "lfdemod.h"
|
||||||
|
#include "commonutil.h" // num_to_bytes
|
||||||
|
|
||||||
|
|
||||||
int CmdLFViking(const char *Cmd);
|
int CmdLFViking(const char *Cmd);
|
||||||
|
|
||||||
int demodViking(void);
|
int demodViking(void);
|
||||||
|
|
|
@ -11,19 +11,6 @@
|
||||||
|
|
||||||
#include "cmdlfvisa2000.h"
|
#include "cmdlfvisa2000.h"
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "cmdparser.h" // command_t
|
|
||||||
#include "comms.h"
|
|
||||||
#include "ui.h"
|
|
||||||
#include "graph.h"
|
|
||||||
#include "cmddata.h"
|
|
||||||
#include "cmdlf.h"
|
|
||||||
#include "protocols.h" // for T55xx config register definitions
|
|
||||||
#include "lfdemod.h" // parityTest
|
|
||||||
|
|
||||||
#define BL0CK1 0x56495332
|
#define BL0CK1 0x56495332
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
@ -171,7 +158,7 @@ static int CmdVisa2kClone(const char *Cmd) {
|
||||||
id = param_get32ex(Cmd, 0, 0, 10);
|
id = param_get32ex(Cmd, 0, 0, 10);
|
||||||
|
|
||||||
//Q5
|
//Q5
|
||||||
if (param_getchar(Cmd, 1) == 'Q' || param_getchar(Cmd, 1) == 'q')
|
if (tolower(param_getchar(Cmd, 1)) == 'q')
|
||||||
blocks[0] = T5555_MODULATION_MANCHESTER | T5555_SET_BITRATE(64) | T5555_ST_TERMINATOR | 3 << T5555_MAXBLOCK_SHIFT;
|
blocks[0] = T5555_MODULATION_MANCHESTER | T5555_SET_BITRATE(64) | T5555_ST_TERMINATOR | 3 << T5555_MAXBLOCK_SHIFT;
|
||||||
|
|
||||||
blocks[2] = id;
|
blocks[2] = id;
|
||||||
|
@ -180,8 +167,9 @@ static int CmdVisa2kClone(const char *Cmd) {
|
||||||
PrintAndLogEx(INFO, "Preparing to clone Visa2000 to T55x7 with CardId: %u", id);
|
PrintAndLogEx(INFO, "Preparing to clone Visa2000 to T55x7 with CardId: %u", id);
|
||||||
print_blocks(blocks, 4);
|
print_blocks(blocks, 4);
|
||||||
|
|
||||||
|
uint8_t res = 0;
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
|
|
||||||
// fast push mode
|
// fast push mode
|
||||||
conn.block_after_ACK = true;
|
conn.block_after_ACK = true;
|
||||||
for (uint8_t i = 0; i < 4; i++) {
|
for (uint8_t i = 0; i < 4; i++) {
|
||||||
|
@ -201,8 +189,19 @@ static int CmdVisa2kClone(const char *Cmd) {
|
||||||
|
|
||||||
PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
|
PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// write block0, needs a detect.
|
||||||
|
if (i == 0)
|
||||||
|
t55xxAquireAndDetect(false, 0, blocks[i], false);
|
||||||
|
|
||||||
|
if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false)
|
||||||
|
res++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( res == 0 )
|
||||||
|
PrintAndLogEx(SUCCESS, "Success writing to tag");
|
||||||
|
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,19 @@
|
||||||
#ifndef CMDLFVISA2000_H__
|
#ifndef CMDLFVISA2000_H__
|
||||||
#define CMDLFVISA2000_H__
|
#define CMDLFVISA2000_H__
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "cmdparser.h" // command_t
|
||||||
|
#include "comms.h"
|
||||||
|
#include "ui.h"
|
||||||
|
#include "graph.h"
|
||||||
|
#include "cmddata.h"
|
||||||
|
#include "cmdlf.h"
|
||||||
|
#include "protocols.h" // for T55xx config register definitions
|
||||||
|
#include "lfdemod.h" // parityTest
|
||||||
|
#include "cmdlft55xx.h" // write verify
|
||||||
|
|
||||||
int CmdLFVisa2k(const char *Cmd);
|
int CmdLFVisa2k(const char *Cmd);
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ const APDUCode APDUCodeTable[] = {
|
||||||
{"6281", APDUCODE_TYPE_WARNING, "Part of returned data may be corrupted"},
|
{"6281", APDUCODE_TYPE_WARNING, "Part of returned data may be corrupted"},
|
||||||
{"6282", APDUCODE_TYPE_WARNING, "End of file/record reached before reading Le bytes"},
|
{"6282", APDUCODE_TYPE_WARNING, "End of file/record reached before reading Le bytes"},
|
||||||
{"6283", APDUCODE_TYPE_WARNING, "Selected file invalidated"},
|
{"6283", APDUCODE_TYPE_WARNING, "Selected file invalidated"},
|
||||||
{"6284", APDUCODE_TYPE_WARNING, "Selected file is not valid. FCI not formated according to ISO"},
|
{"6284", APDUCODE_TYPE_WARNING, "Selected file is not valid. FCI not formatted according to ISO"},
|
||||||
{"6285", APDUCODE_TYPE_WARNING, "No input data available from a sensor on the card. No Purse Engine enslaved for R3bc"},
|
{"6285", APDUCODE_TYPE_WARNING, "No input data available from a sensor on the card. No Purse Engine enslaved for R3bc"},
|
||||||
{"62A2", APDUCODE_TYPE_WARNING, "Wrong R-MAC"},
|
{"62A2", APDUCODE_TYPE_WARNING, "Wrong R-MAC"},
|
||||||
{"62A4", APDUCODE_TYPE_WARNING, "Card locked (during reset( ))"},
|
{"62A4", APDUCODE_TYPE_WARNING, "Card locked (during reset( ))"},
|
||||||
|
@ -143,7 +143,7 @@ const APDUCode APDUCodeTable[] = {
|
||||||
{"6FXX", APDUCODE_TYPE_ERROR, "No precise diagnosis (procedure byte), (ISO 7816-3)"},
|
{"6FXX", APDUCODE_TYPE_ERROR, "No precise diagnosis (procedure byte), (ISO 7816-3)"},
|
||||||
{"9---", APDUCODE_TYPE_NONE, ""},
|
{"9---", APDUCODE_TYPE_NONE, ""},
|
||||||
{"9000", APDUCODE_TYPE_INFO, "Command successfully executed (OK)."},
|
{"9000", APDUCODE_TYPE_INFO, "Command successfully executed (OK)."},
|
||||||
{"9004", APDUCODE_TYPE_WARNING, "PIN not succesfully verified, 3 or more PIN tries left"},
|
{"9004", APDUCODE_TYPE_WARNING, "PIN not successfully verified, 3 or more PIN tries left"},
|
||||||
{"9008", APDUCODE_TYPE_NONE, "Key/file not found"},
|
{"9008", APDUCODE_TYPE_NONE, "Key/file not found"},
|
||||||
{"9080", APDUCODE_TYPE_WARNING, "Unblock Try Counter has reached zero"},
|
{"9080", APDUCODE_TYPE_WARNING, "Unblock Try Counter has reached zero"},
|
||||||
{"9100", APDUCODE_TYPE_NONE, "OK"},
|
{"9100", APDUCODE_TYPE_NONE, "OK"},
|
||||||
|
@ -191,7 +191,7 @@ const APDUCode APDUCodeTable[] = {
|
||||||
{"9681", APDUCODE_TYPE_NONE, "Slave not found"},
|
{"9681", APDUCODE_TYPE_NONE, "Slave not found"},
|
||||||
{"9700", APDUCODE_TYPE_NONE, "PIN blocked and Unblock Try Counter is 1 or 2"},
|
{"9700", APDUCODE_TYPE_NONE, "PIN blocked and Unblock Try Counter is 1 or 2"},
|
||||||
{"9702", APDUCODE_TYPE_NONE, "Main keys are blocked"},
|
{"9702", APDUCODE_TYPE_NONE, "Main keys are blocked"},
|
||||||
{"9704", APDUCODE_TYPE_NONE, "PIN not succesfully verified, 3 or more PIN tries left"},
|
{"9704", APDUCODE_TYPE_NONE, "PIN not successfully verified, 3 or more PIN tries left"},
|
||||||
{"9784", APDUCODE_TYPE_NONE, "Base key"},
|
{"9784", APDUCODE_TYPE_NONE, "Base key"},
|
||||||
{"9785", APDUCODE_TYPE_NONE, "Limit exceeded - C-MAC key"},
|
{"9785", APDUCODE_TYPE_NONE, "Limit exceeded - C-MAC key"},
|
||||||
{"9786", APDUCODE_TYPE_NONE, "SM error - Limit exceeded - R-MAC key"},
|
{"9786", APDUCODE_TYPE_NONE, "SM error - Limit exceeded - R-MAC key"},
|
||||||
|
@ -205,13 +205,13 @@ const APDUCode APDUCodeTable[] = {
|
||||||
{"9850", APDUCODE_TYPE_ERROR, "INCREASE or DECREASE could not be executed because a limit has been reached."},
|
{"9850", APDUCODE_TYPE_ERROR, "INCREASE or DECREASE could not be executed because a limit has been reached."},
|
||||||
{"9862", APDUCODE_TYPE_ERROR, "Authentication Error, application specific (incorrect MAC)"},
|
{"9862", APDUCODE_TYPE_ERROR, "Authentication Error, application specific (incorrect MAC)"},
|
||||||
{"9900", APDUCODE_TYPE_NONE, "1 PIN try left"},
|
{"9900", APDUCODE_TYPE_NONE, "1 PIN try left"},
|
||||||
{"9904", APDUCODE_TYPE_NONE, "PIN not succesfully verified, 1 PIN try left"},
|
{"9904", APDUCODE_TYPE_NONE, "PIN not successfully verified, 1 PIN try left"},
|
||||||
{"9985", APDUCODE_TYPE_NONE, "Wrong status - Cardholder lock"},
|
{"9985", APDUCODE_TYPE_NONE, "Wrong status - Cardholder lock"},
|
||||||
{"9986", APDUCODE_TYPE_ERROR, "Missing privilege"},
|
{"9986", APDUCODE_TYPE_ERROR, "Missing privilege"},
|
||||||
{"9987", APDUCODE_TYPE_NONE, "PIN is not installed"},
|
{"9987", APDUCODE_TYPE_NONE, "PIN is not installed"},
|
||||||
{"9988", APDUCODE_TYPE_NONE, "Wrong status - R-MAC state"},
|
{"9988", APDUCODE_TYPE_NONE, "Wrong status - R-MAC state"},
|
||||||
{"9A00", APDUCODE_TYPE_NONE, "2 PIN try left"},
|
{"9A00", APDUCODE_TYPE_NONE, "2 PIN try left"},
|
||||||
{"9A04", APDUCODE_TYPE_NONE, "PIN not succesfully verified, 2 PIN try left"},
|
{"9A04", APDUCODE_TYPE_NONE, "PIN not successfully verified, 2 PIN try left"},
|
||||||
{"9A71", APDUCODE_TYPE_NONE, "Wrong parameter value - Double agent AID"},
|
{"9A71", APDUCODE_TYPE_NONE, "Wrong parameter value - Double agent AID"},
|
||||||
{"9A72", APDUCODE_TYPE_NONE, "Wrong parameter value - Double agent Type"},
|
{"9A72", APDUCODE_TYPE_NONE, "Wrong parameter value - Double agent Type"},
|
||||||
{"9D05", APDUCODE_TYPE_ERROR, "Incorrect certificate type"},
|
{"9D05", APDUCODE_TYPE_ERROR, "Incorrect certificate type"},
|
||||||
|
@ -258,9 +258,9 @@ const APDUCode APDUCodeTable[] = {
|
||||||
{"9D63", APDUCODE_TYPE_ERROR, "Crypto functions not available"},
|
{"9D63", APDUCODE_TYPE_ERROR, "Crypto functions not available"},
|
||||||
{"9D64", APDUCODE_TYPE_ERROR, "No application loaded"},
|
{"9D64", APDUCODE_TYPE_ERROR, "No application loaded"},
|
||||||
{"9E00", APDUCODE_TYPE_NONE, "PIN not installed"},
|
{"9E00", APDUCODE_TYPE_NONE, "PIN not installed"},
|
||||||
{"9E04", APDUCODE_TYPE_NONE, "PIN not succesfully verified, PIN not installed"},
|
{"9E04", APDUCODE_TYPE_NONE, "PIN not successfully verified, PIN not installed"},
|
||||||
{"9F00", APDUCODE_TYPE_NONE, "PIN blocked and Unblock Try Counter is 3"},
|
{"9F00", APDUCODE_TYPE_NONE, "PIN blocked and Unblock Try Counter is 3"},
|
||||||
{"9F04", APDUCODE_TYPE_NONE, "PIN not succesfully verified, PIN blocked and Unblock Try Counter is 3"},
|
{"9F04", APDUCODE_TYPE_NONE, "PIN not successfully verified, PIN blocked and Unblock Try Counter is 3"},
|
||||||
{"9FXX", APDUCODE_TYPE_NONE, "Command successfully executed; 'xx' bytes of data are available and can be requested using GET RESPONSE."},
|
{"9FXX", APDUCODE_TYPE_NONE, "Command successfully executed; 'xx' bytes of data are available and can be requested using GET RESPONSE."},
|
||||||
{"9XXX", APDUCODE_TYPE_NONE, "Application related status, (ISO 7816-3)"}
|
{"9XXX", APDUCODE_TYPE_NONE, "Application related status, (ISO 7816-3)"}
|
||||||
};
|
};
|
||||||
|
|
|
@ -790,7 +790,7 @@ static int CmdEMVExec(const char *Cmd) {
|
||||||
arg_rem("By default:", "Transaction type - MSD"),
|
arg_rem("By default:", "Transaction type - MSD"),
|
||||||
arg_lit0("vV", "qvsdc", "Transaction type - qVSDC or M/Chip."),
|
arg_lit0("vV", "qvsdc", "Transaction type - qVSDC or M/Chip."),
|
||||||
arg_lit0("cC", "qvsdccda", "Transaction type - qVSDC or M/Chip plus CDA (SDAD generation)."),
|
arg_lit0("cC", "qvsdccda", "Transaction type - qVSDC or M/Chip plus CDA (SDAD generation)."),
|
||||||
arg_lit0("xX", "vsdc", "Transaction type - VSDC. For test only. Not a standart behavior."),
|
arg_lit0("xX", "vsdc", "Transaction type - VSDC. For test only. Not a standard behavior."),
|
||||||
arg_lit0("gG", "acgpo", "VISA. generate AC from GPO."),
|
arg_lit0("gG", "acgpo", "VISA. generate AC from GPO."),
|
||||||
arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
|
arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
|
@ -1380,7 +1380,7 @@ static int CmdEMVScan(const char *Cmd) {
|
||||||
arg_rem("By default:", "Transaction type - MSD"),
|
arg_rem("By default:", "Transaction type - MSD"),
|
||||||
arg_lit0("vV", "qvsdc", "Transaction type - qVSDC or M/Chip."),
|
arg_lit0("vV", "qvsdc", "Transaction type - qVSDC or M/Chip."),
|
||||||
arg_lit0("cC", "qvsdccda", "Transaction type - qVSDC or M/Chip plus CDA (SDAD generation)."),
|
arg_lit0("cC", "qvsdccda", "Transaction type - qVSDC or M/Chip plus CDA (SDAD generation)."),
|
||||||
arg_lit0("xX", "vsdc", "Transaction type - VSDC. For test only. Not a standart behavior."),
|
arg_lit0("xX", "vsdc", "Transaction type - VSDC. For test only. Not a standard behavior."),
|
||||||
arg_lit0("gG", "acgpo", "VISA. generate AC from GPO."),
|
arg_lit0("gG", "acgpo", "VISA. generate AC from GPO."),
|
||||||
arg_lit0("mM", "merge", "Merge output file with card's data. (warning: the file may be corrupted!)"),
|
arg_lit0("mM", "merge", "Merge output file with card's data. (warning: the file may be corrupted!)"),
|
||||||
arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
|
arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
|
||||||
|
|
|
@ -394,7 +394,7 @@ static int EMVSelectWithRetry(EMVCommandChannel channel, bool ActivateField, boo
|
||||||
}
|
}
|
||||||
|
|
||||||
retrycnt = 0;
|
retrycnt = 0;
|
||||||
PrintAndLogEx(NORMAL, "Retry failed [%s]. Skiped...", sprint_hex_inrow(AID, AIDLen));
|
PrintAndLogEx(NORMAL, "Retry failed [%s]. Skipped...", sprint_hex_inrow(AID, AIDLen));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ typedef enum {
|
||||||
|
|
||||||
enum TransactionType {
|
enum TransactionType {
|
||||||
TT_MSD,
|
TT_MSD,
|
||||||
TT_VSDC, // contact only. not standart for contactless
|
TT_VSDC, // contact only. not standard for contactless
|
||||||
TT_QVSDCMCHIP,
|
TT_QVSDCMCHIP,
|
||||||
TT_CDA,
|
TT_CDA,
|
||||||
};
|
};
|
||||||
|
|
|
@ -357,7 +357,7 @@ CborError CborGetArrayBinStringValue(CborValue *elm, uint8_t *data, size_t maxda
|
||||||
return CborGetArrayBinStringValueEx(elm, data, maxdatalen, datalen, NULL, 0);
|
return CborGetArrayBinStringValueEx(elm, data, maxdatalen, datalen, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
CborError CborGetArrayBinStringValueEx(CborValue *elm, uint8_t *data, size_t maxdatalen, size_t *datalen, uint8_t *delimeter, size_t delimeterlen) {
|
CborError CborGetArrayBinStringValueEx(CborValue *elm, uint8_t *data, size_t maxdatalen, size_t *datalen, uint8_t *delimiter, size_t delimiterlen) {
|
||||||
CborValue array;
|
CborValue array;
|
||||||
if (datalen)
|
if (datalen)
|
||||||
*datalen = 0;
|
*datalen = 0;
|
||||||
|
@ -373,9 +373,9 @@ CborError CborGetArrayBinStringValueEx(CborValue *elm, uint8_t *data, size_t max
|
||||||
cbor_check(res);
|
cbor_check(res);
|
||||||
|
|
||||||
totallen += slen;
|
totallen += slen;
|
||||||
if (delimeter) {
|
if (delimiter) {
|
||||||
memcpy(&data[totallen], delimeter, delimeterlen);
|
memcpy(&data[totallen], delimiter, delimiterlen);
|
||||||
totallen += delimeterlen;
|
totallen += delimiterlen;
|
||||||
}
|
}
|
||||||
slen = maxdatalen - totallen;
|
slen = maxdatalen - totallen;
|
||||||
}
|
}
|
||||||
|
@ -404,7 +404,7 @@ CborError CborGetBinStringValue(CborValue *elm, uint8_t *data, size_t maxdatalen
|
||||||
return CborNoError;
|
return CborNoError;
|
||||||
};
|
};
|
||||||
|
|
||||||
CborError CborGetArrayStringValue(CborValue *elm, char *data, size_t maxdatalen, size_t *datalen, char *delimeter) {
|
CborError CborGetArrayStringValue(CborValue *elm, char *data, size_t maxdatalen, size_t *datalen, char *delimiter) {
|
||||||
CborValue array;
|
CborValue array;
|
||||||
if (datalen)
|
if (datalen)
|
||||||
*datalen = 0;
|
*datalen = 0;
|
||||||
|
@ -420,9 +420,9 @@ CborError CborGetArrayStringValue(CborValue *elm, char *data, size_t maxdatalen,
|
||||||
cbor_check(res);
|
cbor_check(res);
|
||||||
|
|
||||||
totallen += slen;
|
totallen += slen;
|
||||||
if (delimeter) {
|
if (delimiter) {
|
||||||
strcat(data, delimeter);
|
strcat(data, delimiter);
|
||||||
totallen += strlen(delimeter);
|
totallen += strlen(delimiter);
|
||||||
}
|
}
|
||||||
slen = maxdatalen - totallen;
|
slen = maxdatalen - totallen;
|
||||||
data[totallen] = 0x00;
|
data[totallen] = 0x00;
|
||||||
|
|
|
@ -25,9 +25,9 @@ int JsonToCbor(json_t *elm, CborEncoder *encoder);
|
||||||
|
|
||||||
int CborMapGetKeyById(CborParser *parser, CborValue *map, uint8_t *data, size_t dataLen, int key);
|
int CborMapGetKeyById(CborParser *parser, CborValue *map, uint8_t *data, size_t dataLen, int key);
|
||||||
CborError CborGetArrayBinStringValue(CborValue *elm, uint8_t *data, size_t maxdatalen, size_t *datalen);
|
CborError CborGetArrayBinStringValue(CborValue *elm, uint8_t *data, size_t maxdatalen, size_t *datalen);
|
||||||
CborError CborGetArrayBinStringValueEx(CborValue *elm, uint8_t *data, size_t maxdatalen, size_t *datalen, uint8_t *delimeter, size_t delimeterlen);
|
CborError CborGetArrayBinStringValueEx(CborValue *elm, uint8_t *data, size_t maxdatalen, size_t *datalen, uint8_t *delimiter, size_t delimiterlen);
|
||||||
CborError CborGetBinStringValue(CborValue *elm, uint8_t *data, size_t maxdatalen, size_t *datalen);
|
CborError CborGetBinStringValue(CborValue *elm, uint8_t *data, size_t maxdatalen, size_t *datalen);
|
||||||
CborError CborGetArrayStringValue(CborValue *elm, char *data, size_t maxdatalen, size_t *datalen, char *delimeter);
|
CborError CborGetArrayStringValue(CborValue *elm, char *data, size_t maxdatalen, size_t *datalen, char *delimiter);
|
||||||
CborError CborGetStringValue(CborValue *elm, char *data, size_t maxdatalen, size_t *datalen);
|
CborError CborGetStringValue(CborValue *elm, char *data, size_t maxdatalen, size_t *datalen);
|
||||||
CborError CborGetStringValueBuf(CborValue *elm);
|
CborError CborGetStringValueBuf(CborValue *elm);
|
||||||
|
|
||||||
|
|
|
@ -122,8 +122,8 @@ end
|
||||||
-- @param ignoreresponse - if set to true, we don't read the device answer packet
|
-- @param ignoreresponse - if set to true, we don't read the device answer packet
|
||||||
-- which is usually recipe for fail. If not sent, the host will wait 2s for a
|
-- which is usually recipe for fail. If not sent, the host will wait 2s for a
|
||||||
-- response of type CMD_ACK
|
-- response of type CMD_ACK
|
||||||
-- @return packet,nil if successfull
|
-- @return packet,nil if successful
|
||||||
-- nil, errormessage if unsuccessfull
|
-- nil, errormessage if unsuccessful
|
||||||
function Command:sendMIX( ignore_response, timeout )
|
function Command:sendMIX( ignore_response, timeout )
|
||||||
local data = self.data
|
local data = self.data
|
||||||
local cmd = self.cmd
|
local cmd = self.cmd
|
||||||
|
|
|
@ -12,8 +12,8 @@ local reader15693 = require('read15')
|
||||||
-- This method library can be set waits or a 13.56 MHz tag, and when one is found, returns info about
|
-- This method library can be set waits or a 13.56 MHz tag, and when one is found, returns info about
|
||||||
-- what tag it is.
|
-- what tag it is.
|
||||||
--
|
--
|
||||||
-- @return if successfull: an table containing card info
|
-- @return if successful: an table containing card info
|
||||||
-- @return if unsuccessfull : nil, error
|
-- @return if unsuccessful : nil, error
|
||||||
local function waitForTag()
|
local function waitForTag()
|
||||||
print("Waiting for card... press Enter to quit")
|
print("Waiting for card... press Enter to quit")
|
||||||
local readers = {reader14443A, reader14443B, reader15693}
|
local readers = {reader14443A, reader14443B, reader15693}
|
||||||
|
|
|
@ -80,8 +80,8 @@ end
|
||||||
|
|
||||||
-- This function does a connect and retrieves som einfo
|
-- This function does a connect and retrieves som einfo
|
||||||
-- @param dont_disconnect - if true, does not disable the field
|
-- @param dont_disconnect - if true, does not disable the field
|
||||||
-- @return if successfull: an table containing card info
|
-- @return if successful: an table containing card info
|
||||||
-- @return if unsuccessfull : nil, error
|
-- @return if unsuccessful : nil, error
|
||||||
local function read14443a(dont_disconnect, no_rats)
|
local function read14443a(dont_disconnect, no_rats)
|
||||||
local command, result, info, err, data
|
local command, result, info, err, data
|
||||||
|
|
||||||
|
@ -118,8 +118,8 @@ end
|
||||||
|
|
||||||
---
|
---
|
||||||
-- Waits for a mifare card to be placed within the vicinity of the reader.
|
-- Waits for a mifare card to be placed within the vicinity of the reader.
|
||||||
-- @return if successfull: an table containing card info
|
-- @return if successful: an table containing card info
|
||||||
-- @return if unsuccessfull : nil, error
|
-- @return if unsuccessful : nil, error
|
||||||
local function waitFor14443a()
|
local function waitFor14443a()
|
||||||
print('Waiting for card... press Enter to quit')
|
print('Waiting for card... press Enter to quit')
|
||||||
while not core.kbd_enter_pressed() do
|
while not core.kbd_enter_pressed() do
|
||||||
|
|
|
@ -55,8 +55,8 @@ local function parse14443b(data)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- This function does a connect and retrieves some info
|
-- This function does a connect and retrieves some info
|
||||||
-- @return if successfull: an table containing card info
|
-- @return if successful: an table containing card info
|
||||||
-- @return if unsuccessfull : nil, error
|
-- @return if unsuccessful : nil, error
|
||||||
local function read14443b(disconnect)
|
local function read14443b(disconnect)
|
||||||
|
|
||||||
local command, result, info, err, data
|
local command, result, info, err, data
|
||||||
|
@ -96,8 +96,8 @@ end
|
||||||
|
|
||||||
---
|
---
|
||||||
-- Waits for a mifare card to be placed within the vicinity of the reader.
|
-- Waits for a mifare card to be placed within the vicinity of the reader.
|
||||||
-- @return if successfull: an table containing card info
|
-- @return if successful: an table containing card info
|
||||||
-- @return if unsuccessfull : nil, error
|
-- @return if unsuccessful : nil, error
|
||||||
local function waitFor14443b()
|
local function waitFor14443b()
|
||||||
print('Waiting for card... press Enter to quit')
|
print('Waiting for card... press Enter to quit')
|
||||||
while not core.kbd_enter_pressed() do
|
while not core.kbd_enter_pressed() do
|
||||||
|
|
|
@ -64,8 +64,8 @@ end
|
||||||
|
|
||||||
-- This function does a connect and retrieves som info
|
-- This function does a connect and retrieves som info
|
||||||
-- @param dont_disconnect - if true, does not disable the field
|
-- @param dont_disconnect - if true, does not disable the field
|
||||||
-- @return if successfull: an table containing card info
|
-- @return if successful: an table containing card info
|
||||||
-- @return if unsuccessfull : nil, error
|
-- @return if unsuccessful : nil, error
|
||||||
local function read15693(slow, dont_readresponse)
|
local function read15693(slow, dont_readresponse)
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
|
@ -130,8 +130,8 @@ end
|
||||||
|
|
||||||
---
|
---
|
||||||
-- Waits for a ISO15693 card to be placed within the vicinity of the reader.
|
-- Waits for a ISO15693 card to be placed within the vicinity of the reader.
|
||||||
-- @return if successfull: an table containing card info
|
-- @return if successful: an table containing card info
|
||||||
-- @return if unsuccessfull : nil, error
|
-- @return if unsuccessful : nil, error
|
||||||
local function waitFor15693()
|
local function waitFor15693()
|
||||||
print('Waiting for card... press Enter to quit')
|
print('Waiting for card... press Enter to quit')
|
||||||
while not core.kbd_enter_pressed() do
|
while not core.kbd_enter_pressed() do
|
||||||
|
|
|
@ -59,7 +59,7 @@ local Utils =
|
||||||
-- @param blockData. Assumed to be on the format {'\0\1\2\3,'\b\e\e\f' ...,
|
-- @param blockData. Assumed to be on the format {'\0\1\2\3,'\b\e\e\f' ...,
|
||||||
-- that is, blockData[row] contains a string with the actual data, not ascii hex representation
|
-- that is, blockData[row] contains a string with the actual data, not ascii hex representation
|
||||||
-- return filename if all went well,
|
-- return filename if all went well,
|
||||||
-- @reurn nil, error message if unsuccessfulls
|
-- @reurn nil, error message if unsuccessful
|
||||||
WriteDumpFile = function(uid, blockData)
|
WriteDumpFile = function(uid, blockData)
|
||||||
local destination = string.format("%s.eml", uid)
|
local destination = string.format("%s.eml", uid)
|
||||||
local file = io.open(destination, "w")
|
local file = io.open(destination, "w")
|
||||||
|
|
|
@ -67,8 +67,8 @@ local function help()
|
||||||
end
|
end
|
||||||
---
|
---
|
||||||
-- Waits for a mifare card to be placed within the vicinity of the reader.
|
-- Waits for a mifare card to be placed within the vicinity of the reader.
|
||||||
-- @return if successfull: an table containing card info
|
-- @return if successful: an table containing card info
|
||||||
-- @return if unsuccessfull : nil, error
|
-- @return if unsuccessful : nil, error
|
||||||
local function wait_for_mifare()
|
local function wait_for_mifare()
|
||||||
while not core.kbd_enter_pressed() do
|
while not core.kbd_enter_pressed() do
|
||||||
res, err = lib14a.read()
|
res, err = lib14a.read()
|
||||||
|
|
|
@ -90,8 +90,8 @@ local function getblockdata(response)
|
||||||
return nil, "Couldn't read block"
|
return nil, "Couldn't read block"
|
||||||
end
|
end
|
||||||
---_ Gets data from a block
|
---_ Gets data from a block
|
||||||
-- @return {block, block+1, block+2, block+3} if successfull
|
-- @return {block, block+1, block+2, block+3} if successful
|
||||||
-- @return nil, errormessage if unsuccessfull
|
-- @return nil, errormessage if unsuccessful
|
||||||
local function getBlock(blockno)
|
local function getBlock(blockno)
|
||||||
local block, err
|
local block, err
|
||||||
local c = Command:newMIX{cmd = cmds.CMD_HF_MIFAREU_READBL, arg1 = blockno, data = 0}
|
local c = Command:newMIX{cmd = cmds.CMD_HF_MIFAREU_READBL, arg1 = blockno, data = 0}
|
||||||
|
|
|
@ -939,12 +939,12 @@ static int l_T55xx_readblock(lua_State *L) {
|
||||||
usepage1 = false;
|
usepage1 = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(NORMAL, "Safety Check Overriden - proceeding despite risk");
|
PrintAndLogEx(NORMAL, "Safety Check Overridden - proceeding despite risk");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!AquireData(usepage1, block, usepwd, password, 0)) {
|
if (!AquireData(usepage1, block, usepwd, password, 0)) {
|
||||||
return returnToLuaWithError(L, "Failed to aquire data from card");
|
return returnToLuaWithError(L, "Failed to acquire data from card");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!DecodeT55xxBlock()) {
|
if (!DecodeT55xxBlock()) {
|
||||||
|
@ -1002,7 +1002,7 @@ static int l_T55xx_detect(lua_State *L) {
|
||||||
|
|
||||||
isok = AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, 0);
|
isok = AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, 0);
|
||||||
if (isok == false) {
|
if (isok == false) {
|
||||||
return returnToLuaWithError(L, "Failed to aquire LF signal data");
|
return returnToLuaWithError(L, "Failed to acquire LF signal data");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -383,14 +383,14 @@ char *sprint_ascii(const uint8_t *data, const size_t len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_blocks(uint32_t *data, size_t len) {
|
void print_blocks(uint32_t *data, size_t len) {
|
||||||
PrintAndLogEx(NORMAL, "Blk | Data ");
|
PrintAndLogEx(SUCCESS, "Blk | Data ");
|
||||||
PrintAndLogEx(NORMAL, "----+------------");
|
PrintAndLogEx(SUCCESS, "----+------------");
|
||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
PrintAndLogEx(ERR, "..empty data");
|
PrintAndLogEx(ERR, "..empty data");
|
||||||
} else {
|
} else {
|
||||||
for (uint8_t i = 0; i < len; i++)
|
for (uint8_t i = 0; i < len; i++)
|
||||||
PrintAndLogEx(NORMAL, "%02d | 0x%08X", i, data[i]);
|
PrintAndLogEx(SUCCESS, " %02d | 0x%08X", i, data[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -419,6 +419,18 @@ uint32_t manchesterEncode2Bytes(uint16_t datain) {
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void manchesterEncodeUint32(uint32_t data_in, uint8_t bitlen_in, uint8_t *bits_out, uint16_t *index) {
|
||||||
|
for (int i = bitlen_in - 1; i >= 0; i--) {
|
||||||
|
if ((data_in >> i) & 1) {
|
||||||
|
bits_out[(*index)++] = 1;
|
||||||
|
bits_out[(*index)++] = 0;
|
||||||
|
} else {
|
||||||
|
bits_out[(*index)++] = 0;
|
||||||
|
bits_out[(*index)++] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//by marshmellow
|
//by marshmellow
|
||||||
//encode binary data into binary manchester
|
//encode binary data into binary manchester
|
||||||
//NOTE: bitstream must have triple the size of "size" available in memory to do the swap
|
//NOTE: bitstream must have triple the size of "size" available in memory to do the swap
|
||||||
|
|
|
@ -61,6 +61,7 @@ size_t fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uin
|
||||||
//void getHiLo(uint8_t *bits, size_t size, int *high, int *low, uint8_t fuzzHi, uint8_t fuzzLo);
|
//void getHiLo(uint8_t *bits, size_t size, int *high, int *low, uint8_t fuzzHi, uint8_t fuzzLo);
|
||||||
void getHiLo(int *high, int *low, uint8_t fuzzHi, uint8_t fuzzLo);
|
void getHiLo(int *high, int *low, uint8_t fuzzHi, uint8_t fuzzLo);
|
||||||
uint32_t manchesterEncode2Bytes(uint16_t datain);
|
uint32_t manchesterEncode2Bytes(uint16_t datain);
|
||||||
|
void manchesterEncodeUint32(uint32_t data_in, uint8_t bitlen_in, uint8_t *bits_out, uint16_t *index);
|
||||||
int ManchesterEncode(uint8_t *bits, size_t size);
|
int ManchesterEncode(uint8_t *bits, size_t size);
|
||||||
uint16_t manrawdecode(uint8_t *bits, size_t *size, uint8_t invert, uint8_t *alignPos);
|
uint16_t manrawdecode(uint8_t *bits, size_t *size, uint8_t invert, uint8_t *alignPos);
|
||||||
int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int *startIdx);
|
int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int *startIdx);
|
||||||
|
|
|
@ -528,7 +528,7 @@ int mbedtls_ecp_tls_write_point(const mbedtls_ecp_group *grp, const mbedtls_ecp_
|
||||||
*
|
*
|
||||||
* \return \c 0 on success,
|
* \return \c 0 on success,
|
||||||
* \return An \c MBEDTLS_ERR_MPI_XXX error code on initialization failure.
|
* \return An \c MBEDTLS_ERR_MPI_XXX error code on initialization failure.
|
||||||
* \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE for unkownn groups.
|
* \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE for unknown groups.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
int mbedtls_ecp_group_load(mbedtls_ecp_group *grp, mbedtls_ecp_group_id id);
|
int mbedtls_ecp_group_load(mbedtls_ecp_group *grp, mbedtls_ecp_group_id id);
|
||||||
|
|
|
@ -558,7 +558,7 @@ void mbedtls_strerror(int ret, char *buf, size_t buflen) {
|
||||||
if (use_ret == -(MBEDTLS_ERR_X509_BUFFER_TOO_SMALL))
|
if (use_ret == -(MBEDTLS_ERR_X509_BUFFER_TOO_SMALL))
|
||||||
mbedtls_snprintf(buf, buflen, "X509 - Destination buffer is too small");
|
mbedtls_snprintf(buf, buflen, "X509 - Destination buffer is too small");
|
||||||
if (use_ret == -(MBEDTLS_ERR_X509_FATAL_ERROR))
|
if (use_ret == -(MBEDTLS_ERR_X509_FATAL_ERROR))
|
||||||
mbedtls_snprintf(buf, buflen, "X509 - A fatal error occured, eg the chain is too long or the vrfy callback failed");
|
mbedtls_snprintf(buf, buflen, "X509 - A fatal error occurred, eg the chain is too long or the vrfy callback failed");
|
||||||
#endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */
|
#endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */
|
||||||
// END generated code
|
// END generated code
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@
|
||||||
#define MBEDTLS_ERR_X509_ALLOC_FAILED -0x2880 /**< Allocation of memory failed. */
|
#define MBEDTLS_ERR_X509_ALLOC_FAILED -0x2880 /**< Allocation of memory failed. */
|
||||||
#define MBEDTLS_ERR_X509_FILE_IO_ERROR -0x2900 /**< Read/write of file failed. */
|
#define MBEDTLS_ERR_X509_FILE_IO_ERROR -0x2900 /**< Read/write of file failed. */
|
||||||
#define MBEDTLS_ERR_X509_BUFFER_TOO_SMALL -0x2980 /**< Destination buffer is too small. */
|
#define MBEDTLS_ERR_X509_BUFFER_TOO_SMALL -0x2980 /**< Destination buffer is too small. */
|
||||||
#define MBEDTLS_ERR_X509_FATAL_ERROR -0x3000 /**< A fatal error occured, eg the chain is too long or the vrfy callback failed. */
|
#define MBEDTLS_ERR_X509_FATAL_ERROR -0x3000 /**< A fatal error occurred, eg the chain is too long or the vrfy callback failed. */
|
||||||
/* \} name */
|
/* \} name */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -251,7 +251,7 @@ int mbedtls_x509_serial_gets(char *buf, size_t size, const mbedtls_x509_buf *ser
|
||||||
*
|
*
|
||||||
* \param to mbedtls_x509_time to check
|
* \param to mbedtls_x509_time to check
|
||||||
*
|
*
|
||||||
* \return 1 if the given time is in the past or an error occured,
|
* \return 1 if the given time is in the past or an error occurred,
|
||||||
* 0 otherwise.
|
* 0 otherwise.
|
||||||
*/
|
*/
|
||||||
int mbedtls_x509_time_is_past(const mbedtls_x509_time *to);
|
int mbedtls_x509_time_is_past(const mbedtls_x509_time *to);
|
||||||
|
@ -265,7 +265,7 @@ int mbedtls_x509_time_is_past(const mbedtls_x509_time *to);
|
||||||
*
|
*
|
||||||
* \param from mbedtls_x509_time to check
|
* \param from mbedtls_x509_time to check
|
||||||
*
|
*
|
||||||
* \return 1 if the given time is in the future or an error occured,
|
* \return 1 if the given time is in the future or an error occurred,
|
||||||
* 0 otherwise.
|
* 0 otherwise.
|
||||||
*/
|
*/
|
||||||
int mbedtls_x509_time_is_future(const mbedtls_x509_time *from);
|
int mbedtls_x509_time_is_future(const mbedtls_x509_time *from);
|
||||||
|
|
|
@ -598,10 +598,10 @@ typedef struct _AT91S_RSTC {
|
||||||
#define AT91C_RSTC_RSTTYP (0x7 << 8) // (RSTC) Reset Type
|
#define AT91C_RSTC_RSTTYP (0x7 << 8) // (RSTC) Reset Type
|
||||||
#define AT91C_RSTC_RSTTYP_POWERUP (0x0 << 8) // (RSTC) Power-up Reset. VDDCORE rising.
|
#define AT91C_RSTC_RSTTYP_POWERUP (0x0 << 8) // (RSTC) Power-up Reset. VDDCORE rising.
|
||||||
#define AT91C_RSTC_RSTTYP_WAKEUP (0x1 << 8) // (RSTC) WakeUp Reset. VDDCORE rising.
|
#define AT91C_RSTC_RSTTYP_WAKEUP (0x1 << 8) // (RSTC) WakeUp Reset. VDDCORE rising.
|
||||||
#define AT91C_RSTC_RSTTYP_WATCHDOG (0x2 << 8) // (RSTC) Watchdog Reset. Watchdog overflow occured.
|
#define AT91C_RSTC_RSTTYP_WATCHDOG (0x2 << 8) // (RSTC) Watchdog Reset. Watchdog overflow occurred.
|
||||||
#define AT91C_RSTC_RSTTYP_SOFTWARE (0x3 << 8) // (RSTC) Software Reset. Processor reset required by the software.
|
#define AT91C_RSTC_RSTTYP_SOFTWARE (0x3 << 8) // (RSTC) Software Reset. Processor reset required by the software.
|
||||||
#define AT91C_RSTC_RSTTYP_USER (0x4 << 8) // (RSTC) User Reset. NRST pin detected low.
|
#define AT91C_RSTC_RSTTYP_USER (0x4 << 8) // (RSTC) User Reset. NRST pin detected low.
|
||||||
#define AT91C_RSTC_RSTTYP_BROWNOUT (0x5 << 8) // (RSTC) Brownout Reset occured.
|
#define AT91C_RSTC_RSTTYP_BROWNOUT (0x5 << 8) // (RSTC) Brownout Reset occurred.
|
||||||
#define AT91C_RSTC_NRSTL (0x1 << 16) // (RSTC) NRST pin level
|
#define AT91C_RSTC_NRSTL (0x1 << 16) // (RSTC) NRST pin level
|
||||||
#define AT91C_RSTC_SRCMP (0x1 << 17) // (RSTC) Software Reset Command in Progress.
|
#define AT91C_RSTC_SRCMP (0x1 << 17) // (RSTC) Software Reset Command in Progress.
|
||||||
// -------- RSTC_RMR : (RSTC Offset: 0x8) Reset Mode Register --------
|
// -------- RSTC_RMR : (RSTC Offset: 0x8) Reset Mode Register --------
|
||||||
|
|
|
@ -197,6 +197,14 @@ typedef struct {
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
} PACKED t55xx_write_block_t;
|
} PACKED t55xx_write_block_t;
|
||||||
|
|
||||||
|
// For CMD_LF_HID_SIMULATE (FSK)
|
||||||
|
typedef struct {
|
||||||
|
uint32_t hi2;
|
||||||
|
uint32_t hi;
|
||||||
|
uint32_t lo;
|
||||||
|
uint8_t longFMT;
|
||||||
|
} PACKED lf_hidsim_t;
|
||||||
|
|
||||||
// For CMD_LF_FSK_SIMULATE (FSK)
|
// For CMD_LF_FSK_SIMULATE (FSK)
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t fchigh;
|
uint8_t fchigh;
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
usb_dev_handle *devh = NULL;
|
usb_dev_handle *devh = NULL;
|
||||||
static unsigned int claimed_iface = 0;
|
static unsigned int claimed_iface = 0;
|
||||||
unsigned char return_on_error = 0;
|
unsigned char return_on_error = 0;
|
||||||
unsigned char error_occured = 0;
|
unsigned char error_occurred = 0;
|
||||||
|
|
||||||
void SendCommandBL(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len) {
|
void SendCommandBL(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len) {
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -37,7 +37,7 @@ void SendCommandBL(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, vo
|
||||||
|
|
||||||
ret = usb_bulk_write(devh, 0x01, (char *)&c, sizeof(PacketCommandOLD), 1000);
|
ret = usb_bulk_write(devh, 0x01, (char *)&c, sizeof(PacketCommandOLD), 1000);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error_occured = 1;
|
error_occurred = 1;
|
||||||
if (return_on_error)
|
if (return_on_error)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ bool ReceiveCommandPoll(PacketResponseOLD *c) {
|
||||||
ret = usb_bulk_read(devh, 0x82, (char *)c, sizeof(PacketResponseOLD), 500);
|
ret = usb_bulk_read(devh, 0x82, (char *)c, sizeof(PacketResponseOLD), 500);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (ret != -ETIMEDOUT) {
|
if (ret != -ETIMEDOUT) {
|
||||||
error_occured = 1;
|
error_occurred = 1;
|
||||||
if (return_on_error)
|
if (return_on_error)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#include "usb_cmd.h"
|
#include "usb_cmd.h"
|
||||||
|
|
||||||
extern unsigned char return_on_error;
|
extern unsigned char return_on_error;
|
||||||
extern unsigned char error_occured;
|
extern unsigned char error_occurred;
|
||||||
|
|
||||||
void SendCommandBL(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len);
|
void SendCommandBL(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len);
|
||||||
bool ReceiveCommandPoll(PacketResponseOLD *c);
|
bool ReceiveCommandPoll(PacketResponseOLD *c);
|
||||||
|
|
Loading…
Reference in a new issue