Merge branch 'master' into update_4x50

merge 20120merge 2012033
This commit is contained in:
tharexde
2020-12-03 21:17:46 +01:00
39 changed files with 890 additions and 583 deletions
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
+1 -1
View File
@@ -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
View File
@@ -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;
}
+4
View File
@@ -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
View File
@@ -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);
}
+4
View File
@@ -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);
+8 -8
View File
@@ -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);
+4
View File
@@ -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);
+4
View File
@@ -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);
+9 -4
View File
@@ -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"
+4
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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) {
+4
View File
@@ -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);
+8 -2
View File
@@ -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