mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-05-12 11:18:11 -07:00
Merge branch 'master' into update_4x50
merge 20120merge 2012033
This commit is contained in:
@@ -22,6 +22,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
||||
- EM4x50: switched to cliparser for all functions (@tharexde)
|
||||
- EM4x50: stabilized and accelerated tag detection (@tharexde)
|
||||
- EM4x50: removed global tag structure on device side (@tharexde)
|
||||
- Fix `hf 15 sim` - Added basic response to GET_SYSTEM_INFO and READBLOCK requests in order to fix iso15693 tag sim
|
||||
- Added `mf mfu sim t 7 n <numreads>` - MFU emulation now supports automatic exit after <num> blocks read. (@cyberpunk-re)
|
||||
- Added T55xx Guide to assist in learning how to use the T55xx chip (@mwalker33)
|
||||
- Fix 'hf iclass wrbl' - dealing with tags in unsecured vs secured pagemode now is correct (@iceman1001)
|
||||
|
||||
+91
-24
@@ -104,10 +104,12 @@
|
||||
#define ISO15693_MAX_COMMAND_LENGTH 45 // allows write single block with the maximum block size of 256bits. Write multiple blocks not supported yet
|
||||
|
||||
// 32 + 2 crc + 1
|
||||
#define ISO15_MAX_FRAME 35
|
||||
#define CMD_ID_RESP 5
|
||||
#define CMD_READ_RESP 13
|
||||
#define CMD_INV_RESP 12
|
||||
#define ISO15_MAX_FRAME 35
|
||||
#define CMD_ID_RESP 5
|
||||
#define CMD_READ_RESP 13
|
||||
#define CMD_INV_RESP 12
|
||||
#define CMD_SYSINFO_RESP 17
|
||||
#define CMD_READBLOCK_RESP 7
|
||||
|
||||
//#define Crc(data, len) Crc(CRC_15693, (data), (len))
|
||||
#define CheckCrc15(data, len) check_crc(CRC_15693, (data), (len))
|
||||
@@ -1679,27 +1681,7 @@ void SimTagIso15693(uint8_t *uid) {
|
||||
|
||||
LED_C_ON();
|
||||
|
||||
// Build INVENTORY command
|
||||
uint8_t resp_inv[CMD_INV_RESP] = {0};
|
||||
|
||||
resp_inv[0] = 0; // No error, no protocol format extension
|
||||
resp_inv[1] = 0; // DSFID (data storage format identifier). 0x00 = not supported
|
||||
|
||||
// 64-bit UID
|
||||
resp_inv[2] = uid[7];
|
||||
resp_inv[3] = uid[6];
|
||||
resp_inv[4] = uid[5];
|
||||
resp_inv[5] = uid[4];
|
||||
resp_inv[6] = uid[3];
|
||||
resp_inv[7] = uid[2];
|
||||
resp_inv[8] = uid[1];
|
||||
resp_inv[9] = uid[0];
|
||||
|
||||
// CRC
|
||||
AddCrc15(resp_inv, 10);
|
||||
CodeIso15693AsTag(resp_inv, CMD_INV_RESP);
|
||||
|
||||
tosend_t *ts = get_tosend();
|
||||
|
||||
enum { NO_FIELD, IDLE, ACTIVATED, SELECTED, HALTED } chip_state = NO_FIELD;
|
||||
|
||||
@@ -1745,11 +1727,96 @@ void SimTagIso15693(uint8_t *uid) {
|
||||
if ((cmd_len >= 5) && (cmd[0] & ISO15_REQ_INVENTORY) && (cmd[1] == ISO15_CMD_INVENTORY)) {
|
||||
bool slow = !(cmd[0] & ISO15_REQ_DATARATE_HIGH);
|
||||
uint32_t response_time = reader_eof_time + DELAY_ISO15693_VCD_TO_VICC_SIM;
|
||||
|
||||
// Build INVENTORY command
|
||||
uint8_t resp_inv[CMD_INV_RESP] = {0};
|
||||
|
||||
resp_inv[0] = 0; // No error, no protocol format extension
|
||||
resp_inv[1] = 0; // DSFID (data storage format identifier). 0x00 = not supported
|
||||
|
||||
// 64-bit UID
|
||||
resp_inv[2] = uid[7];
|
||||
resp_inv[3] = uid[6];
|
||||
resp_inv[4] = uid[5];
|
||||
resp_inv[5] = uid[4];
|
||||
resp_inv[6] = uid[3];
|
||||
resp_inv[7] = uid[2];
|
||||
resp_inv[8] = uid[1];
|
||||
resp_inv[9] = uid[0];
|
||||
|
||||
// CRC
|
||||
AddCrc15(resp_inv, 10);
|
||||
CodeIso15693AsTag(resp_inv, CMD_INV_RESP);
|
||||
|
||||
tosend_t *ts = get_tosend();
|
||||
|
||||
TransmitTo15693Reader(ts->buf, ts->max, &response_time, 0, slow);
|
||||
LogTrace_ISO15693(resp_inv, CMD_INV_RESP, response_time * 32, (response_time * 32) + (ts->max * 32 * 64), NULL, false);
|
||||
|
||||
chip_state = SELECTED;
|
||||
}
|
||||
|
||||
// GET_SYSTEM_INFO
|
||||
if ((cmd[1] == ISO15_CMD_SYSINFO)) {
|
||||
bool slow = !(cmd[0] & ISO15_REQ_DATARATE_HIGH);
|
||||
uint32_t response_time = reader_eof_time + DELAY_ISO15693_VCD_TO_VICC_SIM;
|
||||
|
||||
// Build GET_SYSTEM_INFO command
|
||||
uint8_t resp_sysinfo[CMD_SYSINFO_RESP] = {0};
|
||||
|
||||
resp_sysinfo[0] = 0; // Response flags.
|
||||
resp_sysinfo[1] = 0x0F; // Information flags (0x0F - DSFID, AFI, Mem size, IC)
|
||||
|
||||
// 64-bit UID
|
||||
resp_sysinfo[2] = uid[7];
|
||||
resp_sysinfo[3] = uid[6];
|
||||
resp_sysinfo[4] = uid[5];
|
||||
resp_sysinfo[5] = uid[4];
|
||||
resp_sysinfo[6] = uid[3];
|
||||
resp_sysinfo[7] = uid[2];
|
||||
resp_sysinfo[8] = uid[1];
|
||||
resp_sysinfo[9] = uid[0];
|
||||
|
||||
resp_sysinfo[10] = 0; // DSFID
|
||||
resp_sysinfo[11] = 0; // AFI
|
||||
|
||||
resp_sysinfo[12] = 0x1B; // Memory size.
|
||||
resp_sysinfo[13] = 0x03; // Memory size.
|
||||
resp_sysinfo[14] = 0x01; // IC reference.
|
||||
|
||||
// CRC
|
||||
AddCrc15(resp_sysinfo, 15);
|
||||
CodeIso15693AsTag(resp_sysinfo, CMD_SYSINFO_RESP);
|
||||
|
||||
tosend_t *ts = get_tosend();
|
||||
|
||||
TransmitTo15693Reader(ts->buf, ts->max, &response_time, 0, slow);
|
||||
LogTrace_ISO15693(resp_sysinfo, CMD_SYSINFO_RESP, response_time * 32, (response_time * 32) + (ts->max * 32 * 64), NULL, false);
|
||||
}
|
||||
|
||||
// READ_BLOCK
|
||||
if ((cmd[1] == ISO15_CMD_READ)) {
|
||||
bool slow = !(cmd[0] & ISO15_REQ_DATARATE_HIGH);
|
||||
uint32_t response_time = reader_eof_time + DELAY_ISO15693_VCD_TO_VICC_SIM;
|
||||
|
||||
// Build GET_SYSTEM_INFO command
|
||||
uint8_t resp_readblock[CMD_READBLOCK_RESP] = {0};
|
||||
|
||||
resp_readblock[0] = 0; // Response flags.
|
||||
resp_readblock[1] = 0; // Block data.
|
||||
resp_readblock[2] = 0; // Block data.
|
||||
resp_readblock[3] = 0; // Block data.
|
||||
resp_readblock[4] = 0; // Block data.
|
||||
|
||||
// CRC
|
||||
AddCrc15(resp_readblock, 5);
|
||||
CodeIso15693AsTag(resp_readblock, CMD_READBLOCK_RESP);
|
||||
|
||||
tosend_t *ts = get_tosend();
|
||||
|
||||
TransmitTo15693Reader(ts->buf, ts->max, &response_time, 0, slow);
|
||||
LogTrace_ISO15693(resp_readblock, CMD_READBLOCK_RESP, response_time * 32, (response_time * 32) + (ts->max * 32 * 64), NULL, false);
|
||||
}
|
||||
}
|
||||
|
||||
switch_off();
|
||||
|
||||
+22
-1
@@ -509,10 +509,21 @@ void doCotagAcquisition(void) {
|
||||
bool firsthigh = false, firstlow = false;
|
||||
uint16_t i = 0, noise_counter = 0;
|
||||
|
||||
uint16_t checker = 0;
|
||||
|
||||
while ((i < bufsize - 1) && (noise_counter < COTAG_T1 << 1)) {
|
||||
|
||||
if (BUTTON_PRESS())
|
||||
break;
|
||||
|
||||
if (checker == 4000) {
|
||||
if (data_available())
|
||||
break;
|
||||
else
|
||||
checker = 0;
|
||||
} else {
|
||||
++checker;
|
||||
}
|
||||
|
||||
WDT_HIT();
|
||||
|
||||
@@ -567,12 +578,22 @@ uint16_t doCotagAcquisitionManchester(uint8_t *dest, uint16_t destlen) {
|
||||
bool firsthigh = false, firstlow = false;
|
||||
uint8_t curr = 0, prev = 0;
|
||||
uint16_t i = 0;
|
||||
uint16_t period = 0;
|
||||
uint16_t period = 0, checker = 0;
|
||||
|
||||
while ((i < destlen) && BUTTON_PRESS() == false) {
|
||||
|
||||
WDT_HIT();
|
||||
|
||||
if (checker == 4000) {
|
||||
if (data_available())
|
||||
break;
|
||||
else
|
||||
checker = 0;
|
||||
} else {
|
||||
++checker;
|
||||
}
|
||||
|
||||
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||
volatile uint8_t sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
|
||||
|
||||
+11
-3
@@ -1702,9 +1702,11 @@ int CmdTuneSamples(const char *Cmd) {
|
||||
if (package->peak_v > NON_VOLTAGE && package->peak_f > 0)
|
||||
PrintAndLogEx(SUCCESS, "LF optimal: %5.2f V - %6.2f kHz", (package->peak_v * ANTENNA_ERROR) / 1000.0, LF_DIV2FREQ(package->peak_f));
|
||||
|
||||
// Empirical measures in mV
|
||||
const double vdd_rdv4 = 9000;
|
||||
const double vdd_other = 5400; // Empirical measures in mV
|
||||
const double vdd_other = 5400;
|
||||
double vdd = IfPm3Rdv4Fw() ? vdd_rdv4 : vdd_other;
|
||||
|
||||
if (package->peak_v > NON_VOLTAGE && package->peak_f > 0) {
|
||||
|
||||
// Q measure with Q=f/delta_f
|
||||
@@ -1737,9 +1739,15 @@ int CmdTuneSamples(const char *Cmd) {
|
||||
// cross-check results
|
||||
if (lfq1 > 3) {
|
||||
double approx_vdd = (double)package->peak_v * 3.14 / 2 / lfq1;
|
||||
if ((approx_vdd > (vdd_rdv4 + vdd_other) / 2) && (! IfPm3Rdv4Fw()))
|
||||
// Got 8858 on a RDV4 with large antenna 134/14
|
||||
// Got 8761 on a non-RDV4
|
||||
const double approx_vdd_other_max = 8840;
|
||||
|
||||
// 1% over threshold and supposedly non-RDV4
|
||||
if ((approx_vdd > approx_vdd_other_max * 1.01) && (! IfPm3Rdv4Fw()))
|
||||
PrintAndLogEx(WARNING, "Contradicting measures seem to indicate you're running a " _YELLOW_("PM3_OTHER firmware on a RDV4") ", please check your setup");
|
||||
if ((approx_vdd < (vdd_rdv4 + vdd_other) / 2) && (IfPm3Rdv4Fw()))
|
||||
// 1% below threshold and supposedly RDV4
|
||||
if ((approx_vdd < approx_vdd_other_max * 0.99) && (IfPm3Rdv4Fw()))
|
||||
PrintAndLogEx(WARNING, "Contradicting measures seem to indicate you're running a " _YELLOW_("PM3_RDV4 firmware on a non-RDV4") ", please check your setup");
|
||||
}
|
||||
}
|
||||
|
||||
+33
-27
@@ -568,6 +568,17 @@ static int CmdHFiClassSim(const char *Cmd) {
|
||||
}
|
||||
|
||||
static int CmdHFiClassInfo(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf iclass info",
|
||||
"Act as a iCLASS reader. Reads / fingerprints a iCLASS tag.",
|
||||
"hf iclass info");
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
CLIParserFree(ctx);
|
||||
return info_iclass();
|
||||
}
|
||||
|
||||
@@ -576,8 +587,7 @@ int read_iclass_csn(bool loop, bool verbose) {
|
||||
uint32_t flags = (FLAG_ICLASS_READER_INIT | FLAG_ICLASS_READER_CLEARTRACE);
|
||||
int res = PM3_SUCCESS;
|
||||
|
||||
while (kbd_enter_pressed() == false) {
|
||||
|
||||
do {
|
||||
clearCommandBuffer();
|
||||
SendCommandMIX(CMD_HF_ICLASS_READER, flags, 0, 0, NULL, 0);
|
||||
PacketResponseNG resp;
|
||||
@@ -585,27 +595,24 @@ int read_iclass_csn(bool loop, bool verbose) {
|
||||
|
||||
uint8_t status = resp.oldarg[0] & 0xff;
|
||||
|
||||
if (loop == false) {
|
||||
if (loop) {
|
||||
if (status == 0xFF) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
|
||||
if (status == 0 || status == 0xFF) {
|
||||
if (verbose) PrintAndLogEx(WARNING, "iCLASS / ISO15693 card select failed");
|
||||
res = PM3_EOPABORTED;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (status == 0xFF)
|
||||
continue;
|
||||
}
|
||||
|
||||
picopass_hdr *hdr = (picopass_hdr *)resp.data.asBytes;
|
||||
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(SUCCESS, " CSN: " _GREEN_("%s"), sprint_hex(hdr->csn, sizeof(hdr->csn)));
|
||||
PrintAndLogEx(SUCCESS, " Config: " _GREEN_("%s"), sprint_hex((uint8_t *)&hdr->conf, sizeof(hdr->conf)));
|
||||
|
||||
if (loop == false)
|
||||
break;
|
||||
PrintAndLogEx(SUCCESS, "iCLASS / Picopass CSN: " _GREEN_("%s"), sprint_hex(hdr->csn, sizeof(hdr->csn)));
|
||||
}
|
||||
}
|
||||
} while (loop && kbd_enter_pressed() == false);
|
||||
|
||||
DropField();
|
||||
return res;
|
||||
@@ -615,22 +622,24 @@ static int CmdHFiClassReader(const char *Cmd) {
|
||||
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf iclass reader",
|
||||
"Act as a iCLASS reader. Look for iCLASS tags until Enter or the pm3 button is pressed\n",
|
||||
"hf iclass reader\n"
|
||||
"hf iclass reader -1");
|
||||
"Act as a iCLASS reader. Look for iCLASS tags until Enter or the pm3 button is pressed",
|
||||
"hf iclass reader -@ -> continuous reader mode"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_lit0("1", "one", "read once"),
|
||||
arg_lit0("@", NULL, "optional - continuous reader mode"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
bool read_once = arg_get_lit(ctx, 1);
|
||||
bool cm = arg_get_lit(ctx, 1);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
PrintAndLogEx(INFO, "Starting iCLASS reader mode");
|
||||
PrintAndLogEx(INFO, "press " _YELLOW_("`enter`") " to cancel");
|
||||
return read_iclass_csn(!read_once, true);
|
||||
if (cm) {
|
||||
PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " to exit");
|
||||
}
|
||||
|
||||
return read_iclass_csn(cm, true);
|
||||
}
|
||||
|
||||
static int CmdHFiClassELoad(const char *Cmd) {
|
||||
@@ -3272,10 +3281,10 @@ static int CmdHFiClassPermuteKey(const char *Cmd) {
|
||||
int len = 0;
|
||||
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf iclass permute",
|
||||
CLIParserInit(&ctx, "hf iclass permutekey",
|
||||
"Permute function from 'heart of darkness' paper.",
|
||||
"hf iclass permute --reverse --key 0123456789abcdef\n"
|
||||
"hf iclass permute --key ff55330f0055330f\n");
|
||||
"hf iclass permutekey --reverse --key 0123456789abcdef\n"
|
||||
"hf iclass permutekey --key ff55330f0055330f\n");
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
@@ -3473,10 +3482,7 @@ int info_iclass(void) {
|
||||
|
||||
uint8_t cardtype = get_mem_config(hdr);
|
||||
PrintAndLogEx(SUCCESS, " Card type.... " _GREEN_("%s"), card_types[cardtype]);
|
||||
|
||||
|
||||
}
|
||||
|
||||
DropField();
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ static int CmdHfLTOInfo(const char *Cmd) {
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
CLIParserFree(ctx);
|
||||
return infoLTO(true);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1434,8 +1434,8 @@ int CmdLFfind(const char *Cmd) {
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
PrintAndLogEx(INPLACE, "Searching for COTAG tag...");
|
||||
if (readCOTAGUid()) {
|
||||
PrintAndLogEx(INPLACE, "Searching for COTAG tag...");
|
||||
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("COTAG ID") " found!");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -313,6 +313,10 @@ static int CmdAWIDReader(const char *Cmd) {
|
||||
bool cm = arg_get_lit(ctx, 1);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (cm) {
|
||||
PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " to exit");
|
||||
}
|
||||
|
||||
do {
|
||||
lf_read(false, 12000);
|
||||
demodAWID(!cm);
|
||||
|
||||
+10
-4
@@ -122,15 +122,22 @@ static int CmdCOTAGReader(const char *Cmd) {
|
||||
SendCommandNG(CMD_LF_COTAG_READ, (uint8_t *)&payload, sizeof(payload));
|
||||
|
||||
uint8_t timeout = 3;
|
||||
while (!WaitForResponseTimeout(CMD_LF_COTAG_READ, &resp, 2000)) {
|
||||
int res = PM3_SUCCESS;
|
||||
while (!WaitForResponseTimeout(CMD_LF_COTAG_READ, &resp, 1000)) {
|
||||
timeout--;
|
||||
PrintAndLogEx(NORMAL, "." NOLF);
|
||||
if (timeout == 0) {
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(WARNING, "command execution time out");
|
||||
return PM3_ETIMEOUT;
|
||||
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
|
||||
res = PM3_ETIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
if (res != PM3_SUCCESS) {
|
||||
return res;
|
||||
}
|
||||
|
||||
if (timeout != 3)
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
|
||||
@@ -157,7 +164,6 @@ static command_t CommandTable[] = {
|
||||
{"reader", CmdCOTAGReader, IfPm3Lf, "Attempt to read and extract tag data"},
|
||||
{NULL, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
static int CmdHelp(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CmdsHelp(CommandTable);
|
||||
@@ -170,5 +176,5 @@ int CmdLFCOTAG(const char *Cmd) {
|
||||
}
|
||||
|
||||
int readCOTAGUid(void) {
|
||||
return (CmdCOTAGReader("") == PM3_SUCCESS);
|
||||
return (CmdCOTAGReader("-2") == PM3_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -113,6 +113,10 @@ static int CmdDestronReader(const char *Cmd) {
|
||||
bool cm = arg_get_lit(ctx, 1);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (cm) {
|
||||
PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " to exit");
|
||||
}
|
||||
|
||||
do {
|
||||
lf_read(false, 16000);
|
||||
demodDestron(!cm);
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
static int getFDXBBits(uint64_t national_code, uint16_t country_code, uint8_t is_animal, uint8_t is_extended, uint16_t extended, uint8_t *bits) {
|
||||
static int getFDXBBits(uint64_t national_code, uint16_t country_code, uint8_t is_animal, uint8_t is_extended, uint32_t extended, uint8_t *bits) {
|
||||
|
||||
// add preamble ten 0x00 and one 0x01
|
||||
memset(bits, 0x00, 10);
|
||||
@@ -103,7 +103,7 @@ static int getFDXBBits(uint64_t national_code, uint16_t country_code, uint8_t is
|
||||
}
|
||||
|
||||
// clearing the topbit needed for the preambl detection.
|
||||
static void verify_values(uint64_t *animalid, uint32_t *countryid, uint16_t *extended) {
|
||||
static void verify_values(uint64_t *animalid, uint32_t *countryid, uint32_t *extended) {
|
||||
if ((*animalid & 0x3FFFFFFFFF) != *animalid) {
|
||||
*animalid &= 0x3FFFFFFFFF;
|
||||
PrintAndLogEx(INFO, "Animal ID truncated to 38bits: " _YELLOW_("%"PRIx64), *animalid);
|
||||
@@ -112,8 +112,8 @@ static void verify_values(uint64_t *animalid, uint32_t *countryid, uint16_t *ext
|
||||
*countryid &= 0x3FF;
|
||||
PrintAndLogEx(INFO, "Country ID truncated to 10bits:" _YELLOW_("%03d"), *countryid);
|
||||
}
|
||||
if ((*extended & 0xFFF) != *extended) {
|
||||
*extended &= 0xFFF;
|
||||
if ((*extended & 0xFFFFFF) != *extended) {
|
||||
*extended &= 0xFFFFFF;
|
||||
PrintAndLogEx(INFO, "Extended truncated to 24bits: " _YELLOW_("0x%03X"), *extended);
|
||||
}
|
||||
}
|
||||
@@ -713,7 +713,7 @@ static int CmdFdxBClone(const char *Cmd) {
|
||||
uint64_t national_code = arg_get_u64_def(ctx, 2, 0);
|
||||
|
||||
int extended_len = 0;
|
||||
uint8_t edata[2] = {0};
|
||||
uint8_t edata[3] = {0};
|
||||
CLIGetHexWithReturn(ctx, 3, edata, &extended_len);
|
||||
|
||||
bool is_animal = arg_get_lit(ctx, 4);
|
||||
@@ -726,7 +726,7 @@ static int CmdFdxBClone(const char *Cmd) {
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
uint16_t extended = 0;
|
||||
uint32_t extended = 0;
|
||||
bool has_extended = false;
|
||||
if (extended_len) {
|
||||
extended = bytes_to_num(edata, extended_len);
|
||||
@@ -813,13 +813,13 @@ static int CmdFdxBSim(const char *Cmd) {
|
||||
uint32_t country_code = arg_get_u32_def(ctx, 1, 0);
|
||||
uint64_t national_code = arg_get_u64_def(ctx, 2, 0);
|
||||
int extended_len = 0;
|
||||
uint8_t edata[2] = {0};
|
||||
uint8_t edata[3] = {0};
|
||||
CLIGetHexWithReturn(ctx, 3, edata, &extended_len);
|
||||
|
||||
bool is_animal = arg_get_lit(ctx, 4);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
uint16_t extended = 0;
|
||||
uint32_t extended = 0;
|
||||
bool has_extended = false;
|
||||
if (extended_len) {
|
||||
extended = bytes_to_num(edata, extended_len);
|
||||
|
||||
@@ -154,6 +154,10 @@ static int CmdGallagherReader(const char *Cmd) {
|
||||
bool cm = arg_get_lit(ctx, 1);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (cm) {
|
||||
PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " to exit");
|
||||
}
|
||||
|
||||
do {
|
||||
lf_read(false, 4096 * 2 + 20);
|
||||
demodGallagher(!cm);
|
||||
|
||||
@@ -147,6 +147,10 @@ static int CmdGuardReader(const char *Cmd) {
|
||||
bool cm = arg_get_lit(ctx, 1);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (cm) {
|
||||
PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " to exit");
|
||||
}
|
||||
|
||||
do {
|
||||
lf_read(false, 10000);
|
||||
demodGuard(!cm);
|
||||
|
||||
@@ -45,8 +45,7 @@ static int CmdHelp(const char *Cmd);
|
||||
|
||||
// sending three times. Didn't seem to break the previous sim?
|
||||
static int sendPing(void) {
|
||||
SendCommandNG(CMD_PING, NULL, 0);
|
||||
SendCommandNG(CMD_PING, NULL, 0);
|
||||
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
|
||||
SendCommandNG(CMD_PING, NULL, 0);
|
||||
clearCommandBuffer();
|
||||
PacketResponseNG resp;
|
||||
@@ -183,6 +182,10 @@ static int CmdHIDReader(const char *Cmd) {
|
||||
bool cm = arg_get_lit(ctx, 1);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (cm) {
|
||||
PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " to exit");
|
||||
}
|
||||
|
||||
do {
|
||||
lf_read(false, 16000);
|
||||
demodHID(!cm);
|
||||
@@ -223,7 +226,8 @@ static int CmdHIDSim(const char *Cmd) {
|
||||
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf hid sim",
|
||||
"Enables simulation of HID card with card number.",
|
||||
"Enables simulation of HID card with card number.\n"
|
||||
"Simulation runs until the button is pressed or another USB command is issued.",
|
||||
"lf hid sim -r 2006ec0c86 -> HID 10301 26 bit\n"
|
||||
"lf hid sim -r 2e0ec00c87 -> HID Corporate 35 bit\n"
|
||||
"lf hid sim -r 01f0760643c3 -> HID P10001 40 bit\n"
|
||||
@@ -312,7 +316,8 @@ static int CmdHIDClone(const char *Cmd) {
|
||||
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf hid clone",
|
||||
"Clone HID to T55x7. Tag must be on antenna!",
|
||||
"clone a HID Prox tag to a T55x7, Q5/T5555 or EM4305/4469 tag.\n"
|
||||
"Tag must be on the antenna when issuing this command.",
|
||||
"lf hid clone -r 2006ec0c86 -> HID 10301 26 bit\n"
|
||||
"lf hid clone -r 2e0ec00c87 -> HID Corporate 35 bit\n"
|
||||
"lf hid clone -r 01f0760643c3 -> HID P10001 40 bit\n"
|
||||
|
||||
@@ -117,6 +117,10 @@ static int CmdIdteckReader(const char *Cmd) {
|
||||
bool cm = arg_get_lit(ctx, 1);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (cm) {
|
||||
PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " to exit");
|
||||
}
|
||||
|
||||
do {
|
||||
lf_read(false, 5000);
|
||||
demodIdteck(!cm);
|
||||
|
||||
+183
-128
@@ -38,41 +38,6 @@ static uint8_t preamble224[] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// standard 64 bit indala formats including 26 bit 40134 format
|
||||
static uint8_t preamble64[] = {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
|
||||
|
||||
static int usage_lf_indala_demod(void) {
|
||||
PrintAndLogEx(NORMAL, "Tries to psk demodulate the graphbuffer as Indala ");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Usage: lf indala demod [h] <clock> <0|1> <maxerror>");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " h : This help");
|
||||
PrintAndLogEx(NORMAL, " clock : Set clock (as integer) optional, if not set, autodetect.");
|
||||
PrintAndLogEx(NORMAL, " invert : 1 for invert output");
|
||||
PrintAndLogEx(NORMAL, " maxerror : Set maximum allowed errors, default = 100.");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" lf indala demod"));
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" lf indala demod 32") " = demod a Indala tag from GraphBuffer using a clock of RF/32");
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" lf indala demod 32 1") " = demod a Indala tag from GraphBuffer using a clock of RF/32 and inverting data");
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" lf indala demod 64 1 0") " = demod a Indala tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int usage_lf_indala_sim(void) {
|
||||
PrintAndLogEx(NORMAL, "Enables simulation of Indala card with specified uid.");
|
||||
PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued.");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Usage: lf indala sim [h] <u uid> <c cardnum>");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " h : This help");
|
||||
PrintAndLogEx(NORMAL, " u <uid> : 64/224 UID");
|
||||
PrintAndLogEx(NORMAL, " c <cardnum> : Cardnumber for Heden 2L format (decimal)");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" lf indala sim deadc0de"));
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
#define HEDEN2L_OFFSET 31
|
||||
static void encodeHeden2L(uint8_t *dest, uint32_t cardnumber) {
|
||||
|
||||
@@ -119,7 +84,7 @@ static void encodeHeden2L(uint8_t *dest, uint32_t cardnumber) {
|
||||
dest[i / 8] = bytebits_to_byte(template + i, 8);
|
||||
}
|
||||
|
||||
PrintAndLogEx(INFO, "Heden-2L card number %u", cardnumber);
|
||||
PrintAndLogEx(INFO, "Heden-2L card number " _GREEN_("%u"), cardnumber);
|
||||
}
|
||||
|
||||
static void decodeHeden2L(uint8_t *bits) {
|
||||
@@ -186,7 +151,7 @@ int demodIndalaEx(int clk, int invert, int maxErr, bool verbose) {
|
||||
uint64_t foo = uid2 & 0x7FFFFFFF;
|
||||
|
||||
if (DemodBufferLen == 64) {
|
||||
PrintAndLogEx(SUCCESS, "Indala - len %zu, Raw: %x%08x", DemodBufferLen, uid1, uid2);
|
||||
PrintAndLogEx(SUCCESS, "Indala - len " _GREEN_("%zu") " Raw: %x%08x", DemodBufferLen, uid1, uid2);
|
||||
|
||||
uint16_t p1 = 0;
|
||||
p1 |= DemodBuffer[32 + 3] << 8;
|
||||
@@ -253,7 +218,7 @@ int demodIndalaEx(int clk, int invert, int maxErr, bool verbose) {
|
||||
uint32_t uid7 = bytebits_to_byte(DemodBuffer + 192, 32);
|
||||
PrintAndLogEx(
|
||||
SUCCESS
|
||||
, "Indala - len %zu, Raw: %x%08x%08x%08x%08x%08x%08x"
|
||||
, "Indala - len " _GREEN_("%zu") " Raw: %x%08x%08x%08x%08x%08x%08x"
|
||||
, DemodBufferLen
|
||||
, uid1
|
||||
, uid2
|
||||
@@ -278,28 +243,55 @@ int demodIndala(bool verbose) {
|
||||
|
||||
static int CmdIndalaDemod(const char *Cmd) {
|
||||
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (cmdp == 'h') return usage_lf_indala_demod();
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf indala demod",
|
||||
"Tries to psk demodulate the graphbuffer as Indala Prox",
|
||||
"lf indala demod\n"
|
||||
"lf indala demod --clock 32 -> demod a Indala tag from GraphBuffer using a clock of RF/32\n"
|
||||
"lf indala demod --clock 32 -i -> demod a Indala tag from GraphBuffer using a clock of RF/32 and inverting data\n"
|
||||
"lf indala demod --clock 64 -i --maxerror 0 -> demod a Indala tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"
|
||||
);
|
||||
|
||||
int clk = 32, invert = 0, maxErr = 100;
|
||||
if (strlen(Cmd) > 0) {
|
||||
sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr);
|
||||
}
|
||||
if (clk == 1) {
|
||||
invert = 1;
|
||||
clk = 0;
|
||||
}
|
||||
if (invert != 0 && invert != 1) {
|
||||
PrintAndLogEx(WARNING, "Invalid value for invert: %i", invert);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
return demodIndalaEx(clk, invert, maxErr, true);
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_int0(NULL, "clock", "<dec>", "optional - set clock (as integer), if not set, autodetect."),
|
||||
arg_int0(NULL, "maxerr", "<dec>", "optional - set maximum allowed errors, default = 100"),
|
||||
arg_lit0("i", "invert", "optional - invert output"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
uint32_t clk = arg_get_u32_def(ctx, 1, 32);
|
||||
uint32_t max_err = arg_get_u32_def(ctx, 2, 100);
|
||||
bool invert = arg_get_lit(ctx, 3);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
return demodIndalaEx(clk, invert, max_err, true);
|
||||
}
|
||||
|
||||
// older alternative indala demodulate (has some positives and negatives)
|
||||
// returns false positives more often - but runs against more sets of samples
|
||||
// poor psk signal can be difficult to demod this approach might succeed when the other fails
|
||||
// but the other appears to currently be more accurate than this approach most of the time.
|
||||
static int CmdIndalaDemodAlt(const char *Cmd) {
|
||||
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf indala altdemod",
|
||||
"Tries to psk demodulate the graphbuffer as Indala Prox\n"
|
||||
"This is uses a alternative way to demodulate and was used from the beginning in the Pm3 client.\n"
|
||||
"It's now considered obsolete but remains because it has sometimes its advantages.",
|
||||
"lf indala altdemod\n"
|
||||
"lf indala altdemod --long -> demod a Indala tag from GraphBuffer as 224 bit long format"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_lit0("l", "long", "optional - demod as 224b long format"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
bool is_long = arg_get_lit(ctx, 1);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
// Usage: recover 64bit UID by default, specify "224" as arg to recover a 224bit UID
|
||||
int state = -1;
|
||||
int count = 0;
|
||||
@@ -360,7 +352,7 @@ static int CmdIndalaDemodAlt(const char *Cmd) {
|
||||
|
||||
// Finding the start of a UID
|
||||
int uidlen, long_wait;
|
||||
if (strcmp(Cmd, "224") == 0) {
|
||||
if (is_long) {
|
||||
uidlen = 224;
|
||||
long_wait = 30;
|
||||
} else {
|
||||
@@ -520,6 +512,10 @@ static int CmdIndalaReader(const char *Cmd) {
|
||||
bool cm = arg_get_lit(ctx, 4);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (cm) {
|
||||
PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " to exit");
|
||||
}
|
||||
|
||||
do {
|
||||
lf_read(false, 30000);
|
||||
demodIndalaEx(clk, invert, max_err, !cm);
|
||||
@@ -529,26 +525,56 @@ static int CmdIndalaReader(const char *Cmd) {
|
||||
|
||||
static int CmdIndalaSim(const char *Cmd) {
|
||||
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_indala_sim();
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf indala sim",
|
||||
"Enables simulation of IOProx card with specified facility-code and card number.\n"
|
||||
"Simulation runs until the button is pressed or another USB command is issued.",
|
||||
"lf indala sim --heden 888\n"
|
||||
"lf indala sim --raw a0000000a0002021\n"
|
||||
"lf indala sim --raw 80000001b23523a6c2e31eba3cbee4afb3c6ad1fcf649393928c14e5"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_strx0("r", "raw", "<hex>", "raw bytes"),
|
||||
arg_int0(NULL, "heden", "<decimal>", "Cardnumber for Heden 2L format"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
// raw param
|
||||
int raw_len = 0;
|
||||
uint8_t raw[(7 * 4) + 1 ];
|
||||
CLIGetHexWithReturn(ctx, 1, raw, &raw_len);
|
||||
|
||||
bool is_long_uid = (raw_len == 28);
|
||||
|
||||
int32_t cardnumber;
|
||||
bool got_cn = false;
|
||||
if (is_long_uid == false) {
|
||||
|
||||
// Heden param
|
||||
cardnumber = arg_get_int_def(ctx, 2, -1);
|
||||
got_cn = (cardnumber != -1);
|
||||
}
|
||||
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (got_cn) {
|
||||
encodeHeden2L(raw, cardnumber);
|
||||
raw_len = 8;
|
||||
}
|
||||
|
||||
// convert to binarray
|
||||
uint8_t bs[224];
|
||||
memset(bs, 0x00, sizeof(bs));
|
||||
|
||||
// uid
|
||||
uint8_t hexuid[100];
|
||||
int len = 0;
|
||||
param_gethex_ex(Cmd, 0, hexuid, &len);
|
||||
|
||||
if (len > 28)
|
||||
return usage_lf_indala_sim();
|
||||
|
||||
// convert to binarray
|
||||
uint8_t counter = 223;
|
||||
for (uint8_t i = 0; i < len; i++) {
|
||||
for (uint8_t i = 0; i < raw_len; i++) {
|
||||
uint8_t tmp = raw[i];
|
||||
for (uint8_t j = 0; j < 8; j++) {
|
||||
bs[counter--] = hexuid[i] & 1;
|
||||
hexuid[i] >>= 1;
|
||||
bs[counter--] = tmp & 1;
|
||||
tmp >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -556,7 +582,10 @@ static int CmdIndalaSim(const char *Cmd) {
|
||||
// It has to send either 64bits (8bytes) or 224bits (28bytes). Zero padding needed if not.
|
||||
// lf simpsk 1 c 32 r 2 d 0102030405060708
|
||||
|
||||
PrintAndLogEx(SUCCESS, "Simulating Indala UID: %s", sprint_hex(hexuid, len));
|
||||
PrintAndLogEx(SUCCESS, "Simulating " _YELLOW_("%s") " Indala raw " _YELLOW_("%s")
|
||||
, (is_long_uid) ? "224b" : "64b"
|
||||
, sprint_hex_inrow(raw, raw_len)
|
||||
);
|
||||
PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation or run another command");
|
||||
|
||||
// indala PSK, clock 32, carrier 0
|
||||
@@ -566,8 +595,6 @@ static int CmdIndalaSim(const char *Cmd) {
|
||||
payload->clock = 32;
|
||||
memcpy(payload->data, bs, sizeof(bs));
|
||||
|
||||
PrintAndLogEx(INFO, "Simulating");
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandNG(CMD_LF_PSK_SIMULATE, (uint8_t *)payload, sizeof(lf_psksim_t) + sizeof(bs));
|
||||
free(payload);
|
||||
@@ -584,8 +611,6 @@ static int CmdIndalaSim(const char *Cmd) {
|
||||
static int CmdIndalaClone(const char *Cmd) {
|
||||
|
||||
int32_t cardnumber;
|
||||
uint32_t blocks[8] = {0};
|
||||
uint8_t max = 0;
|
||||
uint8_t fc = 0;
|
||||
uint16_t cn = 0;
|
||||
|
||||
@@ -595,28 +620,27 @@ static int CmdIndalaClone(const char *Cmd) {
|
||||
"lf indala clone --heden 888\n"
|
||||
"lf indala clone --fc 123 --cn 1337\n"
|
||||
"lf indala clone -r a0000000a0002021\n"
|
||||
"lf indala clone -l -r 80000001b23523a6c2e31eba3cbee4afb3c6ad1fcf649393928c14e5");
|
||||
"lf indala clone -r 80000001b23523a6c2e31eba3cbee4afb3c6ad1fcf649393928c14e5");
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_lit0("l", "long", "optional - long UID 224 bits"),
|
||||
arg_int0("c", "heden", "<decimal>", "Cardnumber for Heden 2L format"),
|
||||
arg_strx0("r", "raw", "<hex>", "raw bytes"),
|
||||
arg_lit0("q", "Q5", "optional - specify writing to Q5/T5555 tag"),
|
||||
arg_int0(NULL, "fc", "<decimal>", "Facility Code (26 bit format)"),
|
||||
arg_int0(NULL, "cn", "<decimal>", "Cardnumber (26 bit format)"),
|
||||
arg_strx0("r", "raw", "<hex>", "raw bytes"),
|
||||
arg_int0(NULL, "heden", "<decimal>", "Cardnumber for Heden 2L format"),
|
||||
arg_int0(NULL, "fc", "<decimal>", "Facility Code (26 bit format)"),
|
||||
arg_int0(NULL, "cn", "<decimal>", "Cardnumber (26 bit format)"),
|
||||
arg_lit0(NULL, "q5", "optional - specify writing to Q5/T5555 tag"),
|
||||
arg_lit0(NULL, "em", "optional - specify writing to EM4305/4469 tag"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
bool is_long_uid = arg_get_lit(ctx, 1);
|
||||
|
||||
// raw param
|
||||
int datalen = 0;
|
||||
uint8_t data[(7 * 4) + 1 ];
|
||||
CLIGetHexWithReturn(ctx, 3, data, &datalen);
|
||||
int raw_len = 0;
|
||||
uint8_t raw[(7 * 4) + 1];
|
||||
CLIGetHexWithReturn(ctx, 1, raw, &raw_len);
|
||||
|
||||
bool is_t5555 = arg_get_lit(ctx, 4);
|
||||
bool is_long_uid = (raw_len == 28);
|
||||
bool q5 = arg_get_lit(ctx, 5);
|
||||
bool em = arg_get_lit(ctx, 6);
|
||||
|
||||
bool got_cn = false, got_26 = false;
|
||||
if (is_long_uid == false) {
|
||||
@@ -626,43 +650,59 @@ static int CmdIndalaClone(const char *Cmd) {
|
||||
got_cn = (cardnumber != -1);
|
||||
|
||||
// 26b FC/CN param
|
||||
fc = arg_get_int_def(ctx, 5, 0);
|
||||
cn = arg_get_int_def(ctx, 6, 0);
|
||||
fc = arg_get_int_def(ctx, 3, 0);
|
||||
cn = arg_get_int_def(ctx, 4, 0);
|
||||
got_26 = (fc != 0 && cn != 0);
|
||||
}
|
||||
|
||||
CLIParserFree(ctx);
|
||||
|
||||
PrintAndLogEx(INFO, "Target chip " _YELLOW_("%s"), (is_t5555) ? "Q5/T5555" : "T55x7");
|
||||
if (q5 && em) {
|
||||
PrintAndLogEx(FAILED, "Can't specify both Q5 and EM4305 at the same time");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
uint8_t max = 0;
|
||||
uint32_t blocks[8] = {0};
|
||||
char cardtype[16] = {"T55x7"};
|
||||
|
||||
if (is_long_uid) {
|
||||
|
||||
blocks[0] = T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK2 | (7 << T55x7_MAXBLOCK_SHIFT);
|
||||
if (q5) {
|
||||
blocks[0] = T5555_FIXED | T5555_SET_BITRATE(32) | T5555_MODULATION_PSK2 | (7 << T5555_MAXBLOCK_SHIFT);
|
||||
snprintf(cardtype, sizeof(cardtype), "Q5/T5555");
|
||||
}
|
||||
|
||||
if (em) {
|
||||
blocks[0] = EM4305_INDALA_224_CONFIG_BLOCK;
|
||||
snprintf(cardtype, sizeof(cardtype), "EM4305/4469");
|
||||
}
|
||||
|
||||
blocks[1] = bytes_to_num(raw, 4);
|
||||
blocks[2] = bytes_to_num(raw + 4, 4);
|
||||
blocks[3] = bytes_to_num(raw + 8, 4);
|
||||
blocks[4] = bytes_to_num(raw + 12, 4);
|
||||
blocks[5] = bytes_to_num(raw + 16, 4);
|
||||
blocks[6] = bytes_to_num(raw + 20, 4);
|
||||
blocks[7] = bytes_to_num(raw + 24, 4);
|
||||
max = 8;
|
||||
|
||||
// 224 BIT UID
|
||||
// config for Indala (RF/32;PSK2 with RF/2;Maxblock=7)
|
||||
PrintAndLogEx(INFO, "Preparing to clone Indala 224bit tag");
|
||||
PrintAndLogEx(INFO, "Using raw " _GREEN_("%s"), sprint_hex_inrow(data, datalen));
|
||||
PrintAndLogEx(INFO, "Preparing to clone Indala 224bit to " _YELLOW_("%s") " raw " _GREEN_("%s")
|
||||
, cardtype
|
||||
, sprint_hex_inrow(raw, raw_len)
|
||||
);
|
||||
|
||||
if (is_t5555)
|
||||
blocks[0] = T5555_FIXED | T5555_SET_BITRATE(32) | T5555_MODULATION_PSK2 | (7 << T5555_MAXBLOCK_SHIFT);
|
||||
else
|
||||
blocks[0] = T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK2 | (7 << T55x7_MAXBLOCK_SHIFT);
|
||||
|
||||
blocks[1] = bytes_to_num(data, 4);
|
||||
blocks[2] = bytes_to_num(data + 4, 4);
|
||||
blocks[3] = bytes_to_num(data + 8, 4);
|
||||
blocks[4] = bytes_to_num(data + 12, 4);
|
||||
blocks[5] = bytes_to_num(data + 16, 4);
|
||||
blocks[6] = bytes_to_num(data + 20, 4);
|
||||
blocks[7] = bytes_to_num(data + 24, 4);
|
||||
max = 8;
|
||||
} else {
|
||||
// 64 BIT UID
|
||||
if (got_cn) {
|
||||
PrintAndLogEx(INFO, "Using Indala HEDEN cardnumber %u", cardnumber);
|
||||
encodeHeden2L(data, cardnumber);
|
||||
datalen = 8;
|
||||
encodeHeden2L(raw, cardnumber);
|
||||
raw_len = 8;
|
||||
} else if (got_26) {
|
||||
|
||||
PrintAndLogEx(INFO, "Using Indala 26b FC %u CN %u", fc, cn);
|
||||
PrintAndLogEx(INFO, "Using Indala 26b FC " _GREEN_("%u") " CN " _GREEN_("%u"), fc, cn);
|
||||
|
||||
// Used with the 26bit FC/CSN
|
||||
uint8_t *bits = calloc(INDALA_ARR_LEN, sizeof(uint8_t));
|
||||
@@ -677,37 +717,52 @@ static int CmdIndalaClone(const char *Cmd) {
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
data[0] = bytebits_to_byte(bits, 8);
|
||||
data[1] = bytebits_to_byte(bits + 8, 8);
|
||||
data[2] = bytebits_to_byte(bits + 16, 8);
|
||||
data[3] = bytebits_to_byte(bits + 24, 8);
|
||||
data[4] = bytebits_to_byte(bits + 32, 8);
|
||||
data[5] = bytebits_to_byte(bits + 40, 8);
|
||||
data[6] = bytebits_to_byte(bits + 48, 8);
|
||||
data[7] = bytebits_to_byte(bits + 56, 8);
|
||||
datalen = 8;
|
||||
raw[0] = bytebits_to_byte(bits, 8);
|
||||
raw[1] = bytebits_to_byte(bits + 8, 8);
|
||||
raw[2] = bytebits_to_byte(bits + 16, 8);
|
||||
raw[3] = bytebits_to_byte(bits + 24, 8);
|
||||
raw[4] = bytebits_to_byte(bits + 32, 8);
|
||||
raw[5] = bytebits_to_byte(bits + 40, 8);
|
||||
raw[6] = bytebits_to_byte(bits + 48, 8);
|
||||
raw[7] = bytebits_to_byte(bits + 56, 8);
|
||||
raw_len = 8;
|
||||
|
||||
free(bits);
|
||||
}
|
||||
|
||||
// config for Indala 64 format (RF/32;PSK1 with RF/2;Maxblock=2)
|
||||
PrintAndLogEx(INFO, "Preparing to clone Indala 64bit tag");
|
||||
PrintAndLogEx(INFO, "Using raw " _GREEN_("%s"), sprint_hex_inrow(data, datalen));
|
||||
blocks[0] = T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK1 | (2 << T55x7_MAXBLOCK_SHIFT);
|
||||
|
||||
if (is_t5555)
|
||||
if (q5) {
|
||||
blocks[0] = T5555_FIXED | T5555_SET_BITRATE(32) | T5555_MODULATION_PSK1 | (2 << T5555_MAXBLOCK_SHIFT);
|
||||
else
|
||||
blocks[0] = T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK1 | (2 << T55x7_MAXBLOCK_SHIFT);
|
||||
snprintf(cardtype, sizeof(cardtype), "Q5/T5555");
|
||||
}
|
||||
|
||||
if (em) {
|
||||
blocks[0] = EM4305_INDALA_64_CONFIG_BLOCK;
|
||||
snprintf(cardtype, sizeof(cardtype), "EM4305/4469");
|
||||
}
|
||||
|
||||
blocks[1] = bytes_to_num(data, 4);
|
||||
blocks[2] = bytes_to_num(data + 4, 4);
|
||||
blocks[1] = bytes_to_num(raw, 4);
|
||||
blocks[2] = bytes_to_num(raw + 4, 4);
|
||||
max = 3;
|
||||
|
||||
// config for Indala 64 format (RF/32;PSK1 with RF/2;Maxblock=2)
|
||||
PrintAndLogEx(INFO, "Preparing to clone Indala 64bit to " _YELLOW_("%s") " raw " _GREEN_("%s")
|
||||
, cardtype
|
||||
, sprint_hex_inrow(raw, raw_len)
|
||||
);
|
||||
}
|
||||
|
||||
print_blocks(blocks, max);
|
||||
int res = clone_t55xx_tag(blocks, max);
|
||||
|
||||
int res;
|
||||
if (em) {
|
||||
res = em4x05_clone_tag(blocks, ARRAYLEN(blocks), 0, false);
|
||||
} else {
|
||||
res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
||||
}
|
||||
PrintAndLogEx(SUCCESS, "Done");
|
||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf indala read`") " to verify");
|
||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf indala reader`") " to verify");
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
+96
-83
@@ -1,4 +1,5 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// marshmellow
|
||||
//
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||
@@ -28,58 +29,22 @@
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
static int usage_lf_io_watch(void) {
|
||||
PrintAndLogEx(NORMAL, "Enables IOProx compatible reader mode printing details of scanned tags.");
|
||||
PrintAndLogEx(NORMAL, "By default, values are printed and logged until the button is pressed or another USB command is issued.");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Usage: lf io watch");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" lf io watch"));
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int usage_lf_io_sim(void) {
|
||||
PrintAndLogEx(NORMAL, "Enables simulation of IOProx card with specified facility-code and card number.");
|
||||
PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued.");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Usage: lf io sim [h] <version> <facility-code> <card-number>");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " h : This help");
|
||||
PrintAndLogEx(NORMAL, " <version> : 8bit version (" _YELLOW_("decimal") ")");
|
||||
PrintAndLogEx(NORMAL, " <facility-code> : 8bit value facility code (" _YELLOW_("hex") ")");
|
||||
PrintAndLogEx(NORMAL, " <card number> : 16bit value card number (" _YELLOW_("decimal") ")");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" lf io sim 01 101 1337"));
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int usage_lf_io_clone(void) {
|
||||
PrintAndLogEx(NORMAL, "Enables cloning of IOProx card with specified facility-code and card number onto T55x7 or Q5/T5555 tag");
|
||||
PrintAndLogEx(NORMAL, "The T55x7 must be on the antenna when issuing this command. T55x7 blocks are calculated and printed in the process.");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Usage: lf io clone [h] <version> <facility-code> <card-number> <Q5>");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " h : This help");
|
||||
PrintAndLogEx(NORMAL, " <version> : 8bit version (" _YELLOW_("decimal") ")");
|
||||
PrintAndLogEx(NORMAL, " <facility-code> : 8bit value facility code (" _YELLOW_("hex") ")");
|
||||
PrintAndLogEx(NORMAL, " <card number> : 16bit value card number (" _YELLOW_("decimal") ")");
|
||||
PrintAndLogEx(NORMAL, " <Q5> : optional - specify writing to Q5/T5555 tag");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" lf io clone 01 101 1337"));
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
// this read loops on device side.
|
||||
// uses the demod in lfops.c
|
||||
static int CmdIOProxWatch(const char *Cmd) {
|
||||
uint8_t c = tolower(param_getchar(Cmd, 0));
|
||||
if (c == 'h') return usage_lf_io_watch();
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf io watch",
|
||||
"Enables IOProx compatible reader mode printing details.\n"
|
||||
"By default, values are printed and logged until the button is pressed or another USB command is issued.",
|
||||
"lf io watch"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
PrintAndLogEx(SUCCESS, "Watching for IO Prox cards - place tag on antenna");
|
||||
PrintAndLogEx(INFO, "Press pm3-button to stop reading cards");
|
||||
@@ -91,7 +56,6 @@ static int CmdIOProxWatch(const char *Cmd) {
|
||||
return resp.status;
|
||||
}
|
||||
|
||||
//by marshmellow
|
||||
//IO-Prox demod - FSK RF/64 with preamble of 000000001
|
||||
//print ioprox ID and some format details
|
||||
int demodIOProx(bool verbose) {
|
||||
@@ -193,8 +157,8 @@ int demodIOProx(bool verbose) {
|
||||
static int CmdIOProxDemod(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf io demod",
|
||||
"Try to find IO Prox preamble, if found decode / descramble data",
|
||||
"lf io demod\n"
|
||||
"Try to find IOProx preamble, if found decode / descramble data",
|
||||
"lf io demod"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
@@ -209,7 +173,7 @@ static int CmdIOProxDemod(const char *Cmd) {
|
||||
static int CmdIOProxReader(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf io reader",
|
||||
"read a IO Prox tag",
|
||||
"read a IOProx tag",
|
||||
"lf io reader -@ -> continuous reader mode"
|
||||
);
|
||||
|
||||
@@ -229,29 +193,42 @@ static int CmdIOProxReader(const char *Cmd) {
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdIOProxSim(const char *Cmd) {
|
||||
uint16_t cn = 0;
|
||||
uint8_t version = 0, fc = 0;
|
||||
uint8_t bs[64];
|
||||
memset(bs, 0x00, sizeof(bs));
|
||||
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_io_sim();
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf io sim",
|
||||
"Enables simulation of IOProx card with specified facility-code and card number.\n"
|
||||
"Simulation runs until the button is pressed or another USB command is issued.",
|
||||
"lf io sim --vn 1 --fc 101 --cn 1337"
|
||||
);
|
||||
|
||||
version = param_get8(Cmd, 0);
|
||||
fc = param_get8ex(Cmd, 1, 0, 16);
|
||||
cn = param_get32ex(Cmd, 2, 0, 10);
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_u64_1(NULL, "vn", "<dec>", "8bit version"),
|
||||
arg_u64_1(NULL, "fc", "<dec>", "8bit facility code"),
|
||||
arg_u64_1(NULL, "cn", "<dec>", "16bit card number"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
if (!version || !fc || !cn) return usage_lf_io_sim();
|
||||
uint8_t version = arg_get_u32_def(ctx, 1, 0);
|
||||
uint8_t fc = arg_get_u32_def(ctx, 2, 0);
|
||||
uint16_t cn = arg_get_u32_def(ctx, 3, 0);
|
||||
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if ((cn & 0xFFFF) != cn) {
|
||||
cn &= 0xFFFF;
|
||||
PrintAndLogEx(INFO, "Card Number Truncated to 16-bits (IOProx): %u", cn);
|
||||
}
|
||||
|
||||
PrintAndLogEx(SUCCESS, "Simulating IOProx version: %u FC: %u; CN: %u\n", version, fc, cn);
|
||||
PrintAndLogEx(SUCCESS, "Simulating IOProx version: " _YELLOW_("%u") " FC: " _YELLOW_("%u (0x%02x)") " CN: " _YELLOW_("%u"), version, fc, fc, cn);
|
||||
PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation or run another command");
|
||||
|
||||
uint8_t bs[64];
|
||||
memset(bs, 0x00, sizeof(bs));
|
||||
|
||||
if (getIOProxBits(version, fc, cn, bs) != PM3_SUCCESS) {
|
||||
PrintAndLogEx(ERR, "Error with tag bitstream generation.");
|
||||
return PM3_ESOFT;
|
||||
@@ -270,10 +247,8 @@ static int CmdIOProxSim(const char *Cmd) {
|
||||
clearCommandBuffer();
|
||||
SendCommandNG(CMD_LF_FSK_SIMULATE, (uint8_t *)payload, sizeof(lf_fsksim_t) + sizeof(bs));
|
||||
free(payload);
|
||||
|
||||
PacketResponseNG resp;
|
||||
WaitForResponse(CMD_LF_FSK_SIMULATE, &resp);
|
||||
|
||||
PrintAndLogEx(INFO, "Done");
|
||||
if (resp.status != PM3_EOPABORTED)
|
||||
return resp.status;
|
||||
@@ -282,20 +257,39 @@ static int CmdIOProxSim(const char *Cmd) {
|
||||
|
||||
static int CmdIOProxClone(const char *Cmd) {
|
||||
|
||||
uint16_t cn = 0;
|
||||
uint8_t version = 0, fc = 0;
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf io clone",
|
||||
"Enables simulation of IOProx card with specified facility-code and card number.\n"
|
||||
"Tag must be on the antenna when issuing this command.",
|
||||
"lf io clone --vn 1 --fc 101 --cn 1337"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_u64_1(NULL, "vn", "<dec>", "8bit version"),
|
||||
arg_u64_1(NULL, "fc", "<dec>", "8bit facility code"),
|
||||
arg_u64_1(NULL, "cn", "<dec>", "16bit card number"),
|
||||
arg_lit0(NULL, "q5", "optional - specify writing to Q5/T5555 tag"),
|
||||
arg_lit0(NULL, "em", "optional - specify writing to EM4305/4469 tag"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
uint8_t version = arg_get_u32_def(ctx, 1, 0);
|
||||
uint8_t fc = arg_get_u32_def(ctx, 2, 0);
|
||||
uint16_t cn = arg_get_u32_def(ctx, 3, 0);
|
||||
bool q5 = arg_get_lit(ctx, 4);
|
||||
bool em = arg_get_lit(ctx, 5);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (q5 && em) {
|
||||
PrintAndLogEx(FAILED, "Can't specify both Q5 and EM4305 at the same time");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
uint8_t bits[64];
|
||||
memset(bits, 0, sizeof(bits));
|
||||
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_io_clone();
|
||||
|
||||
version = param_get8(Cmd, 0);
|
||||
fc = param_get8ex(Cmd, 1, 0, 16);
|
||||
cn = param_get32ex(Cmd, 2, 0, 10);
|
||||
|
||||
if (!version || !fc || !cn) return usage_lf_io_clone();
|
||||
|
||||
if ((cn & 0xFFFF) != cn) {
|
||||
cn &= 0xFFFF;
|
||||
PrintAndLogEx(INFO, "Card Number Truncated to 16-bits (IOProx): %u", cn);
|
||||
@@ -307,20 +301,39 @@ static int CmdIOProxClone(const char *Cmd) {
|
||||
}
|
||||
|
||||
uint32_t blocks[3] = {T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_64 | 2 << T55x7_MAXBLOCK_SHIFT, 0, 0};
|
||||
|
||||
bool q5 = tolower(param_getchar(Cmd, 3) == 'q');
|
||||
if (q5)
|
||||
char cardtype[16] = {"T55x7"};
|
||||
// Q5
|
||||
if (q5) {
|
||||
blocks[0] = T5555_FIXED | T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | T5555_SET_BITRATE(64) | 2 << T5555_MAXBLOCK_SHIFT;
|
||||
snprintf(cardtype, sizeof(cardtype), "Q5/T5555");
|
||||
}
|
||||
|
||||
// EM4305
|
||||
if (em) {
|
||||
blocks[0] = EM4305_IOPROX_CONFIG_BLOCK;
|
||||
snprintf(cardtype, sizeof(cardtype), "EM4305/4469");
|
||||
}
|
||||
|
||||
blocks[1] = bytebits_to_byte(bits, 32);
|
||||
blocks[2] = bytebits_to_byte(bits + 32, 32);
|
||||
|
||||
PrintAndLogEx(INFO, "Preparing to clone IOProx to " _YELLOW_("%s") " with Version: %u FC: %u, CN: %u", (q5) ? "Q5/T5555" : "T55x7", version, fc, cn);
|
||||
PrintAndLogEx(INFO, "Preparing to clone IOProx to " _YELLOW_("%s") " with Version: " _GREEN_("%u") " FC: " _GREEN_("%u (0x%02x)") " CN: " _GREEN_("%u")
|
||||
, cardtype
|
||||
, version
|
||||
, fc
|
||||
, fc
|
||||
, cn
|
||||
);
|
||||
print_blocks(blocks, ARRAYLEN(blocks));
|
||||
|
||||
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
||||
int res;
|
||||
if (em) {
|
||||
res = em4x05_clone_tag(blocks, ARRAYLEN(blocks), 0, false);
|
||||
} else {
|
||||
res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
||||
}
|
||||
PrintAndLogEx(SUCCESS, "Done");
|
||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf io read`") " to verify");
|
||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf io reader`") " to verify");
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
+22
-19
@@ -29,21 +29,6 @@
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
static int usage_lf_jablotron_sim(void) {
|
||||
PrintAndLogEx(NORMAL, "Enables simulation of jablotron card with specified card number.");
|
||||
PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued.");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Usage: lf jablotron sim [h] <card ID>");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " h : This help");
|
||||
PrintAndLogEx(NORMAL, " <card ID> : jablotron card ID");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" lf jablotron sim 112233"));
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static uint8_t jablontron_chksum(uint8_t *bits) {
|
||||
uint8_t chksum = 0;
|
||||
for (int i = 16; i < 56; i += 8) {
|
||||
@@ -151,6 +136,10 @@ static int CmdJablotronReader(const char *Cmd) {
|
||||
bool cm = arg_get_lit(ctx, 1);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (cm) {
|
||||
PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " to exit");
|
||||
}
|
||||
|
||||
do {
|
||||
lf_read(false, 16000);
|
||||
demodJablotron(!cm);
|
||||
@@ -247,12 +236,26 @@ static int CmdJablotronClone(const char *Cmd) {
|
||||
}
|
||||
|
||||
static int CmdJablotronSim(const char *Cmd) {
|
||||
uint64_t fullcode = 0;
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf jablotron sim",
|
||||
"Enables simulation of jablotron card with specified card number.\n"
|
||||
"Simulation runs until the button is pressed or another USB command is issued.",
|
||||
"lf jablotron sim --cn 01b669"
|
||||
);
|
||||
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_jablotron_sim();
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_str1(NULL, "cn", "<hex>", "Jablotron card ID - 5 bytes max"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
fullcode = param_get64ex(Cmd, 0, 0, 16);
|
||||
int raw_len = 0;
|
||||
uint8_t raw[5] = {0};
|
||||
CLIGetHexWithReturn(ctx, 1, raw, &raw_len);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
uint64_t fullcode = bytes_to_num(raw, raw_len);
|
||||
|
||||
// clearing the topbit needed for the preambl detection.
|
||||
if ((fullcode & 0x7FFFFFFFFF) != fullcode) {
|
||||
|
||||
@@ -206,6 +206,10 @@ static int CmdKeriReader(const char *Cmd) {
|
||||
bool cm = arg_get_lit(ctx, 1);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (cm) {
|
||||
PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " to exit");
|
||||
}
|
||||
|
||||
do {
|
||||
lf_read(false, 10000);
|
||||
demodKeri(!cm);
|
||||
|
||||
@@ -33,6 +33,7 @@ int demodMotorola(bool verbose) {
|
||||
PrintAndLogEx(DEBUG, "DEBUG: Error - Motorola: PSK Demod failed");
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
size_t size = DemodBufferLen;
|
||||
int ans = detectMotorola(DemodBuffer, &size);
|
||||
if (ans < 0) {
|
||||
@@ -148,6 +149,10 @@ static int CmdMotorolaReader(const char *Cmd) {
|
||||
bool cm = arg_get_lit(ctx, 1);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (cm) {
|
||||
PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " to exit");
|
||||
}
|
||||
|
||||
// Motorola Flexpass seem to work at 74 kHz
|
||||
// and take about 4400 samples to befor modulating
|
||||
sample_config sc = {
|
||||
@@ -161,10 +166,11 @@ static int CmdMotorolaReader(const char *Cmd) {
|
||||
};
|
||||
lf_config(&sc);
|
||||
|
||||
int res;
|
||||
do {
|
||||
// 64 * 32 * 2 * n-ish
|
||||
lf_read(false, 5000);
|
||||
demodMotorola(!cm);
|
||||
res = demodMotorola(!cm);
|
||||
} while (cm && !kbd_enter_pressed());
|
||||
|
||||
// reset back to 125 kHz
|
||||
@@ -172,7 +178,7 @@ static int CmdMotorolaReader(const char *Cmd) {
|
||||
sc.samples_to_skip = 0;
|
||||
lf_config(&sc);
|
||||
|
||||
return PM3_SUCCESS;
|
||||
return res;
|
||||
}
|
||||
|
||||
static int CmdMotorolaClone(const char *Cmd) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user