Merge branch 'master' into update_4x50

update 201130
This commit is contained in:
tharexde 2020-11-30 20:38:25 +01:00
commit efd6c04b7e
49 changed files with 5965 additions and 5685 deletions

View file

@ -251,7 +251,7 @@ print-%: ; @echo $* = $($*)
cliparser:
# Get list of all commands
cat doc/commands.md | grep -e ^\|\` | cut -f 2 -d "\`" | grep -v help | awk '{$$1=$$1};1' > cliparser_all_commands.tmp
cat doc/commands.md | grep -e ^\|\` | cut -f 2 -d "\`" | grep -v 'help\|list\|mem spiffs\|quit\|exit' | awk '{$$1=$$1};1' > cliparser_all_commands.tmp
# Get list of cliparserized commands
grep -r CLIParserInit ./client/src/ | cut -f 2 -d "\"" | awk '{$$1=$$1};1' > cliparser_done.tmp
# Determine commands that still need cliparser conversion

View file

@ -907,7 +907,13 @@ static void PacketReceived(PacketCommandNG *packet) {
break;
}
case CMD_LF_TI_WRITE: {
WriteTItag(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2]);
struct p {
uint32_t high;
uint32_t low;
uint16_t crc;
} PACKED;
struct p *payload = (struct p *)packet->data.asBytes;
WriteTItag(payload->high, payload->low, packet->crc);
break;
}
case CMD_LF_SIMULATE: {

View file

@ -803,7 +803,7 @@ void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc) {
AcquireTiType();
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
DbpString("Now use `lf ti read` to check");
DbpString("Now use `lf ti reader` to check");
StopTicks();
}

View file

@ -4,8 +4,8 @@
typedef struct pm3_device pm3;
pm3 *pm3_open(char *port);
int pm3_console(pm3* dev, char *cmd);
const char *pm3_name_get(pm3* dev);
void pm3_close(pm3* dev);
int pm3_console(pm3 *dev, char *cmd);
const char *pm3_name_get(pm3 *dev);
void pm3_close(pm3 *dev);
pm3 *pm3_get_current_dev(void);
#endif // LIBPM3_H

View file

@ -3038,7 +3038,7 @@ typedef struct {
static size_t iclass_tc = 1;
static void* bf_generate_mac(void *thread_arg) {
static void *bf_generate_mac(void *thread_arg) {
iclass_thread_arg_t *targ = (iclass_thread_arg_t *)thread_arg;
const uint8_t idx = targ->thread_idx;
@ -3086,8 +3086,8 @@ void GenerateMacFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite,
args[i].keys = keys;
args[i].list.premac = list;
memcpy(args[i].csn, CSN, sizeof(args[i].csn) );
memcpy(args[i].cc_nr, CCNR, sizeof(args[i].cc_nr) );
memcpy(args[i].csn, CSN, sizeof(args[i].csn));
memcpy(args[i].cc_nr, CCNR, sizeof(args[i].cc_nr));
}
for (int i = 0; i < iclass_tc; i++) {
@ -3103,7 +3103,7 @@ void GenerateMacFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite,
pthread_join(threads[i], NULL);
}
static void* bf_generate_mackey(void *thread_arg) {
static void *bf_generate_mackey(void *thread_arg) {
iclass_thread_arg_t *targ = (iclass_thread_arg_t *)thread_arg;
const uint8_t idx = targ->thread_idx;
@ -3149,8 +3149,8 @@ void GenerateMacKeyFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elit
args[i].keys = keys;
args[i].list.prekey = list;
memcpy(args[i].csn, CSN, sizeof(args[i].csn) );
memcpy(args[i].cc_nr, CCNR, sizeof(args[i].cc_nr) );
memcpy(args[i].csn, CSN, sizeof(args[i].csn));
memcpy(args[i].cc_nr, CCNR, sizeof(args[i].cc_nr));
}
for (int i = 0; i < iclass_tc; i++) {

View file

@ -13,6 +13,7 @@
#include <string.h>
#include <ctype.h>
#include <inttypes.h>
#include "cliparser.h"
#include "cmdparser.h" // command_t
#include "comms.h"
#include "cmdtrace.h"
@ -36,62 +37,6 @@
static int CmdHelp(const char *Cmd);
static int usage_lto_info(void) {
PrintAndLogEx(NORMAL, "Usage: hf lto info [h]");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h this help");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _YELLOW_(" hf lto info"));
return PM3_SUCCESS;
}
static int usage_lto_rdbl(void) {
PrintAndLogEx(NORMAL, "Usage: hf lto rdbl [h] s <start block> e <end block>");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h this help");
PrintAndLogEx(NORMAL, " s start block in decimal >= 0");
PrintAndLogEx(NORMAL, " e end block in decimal <= 254");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _YELLOW_(" hf lto rdbl s 0 e 254") " - Read data block from 0 to 254");
return PM3_SUCCESS;
}
static int usage_lto_wrbl(void) {
PrintAndLogEx(NORMAL, "Usage: hf lto wrbl [h] b <block> d <data>");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h this help");
PrintAndLogEx(NORMAL, " b block address (decimal, 0 - 254) ");
PrintAndLogEx(NORMAL, " d 32 bytes of data to write (64 hex characters, no space)");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _YELLOW_(" hf lto wrbl b 128 d 0001020304050607080910111213141516171819202122232425262728293031") " - write 00..31 to block address 128");
return PM3_SUCCESS;
}
static int usage_lto_dump(void) {
PrintAndLogEx(NORMAL, "Usage: hf lto dump [h|p] f <filename>");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h this help");
PrintAndLogEx(NORMAL, " f file name");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _YELLOW_(" hf lto dump f myfile"));
return PM3_SUCCESS;
}
static int usage_lto_restore(void) {
PrintAndLogEx(NORMAL, "Usage: hf lto restore [h] f <filename>");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h this help");
PrintAndLogEx(NORMAL, " f file name [.bin|.eml]");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _YELLOW_(" hf lto restore f hf_lto_92C7842CFF.bin|.eml"));
return PM3_SUCCESS;
}
static void lto_switch_off_field(void) {
SendCommandMIX(CMD_HF_ISO14443A_READER, 0, 0, 0, NULL, 0);
}
@ -173,24 +118,16 @@ static int lto_select(uint8_t *id_response, uint8_t id_len, uint8_t *type_respon
}
static int CmdHfLTOInfo(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf lto info",
"Get info from LTO tags",
"hf lto info");
uint8_t cmdp = 0;
bool errors = false;
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h':
return usage_lto_info();
default:
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
}
//Validations
if (errors) {
return usage_lto_info();
}
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
return infoLTO(true);
}
@ -304,48 +241,31 @@ int rdblLTO(uint8_t st_blk, uint8_t end_blk, bool verbose) {
}
static int CmdHfLTOReadBlock(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf lto rdbl",
"Reead blocks from LTO tag",
"hf lto rdbl --first 0 --last 254");
uint8_t cmdp = 0;
bool errors = false;
uint8_t st_blk = 0;
uint8_t end_blk = 254;
void *argtable[] = {
arg_param_begin,
arg_int0(NULL, "first", "<dec>", "The first block number to read as an integer"),
arg_int0(NULL, "last", "<dec>", "The last block number to read as an integer"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h':
return usage_lto_rdbl();
case 's':
st_blk = param_get8(Cmd, cmdp + 1);
if (end_blk < st_blk) {
errors = true;
break;
}
cmdp += 2;
break;
int startblock = arg_get_int_def(ctx, 1, 0);
int endblock = arg_get_int_def(ctx, 2, 254);
case 'e':
end_blk = param_get8(Cmd, cmdp + 1);
if (end_blk < st_blk) {
errors = true;
break;
}
cmdp += 2;
break;
default:
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
}
CLIParserFree(ctx);
//Validations
if (errors) {
usage_lto_rdbl();
if (endblock < startblock) {
PrintAndLogEx(ERR, "First block must be less than last block");
return PM3_EINVARG;
}
return rdblLTO(st_blk, end_blk, true);
return rdblLTO(startblock, endblock, true);
}
static int lto_wrbl(uint8_t blk, uint8_t *data, bool verbose) {
@ -407,46 +327,33 @@ int wrblLTO(uint8_t blk, uint8_t *data, bool verbose) {
}
static int CmdHfLTOWriteBlock(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf lto wrbl",
"Write data to block on LTO tag",
"hf lto wrbl --block 128 -d 0001020304050607080910111213141516171819202122232425262728293031");
uint8_t cmdp = 0;
bool errors = false;
bool b_opt_selected = false;
bool d_opt_selected = false;
uint8_t blk = 128;
void *argtable[] = {
arg_param_begin,
arg_str1("d", "data", "<hex>", "32 bytes of data to write (64 hex symbols, no spaces)"),
arg_int1(NULL, "block", "<dec>", "The block number to write to as an integer"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
int block_data_len = 0;
uint8_t block_data[32] = {0};
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h':
return usage_lto_wrbl();
case 'b':
blk = param_get8(Cmd, cmdp + 1);
b_opt_selected = true;
cmdp += 2;
break;
case 'd':
if (param_gethex(Cmd, cmdp + 1, block_data, 64)) {
PrintAndLogEx(WARNING, "block data must include 64 HEX symbols");
errors = true;
break;
}
d_opt_selected = true;
cmdp += 2;
break;
default:
PrintAndLogEx(WARNING, "unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
CLIGetHexWithReturn(ctx, 1, block_data, &block_data_len);
if (block_data_len != 32) {
PrintAndLogEx(ERR, "Block data is incorrect length");
CLIParserFree(ctx);
return PM3_EINVARG;
}
//Validations
if (errors) {
return usage_lto_wrbl();
} else if (b_opt_selected == false || d_opt_selected == false) {
PrintAndLogEx(WARNING, "Need to specify block address and data.");
return usage_lto_wrbl();
}
int blk = arg_get_int_def(ctx, 2, 0);
CLIParserFree(ctx);
int res = wrblLTO(blk, block_data, true);
if (res == PM3_SUCCESS)
@ -504,35 +411,25 @@ int dumpLTO(uint8_t *dump, bool verbose) {
}
static int CmdHfLTODump(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf lto dump",
"Dump data from LTO tag",
"hf lto dump -f myfile");
uint8_t cmdp = 0;
bool errors = false;
uint32_t dump_len = CM_MEM_MAX_SIZE;
void *argtable[] = {
arg_param_begin,
arg_str1("f", "file", "<filename>", "specify a filename for dumpfile"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
int fnlen = 0;
char filename[FILE_PATH_SIZE] = {0};
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h':
return usage_lto_dump();
case 'f':
if (param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) {
PrintAndLogEx(FAILED, "filename too long");
errors = true;
break;
}
cmdp += 2;
break;
default:
PrintAndLogEx(WARNING, "unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
}
CLIParserFree(ctx);
if (errors) {
usage_lto_dump();
return PM3_EINVARG;
}
uint32_t dump_len = CM_MEM_MAX_SIZE;
uint8_t *dump = calloc(dump_len, sizeof(uint8_t));
if (!dump) {
@ -596,32 +493,23 @@ int restoreLTO(uint8_t *dump, bool verbose) {
}
static int CmdHfLTRestore(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf lto restore",
"Restore data from dumpfile to LTO tag",
"hf lto restore -f hf-lto-92C7842CFF.bin|.eml");
uint8_t cmdp = 0;
bool errors = false;
void *argtable[] = {
arg_param_begin,
arg_str1("f", "file", "<filename>", "specify a filename for dumpfile"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
int fnlen = 0;
char filename[FILE_PATH_SIZE] = {0};
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h':
return usage_lto_restore();
case 'f':
param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE);
if (strlen(filename) < 5)
errors = true;
cmdp += 2;
break;
default:
PrintAndLogEx(WARNING, "unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
}
if (errors || strlen(Cmd) == 0) {
return usage_lto_restore();
}
CLIParserFree(ctx);
size_t dump_len = 0;
char *lowstr = str_dup(filename);

View file

@ -266,6 +266,16 @@ static int get_plus_version(uint8_t *version, int *version_len) {
}
static int CmdHFMFPInfo(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfp info",
"Get info from MIFARE Plus tags",
"hf mfp info");
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") " ---------------------------");

View file

@ -11,96 +11,27 @@
// FSK2a, RF/50, 96 bits (complete)
//-----------------------------------------------------------------------------
#include "cmdlfawid.h" // AWID function declarations
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "commonutil.h" // ARRAYLEN
#include "cmdparser.h" // command_t
#include "comms.h"
#include "graph.h"
#include "cmddata.h"
#include "ui.h" // PrintAndLog
#include "lfdemod.h" // parityTest
#include "cmdlf.h" // lf read
#include "protocols.h" // for T55xx config register definitions
#include "util_posix.h"
#include "cmdlft55xx.h" // verifywrite
#include "cliparser.h"
#include "cmdlfem4x05.h" // EM defines
static int CmdHelp(const char *Cmd);
static int usage_lf_awid_watch(void) {
PrintAndLogEx(NORMAL, "Enables AWID compatible reader mode printing details of scanned AWID26 or AWID50 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 awid watch");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _YELLOW_(" lf awid watch"));
return PM3_SUCCESS;
}
static int usage_lf_awid_sim(void) {
PrintAndLogEx(NORMAL, "Enables simulation of AWID 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 awid sim [h] <format> <facility-code> <card-number>");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h : This help");
PrintAndLogEx(NORMAL, " <format> : format length 26|34|37|50");
PrintAndLogEx(NORMAL, " <facility-code> : 8|16bit value facility code");
PrintAndLogEx(NORMAL, " <card number> : 16|32-bit value card number");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _YELLOW_(" lf awid sim 26 224 1337"));
PrintAndLogEx(NORMAL, _YELLOW_(" lf awid sim 50 2001 13371337"));
return PM3_SUCCESS;
}
static int usage_lf_awid_clone(void) {
PrintAndLogEx(NORMAL, "Enables cloning of AWID card with specified facility-code and card number onto T55x7 or Q5/T5555.");
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 awid clone [h] <format> <facility-code> <card-number> [Q5]");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h : This help");
PrintAndLogEx(NORMAL, " <format> : format length 26|34|37|50");
PrintAndLogEx(NORMAL, " <facility-code> : 8|16bit value facility code");
PrintAndLogEx(NORMAL, " <card number> : 16|32-bit value card number");
PrintAndLogEx(NORMAL, " Q5 : optional - specify writing to Q5/T5555 tag");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _YELLOW_(" lf awid clone 26 224 1337"));
PrintAndLogEx(NORMAL, _YELLOW_(" lf awid clone 50 2001 13371337"));
return PM3_SUCCESS;
}
static int usage_lf_awid_brute(void) {
PrintAndLogEx(NORMAL, "Enables bruteforce of AWID reader with specified facility-code.");
PrintAndLogEx(NORMAL, "This is a attack against reader. if cardnumber is given, it starts with it and goes up / down one step");
PrintAndLogEx(NORMAL, "if cardnumber is not given, it starts with 1 and goes up to 65535");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: lf awid brute [h] [v] a <format> f <facility-code> c <cardnumber> d <delay>");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h : This help");
PrintAndLogEx(NORMAL, " a <format> : format length 26|50");
PrintAndLogEx(NORMAL, " f <facility-code> : 8|16bit value facility code");
PrintAndLogEx(NORMAL, " c <cardnumber> : (optional) cardnumber to start with, max 65535");
PrintAndLogEx(NORMAL, " d <delay> : delay betweens attempts in ms. Default 1000ms");
PrintAndLogEx(NORMAL, " v : verbose logging, show all tries");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _YELLOW_(" lf awid brute a 26 f 224"));
PrintAndLogEx(NORMAL, _YELLOW_(" lf awid brute a 50 f 2001 d 2000"));
PrintAndLogEx(NORMAL, _YELLOW_(" lf awid brute v a 50 f 2001 c 200 d 2000"));
return PM3_SUCCESS;
}
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;
@ -112,7 +43,7 @@ static int sendPing(void) {
static int sendTry(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint32_t delay, uint8_t *bits, size_t bs_len, bool verbose) {
if (verbose)
PrintAndLogEx(INFO, "Trying FC: %u; CN: %u", fc, cn);
PrintAndLogEx(INFO, "Trying FC: " _YELLOW_("%u") " CN: " _YELLOW_("%u"), fc, cn);
if (getAWIDBits(fmtlen, fc, cn, bits) != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Error with tag bitstream generation.");
@ -180,8 +111,19 @@ static void verify_values(uint8_t *fmtlen, uint32_t *fc, uint32_t *cn) {
// this read loops on device side.
// uses the demod in lfops.c
static int CmdAWIDWatch(const char *Cmd) {
uint8_t c = tolower(param_getchar(Cmd, 0));
if (c == 'h') return usage_lf_awid_watch();
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf awid watch",
"Enables AWID compatible reader mode printing details of scanned AWID26 or AWID50 tags.\n"
"Run until the button is pressed or another USB command is issued.",
"lf awid watch"
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
PrintAndLogEx(SUCCESS, "Watching for AWID cards - place tag on antenna");
PrintAndLogEx(INFO, "Press pm3-button to stop reading cards");
@ -339,31 +281,152 @@ int demodAWID(bool verbose) {
}
static int CmdAWIDDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf awid demod",
"Try to find AWID Prox preamble, if found decode / descramble data",
"lf awid demod"
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
return demodAWID(true);
}
// this read is the "normal" read, which download lf signal and tries to demod here.
static int CmdAWIDRead(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
static int CmdAWIDReader(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf awid reader",
"read a AWID Prox tag",
"lf awid reader -@ -> continuous reader mode"
);
void *argtable[] = {
arg_param_begin,
arg_lit0("@", NULL, "optional - continuous reader mode"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
bool cm = arg_get_lit(ctx, 1);
CLIParserFree(ctx);
do {
lf_read(false, 12000);
return demodAWID(true);
demodAWID(!cm);
} while (cm && !kbd_enter_pressed());
return PM3_SUCCESS;
}
static int CmdAWIDClone(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf awid clone",
"clone a AWID Prox tag to a T55x7, Q5/T5555 or EM4305/4469 tag",
"lf awid clone --fmt 26 --fc 123 --cn 1337\n"
"lf awid clone --fmt 50 --fc 2001 --cn 13371337\n"
"lf awid clone --q5 --fmt 26 --fc 123 --cn 1337 -> encode for Q5/T5555 tag\n"
"lf awid clone --em --fmt 26 --fc 123 --cn 1337 -> encode for EM4305/4469"
);
void *argtable[] = {
arg_param_begin,
arg_u64_1(NULL, "fmt", "<dec>", "format length 26|34|37|50"),
arg_u64_1(NULL, "fc", "<dec>", "8|16bit value facility code"),
arg_u64_1(NULL, "cn", "<dec>", "16|32-bit value 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 fmtlen = arg_get_u32_def(ctx, 1, 0);
uint32_t fc = arg_get_u32_def(ctx, 2, 0);
uint32_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;
}
uint32_t blocks[4] = {T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_50 | 3 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0};
char cardtype[16] = {"T55x7"};
// Q5
if (q5) {
//t5555 (Q5) BITRATE = (RF-2)/2 (iceman)
blocks[0] = T5555_FIXED | T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | T5555_SET_BITRATE(50) | 3 << T5555_MAXBLOCK_SHIFT;
snprintf(cardtype, sizeof(cardtype), "Q5/T5555");
}
// EM4305
if (em) {
blocks[0] = EM4305_AWID_CONFIG_BLOCK;
snprintf(cardtype, sizeof(cardtype), "EM4305/4469");
}
verify_values(&fmtlen, &fc, &cn);
uint8_t *bits = calloc(96, sizeof(uint8_t));
if (getAWIDBits(fmtlen, fc, cn, bits) != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Error with tag bitstream generation.");
free(bits);
return PM3_ESOFT;
}
blocks[1] = bytebits_to_byte(bits, 32);
blocks[2] = bytebits_to_byte(bits + 32, 32);
blocks[3] = bytebits_to_byte(bits + 64, 32);
free(bits);
PrintAndLogEx(INFO, "Preparing to clone AWID %u to " _YELLOW_("%s") " with FC: " _GREEN_("%u") " CN: " _GREEN_("%u"), fmtlen, cardtype, fc, cn);
print_blocks(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 awid reader`") " to verify");
return res;
}
static int CmdAWIDSim(const char *Cmd) {
uint32_t fc = 0, cn = 0;
uint8_t fmtlen = 0;
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf awid sim",
"Enables simulation of AWID card with specified facility-code and card number.\n"
"Simulation runs until the button is pressed or another USB command is issued.",
"lf awid sim --fmt 26 --fc 123 --cn 1337\n"
"lf awid sim --fmt 50 --fc 2001 --cn 13371337"
);
void *argtable[] = {
arg_param_begin,
arg_u64_1(NULL, "fmt", "<dec>", "format length 26|32|36|40"),
arg_u64_1(NULL, "fc", "<dec>", "8-bit value facility code"),
arg_u64_1(NULL, "cn", "<dec>", "16-bit value card number"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
uint8_t fmtlen = arg_get_u32_def(ctx, 1, 0);
uint32_t fc = arg_get_u32_def(ctx, 2, 0);
uint32_t cn = arg_get_u32_def(ctx, 3, 0);
CLIParserFree(ctx);
uint8_t bs[96];
memset(bs, 0x00, sizeof(bs));
char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_awid_sim();
fmtlen = param_get8(Cmd, 0);
fc = param_get32ex(Cmd, 1, 0, 10);
cn = param_get32ex(Cmd, 2, 0, 10);
if (!fc || !cn) return usage_lf_awid_sim();
verify_values(&fmtlen, &fc, &cn);
if (getAWIDBits(fmtlen, fc, cn, bs) != PM3_SUCCESS) {
@ -371,7 +434,7 @@ static int CmdAWIDSim(const char *Cmd) {
return PM3_ESOFT;
}
PrintAndLogEx(SUCCESS, "Simulating AWID %u -- FC: %u; CN: %u\n", fmtlen, fc, cn);
PrintAndLogEx(SUCCESS, "Simulating AWID %u -- FC: " _YELLOW_("%u") " CN: " _YELLOW_("%u"), fmtlen, fc, cn);
PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation or run another command");
// AWID uses: FSK2a fcHigh: 10, fcLow: 8, clk: 50, invert: 1
@ -398,97 +461,34 @@ static int CmdAWIDSim(const char *Cmd) {
return PM3_SUCCESS;
}
static int CmdAWIDClone(const char *Cmd) {
uint32_t fc = 0, cn = 0;
uint8_t fmtlen = 0;
char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_awid_clone();
fmtlen = param_get8(Cmd, 0);
fc = param_get32ex(Cmd, 1, 0, 10);
cn = param_get32ex(Cmd, 2, 0, 10);
if (!fc || !cn) return usage_lf_awid_clone();
uint32_t blocks[4] = {T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_50 | 3 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0};
bool q5 = tolower(param_getchar(Cmd, 3)) == 'q';
if (q5)
//t5555 (Q5) BITRATE = (RF-2)/2 (iceman)
blocks[0] = T5555_FIXED | T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | T5555_SET_BITRATE(50) | 3 << T5555_MAXBLOCK_SHIFT;
verify_values(&fmtlen, &fc, &cn);
uint8_t *bits = calloc(96, sizeof(uint8_t));
if (getAWIDBits(fmtlen, fc, cn, bits) != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Error with tag bitstream generation.");
free(bits);
return PM3_ESOFT;
}
blocks[1] = bytebits_to_byte(bits, 32);
blocks[2] = bytebits_to_byte(bits + 32, 32);
blocks[3] = bytebits_to_byte(bits + 64, 32);
free(bits);
PrintAndLogEx(INFO, "Preparing to clone AWID %u to " _YELLOW_("%s") " with FC: %u, CN: %u", fmtlen, (q5) ? "Q5/T5555" : "T55x7", fc, cn);
print_blocks(blocks, ARRAYLEN(blocks));
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
PrintAndLogEx(SUCCESS, "Done");
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf awid read`") " to verify");
return res;
}
static int CmdAWIDBrute(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf awid brute",
"Enables bruteforce of AWID reader with specified facility-code.\n"
"This is a attack against reader. if cardnumber is given, it starts with it and goes up / down one step\n"
"if cardnumber is not given, it starts with 1 and goes up to 65535",
"lf awid brute --fmt 26 --fc 224\n"
"lf awid brute --fmt 50 --fc 2001 --delay 2000\n"
"lf awid brute --fmt 50 --fc 2001 --cn 200 --delay 2000 -v"
);
bool errors = false, verbose = false;
uint32_t fc = 0, cn = 0, delay = 1000;
uint8_t fmtlen = 0;
uint8_t bits[96];
size_t size = sizeof(bits);
memset(bits, 0x00, size);
uint8_t cmdp = 0;
void *argtable[] = {
arg_param_begin,
arg_u64_1(NULL, "fmt", "<dec>", "format length 26|50"),
arg_u64_1(NULL, "fc", "<dec>", "8|16bit value facility code"),
arg_u64_0(NULL, "cn", "<dec>", "optional - card number to start with, max 65535"),
arg_u64_0(NULL, "delay", "<dec>", "optional - delay betweens attempts in ms. Default 1000ms"),
arg_lit0("v", "verbose", "verbose logging, show all tries"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h':
return usage_lf_awid_brute();
case 'f':
fc = param_get32ex(Cmd, cmdp + 1, 0, 10);
if (!fc)
errors = true;
cmdp += 2;
break;
case 'd':
// delay between attemps, defaults to 1000ms.
delay = param_get32ex(Cmd, cmdp + 1, 1000, 10);
cmdp += 2;
break;
case 'c':
cn = param_get32ex(Cmd, cmdp + 1, 0, 10);
// truncate cardnumber.
cn &= 0xFFFF;
cmdp += 2;
break;
case 'a':
fmtlen = param_get8(Cmd, cmdp + 1);
cmdp += 2;
break;
case 'v':
verbose = true;
cmdp++;
break;
default:
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
}
if (fc == 0) errors = true;
if (errors) return usage_lf_awid_brute();
uint8_t fmtlen = arg_get_u32_def(ctx, 1, 0);
uint32_t fc = arg_get_u32_def(ctx, 2, 0);
uint32_t cn = arg_get_u32_def(ctx, 3, 0);
uint32_t delay = arg_get_u32_def(ctx, 4, 1000);
bool verbose = arg_get_lit(ctx, 5);
CLIParserFree(ctx);
// limit fc according to selected format
switch (fmtlen) {
@ -506,12 +506,23 @@ static int CmdAWIDBrute(const char *Cmd) {
break;
}
PrintAndLogEx(SUCCESS, "Bruteforceing AWID %d Reader", fmtlen);
// truncate card number
if ((cn & 0xFFFF) != cn) {
cn &= 0xFFFF;
PrintAndLogEx(INFO, "Card number truncated to 16-bits : %u", cn);
}
PrintAndLogEx(SUCCESS, "Bruteforceing AWID %d reader", fmtlen);
PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation or press Enter");
uint16_t up = cn;
uint16_t down = cn;
uint8_t bits[96];
size_t size = sizeof(bits);
memset(bits, 0x00, size);
// main loop
for (;;) {
@ -525,13 +536,20 @@ static int CmdAWIDBrute(const char *Cmd) {
}
// Do one up
if (up < 0xFFFF)
if (sendTry(fmtlen, fc, up++, delay, bits, size, verbose) != PM3_SUCCESS) return PM3_ESOFT;
if (up < 0xFFFF) {
if (sendTry(fmtlen, fc, up++, delay, bits, size, verbose) != PM3_SUCCESS) {
return PM3_ESOFT;
}
}
// Do one down (if cardnumber is given)
if (cn > 1)
if (down > 1)
if (sendTry(fmtlen, fc, --down, delay, bits, size, verbose) != PM3_SUCCESS) return PM3_ESOFT;
if (cn > 1) {
if (down > 1) {
if (sendTry(fmtlen, fc, --down, delay, bits, size, verbose) != PM3_SUCCESS) {
return PM3_ESOFT;
}
}
}
}
return PM3_SUCCESS;
}
@ -539,7 +557,7 @@ static int CmdAWIDBrute(const char *Cmd) {
static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "this help"},
{"demod", CmdAWIDDemod, AlwaysAvailable, "demodulate an AWID FSK tag from the GraphBuffer"},
{"read", CmdAWIDRead, IfPm3Lf, "attempt to read and extract tag data"},
{"reader", CmdAWIDReader, IfPm3Lf, "attempt to read and extract tag data"},
{"clone", CmdAWIDClone, IfPm3Lf, "clone AWID tag to T55x7 or Q5/T5555"},
{"sim", CmdAWIDSim, IfPm3Lf, "simulate AWID tag"},
{"brute", CmdAWIDBrute, IfPm3Lf, "Bruteforce card number against reader"},

View file

@ -8,33 +8,18 @@
// Low frequency COTAG commands
//-----------------------------------------------------------------------------
#include "cmdlfcotag.h" // COTAG function declarations
#include <string.h>
#include <stdio.h>
#include "cmdparser.h" // command_t
#include "comms.h"
#include "lfdemod.h"
#include "cmddata.h" // getSamples
#include "ui.h" // PrintAndLog
#include "ctype.h" // tolower
#include "cliparser.h"
static int CmdHelp(const char *Cmd);
static int usage_lf_cotag_read(void) {
PrintAndLogEx(NORMAL, "Usage: lf COTAG read [h] <signaldata>");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h : This help");
PrintAndLogEx(NORMAL, " <0|1|2> : 0 - HIGH/LOW signal; maxlength bigbuff");
PrintAndLogEx(NORMAL, " : 1 - translation of HI/LO into bytes with manchester 0,1");
PrintAndLogEx(NORMAL, " : 2 - raw signal; maxlength bigbuff");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Example:");
PrintAndLogEx(NORMAL, " lf cotag read 0");
PrintAndLogEx(NORMAL, " lf cotag read 1");
return PM3_SUCCESS;
}
// COTAG demod should be able to use GraphBuffer,
// when data load samples
int demodCOTAG(bool verbose) {
@ -74,22 +59,63 @@ int demodCOTAG(bool verbose) {
}
static int CmdCOTAGDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf cotag demod",
"Try to find COTAG preamble, if found decode / descramble data",
"lf cotag demod"
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
return demodCOTAG(true);
}
// When reading a COTAG.
// 0 = HIGH/LOW signal - maxlength bigbuff
// 1 = translation for HI/LO into bytes with manchester 0,1 - length 300
// 2 = raw signal - maxlength bigbuff
static int CmdCOTAGRead(const char *Cmd) {
static int CmdCOTAGReader(const char *Cmd) {
if (tolower(Cmd[0]) == 'h')
return usage_lf_cotag_read();
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf cotag reader",
"read a COTAG tag, the current support for COTAG is limited. ",
"lf cotag reader -2"
);
void *argtable[] = {
arg_param_begin,
arg_lit0("1", NULL, "HIGH/LOW signal; maxlength bigbuff"),
arg_lit0("2", NULL, "translation of HIGH/LOW into bytes with manchester 0,1"),
arg_lit0("3", NULL, "raw signal; maxlength bigbuff"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
bool mode0 = arg_get_lit(ctx, 1);
bool mode1 = arg_get_lit(ctx, 2);
bool mode2 = arg_get_lit(ctx, 3);
CLIParserFree(ctx);
if ((mode0 + mode1 + mode2) > 1) {
PrintAndLogEx(ERR, "You can only use one option at a time");
return PM3_EINVARG;
}
uint8_t mode = 0xFF;
if (mode0)
mode = 0;
if (mode1)
mode = 1;
if (mode2)
mode = 2;
struct p {
uint8_t mode;
} PACKED payload;
payload.mode = param_get8ex(Cmd, 0, 1, 10);
payload.mode = mode;
PacketResponseNG resp;
clearCommandBuffer();
@ -128,7 +154,7 @@ static int CmdCOTAGRead(const char *Cmd) {
static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"demod", CmdCOTAGDemod, AlwaysAvailable, "Tries to decode a COTAG signal"},
{"read", CmdCOTAGRead, IfPm3Lf, "Attempt to read and extract tag data"},
{"reader", CmdCOTAGReader, IfPm3Lf, "Attempt to read and extract tag data"},
{NULL, NULL, NULL, NULL}
};
@ -144,5 +170,5 @@ int CmdLFCOTAG(const char *Cmd) {
}
int readCOTAGUid(void) {
return (CmdCOTAGRead("") == PM3_SUCCESS);
return (CmdCOTAGReader("") == PM3_SUCCESS);
}

View file

@ -7,8 +7,7 @@
// Low frequency FDX-A FECAVA Destron tag commands
//-----------------------------------------------------------------------------
#include "cmdlfdestron.h"
#include <ctype.h> //tolower
#include <ctype.h> // tolower
#include <string.h> // memcpy
#include "commonutil.h" // ARRAYLEN
#include "common.h"
@ -21,8 +20,9 @@
#include "protocols.h" // t55xx defines
#include "cmdlft55xx.h" // clone..
#include "cmdlf.h" // cmdlfconfig
#include "cliparser.h" // cli parse input
#include "parity.h"
#include "cliparser.h" // cli parse input
#include "cmdlfem4x05.h" // EM defines
#define DESTRON_FRAME_SIZE 96
#define DESTRON_PREAMBLE_SIZE 16
@ -36,6 +36,7 @@ int demodDestron(bool verbose) {
PrintAndLogEx(DEBUG, "DEBUG: Error - Destron: FSK Demod failed");
return PM3_ESOFT;
}
size_t size = DemodBufferLen;
int ans = detectDestron(DemodBuffer, &size);
if (ans < 0) {
@ -50,12 +51,13 @@ int demodDestron(bool verbose) {
return PM3_ESOFT;
}
setDemodBuff(DemodBuffer, DESTRON_FRAME_SIZE, ans);
setClockGrid(g_DemodClock, g_DemodStartIdx + (ans * g_DemodClock));
uint8_t bits[DESTRON_FRAME_SIZE - DESTRON_PREAMBLE_SIZE] = {0};
size_t bitlen = DESTRON_FRAME_SIZE - DESTRON_PREAMBLE_SIZE;
memcpy(bits, DemodBuffer + 16, DESTRON_FRAME_SIZE - DESTRON_PREAMBLE_SIZE);
memcpy(bits, DemodBuffer + DESTRON_PREAMBLE_SIZE, DESTRON_FRAME_SIZE - DESTRON_PREAMBLE_SIZE);
uint8_t alignPos = 0;
uint16_t errCnt = manrawdecode(bits, &bitlen, 0, &alignPos);
@ -75,65 +77,145 @@ int demodDestron(bool verbose) {
PrintAndLogEx(DEBUG, "DEBUG: Error - Destron: parity errors: %d", parity_err);
return PM3_ESOFT;
}
PrintAndLogEx(SUCCESS, "FDX-A FECAVA Destron: " _GREEN_("%02X%02X%02X%02X%02X"), data[0], data[1], data[2], data[3], data[4]);
PrintAndLogEx(SUCCESS, "FDX-A FECAVA Destron: " _GREEN_("%s"), sprint_hex_inrow(data, 5));
return PM3_SUCCESS;
}
static int CmdDestronDemod(const char *Cmd) {
(void)Cmd;
return demodDestron(true);
}
static int CmdDestronRead(const char *Cmd) {
lf_read(false, 16000);
return demodDestron(true);
}
static int CmdDestronClone(const char *Cmd) {
uint32_t blocks[4] = {0};
uint8_t data[8];
int datalen = 0;
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf destron clone",
"Enables cloning of Destron card with specified uid onto T55x7",
"lf destron clone 1A2B3C4D5E"
CLIParserInit(&ctx, "lf destron demod",
"Try to find Destron preamble, if found decode / descramble data",
"lf destron demod"
);
void *argtable[] = {
arg_param_begin,
arg_strx1(NULL, NULL, "<uid (hex)>", NULL),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
return demodDestron(true);
}
static int CmdDestronReader(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf destron reader",
"read a Destron tag",
"lf destron reader -@ -> continuous reader mode"
);
void *argtable[] = {
arg_param_begin,
arg_lit0("@", NULL, "optional - continuous reader mode"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
bool cm = arg_get_lit(ctx, 1);
CLIParserFree(ctx);
do {
lf_read(false, 16000);
demodDestron(!cm);
} while (cm && !kbd_enter_pressed());
return PM3_SUCCESS;
}
static int CmdDestronClone(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf destron clone",
"clone a Destron tag to a T55x7, Q5/T5555 or EM4305/4469 tag.",
"lf destron clone --uid 1A2B3C4D5E\n"
"lf destron clone --q5 --uid 1A2B3C4D5E -> encode for Q5/T5555 tag\n"
"lf destron clone --em --uid 1A2B3C4D5E -> encode for EM4305/4469"
);
void *argtable[] = {
arg_param_begin,
arg_strx1("u", "uid", "<hex>", "5 bytes max"),
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
};
//TODO add selection of chip for Q5 or T55x7
CLIExecWithReturn(ctx, Cmd, argtable, false);
uint8_t data[8];
int datalen = 0;
CLIGetHexWithReturn(ctx, 1, data, &datalen);
bool q5 = arg_get_lit(ctx, 2);
bool em = arg_get_lit(ctx, 3);
CLIParserFree(ctx);
if (q5 && em) {
PrintAndLogEx(FAILED, "Can't specify both Q5 and EM4305 at the same time");
return PM3_EINVARG;
}
if (datalen > 5) {
PrintAndLogEx(FAILED, "Uid is max 5 bytes. (got %u)", datalen);
return PM3_EINVARG;
}
uint32_t blocks[4] = {0};
blocks[0] = T55x7_BITRATE_RF_50 | T55x7_MODULATION_FSK2 | 3 << T55x7_MAXBLOCK_SHIFT;
char cardtype[16] = {"T55x7"};
// Q5
if (q5) {
blocks[0] = T5555_FIXED | T5555_MODULATION_FSK2 | T5555_SET_BITRATE(50) | 3 << T5555_MAXBLOCK_SHIFT;
snprintf(cardtype, sizeof(cardtype), "Q5/T5555");
}
// EM4305
if (em) {
blocks[0] = EM4305_DESTRON_CONFIG_BLOCK;
snprintf(cardtype, sizeof(cardtype), "EM4305/4469");
}
uint8_t data_ex[12 + 24] = {0}; // ManchesterEncode need extra room
for (int i = 0; i < datalen; i++) {
data_ex[i + 1] = ~data [i] | (evenparity8(data[i]) << 7);
data_ex[i + 1] = ~(data [i] | (oddparity8(data[i]) << 7));
}
// manchester encode it
for (int i = 0; i < 3; i++) {
blocks[i + 1] = manchesterEncode2Bytes((data_ex[i * 2] << 8) + data_ex[i * 2 + 1]);
}
// inject preamble
blocks[1] = (blocks[1] & 0xFFFF) | 0xAAE20000;
PrintAndLogEx(INFO, "Preparing to clone Destron tag with ID: %s", sprint_hex(data, datalen));
blocks[0] = T55x7_BITRATE_RF_50 | T55x7_MODULATION_FSK2 | 3 << T55x7_MAXBLOCK_SHIFT;
PrintAndLogEx(INFO, "Preparing to clone Destron tag to " _YELLOW_("%s") " with ID: " _YELLOW_("%s")
, cardtype
, sprint_hex_inrow(data, datalen)
);
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 Destron read`") " to verify");
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf destron reader`") " to verify");
return res;
}
static int CmdDestronSim(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf destron sim",
"Try to find Destron preamble, if found decode / descramble data",
"lf destron sim"
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
PrintAndLogEx(INFO, " To be implemented, feel free to contribute!");
return PM3_SUCCESS;
}
@ -141,7 +223,7 @@ static int CmdDestronSim(const char *Cmd) {
static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"demod", CmdDestronDemod, AlwaysAvailable, "Demodulate an Destron tag from the GraphBuffer"},
{"read", CmdDestronRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"},
{"reader", CmdDestronReader, IfPm3Lf, "Attempt to read and extract tag data from the antenna"},
{"clone", CmdDestronClone, IfPm3Lf, "Clone Destron tag to T55x7"},
{"sim", CmdDestronSim, IfPm3Lf, "Simulate Destron tag"},
{NULL, NULL, NULL, NULL}
@ -185,5 +267,5 @@ int detectDestron(uint8_t *dest, size_t *size) {
}
int readDestronUid(void) {
return (CmdDestronRead("") == PM3_SUCCESS);
return (CmdDestronReader("") == PM3_SUCCESS);
}

View file

@ -30,7 +30,9 @@
#define EM4305_NORALSY_CONFIG_BLOCK (EM4x05_SET_BITRATE(32) | EM4x05_MODULATION_MANCHESTER | EM4x05_SET_NUM_BLOCKS(3) ) // ASK, data rate 32, 3 data blocks
#define EM4305_PRESCO_CONFIG_BLOCK (EM4x05_SET_BITRATE(32) | EM4x05_MODULATION_MANCHESTER | EM4x05_SET_NUM_BLOCKS(4) ) // ASK/MAN, data rate 32, 4 data blocks
#define EM4305_SECURAKEY_CONFIG_BLOCK (EM4x05_SET_BITRATE(40) | EM4x05_MODULATION_MANCHESTER | EM4x05_SET_NUM_BLOCKS(3) ) // ASK/MAN, data rate 40, 3 data blocks
#define EM4305_GALLAGHER_CONFIG_BLOCK (EM4x05_SET_BITRATE(32) | EM4x05_MODULATION_MANCHESTER | EM4x05_SET_NUM_BLOCKS(3) ) // ASK/MAN, data rate 32, 3 data blocks
#define EM4305_DESTRON_CONFIG_BLOCK (EM4x05_SET_BITRATE(50) | EM4x05_MODULATION_FSK2 | EM4x05_SET_NUM_BLOCKS(3) ) // FSK2a, hid 26 bit, data rate 50, 3 data blocks
#define EM4305_HID_26_CONFIG_BLOCK (EM4x05_SET_BITRATE(50) | EM4x05_MODULATION_FSK2 | EM4x05_SET_NUM_BLOCKS(3) ) // FSK2a, hid 26 bit, data rate 50, 3 data blocks
#define EM4305_PARADOX_CONFIG_BLOCK (EM4x05_SET_BITRATE(50) | EM4x05_MODULATION_FSK2 | EM4x05_SET_NUM_BLOCKS(3) ) // FSK2a, hid 26 bit, data rate 50, 3 data blocks
#define EM4305_AWID_CONFIG_BLOCK (EM4x05_SET_BITRATE(50) | EM4x05_MODULATION_FSK2 | EM4x05_SET_NUM_BLOCKS(3) ) // FSK2a, hid 26 bit, data rate 50, 3 data blocks
@ -47,6 +49,7 @@
#define EM4305_GUARDPROXII_CONFIG_BLOCK (EM4x05_SET_BITRATE(64) | EM4x05_MODULATION_BIPHASE | EM4x05_SET_NUM_BLOCKS(3) ) // Biphase, data rate 64, Direct modulation, 3 data blocks
#define EM4305_NEDAP_64_CONFIG_BLOCK (EM4x05_SET_BITRATE(64) | EM4x05_MODULATION_BIPHASE | EM4x05_SET_NUM_BLOCKS(2) ) // Biphase, data rate 64, 2 data blocks
#define EM4305_NEDAP_128_CONFIG_BLOCK (EM4x05_SET_BITRATE(64) | EM4x05_MODULATION_BIPHASE | EM4x05_SET_NUM_BLOCKS(4) ) // Biphase, data rate 64, 4 data blocks
#define EM4305_FDXB_CONFIG_BLOCK (EM4x05_SET_BITRATE(32) | EM4x05_MODULATION_BIPHASE | EM4x05_SET_NUM_BLOCKS(4) ) // Biphase, data rate 32, 4 data blocks
#define EM4305_PAC_CONFIG_BLOCK (EM4x05_SET_BITRATE(32) | EM4x05_MODULATION_NRZ | EM4x05_SET_NUM_BLOCKS(4) ) // NRZ, data rate 32, 4 data blocks
#define EM4305_VERICHIP_CONFIG_BLOCK (EM4x05_SET_BITRATE(40) | EM4x05_MODULATION_NRZ | EM4x05_SET_NUM_BLOCKS(4) ) // NRZ, data rate 40, 4 data blocks

View file

@ -9,16 +9,13 @@
//-----------------------------------------------------------------------------
#include "cmdlffdxb.h"
#include <inttypes.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h> // tolower
#include "cmdparser.h" // command_t
#include "comms.h"
#include "commonutil.h"
#include "ui.h" // PrintAndLog
#include "cmddata.h"
#include "cmdlf.h" // lf read
@ -26,6 +23,8 @@
#include "protocols.h" // for T55xx config register definitions
#include "lfdemod.h" // parityTest
#include "cmdlft55xx.h" // verifywrite
#include "cliparser.h"
#include "cmdlfem4x05.h" // EM defines
/*
FDX-B ISO11784/85 demod (aka animal tag) BIPHASE, inverted, rf/32, with preamble of 00000000001 (128bits)
@ -48,55 +47,63 @@
static int CmdHelp(const char *Cmd);
static int usage_lf_fdxb_clone(void) {
PrintAndLogEx(NORMAL, "Clone a FDX-B animal tag to a T55x7 or Q5/T5555 tag.");
PrintAndLogEx(NORMAL, "Usage: lf fdxb clone [h] [c <country code>] [n <national code>] [e <extended>] <s> <Q5>");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h : This help");
PrintAndLogEx(NORMAL, " c <country> : (dec) Country code");
PrintAndLogEx(NORMAL, " n <national> : (dec) National code");
PrintAndLogEx(NORMAL, " e <extended> : (hex) Extended data");
PrintAndLogEx(NORMAL, " s : Set animal bit");
PrintAndLogEx(NORMAL, " <Q5> : Specify writing to Q5/T5555 tag");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _YELLOW_(" lf fdxb clone c 999 n 112233 s"));
PrintAndLogEx(NORMAL, _YELLOW_(" lf fdxb clone c 999 n 112233 e 16a"));
return PM3_SUCCESS;
}
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 usage_lf_fdxb_read(void) {
PrintAndLogEx(NORMAL, "Read FDX-B animal tag");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: lf fdxb read [h] [@]");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h : This help");
PrintAndLogEx(NORMAL, " @ : run continuously until a key is pressed (optional)");
PrintAndLogEx(NORMAL, "Note that the continuous mode is less verbose");
return PM3_SUCCESS;
}
// add preamble ten 0x00 and one 0x01
memset(bits, 0x00, 10);
bits[10] = 1;
static int usage_lf_fdxb_sim(void) {
PrintAndLogEx(NORMAL, "Enables simulation of FDX-B animal tag");
PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued.");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: lf fdxb sim [h] [c <country code>] [n <national code>] [e <extended>] <s> <Q5>");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h : This help");
PrintAndLogEx(NORMAL, " c <country> : (dec) Country code");
PrintAndLogEx(NORMAL, " n <national> : (dec) National code");
PrintAndLogEx(NORMAL, " e <extended> : (hex) Extended data");
PrintAndLogEx(NORMAL, " s : Set animal bit");
PrintAndLogEx(NORMAL, " <Q5> : Specify writing to Q5/T5555 tag");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _YELLOW_(" lf fdxb sim c 999 n 112233 s"));
PrintAndLogEx(NORMAL, _YELLOW_(" lf fdxb sim c 999 n 112233 e 16a"));
// 128bits
// every 9th bit is 0x01, but we can just fill the rest with 0x01 and overwrite
memset(bits, 0x01, 128);
// add preamble ten 0x00 and one 0x01
memset(bits, 0x00, 10);
// add reserved
num_to_bytebitsLSBF(0x00, 7, bits + 66);
num_to_bytebitsLSBF(0x00 >> 7, 7, bits + 74);
// add animal flag - OK
bits[81] = is_animal;
// add extended flag - OK
bits[65] = is_extended;
// add national code 40bits - OK
num_to_bytebitsLSBF(national_code >> 0, 8, bits + 11);
num_to_bytebitsLSBF(national_code >> 8, 8, bits + 20);
num_to_bytebitsLSBF(national_code >> 16, 8, bits + 29);
num_to_bytebitsLSBF(national_code >> 24, 8, bits + 38);
num_to_bytebitsLSBF(national_code >> 32, 6, bits + 47);
// add country code - OK
num_to_bytebitsLSBF(country_code >> 0, 2, bits + 53);
num_to_bytebitsLSBF(country_code >> 2, 8, bits + 56);
// add crc-16 - OK
uint8_t raw[8];
for (uint8_t i = 0; i < 8; ++i)
raw[i] = bytebits_to_byte(bits + 11 + i * 9, 8);
init_table(CRC_11784);
uint16_t crc = crc16_fdxb(raw, 8);
num_to_bytebitsLSBF(crc >> 0, 8, bits + 83);
num_to_bytebitsLSBF(crc >> 8, 8, bits + 92);
// extended data - OK
num_to_bytebitsLSBF(extended >> 0, 8, bits + 101);
num_to_bytebitsLSBF(extended >> 8, 8, bits + 110);
num_to_bytebitsLSBF(extended >> 16, 8, bits + 119);
// 8 16 24 32 40 48 49
// A8 28 0C 92 EA 6F 00 01
// A8 28 0C 92 EA 6F 80 00
return PM3_SUCCESS;
}
// clearing the topbit needed for the preambl detection.
static void verify_values(uint64_t *animalid, uint32_t *countryid, uint32_t *extended, uint8_t *is_animal) {
static void verify_values(uint64_t *animalid, uint32_t *countryid, uint16_t *extended) {
if ((*animalid & 0x3FFFFFFFFF) != *animalid) {
*animalid &= 0x3FFFFFFFFF;
PrintAndLogEx(INFO, "Animal ID truncated to 38bits: " _YELLOW_("%"PRIx64), *animalid);
@ -109,8 +116,6 @@ static void verify_values(uint64_t *animalid, uint32_t *countryid, uint32_t *ext
*extended &= 0xFFF;
PrintAndLogEx(INFO, "Extended truncated to 24bits: " _YELLOW_("0x%03X"), *extended);
}
*is_animal &= 0x01;
}
static inline uint32_t bitcount(uint32_t a) {
@ -607,71 +612,75 @@ int demodFDXB(bool verbose) {
}
static int CmdFdxBDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf fdxb demod",
"Try to find FDX-B preamble, if found decode / descramble data",
"lf fdxb demod"
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
return demodFDXB(true);
}
static int CmdFdxBRead(const char *Cmd) {
static int CmdFdxBReader(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf fdxb reader",
"read a FDX-B animal tag\n"
"Note that the continuous mode is less verbose",
"lf fdxb reader -@ -> continuous reader mode"
);
void *argtable[] = {
arg_param_begin,
arg_lit0("@", NULL, "optional - continuous reader mode"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
bool cm = arg_get_lit(ctx, 1);
CLIParserFree(ctx);
sample_config config;
memset(&config, 0, sizeof(sample_config));
int retval = lf_getconfig(&config);
if (retval != PM3_SUCCESS) {
int res = lf_getconfig(&config);
if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "failed to get current device LF config");
return retval;
return res;
}
bool errors = false;
bool continuous = false;
uint8_t cmdp = 0;
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h':
return usage_lf_fdxb_read();
case '@':
continuous = true;
cmdp++;
break;
default:
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
}
//Validations
if (errors) return usage_lf_fdxb_read();
int16_t tmp_div = config.divisor;
if (tmp_div != LF_DIVISOR_134) {
config.divisor = LF_DIVISOR_134;
config.verbose = false;
retval = lf_config(&config);
if (retval != PM3_SUCCESS) {
res = lf_config(&config);
if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "failed to change LF configuration");
return retval;
return res;
}
}
if (continuous) {
PrintAndLogEx(INFO, "Press " _GREEN_("Enter") " to exit");
if (cm) {
PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " to exit");
}
int ret = PM3_SUCCESS;
do {
retval = lf_read(false, 10000);
if (retval != PM3_SUCCESS) {
PrintAndLogEx(ERR, "failed to get LF read from device");
return retval;
}
ret = demodFDXB(!continuous); // be verbose only if not in continuous mode
if (kbd_enter_pressed()) {
break;
}
PrintAndLogEx(INPLACE, "");
} while (continuous);
lf_read(false, 10000);
ret = demodFDXB(!cm); // be verbose only if not in continuous mode
//PrintAndLogEx(INPLACE, "");
} while (cm && !kbd_enter_pressed());
if (tmp_div != LF_DIVISOR_134) {
config.divisor = tmp_div;
retval = lf_config(&config);
if (retval != PM3_SUCCESS) {
res = lf_config(&config);
if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "failed to restore LF configuration");
return retval;
return res;
}
}
return ret;
@ -679,145 +688,159 @@ static int CmdFdxBRead(const char *Cmd) {
static int CmdFdxBClone(const char *Cmd) {
uint32_t country_code = 0, extended = 0;
uint64_t national_code = 0;
uint8_t is_animal = 0, cmdp = 0;
bool errors = false, has_extended = false, q5 = false;
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf fdxb clone",
"clone a FDX-B tag to a T55x7, Q5/T5555 or EM4305/4469 tag.",
"lf fdxb clone --country 999 --national 1337 --animal\n"
"lf fdxb clone --country 999 --national 1337 --extended 016A\n"
"lf fdxb clone --q5 --country 999 --national 1337 -> encode for Q5/T5555 tag\n"
"lf fdxb clone --em --country 999 --national 1337 -> encode for EM4305/4469"
);
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h':
return usage_lf_fdxb_clone();
case 'c': {
country_code = param_get32ex(Cmd, cmdp + 1, 0, 10);
cmdp += 2;
break;
void *argtable[] = {
arg_param_begin,
arg_u64_1("c", "country", "<dec>", "country code"),
arg_u64_1("n", "national", "<dec>", "national code"),
arg_str0(NULL, "extended", "<hex>", "extended data"),
arg_lit0("a", "animal", "optional - set animal bit"),
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);
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};
CLIGetHexWithReturn(ctx, 3, edata, &extended_len);
bool is_animal = arg_get_lit(ctx, 4);
bool q5 = arg_get_lit(ctx, 5);
bool em = arg_get_lit(ctx, 6);
CLIParserFree(ctx);
if (q5 && em) {
PrintAndLogEx(FAILED, "Can't specify both Q5 and EM4305 at the same time");
return PM3_EINVARG;
}
case 'n': {
national_code = param_get64ex(Cmd, cmdp + 1, 0, 10);
cmdp += 2;
break;
}
case 'e': {
extended = param_get32ex(Cmd, cmdp + 1, 0, 16);
uint16_t extended = 0;
bool has_extended = false;
if (extended_len) {
extended = bytes_to_num(edata, extended_len);
has_extended = true;
cmdp += 2;
break;
}
case 's': {
is_animal = 1;
cmdp++;
break;
}
case 'q': {
q5 = true;
cmdp++;
break;
}
default: {
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
}
}
if (errors || strlen(Cmd) == 0) return usage_lf_fdxb_clone();
verify_values(&national_code, &country_code, &extended, &is_animal);
verify_values(&national_code, &country_code, &extended);
PrintAndLogEx(INFO, " Country code %"PRIu32, country_code);
PrintAndLogEx(INFO, " National code %"PRIu64, national_code);
PrintAndLogEx(INFO, " Set animal bit %c", (is_animal) ? 'Y' : 'N');
PrintAndLogEx(INFO, "Set data block bit %c", (has_extended) ? 'Y' : 'N');
PrintAndLogEx(INFO, " Extended data 0x%"PRIX32, extended);
PrintAndLogEx(INFO, " RFU 0");
PrintAndLogEx(INFO, "Country code........ %"PRIu32, country_code);
PrintAndLogEx(INFO, "National code....... %"PRIu64, national_code);
PrintAndLogEx(INFO, "Set animal bit...... %c", (is_animal) ? 'Y' : 'N');
PrintAndLogEx(INFO, "Set data block bit.. %c", (has_extended) ? 'Y' : 'N');
PrintAndLogEx(INFO, "Extended data....... 0x%"PRIX32, extended);
PrintAndLogEx(INFO, "RFU................. 0");
uint8_t *bits = calloc(128, sizeof(uint8_t));
if (getFDXBBits(national_code, country_code, is_animal, has_extended, extended, bits) != PM3_SUCCESS) {
uint8_t *bs = calloc(128, sizeof(uint8_t));
if (getFDXBBits(national_code, country_code, is_animal, has_extended, extended, bs) != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Error with tag bitstream generation.");
free(bits);
free(bs);
return PM3_ESOFT;
}
uint32_t blocks[5] = {T55x7_MODULATION_DIPHASE | T55x7_BITRATE_RF_32 | 4 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0, 0};
char cardtype[16] = {"T55x7"};
//Q5
if (q5)
// Q5
if (q5) {
blocks[0] = T5555_FIXED | T5555_MODULATION_BIPHASE | T5555_INVERT_OUTPUT | T5555_SET_BITRATE(32) | 4 << T5555_MAXBLOCK_SHIFT;
snprintf(cardtype, sizeof(cardtype), "Q5/T5555");
}
// EM4305
if (em) {
blocks[0] = EM4305_FDXB_CONFIG_BLOCK;
snprintf(cardtype, sizeof(cardtype), "EM4305/4469");
}
// convert from bit stream to block data
blocks[1] = bytebits_to_byte(bits, 32);
blocks[2] = bytebits_to_byte(bits + 32, 32);
blocks[3] = bytebits_to_byte(bits + 64, 32);
blocks[4] = bytebits_to_byte(bits + 96, 32);
blocks[1] = bytebits_to_byte(bs, 32);
blocks[2] = bytebits_to_byte(bs + 32, 32);
blocks[3] = bytebits_to_byte(bs + 64, 32);
blocks[4] = bytebits_to_byte(bs + 96, 32);
free(bits);
free(bs);
PrintAndLogEx(INFO, "Preparing to clone FDX-B to " _YELLOW_("%s") " with animal ID: " _GREEN_("%04u-%"PRIu64), (q5) ? "Q5/T5555" : "T55x7", country_code, national_code);
PrintAndLogEx(INFO, "Preparing to clone FDX-B to " _YELLOW_("%s") " with animal ID: " _GREEN_("%04u-%"PRIu64)
, cardtype
, country_code
, national_code
);
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 fdxb read`") " to verify");
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf fdxb reader`") " to verify");
return res;
}
static int CmdFdxBSim(const char *Cmd) {
uint32_t country_code = 0, extended = 0;
uint64_t national_code = 0;
uint8_t is_animal = 0, cmdp = 0;
bool errors = false, has_extended = false;
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf fdxb sim",
"Enables simulation of FDX-B animal tag.\n"
"Simulation runs until the button is pressed or another USB command is issued.",
"lf fdxb sim --country 999 --national 1337 --animal\n"
"lf fdxb sim --country 999 --national 1337 --extended 016A\n"
);
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h':
return usage_lf_fdxb_sim();
case 'c': {
country_code = param_get32ex(Cmd, cmdp + 1, 0, 10);
cmdp += 2;
break;
}
case 'n': {
national_code = param_get64ex(Cmd, cmdp + 1, 0, 10);
cmdp += 2;
break;
}
case 'e': {
extended = param_get32ex(Cmd, cmdp + 1, 0, 10);
void *argtable[] = {
arg_param_begin,
arg_u64_1("c", "country", "<dec>", "country code"),
arg_u64_1("n", "national", "<dec>", "national code"),
arg_str0(NULL, "extended", "<hex>", "extended data"),
arg_lit0("a", "animal", "optional - set animal bit"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
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};
CLIGetHexWithReturn(ctx, 3, edata, &extended_len);
bool is_animal = arg_get_lit(ctx, 4);
CLIParserFree(ctx);
uint16_t extended = 0;
bool has_extended = false;
if (extended_len) {
extended = bytes_to_num(edata, extended_len);
has_extended = true;
cmdp += 2;
break;
}
case 's': {
is_animal = 1;
cmdp++;
break;
}
default: {
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
}
}
if (errors) return usage_lf_fdxb_sim();
verify_values(&national_code, &country_code, &extended, &is_animal);
verify_values(&national_code, &country_code, &extended);
PrintAndLogEx(INFO, " Country code %"PRIu32, country_code);
PrintAndLogEx(INFO, " National code %"PRIu64, national_code);
PrintAndLogEx(INFO, " Set animal bit %c", (is_animal) ? 'Y' : 'N');
PrintAndLogEx(INFO, "Set data block bit %c", (has_extended) ? 'Y' : 'N');
PrintAndLogEx(INFO, " Extended data 0x%"PRIX32, extended);
PrintAndLogEx(INFO, " RFU 0");
PrintAndLogEx(INFO, "Country code........ %"PRIu32, country_code);
PrintAndLogEx(INFO, "National code....... %"PRIu64, national_code);
PrintAndLogEx(INFO, "Set animal bit...... %c", (is_animal) ? 'Y' : 'N');
PrintAndLogEx(INFO, "Set data block bit.. %c", (has_extended) ? 'Y' : 'N');
PrintAndLogEx(INFO, "Extended data....... 0x%"PRIX16, extended);
PrintAndLogEx(INFO, "RFU................. 0");
PrintAndLogEx(SUCCESS, "Simulating FDX-B animal ID: " _GREEN_("%04u-%"PRIu64), country_code, national_code);
PrintAndLogEx(SUCCESS, "Simulating FDX-B animal ID: " _YELLOW_("%04u-%"PRIu64), country_code, national_code);
uint8_t *bits = calloc(128, sizeof(uint8_t));
if (getFDXBBits(national_code, country_code, is_animal, (extended > 0), extended, bits) != PM3_SUCCESS) {
uint8_t *bs = calloc(128, sizeof(uint8_t));
if (getFDXBBits(national_code, country_code, is_animal, (extended > 0), extended, bs) != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Error with tag bitstream generation.");
free(bits);
free(bs);
return PM3_ESOFT;
}
@ -827,12 +850,12 @@ static int CmdFdxBSim(const char *Cmd) {
payload->invert = 1;
payload->separator = 0;
payload->clock = 32;
memcpy(payload->data, bits, 128);
memcpy(payload->data, bs, 128);
clearCommandBuffer();
SendCommandNG(CMD_LF_ASK_SIMULATE, (uint8_t *)payload, sizeof(lf_asksim_t) + 128);
free(bits);
free(bs);
free(payload);
PacketResponseNG resp;
@ -848,7 +871,7 @@ static int CmdFdxBSim(const char *Cmd) {
static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "this help"},
{"demod", CmdFdxBDemod, AlwaysAvailable, "demodulate a FDX-B ISO11784/85 tag from the GraphBuffer"},
{"read", CmdFdxBRead, IfPm3Lf, "attempt to read at 134kHz and extract tag data"},
{"reader", CmdFdxBReader, IfPm3Lf, "attempt to read at 134kHz and extract tag data"},
{"clone", CmdFdxBClone, IfPm3Lf, "clone animal ID tag to T55x7 or Q5/T5555"},
{"sim", CmdFdxBSim, IfPm3Lf, "simulate Animal ID tag"},
{NULL, NULL, NULL, NULL}
@ -878,59 +901,3 @@ int detectFDXB(uint8_t *dest, size_t *size) {
//return start position
return (int)startIdx;
}
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);
bits[10] = 1;
// 128bits
// every 9th bit is 0x01, but we can just fill the rest with 0x01 and overwrite
memset(bits, 0x01, 128);
// add preamble ten 0x00 and one 0x01
memset(bits, 0x00, 10);
// add reserved
num_to_bytebitsLSBF(0x00, 7, bits + 66);
num_to_bytebitsLSBF(0x00 >> 7, 7, bits + 74);
// add animal flag - OK
bits[81] = is_animal;
// add extended flag - OK
bits[65] = is_extended;
// add national code 40bits - OK
num_to_bytebitsLSBF(national_code >> 0, 8, bits + 11);
num_to_bytebitsLSBF(national_code >> 8, 8, bits + 20);
num_to_bytebitsLSBF(national_code >> 16, 8, bits + 29);
num_to_bytebitsLSBF(national_code >> 24, 8, bits + 38);
num_to_bytebitsLSBF(national_code >> 32, 6, bits + 47);
// add country code - OK
num_to_bytebitsLSBF(country_code >> 0, 2, bits + 53);
num_to_bytebitsLSBF(country_code >> 2, 8, bits + 56);
// add crc-16 - OK
uint8_t raw[8];
for (uint8_t i = 0; i < 8; ++i)
raw[i] = bytebits_to_byte(bits + 11 + i * 9, 8);
init_table(CRC_11784);
uint16_t crc = crc16_fdxb(raw, 8);
num_to_bytebitsLSBF(crc >> 0, 8, bits + 83);
num_to_bytebitsLSBF(crc >> 8, 8, bits + 92);
// extended data - OK
num_to_bytebitsLSBF(extended >> 0, 8, bits + 101);
num_to_bytebitsLSBF(extended >> 8, 8, bits + 110);
num_to_bytebitsLSBF(extended >> 16, 8, bits + 119);
// 8 16 24 32 40 48 49
// A8 28 0C 92 EA 6F 00 01
// A8 28 0C 92 EA 6F 80 00
return PM3_SUCCESS;
}

View file

@ -19,7 +19,7 @@ typedef struct {
int CmdLFFdxB(const char *Cmd);
int detectFDXB(uint8_t *dest, size_t *size);
int demodFDXB(bool verbose);
int getFDXBBits(uint64_t national_code, uint16_t country_code, uint8_t is_animal, uint8_t is_extended, uint32_t extended, uint8_t *bits);
//int getFDXBBits(uint64_t national_code, uint16_t country_code, uint8_t is_animal, uint8_t is_extended, uint16_t extended, uint8_t *bits);
#endif

View file

@ -10,8 +10,8 @@
// sample Q5 , ASK RF/32, STT, 96 bits (3blocks) ( 0x9000F006)
//-----------------------------------------------------------------------------
#include "cmdlfgallagher.h"
#include <ctype.h> //tolower
#include <string.h> // memcpy
#include <ctype.h> // tolower
#include <stdio.h>
#include "commonutil.h" // ARRAYLEN
#include "common.h"
@ -24,22 +24,11 @@
#include "protocols.h" // t55xx defines
#include "cmdlft55xx.h" // clone..
#include "crc.h" // CRC8/Cardx
#include "cmdlfem4x05.h" //
#include "cliparser.h"
static int CmdHelp(const char *Cmd);
static int usage_lf_gallagher_clone(void) {
PrintAndLogEx(NORMAL, "clone a GALLAGHER tag to a T55x7 tag.");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: lf gallagher clone [h] [b <raw hex>]");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h : this help");
PrintAndLogEx(NORMAL, " b <raw hex> : raw hex data. 12 bytes max");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _YELLOW_(" lf gallagher clone b 0FFD5461A9DA1346B2D1AC32"));
return PM3_SUCCESS;
}
static void descramble(uint8_t *arr, uint8_t len) {
uint8_t lut[] = {
@ -134,71 +123,163 @@ int demodGallagher(bool verbose) {
}
static int CmdGallagherDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf gallagher demod",
"Try to find GALLAGHER preamble, if found decode / descramble data",
"lf gallagher demod"
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
return demodGallagher(true);
}
static int CmdGallagherRead(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
static int CmdGallagherReader(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf gallagher reader",
"read a GALLAGHER tag",
"lf gallagher reader -@ -> continuous reader mode"
);
void *argtable[] = {
arg_param_begin,
arg_lit0("@", NULL, "optional - continuous reader mode"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
bool cm = arg_get_lit(ctx, 1);
CLIParserFree(ctx);
do {
lf_read(false, 4096 * 2 + 20);
return demodGallagher(true);
demodGallagher(!cm);
} while (cm && !kbd_enter_pressed());
return PM3_SUCCESS;
}
static int CmdGallagherClone(const char *Cmd) {
uint32_t blocks[4];
bool errors = false;
uint8_t cmdp = 0;
int datalen = 0;
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf gallagher clone",
"clone a GALLAGHER tag to a T55x7, Q5/T5555 or EM4305/4469 tag.",
"lf gallagher clone --raw 0FFD5461A9DA1346B2D1AC32\n"
"lf gallagher clone --q5 --raw 0FFD5461A9DA1346B2D1AC32 -> encode for Q5/T5555 tag\n"
"lf gallagher clone --em --raw 0FFD5461A9DA1346B2D1AC32 -> encode for EM4305/4469"
);
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h':
return usage_lf_gallagher_clone();
case 'b': {
void *argtable[] = {
arg_param_begin,
arg_str1("r", "raw", "<hex>", "raw hex data. 12 bytes max"),
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);
int raw_len = 0;
// skip first block, 3*4 = 12 bytes left
uint8_t rawhex[12] = {0};
int res = param_gethex_to_eol(Cmd, cmdp + 1, rawhex, sizeof(rawhex), &datalen);
if (res != 0)
errors = true;
uint8_t raw[12] = {0};
CLIGetHexWithReturn(ctx, 1, raw, &raw_len);
bool q5 = arg_get_lit(ctx, 2);
bool em = arg_get_lit(ctx, 3);
CLIParserFree(ctx);
if (q5 && em) {
PrintAndLogEx(FAILED, "Can't specify both Q5 and EM4305 at the same time");
return PM3_EINVARG;
}
uint32_t blocks[4];
for (uint8_t i = 1; i < ARRAYLEN(blocks); i++) {
blocks[i] = bytes_to_num(rawhex + ((i - 1) * 4), sizeof(uint32_t));
blocks[i] = bytes_to_num(raw + ((i - 1) * 4), sizeof(uint32_t));
}
cmdp += 2;
break;
}
default:
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
}
if (errors || cmdp == 0) return usage_lf_gallagher_clone();
//Pac - compat mode, NRZ, data rate 40, 3 data blocks
blocks[0] = T55x7_MODULATION_MANCHESTER | T55x7_BITRATE_RF_32 | 3 << T55x7_MAXBLOCK_SHIFT;
char cardtype[16] = {"T55x7"};
// Q5
if (q5) {
blocks[0] = T5555_FIXED | T5555_MODULATION_MANCHESTER | T5555_SET_BITRATE(32) | 3 << T5555_MAXBLOCK_SHIFT;
snprintf(cardtype, sizeof(cardtype), "Q5/T5555");
}
PrintAndLogEx(INFO, "Preparing to clone Gallagher to T55x7 with raw hex");
// EM4305
if (em) {
blocks[0] = EM4305_GALLAGHER_CONFIG_BLOCK;
snprintf(cardtype, sizeof(cardtype), "EM4305/4469");
}
PrintAndLogEx(INFO, "Preparing to clone Gallagher to " _YELLOW_("%s") " with raw hex", cardtype);
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 gallagher read`") " to verify");
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf gallagher reader`") " to verify");
return res;
}
static int CmdGallagherSim(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf gallagher sim",
"Enables simulation of GALLAGHER card with specified card number.\n"
"Simulation runs until the button is pressed or another USB command is issued.\n",
"lf gallagher sim --raw 0FFD5461A9DA1346B2D1AC32"
);
void *argtable[] = {
arg_param_begin,
arg_str1("r", "raw", "<hex>", "raw hex data. 12 bytes max"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
int raw_len = 0;
// skip first block, 3*4 = 12 bytes left
uint8_t raw[12] = {0};
CLIGetHexWithReturn(ctx, 1, raw, &raw_len);
CLIParserFree(ctx);
// ASK/MAN sim.
PrintAndLogEx(INFO, " To be implemented, feel free to contribute!");
PrintAndLogEx(SUCCESS, "Simulating Gallagher - raw " _YELLOW_("%s"), sprint_hex_inrow(raw, sizeof(raw)));
uint8_t bs[sizeof(raw) * 8];
bytes_to_bytebits(raw, sizeof(raw), bs);
lf_asksim_t *payload = calloc(1, sizeof(lf_asksim_t) + sizeof(bs));
payload->encoding = 1;
payload->invert = 0;
payload->separator = 0;
payload->clock = 32;
memcpy(payload->data, bs, sizeof(bs));
clearCommandBuffer();
SendCommandNG(CMD_LF_ASK_SIMULATE, (uint8_t *)payload, sizeof(lf_asksim_t) + sizeof(bs));
free(payload);
PacketResponseNG resp;
WaitForResponse(CMD_LF_ASK_SIMULATE, &resp);
PrintAndLogEx(INFO, "Done");
if (resp.status != PM3_EOPABORTED)
return resp.status;
return PM3_SUCCESS;
return PM3_SUCCESS;
}
static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"demod", CmdGallagherDemod, AlwaysAvailable, "Demodulate an GALLAGHER tag from the GraphBuffer"},
{"read", CmdGallagherRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"},
{"reader", CmdGallagherReader, IfPm3Lf, "Attempt to read and extract tag data from the antenna"},
{"clone", CmdGallagherClone, IfPm3Lf, "clone GALLAGHER tag to T55x7"},
{"sim", CmdGallagherSim, IfPm3Lf, "simulate GALLAGHER tag"},
{NULL, NULL, NULL, NULL}

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
@ -8,12 +9,10 @@
// Biphase, rf/ , 96 bits (unknown key calc + some bits)
//-----------------------------------------------------------------------------
#include "cmdlfguard.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "commonutil.h" // ARRAYLEN
#include "cmdparser.h" // command_t
#include "comms.h"
@ -23,48 +22,15 @@
#include "protocols.h" // for T55xx config register definitions
#include "lfdemod.h" // parityTest
#include "cmdlft55xx.h" // verifywrite
#include "cliparser.h"
#include "cmdlfem4x05.h" // EM defines
static int CmdHelp(const char *Cmd);
static int usage_lf_guard_clone(void) {
PrintAndLogEx(NORMAL, "clone a Guardall tag to a T55x7 or Q5/T5555 tag.");
PrintAndLogEx(NORMAL, "The facility-code is 8-bit and the card number is 16-bit. Larger values are truncated. ");
PrintAndLogEx(NORMAL, "Currently work only on 26bit");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: lf gprox clone [h] <format> <Facility-Code> <Card-Number> <Q5>");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " <format> : format length 26|32|36|40");
PrintAndLogEx(NORMAL, " <Facility-Code> : 8-bit value facility code");
PrintAndLogEx(NORMAL, " <Card Number> : 16-bit value card number");
PrintAndLogEx(NORMAL, " <Q5> : Specify writing to Q5/T5555 tag");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _YELLOW_(" lf gprox clone 26 123 11223"));
return PM3_SUCCESS;
}
static int usage_lf_guard_sim(void) {
PrintAndLogEx(NORMAL, "Enables simulation of Guardall card with specified card number.");
PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued.");
PrintAndLogEx(NORMAL, "The facility-code is 8-bit and the card number is 16-bit. Larger values are truncated.");
PrintAndLogEx(NORMAL, "Currently work only on 26bit");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: lf gprox sim [h] <format> <Facility-Code> <Card-Number>");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " <format> : format length 26|32|36|40");
PrintAndLogEx(NORMAL, " <Facility-Code> : 8-bit value facility code");
PrintAndLogEx(NORMAL, " <Card Number> : 16-bit value card number");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _YELLOW_(" lf gprox sim 26 123 11223"));
return PM3_SUCCESS;
}
//by marshmellow
//attempts to demodulate and identify a G_Prox_II verex/chubb card
//WARNING: if it fails during some points it will destroy the DemodBuffer data
// attempts to demodulate and identify a G_Prox_II verex/chubb card
// WARNING: if it fails during some points it will destroy the DemodBuffer data
// but will leave the GraphBuffer intact.
//if successful it will push askraw data back to demod buffer ready for emulation
// if successful it will push askraw data back to demod buffer ready for emulation
int demodGuard(bool verbose) {
(void) verbose; // unused so far
//Differential Biphase
@ -150,43 +116,104 @@ int demodGuard(bool verbose) {
}
static int CmdGuardDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf gproxii demod",
"Try to find Guardall Prox-II preamble, if found decode / descramble data",
"lf gproxii demod"
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
return demodGuard(true);
}
static int CmdGuardRead(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
static int CmdGuardReader(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf gproxii reader",
"read a Guardall tag",
"lf gproxii reader -@ -> continuous reader mode"
);
void *argtable[] = {
arg_param_begin,
arg_lit0("@", NULL, "optional - continuous reader mode"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
bool cm = arg_get_lit(ctx, 1);
CLIParserFree(ctx);
do {
lf_read(false, 10000);
return demodGuard(true);
demodGuard(!cm);
} while (cm && !kbd_enter_pressed());
return PM3_SUCCESS;
}
static int CmdGuardClone(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf gproxii clone",
"clone a Guardall tag to a T55x7, Q5/T5555 or EM4305/4469 tag.\n"
"The facility-code is 8-bit and the card number is 16-bit. Larger values are truncated.\n"
"Currently work only on 26bit",
"lf gproxii clone --fmt 26 --fc 123 --cn 1337\n"
"lf gproxii clone --q5 --fmt 26 --fc 123 --cn 1337 -> encode for Q5/T5555 tag\n"
"lf gproxii clone --em --fmt 26 --fc 123 --cn 1337 -> encode for EM4305/4469"
);
char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_guard_clone();
void *argtable[] = {
arg_param_begin,
arg_u64_1(NULL, "fmt", "<dec>", "format length 26|32|36|40"),
arg_u64_1(NULL, "fc", "<dec>", "8-bit value facility code"),
arg_u64_1(NULL, "cn", "<dec>", "16-bit value 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);
uint32_t facilitycode = 0, cardnumber = 0, fc = 0, cn = 0, fmtlen = 0;
uint32_t fmtlen = arg_get_u32_def(ctx, 1, 0);
uint32_t fc = arg_get_u32_def(ctx, 2, 0);
uint32_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 (sscanf(Cmd, "%u %u %u", &fmtlen, &fc, &cn) != 3) return usage_lf_guard_clone();
if (q5 && em) {
PrintAndLogEx(FAILED, "Can't specify both Q5 and EM4305 at the same time");
return PM3_EINVARG;
}
fmtlen &= 0x7f;
facilitycode = (fc & 0x000000FF);
cardnumber = (cn & 0x0000FFFF);
uint32_t facilitycode = (fc & 0x000000FF);
uint32_t cardnumber = (cn & 0x0000FFFF);
//GuardProxII - compat mode, ASK/Biphase, data rate 64, 3 data blocks
uint32_t blocks[4] = {T55x7_MODULATION_BIPHASE | T55x7_BITRATE_RF_64 | 3 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0};
uint8_t *bs = calloc(96, sizeof(uint8_t));
if (getGuardBits(fmtlen, facilitycode, cardnumber, bs) != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Error with tag bitstream generation.");
free(bs);
return PM3_ESOFT;
}
uint32_t blocks[4] = {T55x7_MODULATION_BIPHASE | T55x7_BITRATE_RF_64 | 3 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0};
char cardtype[16] = {"T55x7"};
// Q5
bool q5 = tolower(param_getchar(Cmd, 3)) == 'q';
if (q5)
if (q5) {
blocks[0] = T5555_FIXED | T5555_MODULATION_BIPHASE | T5555_SET_BITRATE(64) | 3 << T5555_MAXBLOCK_SHIFT;
snprintf(cardtype, sizeof(cardtype), "Q5/T5555");
}
// EM4305
if (em) {
blocks[0] = EM4305_GUARDPROXII_CONFIG_BLOCK;
snprintf(cardtype, sizeof(cardtype), "EM4305/4469");
}
blocks[1] = bytebits_to_byte(bs, 32);
blocks[2] = bytebits_to_byte(bs + 32, 32);
@ -194,37 +221,65 @@ static int CmdGuardClone(const char *Cmd) {
free(bs);
PrintAndLogEx(INFO, "Preparing to clone Guardall to " _YELLOW_("%s") " with Facility Code: %u, Card Number: %u", (q5) ? "Q5/T5555" : "T55x7", facilitycode, cardnumber);
PrintAndLogEx(INFO, "Preparing to clone Guardall to " _YELLOW_("%s") " with Facility Code: " _GREEN_("%u") " Card Number: " _GREEN_("%u")
, cardtype
, facilitycode
, cardnumber
);
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 gprox read`") " to verify");
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf gproxii reader`") " to verify");
return res;
}
static int CmdGuardSim(const char *Cmd) {
uint32_t facilitycode = 0, cardnumber = 0, fc = 0, cn = 0, fmtlen = 0;
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf gproxii sim",
"Enables simulation of Guardall card with specified card number.\n"
"Simulation runs until the button is pressed or another USB command is issued.\n"
"The facility-code is 8-bit and the card number is 16-bit. Larger values are truncated.\n"
"Currently work only on 26bit",
"lf gproxii sim --fmt 26 --fc 123 --cn 1337\n"
);
char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_guard_sim();
void *argtable[] = {
arg_param_begin,
arg_u64_1(NULL, "fmt", "<dec>", "format length 26|32|36|40"),
arg_u64_1(NULL, "fc", "<dec>", "8-bit value facility code"),
arg_u64_1(NULL, "cn", "<dec>", "16-bit value card number"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
if (sscanf(Cmd, "%u %u %u", &fmtlen, &fc, &cn) != 3) return usage_lf_guard_sim();
uint32_t fmtlen = arg_get_u32_def(ctx, 1, 0);
uint32_t fc = arg_get_u32_def(ctx, 2, 0);
uint32_t cn = arg_get_u32_def(ctx, 3, 0);
CLIParserFree(ctx);
fmtlen &= 0x7F;
uint32_t facilitycode = (fc & 0x000000FF);
uint32_t cardnumber = (cn & 0x0000FFFF);
uint8_t bs[96];
memset(bs, 0x00, sizeof(bs));
fmtlen &= 0x7F;
facilitycode = (fc & 0x000000FF);
cardnumber = (cn & 0x0000FFFF);
if (getGuardBits(fmtlen, facilitycode, cardnumber, bs) != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Error with tag bitstream generation.");
return PM3_ESOFT;
}
PrintAndLogEx(SUCCESS, "Simulating Guardall - Facility Code: %u, CardNumber: %u", facilitycode, cardnumber);
PrintAndLogEx(SUCCESS, "Simulating Guardall Prox - Facility Code: " _YELLOW_("%u") " CardNumber: " _YELLOW_("%u")
, facilitycode
, cardnumber
);
// Guard uses: clk: 64, invert: 0, encoding: 2 (ASK Biphase)
lf_asksim_t *payload = calloc(1, sizeof(lf_asksim_t) + sizeof(bs));
@ -250,7 +305,7 @@ static int CmdGuardSim(const char *Cmd) {
static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "this help"},
{"demod", CmdGuardDemod, AlwaysAvailable, "demodulate a G Prox II tag from the GraphBuffer"},
{"read", CmdGuardRead, IfPm3Lf, "attempt to read and extract tag data from the antenna"},
{"reader", CmdGuardReader, IfPm3Lf, "attempt to read and extract tag data from the antenna"},
{"clone", CmdGuardClone, IfPm3Lf, "clone Guardall tag to T55x7 or Q5/T5555"},
{"sim", CmdGuardSim, IfPm3Lf, "simulate Guardall tag"},
{NULL, NULL, NULL, NULL}
@ -267,7 +322,6 @@ int CmdLFGuard(const char *Cmd) {
return CmdsParse(CommandTable, Cmd);
}
// by marshmellow
// demod gProxIIDemod
// error returns as -x
// success returns start position in bitstream

View file

@ -19,13 +19,10 @@
//-----------------------------------------------------------------------------
#include "cmdlfhid.h"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <inttypes.h>
#include "cmdparser.h" // command_t
#include "comms.h"
#include "commonutil.h" // ARRAYLEN
@ -38,6 +35,7 @@
#include "lfdemod.h"
#include "wiegand_formats.h"
#include "wiegand_formatutils.h"
#include "cmdlfem4x05.h" // EM defines
#ifndef BITS
# define BITS 96
@ -153,15 +151,44 @@ int demodHID(bool verbose) {
}
static int CmdHIDDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf hid demod",
"Try to find HID Prox preamble, if found decode / descramble data",
"lf hid demod"
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
return demodHID(true);
}
// this read is the "normal" read, which download lf signal and tries to demod here.
static int CmdHIDRead(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf hid reader",
"read a HID Prox tag",
"lf hid reader -@ -> continuous reader mode"
);
void *argtable[] = {
arg_param_begin,
arg_lit0("@", NULL, "optional - continuous reader mode"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
bool cm = arg_get_lit(ctx, 1);
CLIParserFree(ctx);
do {
lf_read(false, 16000);
return demodHID(true);
demodHID(!cm);
} while (cm && !kbd_enter_pressed());
return PM3_SUCCESS;
}
// this read loops on device side.
@ -212,7 +239,6 @@ static int CmdHIDSim(const char *Cmd) {
arg_int0("i", NULL, "<dec>", "issue level"),
arg_int0("o", "oem", "<dec>", "OEM code"),
arg_strx0("r", "raw", "<hex>", "raw bytes"),
// arg_lit0("q", "Q5", "optional - specify writing to Q5/T5555 tag"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
@ -231,8 +257,6 @@ static int CmdHIDSim(const char *Cmd) {
int raw_len = 0;
char raw[40] = {0};
CLIParamStrToBuf(arg_get_str(ctx, 6), (uint8_t *)raw, sizeof(raw), &raw_len);
//bool q5 = arg_get_lit(ctx, 7);
CLIParserFree(ctx);
wiegand_message_t packed;

View file

@ -9,13 +9,10 @@
// PSK
//-----------------------------------------------------------------------------
#include "cmdlfidteck.h"
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "common.h"
#include "cmdparser.h" // command_t
#include "comms.h"
#include "ui.h"
@ -23,6 +20,8 @@
#include "cmdlf.h"
#include "lfdemod.h"
#include "commonutil.h" // num_to_bytes
#include "cliparser.h"
#include "cmdlfem4x05.h" // EM defines
static int CmdHelp(const char *Cmd);
@ -87,20 +86,49 @@ int demodIdteck(bool verbose) {
}
static int CmdIdteckDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf idteck demod",
"Try to find Idteck preamble, if found decode / descramble data",
"lf idteck demod"
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
return demodIdteck(true);
}
static int CmdIdteckRead(const char *Cmd) {
(void)Cmd;
static int CmdIdteckReader(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf idteck reader",
"read a Idteck tag",
"lf idteck reader -@ -> continuous reader mode"
);
void *argtable[] = {
arg_param_begin,
arg_lit0("@", NULL, "optional - continuous reader mode"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
bool cm = arg_get_lit(ctx, 1);
CLIParserFree(ctx);
do {
lf_read(false, 5000);
return demodIdteck(true);
demodIdteck(!cm);
} while (cm && !kbd_enter_pressed());
return PM3_SUCCESS;
}
static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"demod", CmdIdteckDemod, AlwaysAvailable, "Demodulate an Idteck tag from the GraphBuffer"},
{"read", CmdIdteckRead, IfPm3Lf, "Attempt to read and Extract tag data from the antenna"},
{"reader", CmdIdteckReader, IfPm3Lf, "Attempt to read and Extract tag data from the antenna"},
{NULL, NULL, NULL, NULL}
};

View file

@ -9,13 +9,10 @@
//-----------------------------------------------------------------------------
#include "cmdlfindala.h"
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <inttypes.h>
#include "cmdparser.h" // command_t
#include "comms.h"
#include "graph.h"
@ -28,6 +25,8 @@
#include "cmdlf.h" // lf_read
#include "protocols.h" // t55 defines
#include "cmdlft55xx.h" // verifywrite
#include "cliparser.h"
#include "cmdlfem4x05.h" // EM defines
#define INDALA_ARR_LEN 64
@ -499,16 +498,33 @@ static int CmdIndalaDemodAlt(const char *Cmd) {
}
// this read is the "normal" read, which download lf signal and tries to demod here.
static int CmdIndalaRead(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_lf_indala_demod();
static int CmdIndalaReader(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf indala reader",
"read a Indala Prox tag",
"lf indala reader -@ -> continuous reader mode"
);
int clk = 32, invert = 0, maxErr = 100;
if (strlen(Cmd) > 0) {
sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr);
}
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_lit0("@", NULL, "optional - continuous reader mode"),
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);
bool cm = arg_get_lit(ctx, 4);
CLIParserFree(ctx);
do {
lf_read(false, 30000);
return demodIndalaEx(clk, invert, maxErr, true);
demodIndalaEx(clk, invert, max_err, !cm);
} while (cm && !kbd_enter_pressed());
return PM3_SUCCESS;
}
static int CmdIndalaSim(const char *Cmd) {
@ -699,7 +715,7 @@ static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "this help"},
{"demod", CmdIndalaDemod, AlwaysAvailable, "demodulate an indala tag (PSK1) from GraphBuffer"},
{"altdemod", CmdIndalaDemodAlt, AlwaysAvailable, "alternative method to Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"},
{"read", CmdIndalaRead, IfPm3Lf, "read an Indala Prox tag from the antenna"},
{"reader", CmdIndalaReader, IfPm3Lf, "read an Indala Prox tag from the antenna"},
{"clone", CmdIndalaClone, IfPm3Lf, "clone Indala tag to T55x7 or Q5/T5555"},
{"sim", CmdIndalaSim, IfPm3Lf, "simulate Indala tag"},
{NULL, NULL, NULL, NULL}

View file

@ -9,14 +9,11 @@
//-----------------------------------------------------------------------------
#include "cmdlfio.h"
#include <stdio.h> // sscanf
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "commonutil.h" //ARRAYLEN
#include "commonutil.h" // ARRAYLEN
#include "cmdparser.h" // command_t
#include "comms.h"
#include "graph.h"
@ -26,6 +23,8 @@
#include "protocols.h" // for T55xx config register definitions
#include "cmddata.h"
#include "cmdlft55xx.h" // verifywrite
#include "cliparser.h"
#include "cmdlfem4x05.h" // EM defines
static int CmdHelp(const char *Cmd);
@ -192,14 +191,43 @@ int demodIOProx(bool verbose) {
}
static int CmdIOProxDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf io demod",
"Try to find IO Prox preamble, if found decode / descramble data",
"lf io demod\n"
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
return demodIOProx(true);
}
// this read is the "normal" read, which download lf signal and tries to demod here.
static int CmdIOProxRead(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
static int CmdIOProxReader(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf io reader",
"read a IO Prox tag",
"lf io reader -@ -> continuous reader mode"
);
void *argtable[] = {
arg_param_begin,
arg_lit0("@", NULL, "optional - continuous reader mode"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
bool cm = arg_get_lit(ctx, 1);
CLIParserFree(ctx);
do {
lf_read(false, 12000);
return demodIOProx(true);
demodIOProx(!cm);
} while (cm && !kbd_enter_pressed());
return PM3_SUCCESS;
}
static int CmdIOProxSim(const char *Cmd) {
uint16_t cn = 0;
@ -299,7 +327,7 @@ static int CmdIOProxClone(const char *Cmd) {
static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "this help"},
{"demod", CmdIOProxDemod, AlwaysAvailable, "demodulate an IOProx tag from the GraphBuffer"},
{"read", CmdIOProxRead, IfPm3Lf, "attempt to read and extract tag data"},
{"reader", CmdIOProxReader, IfPm3Lf, "attempt to read and extract tag data"},
{"clone", CmdIOProxClone, IfPm3Lf, "clone IOProx tag to T55x7 or Q5/T5555"},
{"sim", CmdIOProxSim, IfPm3Lf, "simulate IOProx tag"},
{"watch", CmdIOProxWatch, IfPm3Lf, "continuously watch for cards. Reader mode"},

View file

@ -9,12 +9,10 @@
//-----------------------------------------------------------------------------
#include "cmdlfjablotron.h"
#include <string.h>
#include <inttypes.h>
#include <stdlib.h>
#include <ctype.h>
#include "cmdparser.h" // command_t
#include "comms.h"
#include "commonutil.h" // ARRAYLEN
@ -24,25 +22,13 @@
#include "protocols.h" // for T55xx config register definitions
#include "lfdemod.h" // parityTest
#include "cmdlft55xx.h" // verifywrite
#include "cliparser.h"
#include "cmdlfem4x05.h" // EM defines
#define JABLOTRON_ARR_LEN 64
static int CmdHelp(const char *Cmd);
static int usage_lf_jablotron_clone(void) {
PrintAndLogEx(NORMAL, "clone a Jablotron tag to a T55x7 or Q5/T5555 tag.");
PrintAndLogEx(NORMAL, "Usage: lf jablotron clone [h] <card ID> <Q5>");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h : This help");
PrintAndLogEx(NORMAL, " <card ID> : jablotron card ID");
PrintAndLogEx(NORMAL, " <Q5> : specify writing to Q5/T5555 tag");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _YELLOW_(" lf jablotron clone 112233"));
PrintAndLogEx(NORMAL, "");
return PM3_SUCCESS;
}
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.");
@ -134,30 +120,93 @@ int demodJablotron(bool verbose) {
//see ASKDemod for what args are accepted
static int CmdJablotronDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf jablotron demod",
"Try to find Jablotron preamble, if found decode / descramble data",
"lf jablotron demod\n"
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
return demodJablotron(true);
}
static int CmdJablotronRead(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
static int CmdJablotronReader(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf jablotron reader",
"read a jablotron tag",
"lf jablotron reader -@ -> continuous reader mode"
);
void *argtable[] = {
arg_param_begin,
arg_lit0("@", NULL, "optional - continuous reader mode"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
bool cm = arg_get_lit(ctx, 1);
CLIParserFree(ctx);
do {
lf_read(false, 16000);
return demodJablotron(true);
demodJablotron(!cm);
} while (cm && !kbd_enter_pressed());
return PM3_SUCCESS;
}
static int CmdJablotronClone(const char *Cmd) {
uint64_t fullcode = 0;
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf jablotron clone",
"clone a Jablotron tag to a T55x7, Q5/T5555 or EM4305/4469 tag.",
"lf jablotron clone --cn 01b669\n"
"lf jablotron clone --q5 --cn 01b669 -> encode for Q5/T5555 tag\n"
"lf jablotron clone --em --cn 01b669 -> encode for EM4305/4469"
);
void *argtable[] = {
arg_param_begin,
arg_str1(NULL, "cn", "<hex>", "Jablotron card ID - 5 bytes max"),
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);
int raw_len = 0;
uint8_t raw[5] = {0};
CLIGetHexWithReturn(ctx, 1, raw, &raw_len);
bool q5 = arg_get_lit(ctx, 2);
bool em = arg_get_lit(ctx, 3);
CLIParserFree(ctx);
if (q5 && em) {
PrintAndLogEx(FAILED, "Can't specify both Q5 and EM4305 at the same time");
return PM3_EINVARG;
}
uint32_t blocks[3] = {T55x7_MODULATION_DIPHASE | T55x7_BITRATE_RF_64 | 2 << T55x7_MAXBLOCK_SHIFT, 0, 0};
char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_jablotron_clone();
fullcode = param_get64ex(Cmd, 0, 0, 16);
//Q5
bool q5 = tolower(param_getchar(Cmd, 1)) == 'q';
if (q5)
char cardtype[16] = {"T55x7"};
// Q5
if (q5) {
blocks[0] = T5555_FIXED | T5555_MODULATION_BIPHASE | T5555_INVERT_OUTPUT | T5555_SET_BITRATE(64) | 2 << T5555_MAXBLOCK_SHIFT;
snprintf(cardtype, sizeof(cardtype), "Q5/T5555");
}
// EM4305
if (em) {
blocks[0] = EM4305_JABLOTRON_CONFIG_BLOCK;
snprintf(cardtype, sizeof(cardtype), "EM4305/4469");
}
uint64_t fullcode = bytes_to_num(raw, raw_len);
// clearing the topbit needed for the preambl detection.
if ((fullcode & 0x7FFFFFFFFF) != fullcode) {
@ -181,10 +230,20 @@ static int CmdJablotronClone(const char *Cmd) {
free(bits);
PrintAndLogEx(INFO, "Preparing to clone Jablotron to " _YELLOW_("%s") " with FullCode: %"PRIx64, (q5) ? "Q5/T5555" : "T55x7", fullcode);
uint64_t id = getJablontronCardId(fullcode);
PrintAndLogEx(INFO, "Preparing to clone Jablotron to " _YELLOW_("%s") " with FullCode: " _GREEN_("%"PRIx64)" id: " _GREEN_("%"PRIx64), cardtype, fullcode, id);
print_blocks(blocks, ARRAYLEN(blocks));
return 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 jablotron reader`") " to verify");
return res;
}
static int CmdJablotronSim(const char *Cmd) {
@ -201,7 +260,7 @@ static int CmdJablotronSim(const char *Cmd) {
PrintAndLogEx(INFO, "Card Number Truncated to 39bits: %"PRIx64, fullcode);
}
PrintAndLogEx(SUCCESS, "Simulating Jablotron - FullCode: %"PRIx64, fullcode);
PrintAndLogEx(SUCCESS, "Simulating Jablotron - FullCode: " _YELLOW_("%"PRIx64), fullcode);
uint8_t *bs = calloc(JABLOTRON_ARR_LEN, sizeof(uint8_t));
if (bs == NULL) {
@ -236,7 +295,7 @@ static int CmdJablotronSim(const char *Cmd) {
static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"demod", CmdJablotronDemod, AlwaysAvailable, "Demodulate an Jablotron tag from the GraphBuffer"},
{"read", CmdJablotronRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"},
{"reader", CmdJablotronReader, IfPm3Lf, "Attempt to read and extract tag data from the antenna"},
{"clone", CmdJablotronClone, IfPm3Lf, "clone jablotron tag to T55x7 or Q5/T5555"},
{"sim", CmdJablotronSim, IfPm3Lf, "simulate jablotron tag"},
{NULL, NULL, NULL, NULL}

View file

@ -175,7 +175,18 @@ int demodKeri(bool verbose) {
}
static int CmdKeriDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf keri demod",
"Try to find KERI preamble, if found decode / descramble data",
"lf keri demod"
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
return demodKeri(true);
}

View file

@ -116,9 +116,19 @@ int demodMotorola(bool verbose) {
return PM3_SUCCESS;
}
//see PSKDemod for what args are accepted
static int CmdMotorolaDemod(const char *Cmd) {
(void)Cmd;
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf motorola demod",
"Try to find Motorola preamble, if found decode / descramble data",
"lf motorola demod"
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
return demodMotorola(true);
}
@ -235,6 +245,19 @@ static int CmdMotorolaClone(const char *Cmd) {
}
static int CmdMotorolaSim(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf motorola sim",
"Enables simulation of Motorola card with specified card number.\n"
"Simulation runs until the button is pressed or another USB command is issued.",
"lf motorola sim"
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
// PSK sim.
PrintAndLogEx(INFO, " PSK1 at 66 kHz... Interesting.");

View file

@ -11,10 +11,8 @@
#define _GNU_SOURCE
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include "cmdparser.h" // command_t
#include "comms.h"
#include "crc16.h"
@ -24,6 +22,8 @@
#include "cmdlf.h"
#include "lfdemod.h"
#include "protocols.h"
#include "cliparser.h"
#include "cmdlfem4x05.h" // EM defines
#define FIXED_71 0x71
#define FIXED_40 0x40
@ -262,7 +262,18 @@ int demodNedap(bool verbose) {
}
static int CmdLFNedapDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf nedap demod",
"Try to find Nedap preamble, if found decode / descramble data",
"lf nedap demod"
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
return demodNedap(true);
}
/* Index map E E

View file

@ -217,14 +217,25 @@ int demodNexWatch(bool verbose) {
}
static int CmdNexWatchDemod(const char *Cmd) {
(void)Cmd;
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf nexwatch demod",
"Try to find Nexwatch preamble, if found decode / descramble data",
"lf nexwatch demod"
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
return demodNexWatch(true);
}
static int CmdNexWatchReader(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf nexwatch reader",
"read a nexwatch tag",
"read a Nexwatch tag",
"lf nexwatch reader -@ -> continuous reader mode"
);

View file

@ -103,14 +103,25 @@ int demodNoralsy(bool verbose) {
}
static int CmdNoralsyDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf noralsy demod",
"Try to find Noralsy preamble, if found decode / descramble data",
"lf noralsy demod"
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
return demodNoralsy(true);
}
static int CmdNoralsyReader(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf noralsy reader",
"read a noralsy tag",
"read a Noralsy tag",
"lf noralsy reader -@ -> continuous reader mode"
);
@ -133,7 +144,7 @@ static int CmdNoralsyReader(const char *Cmd) {
static int CmdNoralsyClone(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf noralsy clone",
"clone a noralsy tag to a T55x7, Q5/T5555 or EM4305/4469 tag.",
"clone a Noralsy tag to a T55x7, Q5/T5555 or EM4305/4469 tag.",
"lf noralsy clone --cn 112233\n"
"lf noralsy clone --cn 112233 --q5 -> encode for Q5/T5555 tag\n"
"lf noralsy clone --cn 112233 --em -> encode for EM4305/4469"

View file

@ -69,7 +69,7 @@ static int pac_buf_to_cardid(uint8_t *src, const size_t src_size, uint8_t *dst,
// convert a 16 byte array of raw demod data (FF204990XX...) to 8 bytes of PAC_8byte ID
// performs no parity or checksum validation
static void pac_raw_to_cardid(const uint8_t* src, uint8_t *dst) {
static void pac_raw_to_cardid(const uint8_t *src, uint8_t *dst) {
for (int i = 4; i < 12; i++) {
uint8_t shift = 7 - (i + 3) % 4 * 2;
size_t index = i + (i - 1) / 4;
@ -157,7 +157,18 @@ int demodPac(bool verbose) {
}
static int CmdPacDemod(const char *Cmd) {
(void)Cmd;
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf pac demod",
"Try to find PAC/Stanley preamble, if found decode / descramble data",
"lf pac demod"
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
return demodPac(true);
}
@ -165,7 +176,7 @@ static int CmdPacReader(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf pac reader",
"read a pac tag",
"read a PAC/Stanley tag",
"lf pac reader -@ -> continuous reader mode"
);
@ -236,7 +247,7 @@ static int CmdPacClone(const char *Cmd) {
}
if (cnlen == 8 || cnlen == 9) {
pac_cardid_to_raw((char*)cnstr, raw);
pac_cardid_to_raw((char *)cnstr, raw);
} else {
pac_raw_to_cardid(raw, cnstr);
}
@ -321,7 +332,7 @@ static int CmdPacSim(const char *Cmd) {
}
if (cnlen == 8 || cnlen == 9) {
pac_cardid_to_raw((char*)cnstr, raw);
pac_cardid_to_raw((char *)cnstr, raw);
} else {
pac_raw_to_cardid(raw, cnstr);
}

View file

@ -170,7 +170,18 @@ int demodParadox(bool verbose) {
}
static int CmdParadoxDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf paradox demod",
"Try to find Paradox preamble, if found decode / descramble data",
"lf paradox demod"
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
return demodParadox(true);
}
@ -323,7 +334,8 @@ static int CmdParadoxSim(const char *Cmd) {
if (resp.status != PM3_EOPABORTED)
return resp.status;
return PM3_SUCCESS;}
return PM3_SUCCESS;
}
/*
if (sscanf(Cmd, "%u %u", &fc, &cn) != 2) return usage_lf_paradox_sim();

View file

@ -40,7 +40,7 @@ static int detectPresco(uint8_t *dest, size_t *size) {
// convert base 12 ID to sitecode & usercode & 8 bit other unknown code
static int getWiegandFromPrintedPresco(void *arr, uint32_t *fullcode) {
char *s = (char*)arr;
char *s = (char *)arr;
uint8_t val = 0;
for (int i = 0; i < strlen(s); ++i) {
// Get value from number string.
@ -112,7 +112,18 @@ int demodPresco(bool verbose) {
}
static int CmdPrescoDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf presco demod",
"Try to find presco preamble, if found decode / descramble data",
"lf presco demod"
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
return demodPresco(true);
}
@ -162,7 +173,7 @@ static int CmdPrescoClone(const char *Cmd) {
CLIExecWithReturn(ctx, Cmd, argtable, false);
int hex_len = 0;
uint8_t hex[4] = {0,0,0,0};
uint8_t hex[4] = {0, 0, 0, 0};
CLIGetHexWithReturn(ctx, 1, hex, &hex_len);
uint8_t idstr[11];
@ -265,7 +276,7 @@ static int CmdPrescoSim(const char *Cmd) {
CLIExecWithReturn(ctx, Cmd, argtable, false);
int hex_len = 0;
uint8_t hex[4] = {0,0,0,0};
uint8_t hex[4] = {0, 0, 0, 0};
CLIGetHexWithReturn(ctx, 1, hex, &hex_len);
uint8_t idstr[11];

View file

@ -178,7 +178,18 @@ int demodPyramid(bool verbose) {
}
static int CmdPyramidDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf pyramid demod",
"Try to find Farpoint/Pyramid preamble, if found decode / descramble data",
"lf pyramid demod"
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
return demodPyramid(true);
}

View file

@ -114,7 +114,18 @@ int demodSecurakey(bool verbose) {
}
static int CmdSecurakeyDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf securakey demod",
"Try to find Securakey preamble, if found decode / descramble data",
"lf securakey demod"
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
return demodSecurakey(true);
}

View file

@ -272,7 +272,18 @@ out:
}
static int CmdTIDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf ti demod",
"Try to find TI preamble, if found decode / descramble data",
"lf ti demod"
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
return demodTI(true);
}
@ -303,19 +314,43 @@ static int CmdTIReader(const char *Cmd) {
// write new data to a r/w TI tag
static int CmdTIWrite(const char *Cmd) {
int res = 0;
uint64_t arg0, arg1, arg2;
res = sscanf(Cmd, "%012" SCNx64 " %012" SCNx64 " %012" SCNx64 "", &arg0, &arg1, &arg2);
if (res == 2)
arg2 = 0;
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf ti write",
"write to a r/w TI tag.",
"lf ti write --raw 1122334455667788\n"
"lf ti write --raw 1122334455667788 --crc 1122\n"
);
void *argtable[] = {
arg_param_begin,
arg_str1("r", "raw", "<hex>", "raw hex data. 8 bytes max"),
arg_str0(NULL, "crc", "<hex>", "optional - crc"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
int raw_len = 0;
uint8_t raw[8] = {0};
CLIGetHexWithReturn(ctx, 1, raw, &raw_len);
int crc_len = 0;
uint8_t crc[2] = {0};
CLIGetHexWithReturn(ctx, 2, crc, &crc_len);
CLIParserFree(ctx);
struct {
uint32_t high;
uint32_t low;
uint16_t crc;
} PACKED payload;
payload.high = bytes_to_num(raw, 4);
payload.low = bytes_to_num(raw + 4, 4);
payload.crc = bytes_to_num(crc, crc_len);
if (res < 2) {
PrintAndLogEx(WARNING, "Please specify the data as two hex strings, optionally the CRC as a third");
return PM3_EINVARG;
}
clearCommandBuffer();
SendCommandMIX(CMD_LF_TI_WRITE, arg0, arg1, arg2, NULL, 0);
SendCommandNG(CMD_LF_TI_WRITE, (uint8_t*)&payload, sizeof(payload));
PrintAndLogEx(SUCCESS, "Done");
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf ti reader`") " to verify");
return PM3_SUCCESS;
@ -323,7 +358,7 @@ static int CmdTIWrite(const char *Cmd) {
static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"demod", CmdTIDemod, AlwaysAvailable, "Demodulate raw bits for TI-type LF tag from the GraphBuffer"},
{"demod", CmdTIDemod, AlwaysAvailable, "Demodulate raw bits for TI LF tag from the GraphBuffer"},
{"reader", CmdTIReader, IfPm3Lf, "Read and decode a TI 134 kHz tag"},
{"write", CmdTIWrite, IfPm3Lf, "Write new data to a r/w TI 134 kHz tag"},
{NULL, NULL, NULL, NULL}

View file

@ -54,7 +54,18 @@ int demodViking(bool verbose) {
}
static int CmdVikingDemod(const char *Cmd) {
(void)Cmd;
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf viking demod",
"Try to find Viking AM preamble, if found decode / descramble data",
"lf viking demod"
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
return demodViking(true);
}

View file

@ -133,7 +133,18 @@ int demodVisa2k(bool verbose) {
}
static int CmdVisa2kDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf visa2000 demod",
"Try to find visa2000 preamble, if found decode / descramble data",
"lf visa2000 demod"
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
return demodVisa2k(true);
}

View file

@ -32,12 +32,12 @@
#include "fileutils.h"
#ifdef HAVE_LUA_SWIG
extern int luaopen_pm3(lua_State* L);
extern int luaopen_pm3(lua_State *L);
#endif
#ifdef HAVE_PYTHON
#ifdef HAVE_PYTHON_SWIG
extern PyObject* PyInit__pm3(void);
extern PyObject *PyInit__pm3(void);
#endif // HAVE_PYTHON_SWIG
// Partly ripped from PyRun_SimpleFileExFlags

View file

@ -232,7 +232,7 @@ void hash2(uint8_t *key64, uint8_t *outp_keytable) {
if (g_debugMode > 0) {
PrintAndLogEx(DEBUG, "High security custom key (Kcus):");
PrintAndLogEx(DEBUG, "z0 %s", sprint_hex(z[0],8));
PrintAndLogEx(DEBUG, "z0 %s", sprint_hex(z[0], 8));
}
uint8_t y[8][8] = {{0}, {0}};
@ -308,7 +308,7 @@ typedef struct {
static size_t loclass_tc = 1;
static int loclass_found = 0;
static void* bf_thread(void* thread_arg) {
static void *bf_thread(void *thread_arg) {
loclass_thread_arg_t *targ = (loclass_thread_arg_t *)thread_arg;
const uint32_t endmask = targ->endmask;
@ -332,7 +332,7 @@ static void* bf_thread(void* thread_arg) {
int found;
while (!(brute & endmask)) {
found = __atomic_load_n (&loclass_found, __ATOMIC_SEQ_CST);
found = __atomic_load_n(&loclass_found, __ATOMIC_SEQ_CST);
if (found != 0xFF) return NULL;
@ -370,13 +370,13 @@ static void* bf_thread(void* thread_arg) {
// success
if (memcmp(calculated_MAC, mac, 4) == 0) {
loclass_thread_ret_t *r = (loclass_thread_ret_t*)malloc(sizeof(loclass_thread_ret_t));
loclass_thread_ret_t *r = (loclass_thread_ret_t *)malloc(sizeof(loclass_thread_ret_t));
for (uint8_t i = 0 ; i < numbytes_to_recover; i++) {
r->values[i] = keytable[bytes_to_recover[i]] & 0xFF;
}
__atomic_store_n(&loclass_found, targ->thread_idx, __ATOMIC_SEQ_CST);
pthread_exit ((void*)r);
pthread_exit((void *)r);
}
brute += loclass_tc;
@ -385,11 +385,11 @@ static void* bf_thread(void* thread_arg) {
if (numbytes_to_recover == 3) {
if ((brute > 0) && ((brute & 0xFFFF) == 0)) {
PrintAndLogEx(INPLACE, "[ %02x %02x %02x ] %8u / %u", bytes_to_recover[0], bytes_to_recover[1], bytes_to_recover[2] , brute, 0xFFFFFF);
PrintAndLogEx(INPLACE, "[ %02x %02x %02x ] %8u / %u", bytes_to_recover[0], bytes_to_recover[1], bytes_to_recover[2], brute, 0xFFFFFF);
}
} else if (numbytes_to_recover == 2) {
if ((brute > 0) && ((brute & 0x3F) == 0))
PrintAndLogEx(INPLACE, "[ %02x %02x ] %5u / %u" _CLR_ , bytes_to_recover[0], bytes_to_recover[1], brute, 0xFFFF);
PrintAndLogEx(INPLACE, "[ %02x %02x ] %5u / %u" _CLR_, bytes_to_recover[0], bytes_to_recover[1], brute, 0xFFFF);
} else {
if ((brute > 0) && ((brute & 0x1F) == 0))
PrintAndLogEx(INPLACE, "[ %02x ] %3u / %u" _CLR_, bytes_to_recover[0], brute, 0xFF);
@ -397,7 +397,7 @@ static void* bf_thread(void* thread_arg) {
}
pthread_exit(NULL);
void* dummyptr = NULL;
void *dummyptr = NULL;
return dummyptr;
}
@ -455,9 +455,9 @@ int bruteforceItem(loclass_dumpdata_t item, uint16_t keytable[]) {
args[i].numbytes_to_recover = numbytes_to_recover;
args[i].endmask = 1 << 8 * numbytes_to_recover;
memcpy((void*)&args[i].item, (void*)&item, sizeof(loclass_dumpdata_t));
memcpy(args[i].bytes_to_recover, bytes_to_recover, sizeof(args[i].bytes_to_recover) );
memcpy(args[i].key_index, key_index, sizeof(args[i].key_index) );
memcpy((void *)&args[i].item, (void *)&item, sizeof(loclass_dumpdata_t));
memcpy(args[i].bytes_to_recover, bytes_to_recover, sizeof(args[i].bytes_to_recover));
memcpy(args[i].key_index, key_index, sizeof(args[i].key_index));
memcpy(args[i].keytable, keytable, sizeof(args[i].keytable));
}
@ -472,7 +472,7 @@ int bruteforceItem(loclass_dumpdata_t item, uint16_t keytable[]) {
}
}
// wait for threads to terminate:
void* ptrs[loclass_tc];
void *ptrs[loclass_tc];
for (int i = 0; i < loclass_tc; i++)
pthread_join(threads[i], &ptrs[i]);
@ -526,7 +526,7 @@ int bruteforceItem(loclass_dumpdata_t item, uint16_t keytable[]) {
uint8_t key_index[8] = {0};
hash1(item.csn, key_index);
*/
/*
/*
* Determine which bytes to retrieve. A hash is typically
* 01010000454501
* We go through that hash, and in the corresponding keytable, we put markers
@ -571,13 +571,13 @@ int bruteforceItem(loclass_dumpdata_t item, uint16_t keytable[]) {
//A uint32 has room for 4 bytes, we'll only need 24 of those bits to bruteforce up to three bytes,
uint32_t brute = 0;
*/
/*
/*
Determine where to stop the bruteforce. A 1-byte attack stops after 256 tries,
(when brute reaches 0x100). And so on...
bytes_to_recover = 1 --> endmask = 0x000000100
bytes_to_recover = 2 --> endmask = 0x000010000
bytes_to_recover = 3 --> endmask = 0x001000000
*/
*/
/*
uint32_t endmask = 1 << 8 * numbytes_to_recover;
PrintAndLogEx(NORMAL, "----------------------------");
@ -903,11 +903,11 @@ int testElite(bool slowtests) {
int res = PM3_SUCCESS;
PrintAndLogEx(INFO, "Testing hash1...");
res += _testHash1();
PrintAndLogEx((res == PM3_SUCCESS) ? SUCCESS : WARNING, " hash1 (%s)", (res == PM3_SUCCESS) ? _GREEN_("ok") : _RED_("fail") );
PrintAndLogEx((res == PM3_SUCCESS) ? SUCCESS : WARNING, " hash1 (%s)", (res == PM3_SUCCESS) ? _GREEN_("ok") : _RED_("fail"));
PrintAndLogEx(INFO, "Testing key diversification...");
res += _test_iclass_key_permutation();
PrintAndLogEx((res == PM3_SUCCESS) ? SUCCESS : WARNING, " key diversification (%s)", (res == PM3_SUCCESS) ? _GREEN_("ok") : _RED_("fail") );
PrintAndLogEx((res == PM3_SUCCESS) ? SUCCESS : WARNING, " key diversification (%s)", (res == PM3_SUCCESS) ? _GREEN_("ok") : _RED_("fail"));
if (slowtests)
res += _testBruteforce();

View file

@ -613,7 +613,7 @@ static int testDES2(uint8_t *key, uint64_t csn, uint64_t expected) {
uint64_t crypt_csn = x_bytes_to_num(result, 8);
PrintAndLogEx(DEBUG, " {csn} %"PRIx64, crypt_csn);
PrintAndLogEx(DEBUG, " expected %"PRIx64 " (%s)", expected, (expected == crypt_csn) ? _GREEN_("ok") : _RED_("fail") );
PrintAndLogEx(DEBUG, " expected %"PRIx64 " (%s)", expected, (expected == crypt_csn) ? _GREEN_("ok") : _RED_("fail"));
if (expected != crypt_csn)
return PM3_ESOFT;

View file

@ -13,7 +13,7 @@
#include "util_posix.h"
#include "comms.h"
pm3_device* pm3_open(char *port) {
pm3_device *pm3_open(char *port) {
pm3_init();
OpenProxmark(&session.current_device, port, false, 20, false, USART_BAUD_RATE);
if (session.pm3_present && (TestProxmark(session.current_device) != PM3_SUCCESS)) {
@ -30,7 +30,7 @@ pm3_device* pm3_open(char *port) {
return session.current_device;
}
void pm3_close(pm3_device* dev) {
void pm3_close(pm3_device *dev) {
// Clean up the port
if (session.pm3_present) {
clearCommandBuffer();
@ -40,16 +40,16 @@ void pm3_close(pm3_device* dev) {
}
}
int pm3_console(pm3_device* dev, char *Cmd) {
int pm3_console(pm3_device *dev, char *Cmd) {
// For now, there is no real device context:
(void) dev;
return CommandReceived(Cmd);
}
const char *pm3_name_get(pm3_device* dev) {
const char *pm3_name_get(pm3_device *dev) {
return dev->conn->serial_port_name;
}
pm3_device* pm3_get_current_dev(void) {
pm3_device *pm3_get_current_dev(void) {
return session.current_device;
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -446,10 +446,10 @@ void num_to_bytebitsLSBF(uint64_t n, size_t len, uint8_t *dest) {
}
}
void bytes_to_bytebits(void* src, size_t srclen, void* dest) {
void bytes_to_bytebits(void *src, size_t srclen, void *dest) {
uint8_t *s = (uint8_t*)src;
uint8_t *d = (uint8_t*)dest;
uint8_t *s = (uint8_t *)src;
uint8_t *d = (uint8_t *)dest;
uint32_t i = srclen * 8;
while (srclen--) {

View file

@ -56,7 +56,7 @@ void print_blocks(uint32_t *data, size_t len);
int hex_to_bytes(const char *hexValue, uint8_t *bytesValue, size_t maxBytesValueLen);
void num_to_bytebits(uint64_t n, size_t len, uint8_t *dest);
void num_to_bytebitsLSBF(uint64_t n, size_t len, uint8_t *dest);
void bytes_to_bytebits(void* src, size_t srclen, void* dest);
void bytes_to_bytebits(void *src, size_t srclen, void *dest);
// Swap endian on arrays up to 64bytes.
uint8_t *SwapEndian64(const uint8_t *src, const size_t len, const uint8_t blockSize);

View file

@ -143,9 +143,10 @@ PLATFORM_DEFS+=$(STANDALONE_PLATFORM_DEFS)
$(info $(findstring WITH_STANDALONE_*,$(PLATFORM_DEFS)))
# Misc
#PLATFORM_DEFS += -DWITH_LCD
# Misc (LCD support)
ifneq (,$(findstring WITH_LCD,$(PLATFORM_DEFS)))
#PLATFORM_DEFS += -DWITH_LCD
endif
# Add flags dependencies :

View file

@ -1,8 +1,6 @@
clear
pref
rem
quit
exit
analyse lcr
analyse crc
analyse chksum
@ -13,6 +11,7 @@ analyse a
analyse nuid
analyse demodbuff
analyse freq
analyse foo
data biphaserawdecode
data detectclock
data fsktonrz
@ -44,20 +43,15 @@ data print
data samples
data setdebugmode
data tune
emv list
hf list
hf tune
hf search
hf sniff
hf 14a list
hf 14a reader
hf 14a cuids
hf 14a sim
hf 14a sniff
hf 14a config
hf 14b list
hf 14b sriwrite
hf 15 list
hf 15 dump
hf 15 info
hf 15 raw
@ -69,7 +63,6 @@ hf 15 writeafi
hf 15 writedsfid
hf epa cnonces
hf epa preplay
hf felica list
hf felica reader
hf felica sniff
hf felica raw
@ -85,11 +78,9 @@ hf felica rqspecver
hf felica resetmode
hf felica litesim
hf felica litedump
hf fido list
hf fido info
hf iclass info
hf iclass list
hf legic list
hf iclass permutekey
hf legic reader
hf legic info
hf legic dump
@ -101,13 +92,6 @@ hf legic crc
hf legic eload
hf legic esave
hf legic wipe
hf lto dump
hf lto restore
hf lto info
hf lto rdbl
hf lto wrbl
hf lto list
hf mf list
hf mf darkside
hf mf nested
hf mf hardnested
@ -144,7 +128,6 @@ hf mf gen3uid
hf mf gen3blk
hf mf gen3freeze
hf mf ice
hf mfp info
hf mfu info
hf mfu dump
hf mfu restore
@ -161,12 +144,8 @@ hf mfu otptear
hf mfdes enum
hf mfdes getuid
hf mfdes info
hf mfdes list
hf st list
hf thinfilm info
hf thinfilm list
hf thinfilm sim
hf topaz list
hf topaz info
hf topaz reader
hf topaz sim
@ -199,17 +178,6 @@ lf simpsk
lf simbidir
lf sniff
lf tune
lf awid demod
lf awid read
lf awid clone
lf awid sim
lf awid brute
lf awid watch
lf cotag demod
lf cotag read
lf destron demod
lf destron read
lf destron sim
lf em 410x_demod
lf em 410x_read
lf em 410x_sim
@ -229,21 +197,7 @@ lf em 4x50_write
lf em 4x50_write_password
lf em 4x50_read
lf em 4x50_wipe
lf fdxb demod
lf fdxb read
lf fdxb clone
lf fdxb sim
lf gallagher demod
lf gallagher read
lf gallagher clone
lf gallagher sim
lf gproxii demod
lf gproxii read
lf gproxii clone
lf gproxii sim
lf hid demod
lf hid read
lf hitag list
lf hitag info
lf hitag reader
lf hitag sim
@ -251,41 +205,20 @@ lf hitag sniff
lf hitag writer
lf hitag dump
lf hitag cc
lf idteck demod
lf idteck read
lf indala demod
lf indala altdemod
lf indala read
lf indala sim
lf io demod
lf io read
lf io clone
lf io sim
lf io watch
lf jablotron demod
lf jablotron read
lf jablotron clone
lf jablotron sim
lf keri demod
lf motorola demod
lf motorola sim
lf nedap demod
lf nedap generate
lf nedap read
lf nedap clone
lf nedap sim
lf nexwatch demod
lf noralsy demod
lf pac demod
lf paradox demod
lf pcf7931 read
lf pcf7931 write
lf pcf7931 config
lf presco demod
lf pyramid demod
lf securakey demod
lf ti demod
lf ti write
lf t55xx config
lf t55xx dangerraw
lf t55xx detect
@ -306,17 +239,12 @@ lf t55xx recoverpw
lf t55xx sniff
lf t55xx special
lf t55xx wipe
lf viking demod
lf visa2000 demod
mem spiffs
smart list
smart info
smart reader
smart raw
smart upgrade
smart setclock
smart brute
script list
script run
usart btpin
usart btfactory
@ -326,4 +254,3 @@ usart txrx
usart txhex
usart rxhex
usart config
wiegand list

View file

@ -38,6 +38,7 @@ Check column "offline" for their availability.
|`analyse nuid `|Y |`create NUID from 7byte UID`
|`analyse demodbuff `|Y |`Load binary string to demodbuffer`
|`analyse freq `|Y |`Calc wave lengths`
|`analyse foo `|Y |`muxer`
### data
@ -267,7 +268,7 @@ Check column "offline" for their availability.
|`hf iclass encrypt `|Y |`[options..] Encrypt given block data`
|`hf iclass decrypt `|Y |`[options..] Decrypt given block data or tag dump file`
|`hf iclass managekeys `|Y |`[options..] Manage keys to use with iclass commands`
|`hf iclass permute `|N |` Permute function from 'heart of darkness' paper`
|`hf iclass permutekey `|N |` Permute function from 'heart of darkness' paper`
|`hf iclass view `|Y |`[options..] Display content from tag dump file`
@ -538,7 +539,7 @@ Check column "offline" for their availability.
|------- |------- |-----------
|`lf awid help `|Y |`this help`
|`lf awid demod `|Y |`demodulate an AWID FSK tag from the GraphBuffer`
|`lf awid read `|N |`attempt to read and extract tag data`
|`lf awid reader `|N |`attempt to read and extract tag data`
|`lf awid clone `|N |`clone AWID tag to T55x7 or Q5/T5555`
|`lf awid sim `|N |`simulate AWID tag`
|`lf awid brute `|N |`Bruteforce card number against reader`
@ -553,7 +554,7 @@ Check column "offline" for their availability.
|------- |------- |-----------
|`lf cotag help `|Y |`This help`
|`lf cotag demod `|Y |`Tries to decode a COTAG signal`
|`lf cotag read `|N |`Attempt to read and extract tag data`
|`lf cotag reader `|N |`Attempt to read and extract tag data`
### lf destron
@ -564,7 +565,7 @@ Check column "offline" for their availability.
|------- |------- |-----------
|`lf destron help `|Y |`This help`
|`lf destron demod `|Y |`Demodulate an Destron tag from the GraphBuffer`
|`lf destron read `|N |`Attempt to read and extract tag data from the antenna`
|`lf destron reader `|N |`Attempt to read and extract tag data from the antenna`
|`lf destron clone `|N |`Clone Destron tag to T55x7`
|`lf destron sim `|N |`Simulate Destron tag`
@ -609,7 +610,7 @@ Check column "offline" for their availability.
|------- |------- |-----------
|`lf fdxb help `|Y |`this help`
|`lf fdxb demod `|Y |`demodulate a FDX-B ISO11784/85 tag from the GraphBuffer`
|`lf fdxb read `|N |`attempt to read at 134kHz and extract tag data`
|`lf fdxb reader `|N |`attempt to read at 134kHz and extract tag data`
|`lf fdxb clone `|N |`clone animal ID tag to T55x7 or Q5/T5555`
|`lf fdxb sim `|N |`simulate Animal ID tag`
@ -622,7 +623,7 @@ Check column "offline" for their availability.
|------- |------- |-----------
|`lf gallagher help `|Y |`This help`
|`lf gallagher demod `|Y |`Demodulate an GALLAGHER tag from the GraphBuffer`
|`lf gallagher read `|N |`Attempt to read and extract tag data from the antenna`
|`lf gallagher reader `|N |`Attempt to read and extract tag data from the antenna`
|`lf gallagher clone `|N |`clone GALLAGHER tag to T55x7`
|`lf gallagher sim `|N |`simulate GALLAGHER tag`
@ -635,7 +636,7 @@ Check column "offline" for their availability.
|------- |------- |-----------
|`lf gproxii help `|Y |`this help`
|`lf gproxii demod `|Y |`demodulate a G Prox II tag from the GraphBuffer`
|`lf gproxii read `|N |`attempt to read and extract tag data from the antenna`
|`lf gproxii reader `|N |`attempt to read and extract tag data from the antenna`
|`lf gproxii clone `|N |`clone Guardall tag to T55x7 or Q5/T5555`
|`lf gproxii sim `|N |`simulate Guardall tag`
@ -680,7 +681,7 @@ Check column "offline" for their availability.
|------- |------- |-----------
|`lf idteck help `|Y |`This help`
|`lf idteck demod `|Y |`Demodulate an Idteck tag from the GraphBuffer`
|`lf idteck read `|N |`Attempt to read and Extract tag data from the antenna`
|`lf idteck reader `|N |`Attempt to read and Extract tag data from the antenna`
### lf indala
@ -692,7 +693,7 @@ Check column "offline" for their availability.
|`lf indala help `|Y |`this help`
|`lf indala demod `|Y |`demodulate an indala tag (PSK1) from GraphBuffer`
|`lf indala altdemod `|Y |`alternative method to Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)`
|`lf indala read `|N |`read an Indala Prox tag from the antenna`
|`lf indala reader `|N |`read an Indala Prox tag from the antenna`
|`lf indala clone `|N |`clone Indala tag to T55x7 or Q5/T5555`
|`lf indala sim `|N |`simulate Indala tag`
@ -705,7 +706,7 @@ Check column "offline" for their availability.
|------- |------- |-----------
|`lf io help `|Y |`this help`
|`lf io demod `|Y |`demodulate an IOProx tag from the GraphBuffer`
|`lf io read `|N |`attempt to read and extract tag data`
|`lf io reader `|N |`attempt to read and extract tag data`
|`lf io clone `|N |`clone IOProx tag to T55x7 or Q5/T5555`
|`lf io sim `|N |`simulate IOProx tag`
|`lf io watch `|N |`continuously watch for cards. Reader mode`
@ -719,7 +720,7 @@ Check column "offline" for their availability.
|------- |------- |-----------
|`lf jablotron help `|Y |`This help`
|`lf jablotron demod `|Y |`Demodulate an Jablotron tag from the GraphBuffer`
|`lf jablotron read `|N |`Attempt to read and extract tag data from the antenna`
|`lf jablotron reader `|N |`Attempt to read and extract tag data from the antenna`
|`lf jablotron clone `|N |`clone jablotron tag to T55x7 or Q5/T5555`
|`lf jablotron sim `|N |`simulate jablotron tag`
@ -874,7 +875,7 @@ Check column "offline" for their availability.
|command |offline |description
|------- |------- |-----------
|`lf ti help `|Y |`This help`
|`lf ti demod `|Y |`Demodulate raw bits for TI-type LF tag from the GraphBuffer`
|`lf ti demod `|Y |`Demodulate raw bits for TI LF tag from the GraphBuffer`
|`lf ti reader `|N |`Read and decode a TI 134 kHz tag`
|`lf ti write `|N |`Write new data to a r/w TI 134 kHz tag`

6
pm3
View file

@ -133,7 +133,7 @@ function get_pm3_list_Windows {
# Need to look for this first, the call to Win32_serialport "crashes" then native bt serial port. Don't ask why.
#BT direct SERIAL PORTS (COM)
if $FINDBTRFCOMM; then
for DEV in $(powershell.exe -command "Get-CimInstance -ClassName Win32_PnPEntity | Where-Object Caption -like 'Standard Serial over Bluetooth link (COM*' | Select Name" 2> /dev/null | awk 'match($0,/COM([0-9]+)/,m){print m[1]}'); do
for DEV in $(wmic /locale:ms_409 path Win32_PnPEntity Where "Caption LIKE '%Bluetooth%(COM%'" Get Name 2> /dev/null | awk -b 'match($0,/(COM[0-9]+)/,m){print m[1]}'); do
DEV=${DEV/ */}
PM3LIST+=("$DEV")
if [ ${#PM3LIST[*]} -ge "$N" ]; then
@ -143,7 +143,7 @@ function get_pm3_list_Windows {
fi
# Normal SERIAL PORTS (COM)
for DEV in $(powershell.exe -command "Get-CimInstance -ClassName Win32_serialport | Where-Object PNPDeviceID -like '*VID_9AC4&PID_4B8F*' | Select DeviceID" 2>/dev/null | awk '/^COM/{print $1}'); do
for DEV in $(wmic /locale:ms_409 path Win32_SerialPort Where "PNPDeviceID LIKE '%VID_9AC4&PID_4B8F%'" Get DeviceID 2>/dev/null | awk -b '/^COM/{print $1}'); do
DEV=${DEV/ */}
PM3LIST+=("$DEV")
if [ ${#PM3LIST[*]} -ge "$N" ]; then
@ -153,7 +153,7 @@ function get_pm3_list_Windows {
#white BT dongle SERIAL PORTS (COM)
if $FINDBTDONGLE; then
for DEV in $(powershell.exe -command "Get-CimInstance -ClassName Win32_serialport | Where-Object PNPDeviceID -like '*VID_10C4&PID_EA60*' | Select DeviceID" 2>/dev/null | awk '/^COM/{print $1}'); do
for DEV in $(wmic /locale:ms_409 path Win32_SerialPort Where "PNPDeviceID LIKE '%VID_10C4&PID_EA60%'" Get DeviceID 2>/dev/null | awk -b '/^COM/{print $1}'); do
DEV=${DEV/ */}
PM3LIST+=("$DEV")
if [ ${#PM3LIST[*]} -ge "$N" ]; then