mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
Rework Cmd exposed API, use more static and fix [-Wmissing-prototypes], ongoing...
This commit is contained in:
parent
7d48ad19f9
commit
f6a6ec8447
21 changed files with 760 additions and 746 deletions
|
@ -1141,7 +1141,7 @@ int PSKDemod(const char *Cmd, bool verbose) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdIdteckDemod(const char *Cmd) {
|
static int CmdIdteckDemod(const char *Cmd) {
|
||||||
(void)Cmd; // Cmd is not used so far
|
(void)Cmd; // Cmd is not used so far
|
||||||
|
|
||||||
if (!PSKDemod("", false)) {
|
if (!PSKDemod("", false)) {
|
||||||
|
@ -1202,6 +1202,11 @@ int CmdIdteckDemod(const char *Cmd) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int demodIdteck(void) {
|
||||||
|
return CmdIdteckDemod("");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// by marshmellow
|
// by marshmellow
|
||||||
// takes 3 arguments - clock, invert, maxErr as integers
|
// takes 3 arguments - clock, invert, maxErr as integers
|
||||||
// attempts to demodulate nrz only
|
// attempts to demodulate nrz only
|
||||||
|
|
|
@ -54,7 +54,6 @@ int CmdDetectClockRate(const char *Cmd);
|
||||||
int CmdFSKrawdemod(const char *Cmd);
|
int CmdFSKrawdemod(const char *Cmd);
|
||||||
int CmdPSK1rawDemod(const char *Cmd);
|
int CmdPSK1rawDemod(const char *Cmd);
|
||||||
int CmdPSK2rawDemod(const char *Cmd);
|
int CmdPSK2rawDemod(const char *Cmd);
|
||||||
int CmdIdteckDemod(const char *Cmd);
|
|
||||||
int CmdGrid(const char *Cmd);
|
int CmdGrid(const char *Cmd);
|
||||||
int CmdGetBitStream(const char *Cmd);
|
int CmdGetBitStream(const char *Cmd);
|
||||||
int CmdHexsamples(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 CmdDataIIR(const char *Cmd);
|
||||||
|
|
||||||
|
int demodIdteck(void);
|
||||||
|
|
||||||
#define MAX_DEMOD_BUF_LEN (1024*128)
|
#define MAX_DEMOD_BUF_LEN (1024*128)
|
||||||
#define BIGBUF_SIZE 40000
|
#define BIGBUF_SIZE 40000
|
||||||
extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
|
extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
|
||||||
|
|
|
@ -886,8 +886,8 @@ int CmdLFfind(const char *Cmd) {
|
||||||
// The improved noise detection will find Cotag.
|
// The improved noise detection will find Cotag.
|
||||||
if (getSignalProperties()->isnoise) {
|
if (getSignalProperties()->isnoise) {
|
||||||
|
|
||||||
if (CmdLFHitagReader("26") == 0) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Hitag") " found!"); return 1;}
|
if (readHitagUid()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Hitag") " found!"); return 1;}
|
||||||
if (CmdCOTAGRead("") > 0) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("COTAG ID") " 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?");
|
PrintAndLogEx(FAILED, "\n" _YELLOW_("No data found!") " - Signal looks like noise. Maybe not an LF tag?");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -896,16 +896,16 @@ int CmdLFfind(const char *Cmd) {
|
||||||
|
|
||||||
if (EM4x50Read("", false)) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("EM4x50 ID") " found!"); return 1;}
|
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 (demodHID()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("HID Prox ID") " found!"); goto out;}
|
||||||
if (CmdAWIDDemod("")) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("AWID 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 (demodParadox()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Paradox ID") " found!"); goto out;}
|
||||||
|
|
||||||
if (CmdEM410xDemod("")) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("EM410x ID") " found!"); goto out;}
|
if (demodEM410x()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("EM410x ID") " found!"); goto out;}
|
||||||
if (CmdFdxDemod("")) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("FDX-B ID") " found!"); goto out;}
|
if (demodFDX()) { 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 (demodGuard()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Guardall G-Prox II ID") " found!"); goto out; }
|
||||||
if (CmdIdteckDemod("")) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Idteck ID") " found!"); goto out;}
|
if (demodIdteck()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Idteck ID") " found!"); goto out;}
|
||||||
if (CmdIndalaDemod("")) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Indala ID") " found!"); goto out;}
|
if (demodIndala()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Indala ID") " found!"); goto out;}
|
||||||
if (CmdIOProxDemod("")) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("IO Prox 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 (demodJablotron()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Jablotron ID") " found!"); goto out;}
|
||||||
if (demodNedap()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("NEDAP 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;}
|
if (demodNexWatch()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("NexWatch ID") " found!"); goto out;}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#include "cmdlfawid.h" // AWID function declarations
|
#include "cmdlfawid.h" // AWID function declarations
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
/*
|
||||||
static int usage_lf_awid_read(void) {
|
static int usage_lf_awid_read(void) {
|
||||||
PrintAndLogEx(NORMAL, "Enables AWID compatible reader mode printing details of scanned AWID26 or AWID50 tags.");
|
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, "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");
|
PrintAndLogEx(NORMAL, " lf awid read 1");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
static int usage_lf_awid_sim(void) {
|
static int usage_lf_awid_sim(void) {
|
||||||
PrintAndLogEx(NORMAL, "Enables simulation of AWID card with specified facility-code and card number.");
|
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, "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;
|
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) {
|
static void verify_values(uint8_t *fmtlen, uint32_t *fc, uint32_t *cn) {
|
||||||
switch (*fmtlen) {
|
switch (*fmtlen) {
|
||||||
case 50:
|
case 50:
|
||||||
|
@ -218,15 +164,10 @@ static void verify_values(uint8_t *fmtlen, uint32_t *fc, uint32_t *cn) {
|
||||||
break;
|
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.
|
// this read loops on device side.
|
||||||
// uses the demod in lfops.c
|
// 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();
|
if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_awid_read();
|
||||||
uint8_t findone = (Cmd[0] == '1') ? 1 : 0;
|
uint8_t findone = (Cmd[0] == '1') ? 1 : 0;
|
||||||
|
@ -235,11 +176,11 @@ int CmdAWIDRead_device(const char *Cmd) {
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
//by marshmellow
|
//by marshmellow
|
||||||
//AWID Prox demod - FSK2a RF/50 with preamble of 00000001 (always a 96 bit data stream)
|
//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
|
//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
|
(void)Cmd; // Cmd is not used so far
|
||||||
uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0};
|
uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0};
|
||||||
size_t size = getFromGraphBuf(bits);
|
size_t size = getFromGraphBuf(bits);
|
||||||
|
@ -370,7 +311,13 @@ int CmdAWIDDemod(const char *Cmd) {
|
||||||
return 1;
|
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;
|
uint32_t fc = 0, cn = 0;
|
||||||
uint8_t fmtlen = 0;
|
uint8_t fmtlen = 0;
|
||||||
uint8_t bits[96];
|
uint8_t bits[96];
|
||||||
|
@ -410,7 +357,7 @@ int CmdAWIDSim(const char *Cmd) {
|
||||||
return 0;
|
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 blocks[4] = {T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_50 | 3 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0};
|
||||||
uint32_t fc = 0, cn = 0;
|
uint32_t fc = 0, cn = 0;
|
||||||
uint8_t fmtlen = 0;
|
uint8_t fmtlen = 0;
|
||||||
|
@ -461,7 +408,7 @@ int CmdAWIDClone(const char *Cmd) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdAWIDBrute(const char *Cmd) {
|
static int CmdAWIDBrute(const char *Cmd) {
|
||||||
|
|
||||||
bool errors = false, verbose = false;
|
bool errors = false, verbose = false;
|
||||||
uint32_t fc = 0, cn = 0, delay = 1000;
|
uint32_t fc = 0, cn = 0, delay = 1000;
|
||||||
|
@ -567,14 +514,72 @@ static command_t CommandTable[] = {
|
||||||
{NULL, NULL, 0, NULL}
|
{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) {
|
int CmdLFAWID(const char *Cmd) {
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
CmdsParse(CommandTable, Cmd);
|
CmdsParse(CommandTable, Cmd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdHelp(const char *Cmd) {
|
//refactored by marshmellow
|
||||||
(void)Cmd; // Cmd is not used so far
|
int getAWIDBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *bits) {
|
||||||
CmdsHelp(CommandTable);
|
|
||||||
return 0;
|
// 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("");
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,11 +25,8 @@
|
||||||
|
|
||||||
|
|
||||||
int CmdLFAWID(const char *Cmd);
|
int CmdLFAWID(const char *Cmd);
|
||||||
int CmdAWIDDemod(const char *Cmd);
|
|
||||||
int CmdAWIDRead(const char *Cmd);
|
int demodAWID(void);
|
||||||
int CmdAWIDSim(const char *Cmd);
|
|
||||||
int CmdAWIDClone(const char *Cmd);
|
|
||||||
int CmdAWIDBrute(const char *Cmd);
|
|
||||||
int getAWIDBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *bits);
|
int getAWIDBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *bits);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -27,7 +27,7 @@ static int usage_lf_cotag_read(void) {
|
||||||
|
|
||||||
// COTAG demod should be able to use GraphBuffer,
|
// COTAG demod should be able to use GraphBuffer,
|
||||||
// when data load samples
|
// when data load samples
|
||||||
int CmdCOTAGDemod(const char *Cmd) {
|
static int CmdCOTAGDemod(const char *Cmd) {
|
||||||
(void)Cmd; // Cmd is not used so far
|
(void)Cmd; // Cmd is not used so far
|
||||||
|
|
||||||
uint8_t bits[COTAG_BITS] = {0};
|
uint8_t bits[COTAG_BITS] = {0};
|
||||||
|
@ -67,7 +67,7 @@ int CmdCOTAGDemod(const char *Cmd) {
|
||||||
// 0 = HIGH/LOW signal - maxlength bigbuff
|
// 0 = HIGH/LOW signal - maxlength bigbuff
|
||||||
// 1 = translation for HI/LO into bytes with manchester 0,1 - length 300
|
// 1 = translation for HI/LO into bytes with manchester 0,1 - length 300
|
||||||
// 2 = raw signal - maxlength bigbuff
|
// 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();
|
if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_cotag_read();
|
||||||
|
|
||||||
|
@ -110,14 +110,22 @@ static command_t CommandTable[] = {
|
||||||
{NULL, NULL, 0, NULL}
|
{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) {
|
int CmdLFCOTAG(const char *Cmd) {
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
CmdsParse(CommandTable, Cmd);
|
CmdsParse(CommandTable, Cmd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdHelp(const char *Cmd) {
|
int demodCOTAG(void) {
|
||||||
(void)Cmd; // Cmd is not used so far
|
return CmdCOTAGDemod("");
|
||||||
CmdsHelp(CommandTable);
|
}
|
||||||
return 0;
|
|
||||||
|
int readCOTAGUid(void) {
|
||||||
|
return CmdCOTAGRead > 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int CmdLFCOTAG(const char *Cmd);
|
int CmdLFCOTAG(const char *Cmd);
|
||||||
int CmdCOTAGRead(const char *Cmd);
|
int demodCOTAG(void);
|
||||||
int CmdCOTAGDemod(const char *Cmd);
|
int readCOTAGUid(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -188,7 +188,7 @@ static int usage_lf_em4x05_info(void) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Construct the graph for emulating an EM410X tag
|
// 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];
|
int i, j, binary[4], parity[4];
|
||||||
uint32_t n;
|
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;
|
if (!ASKDemod_ext(Cmd, false, false, 1, &st)) return 0;
|
||||||
return AskEm410xDecode(verbose, hi, lo);
|
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.
|
// this read loops on device side.
|
||||||
// uses the demod in lfops.c
|
// 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));
|
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||||
uint8_t findone = (cmdp == '1') ? 1 : 0;
|
uint8_t findone = (cmdp == '1') ? 1 : 0;
|
||||||
UsbCommand c = {CMD_EM410X_DEMOD, {findone, 0, 0}, {{0}}};
|
UsbCommand c = {CMD_EM410X_DEMOD, {findone, 0, 0}, {{0}}};
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
//by marshmellow
|
//by marshmellow
|
||||||
//takes 3 arguments - clock, invert and maxErr as integers
|
//takes 3 arguments - clock, invert and maxErr as integers
|
||||||
//attempts to demodulate ask while decoding manchester
|
//attempts to demodulate ask while decoding manchester
|
||||||
//prints binary found and saves in graphbuffer for further commands
|
//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));
|
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||||
if (strlen(Cmd) > 10 || cmdp == 'h') return usage_lf_em410x_demod();
|
if (strlen(Cmd) > 10 || cmdp == 'h') return usage_lf_em410x_demod();
|
||||||
|
|
||||||
|
@ -417,8 +411,14 @@ int CmdEM410xDemod(const char *Cmd) {
|
||||||
return 1;
|
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
|
// emulate an EM410X tag
|
||||||
int CmdEM410xSim(const char *Cmd) {
|
static int CmdEM410xSim(const char *Cmd) {
|
||||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||||
if (cmdp == 'h') return usage_lf_em410x_sim();
|
if (cmdp == 'h') return usage_lf_em410x_sim();
|
||||||
|
|
||||||
|
@ -443,7 +443,7 @@ int CmdEM410xSim(const char *Cmd) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdEM410xBrute(const char *Cmd) {
|
static int CmdEM410xBrute(const char *Cmd) {
|
||||||
char filename[FILE_PATH_SIZE] = {0};
|
char filename[FILE_PATH_SIZE] = {0};
|
||||||
FILE *f = NULL;
|
FILE *f = NULL;
|
||||||
char buf[11];
|
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
|
* 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
|
(void)Cmd; // Cmd is not used so far
|
||||||
do {
|
do {
|
||||||
if (ukbhit()) {
|
if (ukbhit()) {
|
||||||
|
@ -581,7 +581,7 @@ int CmdEM410xWatch(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//currently only supports manchester modulations
|
//currently only supports manchester modulations
|
||||||
int CmdEM410xWatchnSpoof(const char *Cmd) {
|
static int CmdEM410xWatchnSpoof(const char *Cmd) {
|
||||||
|
|
||||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||||
if (cmdp == 'h') return usage_lf_em410x_ws();
|
if (cmdp == 'h') return usage_lf_em410x_ws();
|
||||||
|
@ -593,7 +593,7 @@ int CmdEM410xWatchnSpoof(const char *Cmd) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdEM410xWrite(const char *Cmd) {
|
static int CmdEM410xWrite(const char *Cmd) {
|
||||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||||
if (cmdp == 0x00 || cmdp == 'h') return usage_lf_em410x_write();
|
if (cmdp == 0x00 || cmdp == 'h') return usage_lf_em410x_write();
|
||||||
|
|
||||||
|
@ -956,18 +956,18 @@ int EM4x50Read(const char *Cmd, bool verbose) {
|
||||||
return (int)AllPTest;
|
return (int)AllPTest;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdEM4x50Read(const char *Cmd) {
|
static int CmdEM4x50Read(const char *Cmd) {
|
||||||
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
|
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
|
||||||
if (ctmp == 'h') return usage_lf_em4x50_read();
|
if (ctmp == 'h') return usage_lf_em4x50_read();
|
||||||
return EM4x50Read(Cmd, true);
|
return EM4x50Read(Cmd, true);
|
||||||
}
|
}
|
||||||
int CmdEM4x50Write(const char *Cmd) {
|
static int CmdEM4x50Write(const char *Cmd) {
|
||||||
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
|
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
|
||||||
if (ctmp == 'h') return usage_lf_em4x50_write();
|
if (ctmp == 'h') return usage_lf_em4x50_write();
|
||||||
PrintAndLogEx(NORMAL, "no implemented yet");
|
PrintAndLogEx(NORMAL, "no implemented yet");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int CmdEM4x50Dump(const char *Cmd) {
|
static int CmdEM4x50Dump(const char *Cmd) {
|
||||||
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
|
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
|
||||||
if (ctmp == 'h') return usage_lf_em4x50_dump();
|
if (ctmp == 'h') return usage_lf_em4x50_dump();
|
||||||
PrintAndLogEx(NORMAL, "no implemented yet");
|
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);
|
return demodEM4x05resp(word);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdEM4x05Dump(const char *Cmd) {
|
static int CmdEM4x05Dump(const char *Cmd) {
|
||||||
uint8_t addr = 0;
|
uint8_t addr = 0;
|
||||||
uint32_t pwd = 0;
|
uint32_t pwd = 0;
|
||||||
bool usePwd = false;
|
bool usePwd = false;
|
||||||
|
@ -1176,7 +1176,7 @@ int CmdEM4x05Dump(const char *Cmd) {
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdEM4x05Read(const char *Cmd) {
|
static int CmdEM4x05Read(const char *Cmd) {
|
||||||
uint8_t addr;
|
uint8_t addr;
|
||||||
uint32_t pwd;
|
uint32_t pwd;
|
||||||
bool usePwd = false;
|
bool usePwd = false;
|
||||||
|
@ -1206,7 +1206,7 @@ int CmdEM4x05Read(const char *Cmd) {
|
||||||
return isOk;
|
return isOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdEM4x05Write(const char *Cmd) {
|
static int CmdEM4x05Write(const char *Cmd) {
|
||||||
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
|
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
|
||||||
if (strlen(Cmd) == 0 || ctmp == 'h') return usage_lf_em4x05_write();
|
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;
|
return (res > 0) ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdEM4x05Info(const char *Cmd) {
|
static int CmdEM4x05Info(const char *Cmd) {
|
||||||
#define EM_SERIAL_BLOCK 1
|
#define EM_SERIAL_BLOCK 1
|
||||||
#define EM_CONFIG_BLOCK 4
|
#define EM_CONFIG_BLOCK 4
|
||||||
#define EM_PROT1_BLOCK 14
|
#define EM_PROT1_BLOCK 14
|
||||||
|
@ -1488,14 +1488,18 @@ static command_t CommandTable[] = {
|
||||||
{NULL, NULL, 0, NULL}
|
{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) {
|
int CmdLFEM4X(const char *Cmd) {
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
CmdsParse(CommandTable, Cmd);
|
CmdsParse(CommandTable, Cmd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdHelp(const char *Cmd) {
|
int demodEM410x(void) {
|
||||||
(void)Cmd; // Cmd is not used so far
|
return CmdEM410xDemod("");
|
||||||
CmdsHelp(CommandTable);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,21 +27,7 @@
|
||||||
|
|
||||||
int CmdLFEM4X(const char *Cmd);
|
int CmdLFEM4X(const char *Cmd);
|
||||||
|
|
||||||
int CmdEM410xDemod(const char *Cmd);
|
int demodEM410x(void);
|
||||||
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 EM4x50Read(const char *Cmd, bool verbose);
|
int EM4x50Read(const char *Cmd, bool verbose);
|
||||||
bool EM4x05IsBlock0(uint32_t *word);
|
bool EM4x05IsBlock0(uint32_t *word);
|
||||||
|
|
||||||
|
|
|
@ -64,20 +64,6 @@ static int usage_lf_fdx_sim(void) {
|
||||||
return 0;
|
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.
|
// clearing the topbit needed for the preambl detection.
|
||||||
static void verify_values(uint32_t countryid, uint64_t animalid) {
|
static void verify_values(uint32_t countryid, uint64_t animalid) {
|
||||||
if ((animalid & 0x3FFFFFFFFF) != 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)
|
// FDX-B ISO11784/85 demod (aka animal tag) BIPHASE, inverted, rf/32, with preamble of 00000000001 (128bits)
|
||||||
// 8 databits + 1 parity (1)
|
// 8 databits + 1 parity (1)
|
||||||
// CIITT 16 chksum
|
// CIITT 16 chksum
|
||||||
|
@ -157,7 +93,8 @@ int getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t
|
||||||
|
|
||||||
-- sample: 985121004515220 [ 37FF65B88EF94 ]
|
-- sample: 985121004515220 [ 37FF65B88EF94 ]
|
||||||
*/
|
*/
|
||||||
int CmdFDXBdemodBI(const char *Cmd) {
|
/*
|
||||||
|
static int CmdFDXBdemodBI(const char *Cmd) {
|
||||||
(void)Cmd; // Cmd is not used so far
|
(void)Cmd; // Cmd is not used so far
|
||||||
|
|
||||||
int clk = 32;
|
int clk = 32;
|
||||||
|
@ -229,11 +166,11 @@ int CmdFDXBdemodBI(const char *Cmd) {
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
//see ASKDemod for what args are accepted
|
//see ASKDemod for what args are accepted
|
||||||
//almost the same demod as cmddata.c/CmdFDXBdemodBI
|
//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
|
(void)Cmd; // Cmd is not used so far
|
||||||
|
|
||||||
//Differential Biphase / di-phase (inverted biphase)
|
//Differential Biphase / di-phase (inverted biphase)
|
||||||
|
@ -303,12 +240,12 @@ int CmdFdxDemod(const char *Cmd) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdFdxRead(const char *Cmd) {
|
static int CmdFdxRead(const char *Cmd) {
|
||||||
lf_read(true, 10000);
|
lf_read(true, 10000);
|
||||||
return CmdFdxDemod(Cmd);
|
return CmdFdxDemod(Cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdFdxClone(const char *Cmd) {
|
static int CmdFdxClone(const char *Cmd) {
|
||||||
|
|
||||||
uint32_t countryid = 0;
|
uint32_t countryid = 0;
|
||||||
uint64_t animalid = 0;
|
uint64_t animalid = 0;
|
||||||
|
@ -360,7 +297,7 @@ int CmdFdxClone(const char *Cmd) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdFdxSim(const char *Cmd) {
|
static int CmdFdxSim(const char *Cmd) {
|
||||||
uint32_t countryid = 0;
|
uint32_t countryid = 0;
|
||||||
uint64_t animalid = 0;
|
uint64_t animalid = 0;
|
||||||
|
|
||||||
|
@ -399,14 +336,83 @@ static command_t CommandTable[] = {
|
||||||
{NULL, NULL, 0, NULL}
|
{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) {
|
int CmdLFFdx(const char *Cmd) {
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
CmdsParse(CommandTable, Cmd);
|
CmdsParse(CommandTable, Cmd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdHelp(const char *Cmd) {
|
// Ask/Biphase Demod then try to locate an ISO 11784/85 ID
|
||||||
(void)Cmd; // Cmd is not used so far
|
// BitStream must contain previously askrawdemod and biphasedemoded data
|
||||||
CmdsHelp(CommandTable);
|
int detectFDXB(uint8_t *dest, size_t *size) {
|
||||||
return 0;
|
//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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,11 +20,8 @@
|
||||||
#include "lfdemod.h" // parityTest
|
#include "lfdemod.h" // parityTest
|
||||||
|
|
||||||
int CmdLFFdx(const char *Cmd);
|
int CmdLFFdx(const char *Cmd);
|
||||||
int CmdFdxClone(const char *Cmd);
|
int detectFDXB(uint8_t *dest, size_t *size);
|
||||||
int CmdFdxSim(const char *Cmd);
|
int demodFDX(void);
|
||||||
int CmdFdxRead(const char *Cmd);
|
|
||||||
int CmdFdxDemod(const char *Cmd);
|
|
||||||
|
|
||||||
int getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t isextended, uint32_t extended, uint8_t *bits);
|
int getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t isextended, uint32_t extended, uint8_t *bits);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -44,8 +44,241 @@ static int usage_lf_guard_sim(void) {
|
||||||
return 0;
|
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.
|
// 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 xorKey = 0x66;
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
|
@ -139,231 +372,3 @@ int GetGuardBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits) {
|
||||||
return 1;
|
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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -23,9 +23,7 @@
|
||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
|
|
||||||
int CmdLFGuard(const char *Cmd);
|
int CmdLFGuard(const char *Cmd);
|
||||||
int CmdGuardDemod(const char *Cmd);
|
int detectGProxII(uint8_t *bits, size_t *size);
|
||||||
int CmdGuardRead(const char *Cmd);
|
int demodGuard(void);
|
||||||
int CmdGuardClone(const char *Cmd);
|
int getGuardBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits);
|
||||||
int CmdGuardSim(const char *Cmd);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
/*
|
||||||
static int usage_lf_hid_read(void) {
|
static int usage_lf_hid_read(void) {
|
||||||
PrintAndLogEx(NORMAL, "Enables HID compatible reader mode printing details.");
|
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.");
|
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");
|
PrintAndLogEx(NORMAL, " lf hid read 1");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
static int usage_lf_hid_wiegand(void) {
|
static int usage_lf_hid_wiegand(void) {
|
||||||
PrintAndLogEx(NORMAL, "This command converts facility code/card number to Wiegand code");
|
PrintAndLogEx(NORMAL, "This command converts facility code/card number to Wiegand code");
|
||||||
PrintAndLogEx(NORMAL, "");
|
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)
|
//by marshmellow (based on existing demod + holiman's refactor)
|
||||||
//HID Prox demod - FSK RF/50 with preamble of 00011101 (then manchester encoded)
|
//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
|
//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
|
(void)Cmd; // Cmd is not used so far
|
||||||
//raw fsk demod no manchester decoding no start bit finding just get binary from wave
|
//raw fsk demod no manchester decoding no start bit finding just get binary from wave
|
||||||
uint32_t hi2 = 0, hi = 0, lo = 0;
|
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.
|
// 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);
|
lf_read(true, 12000);
|
||||||
return CmdHIDDemod(Cmd);
|
return CmdHIDDemod(Cmd);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
// this read loops on device side.
|
// this read loops on device side.
|
||||||
// uses the demod in lfops.c
|
// 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();
|
if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_hid_read();
|
||||||
uint8_t findone = (Cmd[0] == '1') ? 1 : 0;
|
uint8_t findone = (Cmd[0] == '1') ? 1 : 0;
|
||||||
|
@ -246,8 +247,8 @@ int CmdHIDRead_device(const char *Cmd) {
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
int CmdHIDSim(const char *Cmd) {
|
static int CmdHIDSim(const char *Cmd) {
|
||||||
uint32_t hi = 0, lo = 0;
|
uint32_t hi = 0, lo = 0;
|
||||||
uint32_t n = 0, i = 0;
|
uint32_t n = 0, i = 0;
|
||||||
|
|
||||||
|
@ -268,7 +269,7 @@ int CmdHIDSim(const char *Cmd) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdHIDClone(const char *Cmd) {
|
static int CmdHIDClone(const char *Cmd) {
|
||||||
|
|
||||||
uint32_t hi2 = 0, hi = 0, lo = 0;
|
uint32_t hi2 = 0, hi = 0, lo = 0;
|
||||||
uint32_t n = 0, i = 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;
|
uint32_t oem = 0, fc = 0;
|
||||||
uint64_t cardnum = 0;
|
uint64_t cardnum = 0;
|
||||||
uint8_t bits[BITS] = {0};
|
uint8_t bits[BITS] = {0};
|
||||||
|
@ -515,7 +516,7 @@ int CmdHIDWiegand(const char *Cmd) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdHIDBrute(const char *Cmd) {
|
static int CmdHIDBrute(const char *Cmd) {
|
||||||
|
|
||||||
bool errors = false, verbose = false;
|
bool errors = false, verbose = false;
|
||||||
uint32_t fc = 0, cn = 0, delay = 1000;
|
uint32_t fc = 0, cn = 0, delay = 1000;
|
||||||
|
@ -615,14 +616,18 @@ static command_t CommandTable[] = {
|
||||||
{NULL, NULL, 0, NULL}
|
{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) {
|
int CmdLFHID(const char *Cmd) {
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
CmdsParse(CommandTable, Cmd);
|
CmdsParse(CommandTable, Cmd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdHelp(const char *Cmd) {
|
int demodHID(void) {
|
||||||
(void)Cmd; // Cmd is not used so far
|
return CmdHIDDemod("");
|
||||||
CmdsHelp(CommandTable);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,13 +25,8 @@
|
||||||
#include "lfdemod.h"
|
#include "lfdemod.h"
|
||||||
|
|
||||||
int CmdLFHID(const char *Cmd);
|
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 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);
|
void calcWiegand(uint8_t fmtlen, uint16_t fc, uint64_t cardno, uint8_t *bits, uint8_t oem);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -64,6 +64,7 @@ static int usage_hitag_info(void) {
|
||||||
PrintAndLogEx(NORMAL, " lf hitag info");
|
PrintAndLogEx(NORMAL, " lf hitag info");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
static int usage_hitag_dump(void) {
|
static int usage_hitag_dump(void) {
|
||||||
PrintAndLogEx(NORMAL, "Usage: lf hitag dump [h] p <pwd> f <name>");
|
PrintAndLogEx(NORMAL, "Usage: lf hitag dump [h] p <pwd> f <name>");
|
||||||
PrintAndLogEx(NORMAL, "Options:");
|
PrintAndLogEx(NORMAL, "Options:");
|
||||||
|
@ -76,6 +77,7 @@ static int usage_hitag_dump(void) {
|
||||||
PrintAndLogEx(NORMAL, " lf hitag dump p 4D494B52 f mydump");
|
PrintAndLogEx(NORMAL, " lf hitag dump p 4D494B52 f mydump");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
static int usage_hitag_reader(void) {
|
static int usage_hitag_reader(void) {
|
||||||
PrintAndLogEx(NORMAL, "Hitag reader functions");
|
PrintAndLogEx(NORMAL, "Hitag reader functions");
|
||||||
PrintAndLogEx(NORMAL, "Usage: lf hitag reader [h] <reader function #>");
|
PrintAndLogEx(NORMAL, "Usage: lf hitag reader [h] <reader function #>");
|
||||||
|
@ -120,7 +122,7 @@ static int usage_hitag_checkchallenges(void) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdLFHitagList(const char *Cmd) {
|
static int CmdLFHitagList(const char *Cmd) {
|
||||||
(void)Cmd; // Cmd is not used so far
|
(void)Cmd; // Cmd is not used so far
|
||||||
CmdTraceList("hitag");
|
CmdTraceList("hitag");
|
||||||
return 0;
|
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));
|
char ctmp = tolower(param_getchar(Cmd, 0));
|
||||||
if (ctmp == 'h') return usage_hitag_sniff();
|
if (ctmp == 'h') return usage_hitag_sniff();
|
||||||
|
@ -264,7 +266,7 @@ int CmdLFHitagSniff(const char *Cmd) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdLFHitagSim(const char *Cmd) {
|
static int CmdLFHitagSim(const char *Cmd) {
|
||||||
|
|
||||||
bool errors = false;
|
bool errors = false;
|
||||||
bool tag_mem_supplied = false;
|
bool tag_mem_supplied = false;
|
||||||
|
@ -476,7 +478,7 @@ static bool getHitagUid(uint32_t *uid) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdLFHitagInfo(const char *Cmd) {
|
static int CmdLFHitagInfo(const char *Cmd) {
|
||||||
PrintAndLogEx(INFO, "Hitag2 tag information ");
|
PrintAndLogEx(INFO, "Hitag2 tag information ");
|
||||||
PrintAndLogEx(INFO, "To be done!");
|
PrintAndLogEx(INFO, "To be done!");
|
||||||
PrintAndLogEx(INFO, "------------------------------------");
|
PrintAndLogEx(INFO, "------------------------------------");
|
||||||
|
@ -509,7 +511,7 @@ int CmdLFHitagInfo(const char *Cmd) {
|
||||||
// TODO: iceman
|
// 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 !?
|
// 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}}};
|
UsbCommand c = {CMD_READER_HITAG, {0, 0, 0}, {{0}}};
|
||||||
hitag_data *htd = (hitag_data *)c.d.asBytes;
|
hitag_data *htd = (hitag_data *)c.d.asBytes;
|
||||||
|
@ -590,7 +592,7 @@ int CmdLFHitagReader(const char *Cmd) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdLFHitagCheckChallenges(const char *Cmd) {
|
static int CmdLFHitagCheckChallenges(const char *Cmd) {
|
||||||
|
|
||||||
UsbCommand c = { CMD_TEST_HITAGS_TRACES, {0, 0, 0}, {{0}}};
|
UsbCommand c = { CMD_TEST_HITAGS_TRACES, {0, 0, 0}, {{0}}};
|
||||||
char filename[FILE_PATH_SIZE] = { 0x00 };
|
char filename[FILE_PATH_SIZE] = { 0x00 };
|
||||||
|
@ -640,7 +642,7 @@ int CmdLFHitagCheckChallenges(const char *Cmd) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdLFHitagWriter(const char *Cmd) {
|
static int CmdLFHitagWriter(const char *Cmd) {
|
||||||
UsbCommand c = { CMD_WR_HITAG_S, {0, 0, 0}, {{0}}};
|
UsbCommand c = { CMD_WR_HITAG_S, {0, 0, 0}, {{0}}};
|
||||||
hitag_data *htd = (hitag_data *)c.d.asBytes;
|
hitag_data *htd = (hitag_data *)c.d.asBytes;
|
||||||
hitag_function htf = param_get32ex(Cmd, 0, 0, 10);
|
hitag_function htf = param_get32ex(Cmd, 0, 0, 10);
|
||||||
|
@ -681,7 +683,8 @@ int CmdLFHitagWriter(const char *Cmd) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdLFHitagDump(const char *Cmd) {
|
/*
|
||||||
|
static int CmdLFHitagDump(const char *Cmd) {
|
||||||
PrintAndLogEx(INFO, "Dumping of tag memory");
|
PrintAndLogEx(INFO, "Dumping of tag memory");
|
||||||
PrintAndLogEx(INFO, "To be done!");
|
PrintAndLogEx(INFO, "To be done!");
|
||||||
|
|
||||||
|
@ -689,6 +692,7 @@ int CmdLFHitagDump(const char *Cmd) {
|
||||||
if (ctmp == 'h') return usage_hitag_dump();
|
if (ctmp == 'h') return usage_hitag_dump();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
static command_t CommandTable[] = {
|
static command_t CommandTable[] = {
|
||||||
{"help", CmdHelp, 1, "This help" },
|
{"help", CmdHelp, 1, "This help" },
|
||||||
|
@ -702,14 +706,18 @@ static command_t CommandTable[] = {
|
||||||
{ NULL, NULL, 0, NULL }
|
{ 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) {
|
int CmdLFHitag(const char *Cmd) {
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
CmdsParse(CommandTable, Cmd);
|
CmdsParse(CommandTable, Cmd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdHelp(const char *Cmd) {
|
int readHitagUid(void) {
|
||||||
(void)Cmd; // Cmd is not used so far
|
return CmdLFHitagReader("26") == 0;
|
||||||
CmdsHelp(CommandTable);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,13 +13,6 @@
|
||||||
|
|
||||||
int CmdLFHitag(const char *Cmd);
|
int CmdLFHitag(const char *Cmd);
|
||||||
|
|
||||||
int CmdLFHitagList(const char *Cmd);
|
int readHitagUid(void);
|
||||||
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);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -50,126 +50,10 @@ static int usage_lf_indala_sim(void) {
|
||||||
return 0;
|
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
|
// Indala 26 bit decode
|
||||||
// by marshmellow
|
// by marshmellow
|
||||||
// optional arguments - same as PSKDemod (clock & invert & maxerr)
|
// 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));
|
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||||
if (cmdp == 'h') return usage_lf_indala_demod();
|
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
|
// returns false positives more often - but runs against more sets of samples
|
||||||
// poor psk signal can be difficult to demod this approach might succeed when the other fails
|
// poor psk signal can be difficult to demod this approach might succeed when the other fails
|
||||||
// but the other appears to currently be more accurate than this approach most of the time.
|
// but the other appears to currently be more accurate than this approach most of the time.
|
||||||
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
|
// Usage: recover 64bit UID by default, specify "224" as arg to recover a 224bit UID
|
||||||
int state = -1;
|
int state = -1;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
@ -477,7 +361,13 @@ int CmdIndalaDemodAlt(const char *Cmd) {
|
||||||
return 1;
|
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));
|
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||||
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_indala_sim();
|
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_indala_sim();
|
||||||
|
@ -522,7 +412,7 @@ int CmdIndalaSim(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// iceman - needs refactoring
|
// iceman - needs refactoring
|
||||||
int CmdIndalaClone(const char *Cmd) {
|
static int CmdIndalaClone(const char *Cmd) {
|
||||||
|
|
||||||
bool isLongUid = false;
|
bool isLongUid = false;
|
||||||
uint8_t data[7 * 4];
|
uint8_t data[7 * 4];
|
||||||
|
@ -582,14 +472,128 @@ static command_t CommandTable[] = {
|
||||||
{NULL, NULL, 0, NULL}
|
{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) {
|
int CmdLFINDALA(const char *Cmd) {
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
CmdsParse(CommandTable, Cmd);
|
CmdsParse(CommandTable, Cmd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdHelp(const char *Cmd) {
|
// redesigned by marshmellow adjusted from existing decode functions
|
||||||
(void)Cmd; // Cmd is not used so far
|
// indala id decoding
|
||||||
CmdsHelp(CommandTable);
|
int detectIndala(uint8_t *dest, size_t *size, uint8_t *invert) {
|
||||||
return 0;
|
|
||||||
|
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("");
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,14 +25,10 @@
|
||||||
|
|
||||||
int CmdLFINDALA(const char *Cmd);
|
int CmdLFINDALA(const char *Cmd);
|
||||||
|
|
||||||
int CmdIndalaDemod(const char *Cmd);
|
int detectIndala(uint8_t *dest, size_t *size, uint8_t *invert);
|
||||||
int CmdIndalaDemodAlt(const char *Cmd);
|
|
||||||
int CmdIndalaRead(const char *Cmd);
|
|
||||||
int CmdIndalaClone(const char *Cmd);
|
|
||||||
int CmdIndalaSim(const char *Cmd);
|
|
||||||
|
|
||||||
int detectIndala26(uint8_t *bitStream, 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 detectIndala64(uint8_t *bitStream, size_t *size, uint8_t *invert);
|
||||||
int detectIndala224(uint8_t *bitStream, size_t *size, uint8_t *invert);
|
int detectIndala224(uint8_t *bitStream, size_t *size, uint8_t *invert);
|
||||||
|
int demodIndala(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
243
client/cmdlfio.c
243
client/cmdlfio.c
|
@ -11,7 +11,7 @@
|
||||||
#include "cmdlfio.h"
|
#include "cmdlfio.h"
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
/*
|
||||||
static int usage_lf_io_read(void) {
|
static int usage_lf_io_read(void) {
|
||||||
PrintAndLogEx(NORMAL, "Enables IOProx compatible reader mode printing details of scanned tags.");
|
PrintAndLogEx(NORMAL, "Enables IOProx compatible reader mode printing details of scanned tags.");
|
||||||
PrintAndLogEx(NORMAL, "By default, values are printed and logged until the button is pressed or another USB command is issued.");
|
PrintAndLogEx(NORMAL, "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");
|
PrintAndLogEx(NORMAL, " lf io read 1");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
static int usage_lf_io_sim(void) {
|
static int usage_lf_io_sim(void) {
|
||||||
PrintAndLogEx(NORMAL, "Enables simulation of IOProx card with specified facility-code and card number.");
|
PrintAndLogEx(NORMAL, "Enables simulation of IOProx card with specified facility-code and card number.");
|
||||||
PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued.");
|
PrintAndLogEx(NORMAL, "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");
|
PrintAndLogEx(NORMAL, " lf io clone 26 101 1337");
|
||||||
return 0;
|
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.
|
// this read loops on device side.
|
||||||
// uses the demod in lfops.c
|
// 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();
|
if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_io_read();
|
||||||
int findone = (Cmd[0] == '1') ? 1 : 0;
|
int findone = (Cmd[0] == '1') ? 1 : 0;
|
||||||
UsbCommand c = {CMD_IO_DEMOD_FSK, {findone, 0, 0}, {{0}}};
|
UsbCommand c = {CMD_IO_DEMOD_FSK, {findone, 0, 0}, {{0}}};
|
||||||
|
@ -76,11 +71,11 @@ int CmdIOProxRead_device(const char *Cmd) {
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
//by marshmellow
|
//by marshmellow
|
||||||
//IO-Prox demod - FSK RF/64 with preamble of 000000001
|
//IO-Prox demod - FSK RF/64 with preamble of 000000001
|
||||||
//print ioprox ID and some format details
|
//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
|
(void)Cmd; // Cmd is not used so far
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
|
@ -177,6 +172,124 @@ int CmdIOProxDemod(const char *Cmd) {
|
||||||
return retval;
|
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
|
//Index map
|
||||||
//0 10 20 30 40 50 60
|
//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;
|
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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -17,11 +17,8 @@
|
||||||
#include "cmddata.h"
|
#include "cmddata.h"
|
||||||
|
|
||||||
int CmdLFIO(const char *Cmd);
|
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);
|
int getIOProxBits(uint8_t version, uint8_t fc, uint16_t cn, uint8_t *bits);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue