Rework Cmd exposed API, use more static and fix [-Wmissing-prototypes], ongoing...

This commit is contained in:
Philippe Teuwen 2019-04-12 01:55:25 +02:00
commit f6a6ec8447
21 changed files with 760 additions and 746 deletions

View file

@ -1141,7 +1141,7 @@ int PSKDemod(const char *Cmd, bool verbose) {
return 1;
}
int CmdIdteckDemod(const char *Cmd) {
static int CmdIdteckDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
if (!PSKDemod("", false)) {
@ -1202,6 +1202,11 @@ int CmdIdteckDemod(const char *Cmd) {
return 1;
}
int demodIdteck(void) {
return CmdIdteckDemod("");
}
// by marshmellow
// takes 3 arguments - clock, invert, maxErr as integers
// attempts to demodulate nrz only

View file

@ -54,7 +54,6 @@ int CmdDetectClockRate(const char *Cmd);
int CmdFSKrawdemod(const char *Cmd);
int CmdPSK1rawDemod(const char *Cmd);
int CmdPSK2rawDemod(const char *Cmd);
int CmdIdteckDemod(const char *Cmd);
int CmdGrid(const char *Cmd);
int CmdGetBitStream(const char *Cmd);
int CmdHexsamples(const char *Cmd);
@ -88,6 +87,8 @@ int AskEdgeDetect(const int *in, int *out, int len, int threshold);
int CmdDataIIR(const char *Cmd);
int demodIdteck(void);
#define MAX_DEMOD_BUF_LEN (1024*128)
#define BIGBUF_SIZE 40000
extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];

View file

@ -886,8 +886,8 @@ int CmdLFfind(const char *Cmd) {
// The improved noise detection will find Cotag.
if (getSignalProperties()->isnoise) {
if (CmdLFHitagReader("26") == 0) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Hitag") " found!"); return 1;}
if (CmdCOTAGRead("") > 0) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("COTAG ID") " found!"); return 1;}
if (readHitagUid()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Hitag") " found!"); return 1;}
if (readCOTAGUid()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("COTAG ID") " found!"); return 1;}
PrintAndLogEx(FAILED, "\n" _YELLOW_("No data found!") " - Signal looks like noise. Maybe not an LF tag?");
return 0;
@ -896,16 +896,16 @@ int CmdLFfind(const char *Cmd) {
if (EM4x50Read("", false)) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("EM4x50 ID") " found!"); return 1;}
if (CmdHIDDemod("")) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("HID Prox ID") " found!"); goto out;}
if (CmdAWIDDemod("")) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("AWID ID") " found!"); goto out;}
if (demodHID()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("HID Prox ID") " found!"); goto out;}
if (demodAWID()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("AWID ID") " found!"); goto out;}
if (demodParadox()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Paradox ID") " found!"); goto out;}
if (CmdEM410xDemod("")) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("EM410x ID") " found!"); goto out;}
if (CmdFdxDemod("")) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("FDX-B ID") " found!"); goto out;}
if (CmdGuardDemod("")) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Guardall G-Prox II ID") " found!"); goto out; }
if (CmdIdteckDemod("")) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Idteck ID") " found!"); goto out;}
if (CmdIndalaDemod("")) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Indala ID") " found!"); goto out;}
if (CmdIOProxDemod("")) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("IO Prox ID") " found!"); goto out;}
if (demodEM410x()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("EM410x ID") " found!"); goto out;}
if (demodFDX()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("FDX-B ID") " found!"); goto out;}
if (demodGuard()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Guardall G-Prox II ID") " found!"); goto out; }
if (demodIdteck()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Idteck ID") " found!"); goto out;}
if (demodIndala()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Indala ID") " found!"); goto out;}
if (demodIOProx()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("IO Prox ID") " found!"); goto out;}
if (demodJablotron()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Jablotron ID") " found!"); goto out;}
if (demodNedap()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("NEDAP ID") " found!"); goto out;}
if (demodNexWatch()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("NexWatch ID") " found!"); goto out;}

View file

@ -13,7 +13,7 @@
#include "cmdlfawid.h" // AWID function declarations
static int CmdHelp(const char *Cmd);
/*
static int usage_lf_awid_read(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.");
@ -29,7 +29,7 @@ static int usage_lf_awid_read(void) {
PrintAndLogEx(NORMAL, " lf awid read 1");
return 0;
}
*/
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.");
@ -122,60 +122,6 @@ static bool sendTry(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint32_t delay, ui
return true;
}
//refactored by marshmellow
int getAWIDBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *bits) {
// the return bits, preamble 0000 0001
bits[7] = 1;
uint8_t pre[66];
memset(pre, 0, sizeof(pre));
// add formatlength
num_to_bytebits(fmtlen, 8, pre);
// add facilitycode, cardnumber and wiegand parity bits
switch (fmtlen) {
case 26: {
uint8_t wiegand[24];
num_to_bytebits(fc, 8, wiegand);
num_to_bytebits(cn, 16, wiegand + 8);
wiegand_add_parity(pre + 8, wiegand, sizeof(wiegand));
break;
}
case 34: {
uint8_t wiegand[32];
num_to_bytebits(fc, 8, wiegand);
num_to_bytebits(cn, 24, wiegand + 8);
wiegand_add_parity(pre + 8, wiegand, sizeof(wiegand));
break;
}
case 37: {
uint8_t wiegand[31];
num_to_bytebits(fc, 13, wiegand);
num_to_bytebits(cn, 18, wiegand + 13);
wiegand_add_parity(pre + 8, wiegand, sizeof(wiegand));
break;
}
case 50: {
uint8_t wiegand[48];
num_to_bytebits(fc, 16, wiegand);
num_to_bytebits(cn, 32, wiegand + 16);
wiegand_add_parity(pre + 8, wiegand, sizeof(wiegand));
break;
}
}
// add AWID 4bit parity
size_t bitLen = addParity(pre, bits + 8, 66, 4, 1);
if (bitLen != 88) return 0;
PrintAndLogEx(SUCCESS, "awid raw bits:\n %s \n", sprint_bin(bits, bitLen));
return 1;
}
static void verify_values(uint8_t *fmtlen, uint32_t *fc, uint32_t *cn) {
switch (*fmtlen) {
case 50:
@ -218,15 +164,10 @@ static void verify_values(uint8_t *fmtlen, uint32_t *fc, uint32_t *cn) {
break;
}
}
// this read is the "normal" read, which download lf signal and tries to demod here.
int CmdAWIDRead(const char *Cmd) {
lf_read(true, 12000);
return CmdAWIDDemod(Cmd);
}
/*
// this read loops on device side.
// uses the demod in lfops.c
int CmdAWIDRead_device(const char *Cmd) {
static int CmdAWIDRead_device(const char *Cmd) {
if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_awid_read();
uint8_t findone = (Cmd[0] == '1') ? 1 : 0;
@ -235,11 +176,11 @@ int CmdAWIDRead_device(const char *Cmd) {
SendCommand(&c);
return 0;
}
*/
//by marshmellow
//AWID Prox demod - FSK2a RF/50 with preamble of 00000001 (always a 96 bit data stream)
//print full AWID Prox ID and some bit format details if found
int CmdAWIDDemod(const char *Cmd) {
static int CmdAWIDDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0};
size_t size = getFromGraphBuf(bits);
@ -370,7 +311,13 @@ int CmdAWIDDemod(const char *Cmd) {
return 1;
}
int CmdAWIDSim(const char *Cmd) {
// this read is the "normal" read, which download lf signal and tries to demod here.
static int CmdAWIDRead(const char *Cmd) {
lf_read(true, 12000);
return CmdAWIDDemod(Cmd);
}
static int CmdAWIDSim(const char *Cmd) {
uint32_t fc = 0, cn = 0;
uint8_t fmtlen = 0;
uint8_t bits[96];
@ -410,7 +357,7 @@ int CmdAWIDSim(const char *Cmd) {
return 0;
}
int CmdAWIDClone(const char *Cmd) {
static int CmdAWIDClone(const char *Cmd) {
uint32_t blocks[4] = {T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_50 | 3 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0};
uint32_t fc = 0, cn = 0;
uint8_t fmtlen = 0;
@ -461,7 +408,7 @@ int CmdAWIDClone(const char *Cmd) {
return 0;
}
int CmdAWIDBrute(const char *Cmd) {
static int CmdAWIDBrute(const char *Cmd) {
bool errors = false, verbose = false;
uint32_t fc = 0, cn = 0, delay = 1000;
@ -567,14 +514,72 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
static int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;
}
int CmdLFAWID(const char *Cmd) {
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;
//refactored by marshmellow
int getAWIDBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *bits) {
// the return bits, preamble 0000 0001
bits[7] = 1;
uint8_t pre[66];
memset(pre, 0, sizeof(pre));
// add formatlength
num_to_bytebits(fmtlen, 8, pre);
// add facilitycode, cardnumber and wiegand parity bits
switch (fmtlen) {
case 26: {
uint8_t wiegand[24];
num_to_bytebits(fc, 8, wiegand);
num_to_bytebits(cn, 16, wiegand + 8);
wiegand_add_parity(pre + 8, wiegand, sizeof(wiegand));
break;
}
case 34: {
uint8_t wiegand[32];
num_to_bytebits(fc, 8, wiegand);
num_to_bytebits(cn, 24, wiegand + 8);
wiegand_add_parity(pre + 8, wiegand, sizeof(wiegand));
break;
}
case 37: {
uint8_t wiegand[31];
num_to_bytebits(fc, 13, wiegand);
num_to_bytebits(cn, 18, wiegand + 13);
wiegand_add_parity(pre + 8, wiegand, sizeof(wiegand));
break;
}
case 50: {
uint8_t wiegand[48];
num_to_bytebits(fc, 16, wiegand);
num_to_bytebits(cn, 32, wiegand + 16);
wiegand_add_parity(pre + 8, wiegand, sizeof(wiegand));
break;
}
}
// add AWID 4bit parity
size_t bitLen = addParity(pre, bits + 8, 66, 4, 1);
if (bitLen != 88) return 0;
PrintAndLogEx(SUCCESS, "awid raw bits:\n %s \n", sprint_bin(bits, bitLen));
return 1;
}
int demodAWID(void) {
return CmdAWIDDemod("");
}

View file

@ -25,11 +25,8 @@
int CmdLFAWID(const char *Cmd);
int CmdAWIDDemod(const char *Cmd);
int CmdAWIDRead(const char *Cmd);
int CmdAWIDSim(const char *Cmd);
int CmdAWIDClone(const char *Cmd);
int CmdAWIDBrute(const char *Cmd);
int demodAWID(void);
int getAWIDBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *bits);
#endif

View file

@ -27,7 +27,7 @@ static int usage_lf_cotag_read(void) {
// COTAG demod should be able to use GraphBuffer,
// when data load samples
int CmdCOTAGDemod(const char *Cmd) {
static int CmdCOTAGDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
uint8_t bits[COTAG_BITS] = {0};
@ -67,7 +67,7 @@ int CmdCOTAGDemod(const char *Cmd) {
// 0 = HIGH/LOW signal - maxlength bigbuff
// 1 = translation for HI/LO into bytes with manchester 0,1 - length 300
// 2 = raw signal - maxlength bigbuff
int CmdCOTAGRead(const char *Cmd) {
static int CmdCOTAGRead(const char *Cmd) {
if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_cotag_read();
@ -110,14 +110,22 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
static int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;
}
int CmdLFCOTAG(const char *Cmd) {
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;
int demodCOTAG(void) {
return CmdCOTAGDemod("");
}
int readCOTAGUid(void) {
return CmdCOTAGRead > 0;
}

View file

@ -24,7 +24,6 @@
#endif
int CmdLFCOTAG(const char *Cmd);
int CmdCOTAGRead(const char *Cmd);
int CmdCOTAGDemod(const char *Cmd);
int demodCOTAG(void);
int readCOTAGUid(void);
#endif

View file

@ -188,7 +188,7 @@ static int usage_lf_em4x05_info(void) {
*/
// Construct the graph for emulating an EM410X tag
void ConstructEM410xEmulGraph(const char *uid, const uint8_t clock) {
static void ConstructEM410xEmulGraph(const char *uid, const uint8_t clock) {
int i, j, binary[4], parity[4];
uint32_t n;
@ -383,28 +383,22 @@ int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo, bool verbose) {
if (!ASKDemod_ext(Cmd, false, false, 1, &st)) return 0;
return AskEm410xDecode(verbose, hi, lo);
}
// this read is the "normal" read, which download lf signal and tries to demod here.
int CmdEM410xRead(const char *Cmd) {
lf_read(true, 8192);
return CmdEM410xDemod(Cmd);
}
/*
// this read loops on device side.
// uses the demod in lfops.c
int CmdEM410xRead_device(const char *Cmd) {
static int CmdEM410xRead_device(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
uint8_t findone = (cmdp == '1') ? 1 : 0;
UsbCommand c = {CMD_EM410X_DEMOD, {findone, 0, 0}, {{0}}};
SendCommand(&c);
return 0;
}
*/
//by marshmellow
//takes 3 arguments - clock, invert and maxErr as integers
//attempts to demodulate ask while decoding manchester
//prints binary found and saves in graphbuffer for further commands
int CmdEM410xDemod(const char *Cmd) {
static int CmdEM410xDemod(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) > 10 || cmdp == 'h') return usage_lf_em410x_demod();
@ -417,8 +411,14 @@ int CmdEM410xDemod(const char *Cmd) {
return 1;
}
// this read is the "normal" read, which download lf signal and tries to demod here.
static int CmdEM410xRead(const char *Cmd) {
lf_read(true, 8192);
return CmdEM410xDemod(Cmd);
}
// emulate an EM410X tag
int CmdEM410xSim(const char *Cmd) {
static int CmdEM410xSim(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_lf_em410x_sim();
@ -443,7 +443,7 @@ int CmdEM410xSim(const char *Cmd) {
return 0;
}
int CmdEM410xBrute(const char *Cmd) {
static int CmdEM410xBrute(const char *Cmd) {
char filename[FILE_PATH_SIZE] = {0};
FILE *f = NULL;
char buf[11];
@ -565,7 +565,7 @@ int CmdEM410xBrute(const char *Cmd) {
*
* EDIT -- capture enough to get 2 complete preambles at the slowest data rate known to be used (rf/64) (64*64*2+9 = 8201) marshmellow
*/
int CmdEM410xWatch(const char *Cmd) {
static int CmdEM410xWatch(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
do {
if (ukbhit()) {
@ -581,7 +581,7 @@ int CmdEM410xWatch(const char *Cmd) {
}
//currently only supports manchester modulations
int CmdEM410xWatchnSpoof(const char *Cmd) {
static int CmdEM410xWatchnSpoof(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_lf_em410x_ws();
@ -593,7 +593,7 @@ int CmdEM410xWatchnSpoof(const char *Cmd) {
return 0;
}
int CmdEM410xWrite(const char *Cmd) {
static int CmdEM410xWrite(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 0x00 || cmdp == 'h') return usage_lf_em410x_write();
@ -956,18 +956,18 @@ int EM4x50Read(const char *Cmd, bool verbose) {
return (int)AllPTest;
}
int CmdEM4x50Read(const char *Cmd) {
static int CmdEM4x50Read(const char *Cmd) {
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
if (ctmp == 'h') return usage_lf_em4x50_read();
return EM4x50Read(Cmd, true);
}
int CmdEM4x50Write(const char *Cmd) {
static int CmdEM4x50Write(const char *Cmd) {
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
if (ctmp == 'h') return usage_lf_em4x50_write();
PrintAndLogEx(NORMAL, "no implemented yet");
return 0;
}
int CmdEM4x50Dump(const char *Cmd) {
static int CmdEM4x50Dump(const char *Cmd) {
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
if (ctmp == 'h') return usage_lf_em4x50_dump();
PrintAndLogEx(NORMAL, "no implemented yet");
@ -1143,7 +1143,7 @@ int EM4x05ReadWord_ext(uint8_t addr, uint32_t pwd, bool usePwd, uint32_t *word)
return demodEM4x05resp(word);
}
int CmdEM4x05Dump(const char *Cmd) {
static int CmdEM4x05Dump(const char *Cmd) {
uint8_t addr = 0;
uint32_t pwd = 0;
bool usePwd = false;
@ -1176,7 +1176,7 @@ int CmdEM4x05Dump(const char *Cmd) {
return success;
}
int CmdEM4x05Read(const char *Cmd) {
static int CmdEM4x05Read(const char *Cmd) {
uint8_t addr;
uint32_t pwd;
bool usePwd = false;
@ -1206,7 +1206,7 @@ int CmdEM4x05Read(const char *Cmd) {
return isOk;
}
int CmdEM4x05Write(const char *Cmd) {
static int CmdEM4x05Write(const char *Cmd) {
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) == 0 || ctmp == 'h') return usage_lf_em4x05_write();
@ -1419,7 +1419,7 @@ bool EM4x05IsBlock0(uint32_t *word) {
return (res > 0) ? true : false;
}
int CmdEM4x05Info(const char *Cmd) {
static int CmdEM4x05Info(const char *Cmd) {
#define EM_SERIAL_BLOCK 1
#define EM_CONFIG_BLOCK 4
#define EM_PROT1_BLOCK 14
@ -1488,14 +1488,18 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
static int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;
}
int CmdLFEM4X(const char *Cmd) {
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;
int demodEM410x(void) {
return CmdEM410xDemod("");
}

View file

@ -27,21 +27,7 @@
int CmdLFEM4X(const char *Cmd);
int CmdEM410xDemod(const char *Cmd);
int CmdEM410xRead(const char *Cmd);
int CmdEM410xSim(const char *Cmd);
int CmdEM410xBrute(const char *Cmd);
int CmdEM410xWatch(const char *Cmd);
int CmdEM410xWatchnSpoof(const char *Cmd);
int CmdEM410xWrite(const char *Cmd);
int CmdEM4x05Dump(const char *Cmd);
int CmdEM4x05Info(const char *Cmd);
int CmdEM4x05Read(const char *Cmd);
int CmdEM4x05Write(const char *Cmd);
int CmdEM4x50Read(const char *Cmd);
int CmdEM4x50Write(const char *Cmd);
int CmdEM4x50Dump(const char *Cmd);
int demodEM410x(void);
int EM4x50Read(const char *Cmd, bool verbose);
bool EM4x05IsBlock0(uint32_t *word);

View file

@ -64,20 +64,6 @@ static int usage_lf_fdx_sim(void) {
return 0;
}
// Ask/Biphase Demod then try to locate an ISO 11784/85 ID
// BitStream must contain previously askrawdemod and biphasedemoded data
int detectFDXB(uint8_t *dest, size_t *size) {
//make sure buffer has enough data
if (*size < 128 * 2) return -1;
size_t startIdx = 0;
uint8_t preamble[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
if (!preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx))
return -2; //preamble not found
if (*size != 128) return -3; //wrong demoded size
//return start position
return (int)startIdx;
}
// clearing the topbit needed for the preambl detection.
static void verify_values(uint32_t countryid, uint64_t animalid) {
if ((animalid & 0x3FFFFFFFFF) != animalid) {
@ -90,56 +76,6 @@ static void verify_values(uint32_t countryid, uint64_t animalid) {
}
}
int getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t isextended, 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[65] = isanimal;
// add extended flag - OK
bits[81] = isextended;
// add national code 40bits - OK
num_to_bytebitsLSBF(national_id >> 0, 8, bits + 11);
num_to_bytebitsLSBF(national_id >> 8, 8, bits + 20);
num_to_bytebitsLSBF(national_id >> 16, 8, bits + 29);
num_to_bytebitsLSBF(national_id >> 24, 8, bits + 38);
num_to_bytebitsLSBF(national_id >> 32, 6, bits + 47);
// add country code - OK
num_to_bytebitsLSBF(country >> 0, 2, bits + 53);
num_to_bytebitsLSBF(country >> 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);
uint16_t crc = crc16_kermit(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);
return 1;
}
// FDX-B ISO11784/85 demod (aka animal tag) BIPHASE, inverted, rf/32, with preamble of 00000000001 (128bits)
// 8 databits + 1 parity (1)
// CIITT 16 chksum
@ -157,7 +93,8 @@ int getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t
-- sample: 985121004515220 [ 37FF65B88EF94 ]
*/
int CmdFDXBdemodBI(const char *Cmd) {
/*
static int CmdFDXBdemodBI(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
int clk = 32;
@ -229,11 +166,11 @@ int CmdFDXBdemodBI(const char *Cmd) {
}
return 1;
}
*/
//see ASKDemod for what args are accepted
//almost the same demod as cmddata.c/CmdFDXBdemodBI
int CmdFdxDemod(const char *Cmd) {
static int CmdFdxDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
//Differential Biphase / di-phase (inverted biphase)
@ -303,12 +240,12 @@ int CmdFdxDemod(const char *Cmd) {
return 1;
}
int CmdFdxRead(const char *Cmd) {
static int CmdFdxRead(const char *Cmd) {
lf_read(true, 10000);
return CmdFdxDemod(Cmd);
}
int CmdFdxClone(const char *Cmd) {
static int CmdFdxClone(const char *Cmd) {
uint32_t countryid = 0;
uint64_t animalid = 0;
@ -360,7 +297,7 @@ int CmdFdxClone(const char *Cmd) {
return 0;
}
int CmdFdxSim(const char *Cmd) {
static int CmdFdxSim(const char *Cmd) {
uint32_t countryid = 0;
uint64_t animalid = 0;
@ -399,14 +336,83 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
static int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;
}
int CmdLFFdx(const char *Cmd) {
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;
// Ask/Biphase Demod then try to locate an ISO 11784/85 ID
// BitStream must contain previously askrawdemod and biphasedemoded data
int detectFDXB(uint8_t *dest, size_t *size) {
//make sure buffer has enough data
if (*size < 128 * 2) return -1;
size_t startIdx = 0;
uint8_t preamble[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
if (!preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx))
return -2; //preamble not found
if (*size != 128) return -3; //wrong demoded size
//return start position
return (int)startIdx;
}
int demodFDX(void) {
return CmdFdxDemod("");
}
int getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t isextended, 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[65] = isanimal;
// add extended flag - OK
bits[81] = isextended;
// add national code 40bits - OK
num_to_bytebitsLSBF(national_id >> 0, 8, bits + 11);
num_to_bytebitsLSBF(national_id >> 8, 8, bits + 20);
num_to_bytebitsLSBF(national_id >> 16, 8, bits + 29);
num_to_bytebitsLSBF(national_id >> 24, 8, bits + 38);
num_to_bytebitsLSBF(national_id >> 32, 6, bits + 47);
// add country code - OK
num_to_bytebitsLSBF(country >> 0, 2, bits + 53);
num_to_bytebitsLSBF(country >> 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);
uint16_t crc = crc16_kermit(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);
return 1;
}

View file

@ -20,11 +20,8 @@
#include "lfdemod.h" // parityTest
int CmdLFFdx(const char *Cmd);
int CmdFdxClone(const char *Cmd);
int CmdFdxSim(const char *Cmd);
int CmdFdxRead(const char *Cmd);
int CmdFdxDemod(const char *Cmd);
int detectFDXB(uint8_t *dest, size_t *size);
int demodFDX(void);
int getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t isextended, uint32_t extended, uint8_t *bits);
#endif

View file

@ -44,8 +44,241 @@ static int usage_lf_guard_sim(void) {
return 0;
}
//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
// but will leave the GraphBuffer intact.
//if successful it will push askraw data back to demod buffer ready for emulation
static int CmdGuardDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
//Differential Biphase
//get binary from ask wave
if (!ASKbiphaseDemod("0 64 0 0", false)) {
PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII ASKbiphaseDemod failed");
return 0;
}
size_t size = DemodBufferLen;
int preambleIndex = detectGProxII(DemodBuffer, &size);
if (preambleIndex < 0) {
if (preambleIndex == -1)
PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII too few bits found");
else if (preambleIndex == -2)
PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII preamble not found");
else if (preambleIndex == -3)
PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII size not correct: %d", size);
else if (preambleIndex == -5)
PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII wrong spacerbits");
else
PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII ans: %d", preambleIndex);
return 0;
}
//got a good demod of 96 bits
uint8_t ByteStream[8] = {0x00};
uint8_t xorKey = 0;
size_t startIdx = preambleIndex + 6; //start after 6 bit preamble
uint8_t bits_no_spacer[90];
//so as to not mess with raw DemodBuffer copy to a new sample array
memcpy(bits_no_spacer, DemodBuffer + startIdx, 90);
// remove the 18 (90/5=18) parity bits (down to 72 bits (96-6-18=72))
size_t len = removeParity(bits_no_spacer, 0, 5, 3, 90); //source, startloc, paritylen, ptype, length_to_run
if (len != 72) {
PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII spacer removal did not produce 72 bits: %u, start: %u", len, startIdx);
return 0;
}
// get key and then get all 8 bytes of payload decoded
xorKey = (uint8_t)bytebits_to_byteLSBF(bits_no_spacer, 8);
for (size_t idx = 0; idx < 8; idx++) {
ByteStream[idx] = ((uint8_t)bytebits_to_byteLSBF(bits_no_spacer + 8 + (idx * 8), 8)) ^ xorKey;
PrintAndLogEx(DEBUG, "DEBUG: gProxII byte %u after xor: %02x", (unsigned int)idx, ByteStream[idx]);
}
setDemodBuff(DemodBuffer, 96, preambleIndex);
setClockGrid(g_DemodClock, g_DemodStartIdx + (preambleIndex * g_DemodClock));
//ByteStream contains 8 Bytes (64 bits) of decrypted raw tag data
uint8_t fmtLen = ByteStream[0] >> 2;
uint32_t FC = 0;
uint32_t Card = 0;
//get raw 96 bits to print
uint32_t raw1 = bytebits_to_byte(DemodBuffer, 32);
uint32_t raw2 = bytebits_to_byte(DemodBuffer + 32, 32);
uint32_t raw3 = bytebits_to_byte(DemodBuffer + 64, 32);
bool unknown = false;
switch (fmtLen) {
case 36:
FC = ((ByteStream[3] & 0x7F) << 7) | (ByteStream[4] >> 1);
Card = ((ByteStream[4] & 1) << 19) | (ByteStream[5] << 11) | (ByteStream[6] << 3) | (ByteStream[7] >> 5);
break;
case 26:
FC = ((ByteStream[3] & 0x7F) << 1) | (ByteStream[4] >> 7);
Card = ((ByteStream[4] & 0x7F) << 9) | (ByteStream[5] << 1) | (ByteStream[6] >> 7);
break;
default :
unknown = true;
break;
}
if (!unknown)
PrintAndLogEx(SUCCESS, "G-Prox-II Found: Format Len: %ubit - FC: %u - Card: %u, Raw: %08x%08x%08x", fmtLen, FC, Card, raw1, raw2, raw3);
else
PrintAndLogEx(SUCCESS, "Unknown G-Prox-II Fmt Found: Format Len: %u, Raw: %08x%08x%08x", fmtLen, raw1, raw2, raw3);
return 1;
}
static int CmdGuardRead(const char *Cmd) {
lf_read(true, 10000);
return CmdGuardDemod(Cmd);
}
static int CmdGuardClone(const char *Cmd) {
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_guard_clone();
uint32_t facilitycode = 0, cardnumber = 0, fc = 0, cn = 0, fmtlen = 0;
uint8_t i;
uint8_t bs[96];
memset(bs, 0x00, sizeof(bs));
//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};
if (sscanf(Cmd, "%u %u %u", &fmtlen, &fc, &cn) != 3) return usage_lf_guard_clone();
fmtlen &= 0x7f;
facilitycode = (fc & 0x000000FF);
cardnumber = (cn & 0x0000FFFF);
if (!getGuardBits(fmtlen, facilitycode, cardnumber, bs)) {
PrintAndLogEx(WARNING, "Error with tag bitstream generation.");
return 1;
}
// Q5
if (param_getchar(Cmd, 3) == 'Q' || param_getchar(Cmd, 3) == 'q')
blocks[0] = T5555_MODULATION_FSK2 | T5555_SET_BITRATE(50) | 3 << T5555_MAXBLOCK_SHIFT;
blocks[1] = bytebits_to_byte(bs, 32);
blocks[2] = bytebits_to_byte(bs + 32, 32);
blocks[3] = bytebits_to_byte(bs + 64, 32);
PrintAndLogEx(INFO, "Preparing to clone Guardall to T55x7 with Facility Code: %u, Card Number: %u", facilitycode, cardnumber);
print_blocks(blocks, 4);
UsbCommand resp;
UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {0, 0, 0}, {{0}}};
for (i = 0; i < 4; ++i) {
c.arg[0] = blocks[i];
c.arg[1] = i;
clearCommandBuffer();
SendCommand(&c);
if (!WaitForResponseTimeout(CMD_ACK, &resp, T55XX_WRITE_TIMEOUT)) {
PrintAndLogEx(WARNING, "Error occurred, device did not respond during write operation.");
return -1;
}
}
return 0;
}
static int CmdGuardSim(const char *Cmd) {
// Guard uses: clk: 64, invert: 0, encoding: 2 (ASK Biphase)
uint8_t clock1 = 64, encoding = 2, separator = 0, invert = 0;
uint32_t facilitycode = 0, cardnumber = 0, fc = 0, cn = 0, fmtlen = 0;
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_guard_sim();
if (sscanf(Cmd, "%u %u %u", &fmtlen, &fc, &cn) != 3) return usage_lf_guard_sim();
uint8_t bs[96];
size_t size = sizeof(bs);
memset(bs, 0x00, size);
fmtlen &= 0x7F;
facilitycode = (fc & 0x000000FF);
cardnumber = (cn & 0x0000FFFF);
if (!getGuardBits(fmtlen, facilitycode, cardnumber, bs)) {
PrintAndLogEx(WARNING, "Error with tag bitstream generation.");
return 1;
}
PrintAndLogEx(SUCCESS, "Simulating Guardall - Facility Code: %u, CardNumber: %u", facilitycode, cardnumber);
uint64_t arg1, arg2;
arg1 = (clock1 << 8) | encoding;
arg2 = (invert << 8) | separator;
UsbCommand c = {CMD_ASK_SIM_TAG, {arg1, arg2, size}, {{0}}};
memcpy(c.d.asBytes, bs, size);
clearCommandBuffer();
SendCommand(&c);
return 0;
}
static command_t CommandTable[] = {
{"help", CmdHelp, 1, "this help"},
{"demod", CmdGuardDemod, 1, "demodulate a G Prox II tag from the GraphBuffer"},
{"read", CmdGuardRead, 0, "attempt to read and extract tag data from the antenna"},
{"clone", CmdGuardClone, 0, "clone Guardall tag"},
{"sim", CmdGuardSim, 0, "simulate Guardall tag"},
{NULL, NULL, 0, NULL}
};
static int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;
}
int CmdLFGuard(const char *Cmd) {
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
// by marshmellow
// demod gProxIIDemod
// error returns as -x
// success returns start position in bitstream
// Bitstream must contain previously askrawdemod and biphasedemoded data
int detectGProxII(uint8_t *bits, size_t *size) {
size_t startIdx = 0;
uint8_t preamble[] = {1, 1, 1, 1, 1, 0};
// sanity check
if (*size < sizeof(preamble)) return -1;
if (!preambleSearch(bits, preamble, sizeof(preamble), size, &startIdx))
return -2; //preamble not found
//gProxII should be 96 bits
if (*size != 96) return -3;
//check first 6 spacer bits to verify format
if (!bits[startIdx + 5] && !bits[startIdx + 10] && !bits[startIdx + 15] && !bits[startIdx + 20] && !bits[startIdx + 25] && !bits[startIdx + 30]) {
//confirmed proper separator bits found
//return start position
return (int) startIdx;
}
return -5; //spacer bits not found - not a valid gproxII
}
int demodGuard(void) {
return CmdGuardDemod("");
}
// Works for 26bits.
int GetGuardBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits) {
int getGuardBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits) {
uint8_t xorKey = 0x66;
uint8_t i;
@ -139,231 +372,3 @@ int GetGuardBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits) {
return 1;
}
// by marshmellow
// demod gProxIIDemod
// error returns as -x
// success returns start position in bitstream
// Bitstream must contain previously askrawdemod and biphasedemoded data
int detectGProxII(uint8_t *bits, size_t *size) {
size_t startIdx = 0;
uint8_t preamble[] = {1, 1, 1, 1, 1, 0};
// sanity check
if (*size < sizeof(preamble)) return -1;
if (!preambleSearch(bits, preamble, sizeof(preamble), size, &startIdx))
return -2; //preamble not found
//gProxII should be 96 bits
if (*size != 96) return -3;
//check first 6 spacer bits to verify format
if (!bits[startIdx + 5] && !bits[startIdx + 10] && !bits[startIdx + 15] && !bits[startIdx + 20] && !bits[startIdx + 25] && !bits[startIdx + 30]) {
//confirmed proper separator bits found
//return start position
return (int) startIdx;
}
return -5; //spacer bits not found - not a valid gproxII
}
//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
// but will leave the GraphBuffer intact.
//if successful it will push askraw data back to demod buffer ready for emulation
int CmdGuardDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
//Differential Biphase
//get binary from ask wave
if (!ASKbiphaseDemod("0 64 0 0", false)) {
PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII ASKbiphaseDemod failed");
return 0;
}
size_t size = DemodBufferLen;
int preambleIndex = detectGProxII(DemodBuffer, &size);
if (preambleIndex < 0) {
if (preambleIndex == -1)
PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII too few bits found");
else if (preambleIndex == -2)
PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII preamble not found");
else if (preambleIndex == -3)
PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII size not correct: %d", size);
else if (preambleIndex == -5)
PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII wrong spacerbits");
else
PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII ans: %d", preambleIndex);
return 0;
}
//got a good demod of 96 bits
uint8_t ByteStream[8] = {0x00};
uint8_t xorKey = 0;
size_t startIdx = preambleIndex + 6; //start after 6 bit preamble
uint8_t bits_no_spacer[90];
//so as to not mess with raw DemodBuffer copy to a new sample array
memcpy(bits_no_spacer, DemodBuffer + startIdx, 90);
// remove the 18 (90/5=18) parity bits (down to 72 bits (96-6-18=72))
size_t len = removeParity(bits_no_spacer, 0, 5, 3, 90); //source, startloc, paritylen, ptype, length_to_run
if (len != 72) {
PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII spacer removal did not produce 72 bits: %u, start: %u", len, startIdx);
return 0;
}
// get key and then get all 8 bytes of payload decoded
xorKey = (uint8_t)bytebits_to_byteLSBF(bits_no_spacer, 8);
for (size_t idx = 0; idx < 8; idx++) {
ByteStream[idx] = ((uint8_t)bytebits_to_byteLSBF(bits_no_spacer + 8 + (idx * 8), 8)) ^ xorKey;
PrintAndLogEx(DEBUG, "DEBUG: gProxII byte %u after xor: %02x", (unsigned int)idx, ByteStream[idx]);
}
setDemodBuff(DemodBuffer, 96, preambleIndex);
setClockGrid(g_DemodClock, g_DemodStartIdx + (preambleIndex * g_DemodClock));
//ByteStream contains 8 Bytes (64 bits) of decrypted raw tag data
uint8_t fmtLen = ByteStream[0] >> 2;
uint32_t FC = 0;
uint32_t Card = 0;
//get raw 96 bits to print
uint32_t raw1 = bytebits_to_byte(DemodBuffer, 32);
uint32_t raw2 = bytebits_to_byte(DemodBuffer + 32, 32);
uint32_t raw3 = bytebits_to_byte(DemodBuffer + 64, 32);
bool unknown = false;
switch (fmtLen) {
case 36:
FC = ((ByteStream[3] & 0x7F) << 7) | (ByteStream[4] >> 1);
Card = ((ByteStream[4] & 1) << 19) | (ByteStream[5] << 11) | (ByteStream[6] << 3) | (ByteStream[7] >> 5);
break;
case 26:
FC = ((ByteStream[3] & 0x7F) << 1) | (ByteStream[4] >> 7);
Card = ((ByteStream[4] & 0x7F) << 9) | (ByteStream[5] << 1) | (ByteStream[6] >> 7);
break;
default :
unknown = true;
break;
}
if (!unknown)
PrintAndLogEx(SUCCESS, "G-Prox-II Found: Format Len: %ubit - FC: %u - Card: %u, Raw: %08x%08x%08x", fmtLen, FC, Card, raw1, raw2, raw3);
else
PrintAndLogEx(SUCCESS, "Unknown G-Prox-II Fmt Found: Format Len: %u, Raw: %08x%08x%08x", fmtLen, raw1, raw2, raw3);
return 1;
}
int CmdGuardRead(const char *Cmd) {
lf_read(true, 10000);
return CmdGuardDemod(Cmd);
}
int CmdGuardClone(const char *Cmd) {
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_guard_clone();
uint32_t facilitycode = 0, cardnumber = 0, fc = 0, cn = 0, fmtlen = 0;
uint8_t i;
uint8_t bs[96];
memset(bs, 0x00, sizeof(bs));
//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};
if (sscanf(Cmd, "%u %u %u", &fmtlen, &fc, &cn) != 3) return usage_lf_guard_clone();
fmtlen &= 0x7f;
facilitycode = (fc & 0x000000FF);
cardnumber = (cn & 0x0000FFFF);
if (!GetGuardBits(fmtlen, facilitycode, cardnumber, bs)) {
PrintAndLogEx(WARNING, "Error with tag bitstream generation.");
return 1;
}
// Q5
if (param_getchar(Cmd, 3) == 'Q' || param_getchar(Cmd, 3) == 'q')
blocks[0] = T5555_MODULATION_FSK2 | T5555_SET_BITRATE(50) | 3 << T5555_MAXBLOCK_SHIFT;
blocks[1] = bytebits_to_byte(bs, 32);
blocks[2] = bytebits_to_byte(bs + 32, 32);
blocks[3] = bytebits_to_byte(bs + 64, 32);
PrintAndLogEx(INFO, "Preparing to clone Guardall to T55x7 with Facility Code: %u, Card Number: %u", facilitycode, cardnumber);
print_blocks(blocks, 4);
UsbCommand resp;
UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {0, 0, 0}, {{0}}};
for (i = 0; i < 4; ++i) {
c.arg[0] = blocks[i];
c.arg[1] = i;
clearCommandBuffer();
SendCommand(&c);
if (!WaitForResponseTimeout(CMD_ACK, &resp, T55XX_WRITE_TIMEOUT)) {
PrintAndLogEx(WARNING, "Error occurred, device did not respond during write operation.");
return -1;
}
}
return 0;
}
int CmdGuardSim(const char *Cmd) {
// Guard uses: clk: 64, invert: 0, encoding: 2 (ASK Biphase)
uint8_t clock1 = 64, encoding = 2, separator = 0, invert = 0;
uint32_t facilitycode = 0, cardnumber = 0, fc = 0, cn = 0, fmtlen = 0;
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_guard_sim();
if (sscanf(Cmd, "%u %u %u", &fmtlen, &fc, &cn) != 3) return usage_lf_guard_sim();
uint8_t bs[96];
size_t size = sizeof(bs);
memset(bs, 0x00, size);
fmtlen &= 0x7F;
facilitycode = (fc & 0x000000FF);
cardnumber = (cn & 0x0000FFFF);
if (!GetGuardBits(fmtlen, facilitycode, cardnumber, bs)) {
PrintAndLogEx(WARNING, "Error with tag bitstream generation.");
return 1;
}
PrintAndLogEx(SUCCESS, "Simulating Guardall - Facility Code: %u, CardNumber: %u", facilitycode, cardnumber);
uint64_t arg1, arg2;
arg1 = (clock1 << 8) | encoding;
arg2 = (invert << 8) | separator;
UsbCommand c = {CMD_ASK_SIM_TAG, {arg1, arg2, size}, {{0}}};
memcpy(c.d.asBytes, bs, size);
clearCommandBuffer();
SendCommand(&c);
return 0;
}
static command_t CommandTable[] = {
{"help", CmdHelp, 1, "this help"},
{"demod", CmdGuardDemod, 1, "demodulate a G Prox II tag from the GraphBuffer"},
{"read", CmdGuardRead, 0, "attempt to read and extract tag data from the antenna"},
{"clone", CmdGuardClone, 0, "clone Guardall tag"},
{"sim", CmdGuardSim, 0, "simulate Guardall tag"},
{NULL, NULL, 0, NULL}
};
int CmdLFGuard(const char *Cmd) {
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;
}

View file

@ -23,9 +23,7 @@
#include "crc.h"
int CmdLFGuard(const char *Cmd);
int CmdGuardDemod(const char *Cmd);
int CmdGuardRead(const char *Cmd);
int CmdGuardClone(const char *Cmd);
int CmdGuardSim(const char *Cmd);
int detectGProxII(uint8_t *bits, size_t *size);
int demodGuard(void);
int getGuardBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits);
#endif

View file

@ -15,7 +15,7 @@
#endif
static int CmdHelp(const char *Cmd);
/*
static int usage_lf_hid_read(void) {
PrintAndLogEx(NORMAL, "Enables HID compatible reader mode printing details.");
PrintAndLogEx(NORMAL, "By default, values are printed and logged until the button is pressed or another USB command is issued.");
@ -31,6 +31,7 @@ static int usage_lf_hid_read(void) {
PrintAndLogEx(NORMAL, " lf hid read 1");
return 0;
}
*/
static int usage_lf_hid_wiegand(void) {
PrintAndLogEx(NORMAL, "This command converts facility code/card number to Wiegand code");
PrintAndLogEx(NORMAL, "");
@ -124,7 +125,7 @@ static bool sendTry(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint32_t delay, ui
//by marshmellow (based on existing demod + holiman's refactor)
//HID Prox demod - FSK RF/50 with preamble of 00011101 (then manchester encoded)
//print full HID Prox ID and some bit format details if found
int CmdHIDDemod(const char *Cmd) {
static int CmdHIDDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
//raw fsk demod no manchester decoding no start bit finding just get binary from wave
uint32_t hi2 = 0, hi = 0, lo = 0;
@ -230,14 +231,14 @@ int CmdHIDDemod(const char *Cmd) {
}
// this read is the "normal" read, which download lf signal and tries to demod here.
int CmdHIDRead(const char *Cmd) {
static int CmdHIDRead(const char *Cmd) {
lf_read(true, 12000);
return CmdHIDDemod(Cmd);
}
/*
// this read loops on device side.
// uses the demod in lfops.c
int CmdHIDRead_device(const char *Cmd) {
static int CmdHIDRead_device(const char *Cmd) {
if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_hid_read();
uint8_t findone = (Cmd[0] == '1') ? 1 : 0;
@ -246,8 +247,8 @@ int CmdHIDRead_device(const char *Cmd) {
SendCommand(&c);
return 0;
}
int CmdHIDSim(const char *Cmd) {
*/
static int CmdHIDSim(const char *Cmd) {
uint32_t hi = 0, lo = 0;
uint32_t n = 0, i = 0;
@ -268,7 +269,7 @@ int CmdHIDSim(const char *Cmd) {
return 0;
}
int CmdHIDClone(const char *Cmd) {
static int CmdHIDClone(const char *Cmd) {
uint32_t hi2 = 0, hi = 0, lo = 0;
uint32_t n = 0, i = 0;
@ -473,7 +474,7 @@ void calcWiegand(uint8_t fmtlen, uint16_t fc, uint64_t cardno, uint8_t *bits, ui
}
}
int CmdHIDWiegand(const char *Cmd) {
static int CmdHIDWiegand(const char *Cmd) {
uint32_t oem = 0, fc = 0;
uint64_t cardnum = 0;
uint8_t bits[BITS] = {0};
@ -515,7 +516,7 @@ int CmdHIDWiegand(const char *Cmd) {
return 0;
}
int CmdHIDBrute(const char *Cmd) {
static int CmdHIDBrute(const char *Cmd) {
bool errors = false, verbose = false;
uint32_t fc = 0, cn = 0, delay = 1000;
@ -615,14 +616,18 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
static int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;
}
int CmdLFHID(const char *Cmd) {
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;
int demodHID(void) {
return CmdHIDDemod("");
}

View file

@ -25,13 +25,8 @@
#include "lfdemod.h"
int CmdLFHID(const char *Cmd);
int CmdHIDDemod(const char *Cmd);
int CmdHIDRead(const char *Cmd);
int CmdHIDSim(const char *Cmd);
int CmdHIDClone(const char *Cmd);
int CmdHIDWiegand(const char *Cmd);
int CmdHIDBrute(const char *Cmd);
int demodHID(void);
//void calc26(uint16_t fc, uint32_t cardno, uint8_t *out);
void calcWiegand(uint8_t fmtlen, uint16_t fc, uint64_t cardno, uint8_t *bits, uint8_t oem);
#endif

View file

@ -64,6 +64,7 @@ static int usage_hitag_info(void) {
PrintAndLogEx(NORMAL, " lf hitag info");
return 0;
}
/*
static int usage_hitag_dump(void) {
PrintAndLogEx(NORMAL, "Usage: lf hitag dump [h] p <pwd> f <name>");
PrintAndLogEx(NORMAL, "Options:");
@ -76,6 +77,7 @@ static int usage_hitag_dump(void) {
PrintAndLogEx(NORMAL, " lf hitag dump p 4D494B52 f mydump");
return 0;
}
*/
static int usage_hitag_reader(void) {
PrintAndLogEx(NORMAL, "Hitag reader functions");
PrintAndLogEx(NORMAL, "Usage: lf hitag reader [h] <reader function #>");
@ -120,7 +122,7 @@ static int usage_hitag_checkchallenges(void) {
return 0;
}
int CmdLFHitagList(const char *Cmd) {
static int CmdLFHitagList(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdTraceList("hitag");
return 0;
@ -253,7 +255,7 @@ int CmdLFHitagList(const char *Cmd) {
*/
}
int CmdLFHitagSniff(const char *Cmd) {
static int CmdLFHitagSniff(const char *Cmd) {
char ctmp = tolower(param_getchar(Cmd, 0));
if (ctmp == 'h') return usage_hitag_sniff();
@ -264,7 +266,7 @@ int CmdLFHitagSniff(const char *Cmd) {
return 0;
}
int CmdLFHitagSim(const char *Cmd) {
static int CmdLFHitagSim(const char *Cmd) {
bool errors = false;
bool tag_mem_supplied = false;
@ -476,7 +478,7 @@ static bool getHitagUid(uint32_t *uid) {
return true;
}
int CmdLFHitagInfo(const char *Cmd) {
static int CmdLFHitagInfo(const char *Cmd) {
PrintAndLogEx(INFO, "Hitag2 tag information ");
PrintAndLogEx(INFO, "To be done!");
PrintAndLogEx(INFO, "------------------------------------");
@ -509,7 +511,7 @@ int CmdLFHitagInfo(const char *Cmd) {
// TODO: iceman
// Hitag2 reader, problem is that this command mixes up stuff. So 26 give uid. 21 etc will also give you a memory dump !?
//
int CmdLFHitagReader(const char *Cmd) {
static int CmdLFHitagReader(const char *Cmd) {
UsbCommand c = {CMD_READER_HITAG, {0, 0, 0}, {{0}}};
hitag_data *htd = (hitag_data *)c.d.asBytes;
@ -590,7 +592,7 @@ int CmdLFHitagReader(const char *Cmd) {
return 0;
}
int CmdLFHitagCheckChallenges(const char *Cmd) {
static int CmdLFHitagCheckChallenges(const char *Cmd) {
UsbCommand c = { CMD_TEST_HITAGS_TRACES, {0, 0, 0}, {{0}}};
char filename[FILE_PATH_SIZE] = { 0x00 };
@ -640,7 +642,7 @@ int CmdLFHitagCheckChallenges(const char *Cmd) {
return 0;
}
int CmdLFHitagWriter(const char *Cmd) {
static int CmdLFHitagWriter(const char *Cmd) {
UsbCommand c = { CMD_WR_HITAG_S, {0, 0, 0}, {{0}}};
hitag_data *htd = (hitag_data *)c.d.asBytes;
hitag_function htf = param_get32ex(Cmd, 0, 0, 10);
@ -681,7 +683,8 @@ int CmdLFHitagWriter(const char *Cmd) {
return 0;
}
int CmdLFHitagDump(const char *Cmd) {
/*
static int CmdLFHitagDump(const char *Cmd) {
PrintAndLogEx(INFO, "Dumping of tag memory");
PrintAndLogEx(INFO, "To be done!");
@ -689,6 +692,7 @@ int CmdLFHitagDump(const char *Cmd) {
if (ctmp == 'h') return usage_hitag_dump();
return 0;
}
*/
static command_t CommandTable[] = {
{"help", CmdHelp, 1, "This help" },
@ -702,14 +706,18 @@ static command_t CommandTable[] = {
{ NULL, NULL, 0, NULL }
};
static int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;
}
int CmdLFHitag(const char *Cmd) {
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;
int readHitagUid(void) {
return CmdLFHitagReader("26") == 0;
}

View file

@ -13,13 +13,6 @@
int CmdLFHitag(const char *Cmd);
int CmdLFHitagList(const char *Cmd);
int CmdLFHitagSniff(const char *Cmd);
int CmdLFHitagSim(const char *Cmd);
int CmdLFHitagInfo(const char *Cmd);
int CmdLFHitagReader(const char *Cmd);
int CmdLFHitagCheckChallenges(const char *Cmd);
int CmdLFHitagWriter(const char *Cmd);
int CmdLFHitagDump(const char *Cmd);
int readHitagUid(void);
#endif

View file

@ -50,126 +50,10 @@ static int usage_lf_indala_sim(void) {
return 0;
}
// redesigned by marshmellow adjusted from existing decode functions
// indala id decoding
static int detectIndala(uint8_t *dest, size_t *size, uint8_t *invert) {
uint8_t preamble64_i[] = {0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0};
uint8_t preamble224_i[] = {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0};
size_t idx = 0;
size_t found_size = *size;
// PSK1
bool res = preambleSearch(dest, preamble64, sizeof(preamble64), &found_size, &idx);
if (res) {
PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK1 found 64");
goto out;
}
idx = 0;
found_size = *size;
res = preambleSearch(dest, preamble64_i, sizeof(preamble64_i), &found_size, &idx);
if (res) {
PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK1 found 64 inverted preamble");
goto inv;
}
/*
idx = 0;
found_size = *size;
res = preambleSearch(dest, preamble224, sizeof(preamble224), &found_size, &idx);
if ( res ) {
PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK1 found 224");
goto out;
}
idx = 0;
found_size = *size;
res = preambleSearch(dest, preamble224_i, sizeof(preamble224_i), &found_size, &idx);
if ( res ) {
PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK1 found 224 inverted preamble");
goto inv;
}
*/
// PSK2
psk1TOpsk2(dest, *size);
PrintAndLogEx(DEBUG, "DEBUG: detectindala Converting PSK1 -> PSK2");
idx = 0;
found_size = *size;
res = preambleSearch(dest, preamble64, sizeof(preamble64), &found_size, &idx);
if (res) {
PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK2 found 64 preamble");
goto out;
}
idx = 0;
found_size = *size;
res = preambleSearch(dest, preamble224, sizeof(preamble224), &found_size, &idx);
if (res) {
PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK2 found 224 preamble");
goto out;
}
idx = 0;
found_size = *size;
res = preambleSearch(dest, preamble64_i, sizeof(preamble64_i), &found_size, &idx);
if (res) {
PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK2 found 64 inverted preamble");
goto inv;
}
idx = 0;
found_size = *size;
res = preambleSearch(dest, preamble224_i, sizeof(preamble224_i), &found_size, &idx);
if (res) {
PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK2 found 224 inverted preamble");
goto inv;
}
inv:
if (res == 0) {
return -4;
}
*invert ^= 1;
if (*invert && idx > 0) {
for (size_t i = idx - 1; i < found_size + idx + 2; i++) {
dest[i] ^= 1;
}
}
PrintAndLogEx(DEBUG, "DEBUG: Warning - Indala had to invert bits");
out:
*size = found_size;
//PrintAndLogEx(INFO, "DEBUG: detectindala RES = %d | %d | %d", res, found_size, idx);
if (found_size != 224 && found_size != 64) {
PrintAndLogEx(INFO, "DEBUG: detectindala | %d", found_size);
return -5;
}
// 224 formats are typically PSK2 (afaik 2017 Marshmellow)
// note loses 1 bit at beginning of transformation...
return (int) idx;
}
// this read is the "normal" read, which download lf signal and tries to demod here.
int CmdIndalaRead(const char *Cmd) {
lf_read(true, 30000);
return CmdIndalaDemod(Cmd);
}
// Indala 26 bit decode
// by marshmellow
// optional arguments - same as PSKDemod (clock & invert & maxerr)
int CmdIndalaDemod(const char *Cmd) {
static int CmdIndalaDemod(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_lf_indala_demod();
@ -283,7 +167,7 @@ int CmdIndalaDemod(const char *Cmd) {
// returns false positives more often - but runs against more sets of samples
// poor psk signal can be difficult to demod this approach might succeed when the other fails
// but the other appears to currently be more accurate than this approach most of the time.
int CmdIndalaDemodAlt(const char *Cmd) {
static int CmdIndalaDemodAlt(const char *Cmd) {
// Usage: recover 64bit UID by default, specify "224" as arg to recover a 224bit UID
int state = -1;
int count = 0;
@ -477,7 +361,13 @@ int CmdIndalaDemodAlt(const char *Cmd) {
return 1;
}
int CmdIndalaSim(const char *Cmd) {
// this read is the "normal" read, which download lf signal and tries to demod here.
static int CmdIndalaRead(const char *Cmd) {
lf_read(true, 30000);
return CmdIndalaDemod(Cmd);
}
static int CmdIndalaSim(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_indala_sim();
@ -522,7 +412,7 @@ int CmdIndalaSim(const char *Cmd) {
}
// iceman - needs refactoring
int CmdIndalaClone(const char *Cmd) {
static int CmdIndalaClone(const char *Cmd) {
bool isLongUid = false;
uint8_t data[7 * 4];
@ -582,14 +472,128 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
static int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;
}
int CmdLFINDALA(const char *Cmd) {
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;
// redesigned by marshmellow adjusted from existing decode functions
// indala id decoding
int detectIndala(uint8_t *dest, size_t *size, uint8_t *invert) {
uint8_t preamble64_i[] = {0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0};
uint8_t preamble224_i[] = {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0};
size_t idx = 0;
size_t found_size = *size;
// PSK1
bool res = preambleSearch(dest, preamble64, sizeof(preamble64), &found_size, &idx);
if (res) {
PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK1 found 64");
goto out;
}
idx = 0;
found_size = *size;
res = preambleSearch(dest, preamble64_i, sizeof(preamble64_i), &found_size, &idx);
if (res) {
PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK1 found 64 inverted preamble");
goto inv;
}
/*
idx = 0;
found_size = *size;
res = preambleSearch(dest, preamble224, sizeof(preamble224), &found_size, &idx);
if ( res ) {
PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK1 found 224");
goto out;
}
idx = 0;
found_size = *size;
res = preambleSearch(dest, preamble224_i, sizeof(preamble224_i), &found_size, &idx);
if ( res ) {
PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK1 found 224 inverted preamble");
goto inv;
}
*/
// PSK2
psk1TOpsk2(dest, *size);
PrintAndLogEx(DEBUG, "DEBUG: detectindala Converting PSK1 -> PSK2");
idx = 0;
found_size = *size;
res = preambleSearch(dest, preamble64, sizeof(preamble64), &found_size, &idx);
if (res) {
PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK2 found 64 preamble");
goto out;
}
idx = 0;
found_size = *size;
res = preambleSearch(dest, preamble224, sizeof(preamble224), &found_size, &idx);
if (res) {
PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK2 found 224 preamble");
goto out;
}
idx = 0;
found_size = *size;
res = preambleSearch(dest, preamble64_i, sizeof(preamble64_i), &found_size, &idx);
if (res) {
PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK2 found 64 inverted preamble");
goto inv;
}
idx = 0;
found_size = *size;
res = preambleSearch(dest, preamble224_i, sizeof(preamble224_i), &found_size, &idx);
if (res) {
PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK2 found 224 inverted preamble");
goto inv;
}
inv:
if (res == 0) {
return -4;
}
*invert ^= 1;
if (*invert && idx > 0) {
for (size_t i = idx - 1; i < found_size + idx + 2; i++) {
dest[i] ^= 1;
}
}
PrintAndLogEx(DEBUG, "DEBUG: Warning - Indala had to invert bits");
out:
*size = found_size;
//PrintAndLogEx(INFO, "DEBUG: detectindala RES = %d | %d | %d", res, found_size, idx);
if (found_size != 224 && found_size != 64) {
PrintAndLogEx(INFO, "DEBUG: detectindala | %d", found_size);
return -5;
}
// 224 formats are typically PSK2 (afaik 2017 Marshmellow)
// note loses 1 bit at beginning of transformation...
return (int) idx;
}
int demodIndala(void) {
return CmdIndalaDemod("");
}

View file

@ -25,14 +25,10 @@
int CmdLFINDALA(const char *Cmd);
int CmdIndalaDemod(const char *Cmd);
int CmdIndalaDemodAlt(const char *Cmd);
int CmdIndalaRead(const char *Cmd);
int CmdIndalaClone(const char *Cmd);
int CmdIndalaSim(const char *Cmd);
int detectIndala(uint8_t *dest, size_t *size, uint8_t *invert);
int detectIndala26(uint8_t *bitStream, size_t *size, uint8_t *invert);
int detectIndala64(uint8_t *bitStream, size_t *size, uint8_t *invert);
int detectIndala224(uint8_t *bitStream, size_t *size, uint8_t *invert);
int demodIndala(void);
#endif

View file

@ -11,7 +11,7 @@
#include "cmdlfio.h"
static int CmdHelp(const char *Cmd);
/*
static int usage_lf_io_read(void) {
PrintAndLogEx(NORMAL, "Enables IOProx compatible reader mode printing details of scanned tags.");
PrintAndLogEx(NORMAL, "By default, values are printed and logged until the button is pressed or another USB command is issued.");
@ -27,7 +27,7 @@ static int usage_lf_io_read(void) {
PrintAndLogEx(NORMAL, " lf io read 1");
return 0;
}
*/
static int usage_lf_io_sim(void) {
PrintAndLogEx(NORMAL, "Enables simulation of IOProx card with specified facility-code and card number.");
PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued.");
@ -60,15 +60,10 @@ static int usage_lf_io_clone(void) {
PrintAndLogEx(NORMAL, " lf io clone 26 101 1337");
return 0;
}
// this read is the "normal" read, which download lf signal and tries to demod here.
int CmdIOProxRead(const char *Cmd) {
lf_read(true, 12000);
return CmdIOProxDemod(Cmd);
}
/*
// this read loops on device side.
// uses the demod in lfops.c
int CmdIOProxRead_device(const char *Cmd) {
static int CmdIOProxRead_device(const char *Cmd) {
if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_io_read();
int findone = (Cmd[0] == '1') ? 1 : 0;
UsbCommand c = {CMD_IO_DEMOD_FSK, {findone, 0, 0}, {{0}}};
@ -76,11 +71,11 @@ int CmdIOProxRead_device(const char *Cmd) {
SendCommand(&c);
return 0;
}
*/
//by marshmellow
//IO-Prox demod - FSK RF/64 with preamble of 000000001
//print ioprox ID and some format details
int CmdIOProxDemod(const char *Cmd) {
static int CmdIOProxDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
int retval = 0;
int idx = 0;
@ -177,6 +172,124 @@ int CmdIOProxDemod(const char *Cmd) {
return retval;
}
// this read is the "normal" read, which download lf signal and tries to demod here.
static int CmdIOProxRead(const char *Cmd) {
lf_read(true, 12000);
return CmdIOProxDemod(Cmd);
}
static int CmdIOProxSim(const char *Cmd) {
uint16_t cn = 0;
uint8_t version = 0, fc = 0;
uint8_t bits[64];
size_t size = sizeof(bits);
memset(bits, 0x00, size);
char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_io_sim();
version = param_get8(Cmd, 0);
fc = param_get8(Cmd, 1);
cn = param_get32ex(Cmd, 2, 0, 10);
if (!version || !fc || !cn) return usage_lf_io_sim();
if ((cn & 0xFFFF) != cn) {
cn &= 0xFFFF;
PrintAndLogEx(INFO, "Card Number Truncated to 16-bits (IOProx): %u", cn);
}
// clock 64, FSK2a fcHIGH 10 | fcLOW 8
uint8_t clk = 64, invert = 1, high = 10, low = 8;
uint16_t arg1, arg2;
arg1 = high << 8 | low;
arg2 = invert << 8 | clk;
PrintAndLogEx(SUCCESS, "Simulating IOProx version: %u FC: %u; CN: %u\n", version, fc, cn);
PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation or run another command");
if (!getIOProxBits(version, fc, cn, bits)) {
PrintAndLogEx(WARNING, "Error with tag bitstream generation.");
return 1;
}
// IOProx uses: fcHigh: 10, fcLow: 8, clk: 64, invert: 1
// arg1 --- fcHigh<<8 + fcLow
// arg2 --- Invert and clk setting
// size --- 64 bits == 8 bytes
UsbCommand c = {CMD_FSK_SIM_TAG, {arg1, arg2, size}, {{0}}};
memcpy(c.d.asBytes, bits, size);
clearCommandBuffer();
SendCommand(&c);
return 0;
}
static int CmdIOProxClone(const char *Cmd) {
uint32_t blocks[3] = {T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_64 | 2 << T55x7_MAXBLOCK_SHIFT, 0, 0};
uint16_t cn = 0;
uint8_t version = 0, fc = 0;
uint8_t bits[64];
memset(bits, 0, sizeof(bits));
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_io_clone();
version = param_get8(Cmd, 0);
fc = param_get8(Cmd, 1);
cn = param_get32ex(Cmd, 2, 0, 10);
if (!version || !fc || !cn) return usage_lf_io_clone();
if ((cn & 0xFFFF) != cn) {
cn &= 0xFFFF;
PrintAndLogEx(INFO, "Card Number Truncated to 16-bits (IOProx): %u", cn);
}
if (!getIOProxBits(version, fc, cn, bits)) {
PrintAndLogEx(WARNING, "Error with tag bitstream generation.");
return 1;
}
if (param_getchar(Cmd, 3) == 'Q' || param_getchar(Cmd, 3) == 'q')
blocks[0] = T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | T5555_SET_BITRATE(64) | 2 << T5555_MAXBLOCK_SHIFT;
blocks[1] = bytebits_to_byte(bits, 32);
blocks[2] = bytebits_to_byte(bits + 32, 32);
PrintAndLogEx(INFO, "Preparing to clone IOProx to T55x7 with Version: %u FC: %u, CN: %u", version, fc, cn);
print_blocks(blocks, 3);
//UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {0,0,0}, {{0}}};
UsbCommand c = {CMD_IO_CLONE_TAG, {blocks[1], blocks[2], 0}, {{0}}};
clearCommandBuffer();
SendCommand(&c);
return 0;
}
static command_t CommandTable[] = {
{"help", CmdHelp, 1, "this help"},
{"demod", CmdIOProxDemod, 1, "demodulate an IOProx tag from the GraphBuffer"},
{"read", CmdIOProxRead, 1, "attempt to read and extract tag data"},
{"clone", CmdIOProxClone, 0, "clone IOProx to T55x7"},
{"sim", CmdIOProxSim, 0, "simulate IOProx tag"},
{NULL, NULL, 0, NULL}
};
static int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;
}
int CmdLFIO(const char *Cmd) {
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int demodIOProx(void) {
return CmdIOProxDemod("");
}
//Index map
//0 10 20 30 40 50 60
//| | | | | | |
@ -244,111 +357,3 @@ int getIOProxBits(uint8_t version, uint8_t fc, uint16_t cn, uint8_t *bits) {
return 1;
}
int CmdIOProxSim(const char *Cmd) {
uint16_t cn = 0;
uint8_t version = 0, fc = 0;
uint8_t bits[64];
size_t size = sizeof(bits);
memset(bits, 0x00, size);
char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_io_sim();
version = param_get8(Cmd, 0);
fc = param_get8(Cmd, 1);
cn = param_get32ex(Cmd, 2, 0, 10);
if (!version || !fc || !cn) return usage_lf_io_sim();
if ((cn & 0xFFFF) != cn) {
cn &= 0xFFFF;
PrintAndLogEx(INFO, "Card Number Truncated to 16-bits (IOProx): %u", cn);
}
// clock 64, FSK2a fcHIGH 10 | fcLOW 8
uint8_t clk = 64, invert = 1, high = 10, low = 8;
uint16_t arg1, arg2;
arg1 = high << 8 | low;
arg2 = invert << 8 | clk;
PrintAndLogEx(SUCCESS, "Simulating IOProx version: %u FC: %u; CN: %u\n", version, fc, cn);
PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation or run another command");
if (!getIOProxBits(version, fc, cn, bits)) {
PrintAndLogEx(WARNING, "Error with tag bitstream generation.");
return 1;
}
// IOProx uses: fcHigh: 10, fcLow: 8, clk: 64, invert: 1
// arg1 --- fcHigh<<8 + fcLow
// arg2 --- Invert and clk setting
// size --- 64 bits == 8 bytes
UsbCommand c = {CMD_FSK_SIM_TAG, {arg1, arg2, size}, {{0}}};
memcpy(c.d.asBytes, bits, size);
clearCommandBuffer();
SendCommand(&c);
return 0;
}
int CmdIOProxClone(const char *Cmd) {
uint32_t blocks[3] = {T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_64 | 2 << T55x7_MAXBLOCK_SHIFT, 0, 0};
uint16_t cn = 0;
uint8_t version = 0, fc = 0;
uint8_t bits[64];
memset(bits, 0, sizeof(bits));
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_io_clone();
version = param_get8(Cmd, 0);
fc = param_get8(Cmd, 1);
cn = param_get32ex(Cmd, 2, 0, 10);
if (!version || !fc || !cn) return usage_lf_io_clone();
if ((cn & 0xFFFF) != cn) {
cn &= 0xFFFF;
PrintAndLogEx(INFO, "Card Number Truncated to 16-bits (IOProx): %u", cn);
}
if (!getIOProxBits(version, fc, cn, bits)) {
PrintAndLogEx(WARNING, "Error with tag bitstream generation.");
return 1;
}
if (param_getchar(Cmd, 3) == 'Q' || param_getchar(Cmd, 3) == 'q')
blocks[0] = T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | T5555_SET_BITRATE(64) | 2 << T5555_MAXBLOCK_SHIFT;
blocks[1] = bytebits_to_byte(bits, 32);
blocks[2] = bytebits_to_byte(bits + 32, 32);
PrintAndLogEx(INFO, "Preparing to clone IOProx to T55x7 with Version: %u FC: %u, CN: %u", version, fc, cn);
print_blocks(blocks, 3);
//UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {0,0,0}, {{0}}};
UsbCommand c = {CMD_IO_CLONE_TAG, {blocks[1], blocks[2], 0}, {{0}}};
clearCommandBuffer();
SendCommand(&c);
return 0;
}
static command_t CommandTable[] = {
{"help", CmdHelp, 1, "this help"},
{"demod", CmdIOProxDemod, 1, "demodulate an IOProx tag from the GraphBuffer"},
{"read", CmdIOProxRead, 1, "attempt to read and extract tag data"},
{"clone", CmdIOProxClone, 0, "clone IOProx to T55x7"},
{"sim", CmdIOProxSim, 0, "simulate IOProx tag"},
{NULL, NULL, 0, NULL}
};
int CmdLFIO(const char *Cmd) {
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;
}

View file

@ -17,11 +17,8 @@
#include "cmddata.h"
int CmdLFIO(const char *Cmd);
int CmdIOProxDemod(const char *Cmd);
int CmdIOProxRead(const char *Cmd);
int CmdIOProxSim(const char *Cmd);
int CmdIOProxClone(const char *Cmd);
int demodIOProx(void);
int getIOProxBits(uint8_t version, uint8_t fc, uint16_t cn, uint8_t *bits);
#endif