mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-23 22:55:37 -07:00
...
This commit is contained in:
parent
effe02d1d3
commit
54e7f8d438
1 changed files with 179 additions and 128 deletions
|
@ -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
|
// 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 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
|
#define HEDEN2L_OFFSET 31
|
||||||
static void encodeHeden2L(uint8_t *dest, uint32_t cardnumber) {
|
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);
|
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) {
|
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;
|
uint64_t foo = uid2 & 0x7FFFFFFF;
|
||||||
|
|
||||||
if (DemodBufferLen == 64) {
|
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;
|
uint16_t p1 = 0;
|
||||||
p1 |= DemodBuffer[32 + 3] << 8;
|
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);
|
uint32_t uid7 = bytebits_to_byte(DemodBuffer + 192, 32);
|
||||||
PrintAndLogEx(
|
PrintAndLogEx(
|
||||||
SUCCESS
|
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
|
, DemodBufferLen
|
||||||
, uid1
|
, uid1
|
||||||
, uid2
|
, uid2
|
||||||
|
@ -278,28 +243,55 @@ int demodIndala(bool verbose) {
|
||||||
|
|
||||||
static int CmdIndalaDemod(const char *Cmd) {
|
static int CmdIndalaDemod(const char *Cmd) {
|
||||||
|
|
||||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
CLIParserContext *ctx;
|
||||||
if (cmdp == 'h') return usage_lf_indala_demod();
|
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;
|
void *argtable[] = {
|
||||||
if (strlen(Cmd) > 0) {
|
arg_param_begin,
|
||||||
sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr);
|
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"),
|
||||||
if (clk == 1) {
|
arg_lit0("i", "invert", "optional - invert output"),
|
||||||
invert = 1;
|
arg_param_end
|
||||||
clk = 0;
|
};
|
||||||
}
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
if (invert != 0 && invert != 1) {
|
uint32_t clk = arg_get_u32_def(ctx, 1, 32);
|
||||||
PrintAndLogEx(WARNING, "Invalid value for invert: %i", invert);
|
uint32_t max_err = arg_get_u32_def(ctx, 2, 100);
|
||||||
return PM3_EINVARG;
|
bool invert = arg_get_lit(ctx, 3);
|
||||||
}
|
CLIParserFree(ctx);
|
||||||
return demodIndalaEx(clk, invert, maxErr, true);
|
|
||||||
|
return demodIndalaEx(clk, invert, max_err, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// older alternative indala demodulate (has some positives and negatives)
|
// older alternative indala demodulate (has some positives and negatives)
|
||||||
// returns false positives more often - but runs against more sets of samples
|
// 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
|
// 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.
|
// but the other appears to currently be more accurate than this approach most of the time.
|
||||||
static int CmdIndalaDemodAlt(const char *Cmd) {
|
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
|
// Usage: recover 64bit UID by default, specify "224" as arg to recover a 224bit UID
|
||||||
int state = -1;
|
int state = -1;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
@ -360,7 +352,7 @@ static int CmdIndalaDemodAlt(const char *Cmd) {
|
||||||
|
|
||||||
// Finding the start of a UID
|
// Finding the start of a UID
|
||||||
int uidlen, long_wait;
|
int uidlen, long_wait;
|
||||||
if (strcmp(Cmd, "224") == 0) {
|
if (is_long) {
|
||||||
uidlen = 224;
|
uidlen = 224;
|
||||||
long_wait = 30;
|
long_wait = 30;
|
||||||
} else {
|
} else {
|
||||||
|
@ -533,26 +525,56 @@ static int CmdIndalaReader(const char *Cmd) {
|
||||||
|
|
||||||
static int CmdIndalaSim(const char *Cmd) {
|
static int CmdIndalaSim(const char *Cmd) {
|
||||||
|
|
||||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
CLIParserContext *ctx;
|
||||||
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_indala_sim();
|
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];
|
uint8_t bs[224];
|
||||||
memset(bs, 0x00, sizeof(bs));
|
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;
|
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++) {
|
for (uint8_t j = 0; j < 8; j++) {
|
||||||
bs[counter--] = hexuid[i] & 1;
|
bs[counter--] = tmp & 1;
|
||||||
hexuid[i] >>= 1;
|
tmp >>= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -560,7 +582,10 @@ static int CmdIndalaSim(const char *Cmd) {
|
||||||
// It has to send either 64bits (8bytes) or 224bits (28bytes). Zero padding needed if not.
|
// It has to send either 64bits (8bytes) or 224bits (28bytes). Zero padding needed if not.
|
||||||
// lf simpsk 1 c 32 r 2 d 0102030405060708
|
// 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");
|
PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation or run another command");
|
||||||
|
|
||||||
// indala PSK, clock 32, carrier 0
|
// indala PSK, clock 32, carrier 0
|
||||||
|
@ -570,8 +595,6 @@ static int CmdIndalaSim(const char *Cmd) {
|
||||||
payload->clock = 32;
|
payload->clock = 32;
|
||||||
memcpy(payload->data, bs, sizeof(bs));
|
memcpy(payload->data, bs, sizeof(bs));
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "Simulating");
|
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandNG(CMD_LF_PSK_SIMULATE, (uint8_t *)payload, sizeof(lf_psksim_t) + sizeof(bs));
|
SendCommandNG(CMD_LF_PSK_SIMULATE, (uint8_t *)payload, sizeof(lf_psksim_t) + sizeof(bs));
|
||||||
free(payload);
|
free(payload);
|
||||||
|
@ -588,8 +611,6 @@ static int CmdIndalaSim(const char *Cmd) {
|
||||||
static int CmdIndalaClone(const char *Cmd) {
|
static int CmdIndalaClone(const char *Cmd) {
|
||||||
|
|
||||||
int32_t cardnumber;
|
int32_t cardnumber;
|
||||||
uint32_t blocks[8] = {0};
|
|
||||||
uint8_t max = 0;
|
|
||||||
uint8_t fc = 0;
|
uint8_t fc = 0;
|
||||||
uint16_t cn = 0;
|
uint16_t cn = 0;
|
||||||
|
|
||||||
|
@ -599,28 +620,27 @@ static int CmdIndalaClone(const char *Cmd) {
|
||||||
"lf indala clone --heden 888\n"
|
"lf indala clone --heden 888\n"
|
||||||
"lf indala clone --fc 123 --cn 1337\n"
|
"lf indala clone --fc 123 --cn 1337\n"
|
||||||
"lf indala clone -r a0000000a0002021\n"
|
"lf indala clone -r a0000000a0002021\n"
|
||||||
"lf indala clone -l -r 80000001b23523a6c2e31eba3cbee4afb3c6ad1fcf649393928c14e5");
|
"lf indala clone -r 80000001b23523a6c2e31eba3cbee4afb3c6ad1fcf649393928c14e5");
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
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_strx0("r", "raw", "<hex>", "raw bytes"),
|
||||||
arg_lit0("q", "Q5", "optional - specify writing to Q5/T5555 tag"),
|
arg_int0(NULL, "heden", "<decimal>", "Cardnumber for Heden 2L format"),
|
||||||
arg_int0(NULL, "fc", "<decimal>", "Facility Code (26 bit format)"),
|
arg_int0(NULL, "fc", "<decimal>", "Facility Code (26 bit format)"),
|
||||||
arg_int0(NULL, "cn", "<decimal>", "Cardnumber (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
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
|
||||||
bool is_long_uid = arg_get_lit(ctx, 1);
|
|
||||||
|
|
||||||
// raw param
|
// raw param
|
||||||
int datalen = 0;
|
int raw_len = 0;
|
||||||
uint8_t data[(7 * 4) + 1 ];
|
uint8_t raw[(7 * 4) + 1];
|
||||||
CLIGetHexWithReturn(ctx, 3, data, &datalen);
|
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;
|
bool got_cn = false, got_26 = false;
|
||||||
if (is_long_uid == false) {
|
if (is_long_uid == false) {
|
||||||
|
@ -630,43 +650,59 @@ static int CmdIndalaClone(const char *Cmd) {
|
||||||
got_cn = (cardnumber != -1);
|
got_cn = (cardnumber != -1);
|
||||||
|
|
||||||
// 26b FC/CN param
|
// 26b FC/CN param
|
||||||
fc = arg_get_int_def(ctx, 5, 0);
|
fc = arg_get_int_def(ctx, 3, 0);
|
||||||
cn = arg_get_int_def(ctx, 6, 0);
|
cn = arg_get_int_def(ctx, 4, 0);
|
||||||
got_26 = (fc != 0 && cn != 0);
|
got_26 = (fc != 0 && cn != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
CLIParserFree(ctx);
|
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) {
|
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
|
// 224 BIT UID
|
||||||
// config for Indala (RF/32;PSK2 with RF/2;Maxblock=7)
|
// config for Indala (RF/32;PSK2 with RF/2;Maxblock=7)
|
||||||
PrintAndLogEx(INFO, "Preparing to clone Indala 224bit tag");
|
PrintAndLogEx(INFO, "Preparing to clone Indala 224bit to " _YELLOW_("%s") " raw " _GREEN_("%s")
|
||||||
PrintAndLogEx(INFO, "Using raw " _GREEN_("%s"), sprint_hex_inrow(data, datalen));
|
, 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 {
|
} else {
|
||||||
// 64 BIT UID
|
// 64 BIT UID
|
||||||
if (got_cn) {
|
if (got_cn) {
|
||||||
PrintAndLogEx(INFO, "Using Indala HEDEN cardnumber %u", cardnumber);
|
encodeHeden2L(raw, cardnumber);
|
||||||
encodeHeden2L(data, cardnumber);
|
raw_len = 8;
|
||||||
datalen = 8;
|
|
||||||
} else if (got_26) {
|
} 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
|
// Used with the 26bit FC/CSN
|
||||||
uint8_t *bits = calloc(INDALA_ARR_LEN, sizeof(uint8_t));
|
uint8_t *bits = calloc(INDALA_ARR_LEN, sizeof(uint8_t));
|
||||||
|
@ -681,37 +717,52 @@ static int CmdIndalaClone(const char *Cmd) {
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
data[0] = bytebits_to_byte(bits, 8);
|
raw[0] = bytebits_to_byte(bits, 8);
|
||||||
data[1] = bytebits_to_byte(bits + 8, 8);
|
raw[1] = bytebits_to_byte(bits + 8, 8);
|
||||||
data[2] = bytebits_to_byte(bits + 16, 8);
|
raw[2] = bytebits_to_byte(bits + 16, 8);
|
||||||
data[3] = bytebits_to_byte(bits + 24, 8);
|
raw[3] = bytebits_to_byte(bits + 24, 8);
|
||||||
data[4] = bytebits_to_byte(bits + 32, 8);
|
raw[4] = bytebits_to_byte(bits + 32, 8);
|
||||||
data[5] = bytebits_to_byte(bits + 40, 8);
|
raw[5] = bytebits_to_byte(bits + 40, 8);
|
||||||
data[6] = bytebits_to_byte(bits + 48, 8);
|
raw[6] = bytebits_to_byte(bits + 48, 8);
|
||||||
data[7] = bytebits_to_byte(bits + 56, 8);
|
raw[7] = bytebits_to_byte(bits + 56, 8);
|
||||||
datalen = 8;
|
raw_len = 8;
|
||||||
|
|
||||||
free(bits);
|
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));
|
|
||||||
|
|
||||||
if (is_t5555)
|
|
||||||
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);
|
blocks[0] = T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK1 | (2 << T55x7_MAXBLOCK_SHIFT);
|
||||||
|
|
||||||
blocks[1] = bytes_to_num(data, 4);
|
if (q5) {
|
||||||
blocks[2] = bytes_to_num(data + 4, 4);
|
blocks[0] = T5555_FIXED | T5555_SET_BITRATE(32) | T5555_MODULATION_PSK1 | (2 << T5555_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(raw, 4);
|
||||||
|
blocks[2] = bytes_to_num(raw + 4, 4);
|
||||||
max = 3;
|
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);
|
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(SUCCESS, "Done");
|
||||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf indala read`") " to verify");
|
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf indala reader`") " to verify");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue