mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-14 10:37:23 -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;
|
||||
}
|
||||
|
||||
int CmdIdteckDemod(const char *Cmd) {
|
||||
static int CmdIdteckDemod(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
|
||||
if (!PSKDemod("", false)) {
|
||||
|
@ -1202,6 +1202,11 @@ int CmdIdteckDemod(const char *Cmd) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int demodIdteck(void) {
|
||||
return CmdIdteckDemod("");
|
||||
}
|
||||
|
||||
|
||||
// by marshmellow
|
||||
// takes 3 arguments - clock, invert, maxErr as integers
|
||||
// attempts to demodulate nrz only
|
||||
|
|
|
@ -54,7 +54,6 @@ int CmdDetectClockRate(const char *Cmd);
|
|||
int CmdFSKrawdemod(const char *Cmd);
|
||||
int CmdPSK1rawDemod(const char *Cmd);
|
||||
int CmdPSK2rawDemod(const char *Cmd);
|
||||
int CmdIdteckDemod(const char *Cmd);
|
||||
int CmdGrid(const char *Cmd);
|
||||
int CmdGetBitStream(const char *Cmd);
|
||||
int CmdHexsamples(const char *Cmd);
|
||||
|
@ -88,6 +87,8 @@ int AskEdgeDetect(const int *in, int *out, int len, int threshold);
|
|||
|
||||
int CmdDataIIR(const char *Cmd);
|
||||
|
||||
int demodIdteck(void);
|
||||
|
||||
#define MAX_DEMOD_BUF_LEN (1024*128)
|
||||
#define BIGBUF_SIZE 40000
|
||||
extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
|
||||
|
|
|
@ -886,8 +886,8 @@ int CmdLFfind(const char *Cmd) {
|
|||
// The improved noise detection will find Cotag.
|
||||
if (getSignalProperties()->isnoise) {
|
||||
|
||||
if (CmdLFHitagReader("26") == 0) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Hitag") " found!"); return 1;}
|
||||
if (CmdCOTAGRead("") > 0) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("COTAG ID") " found!"); return 1;}
|
||||
if (readHitagUid()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Hitag") " found!"); return 1;}
|
||||
if (readCOTAGUid()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("COTAG ID") " found!"); return 1;}
|
||||
|
||||
PrintAndLogEx(FAILED, "\n" _YELLOW_("No data found!") " - Signal looks like noise. Maybe not an LF tag?");
|
||||
return 0;
|
||||
|
@ -896,16 +896,16 @@ int CmdLFfind(const char *Cmd) {
|
|||
|
||||
if (EM4x50Read("", false)) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("EM4x50 ID") " found!"); return 1;}
|
||||
|
||||
if (CmdHIDDemod("")) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("HID Prox ID") " found!"); goto out;}
|
||||
if (CmdAWIDDemod("")) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("AWID ID") " found!"); goto out;}
|
||||
if (demodHID()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("HID Prox ID") " found!"); goto out;}
|
||||
if (demodAWID()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("AWID ID") " found!"); goto out;}
|
||||
if (demodParadox()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Paradox ID") " found!"); goto out;}
|
||||
|
||||
if (CmdEM410xDemod("")) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("EM410x ID") " found!"); goto out;}
|
||||
if (CmdFdxDemod("")) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("FDX-B ID") " found!"); goto out;}
|
||||
if (CmdGuardDemod("")) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Guardall G-Prox II ID") " found!"); goto out; }
|
||||
if (CmdIdteckDemod("")) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Idteck ID") " found!"); goto out;}
|
||||
if (CmdIndalaDemod("")) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Indala ID") " found!"); goto out;}
|
||||
if (CmdIOProxDemod("")) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("IO Prox ID") " found!"); goto out;}
|
||||
if (demodEM410x()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("EM410x ID") " found!"); goto out;}
|
||||
if (demodFDX()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("FDX-B ID") " found!"); goto out;}
|
||||
if (demodGuard()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Guardall G-Prox II ID") " found!"); goto out; }
|
||||
if (demodIdteck()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Idteck ID") " found!"); goto out;}
|
||||
if (demodIndala()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Indala ID") " found!"); goto out;}
|
||||
if (demodIOProx()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("IO Prox ID") " found!"); goto out;}
|
||||
if (demodJablotron()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Jablotron ID") " found!"); goto out;}
|
||||
if (demodNedap()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("NEDAP ID") " found!"); goto out;}
|
||||
if (demodNexWatch()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("NexWatch ID") " found!"); goto out;}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include "cmdlfawid.h" // AWID function declarations
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
/*
|
||||
static int usage_lf_awid_read(void) {
|
||||
PrintAndLogEx(NORMAL, "Enables AWID compatible reader mode printing details of scanned AWID26 or AWID50 tags.");
|
||||
PrintAndLogEx(NORMAL, "By default, values are printed and logged until the button is pressed or another USB command is issued.");
|
||||
|
@ -29,7 +29,7 @@ static int usage_lf_awid_read(void) {
|
|||
PrintAndLogEx(NORMAL, " lf awid read 1");
|
||||
return 0;
|
||||
}
|
||||
|
||||
*/
|
||||
static int usage_lf_awid_sim(void) {
|
||||
PrintAndLogEx(NORMAL, "Enables simulation of AWID card with specified facility-code and card number.");
|
||||
PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued.");
|
||||
|
@ -122,60 +122,6 @@ static bool sendTry(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint32_t delay, ui
|
|||
return true;
|
||||
}
|
||||
|
||||
//refactored by marshmellow
|
||||
int getAWIDBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *bits) {
|
||||
|
||||
// the return bits, preamble 0000 0001
|
||||
bits[7] = 1;
|
||||
|
||||
uint8_t pre[66];
|
||||
memset(pre, 0, sizeof(pre));
|
||||
|
||||
// add formatlength
|
||||
num_to_bytebits(fmtlen, 8, pre);
|
||||
|
||||
// add facilitycode, cardnumber and wiegand parity bits
|
||||
switch (fmtlen) {
|
||||
case 26: {
|
||||
uint8_t wiegand[24];
|
||||
num_to_bytebits(fc, 8, wiegand);
|
||||
num_to_bytebits(cn, 16, wiegand + 8);
|
||||
wiegand_add_parity(pre + 8, wiegand, sizeof(wiegand));
|
||||
break;
|
||||
}
|
||||
case 34: {
|
||||
uint8_t wiegand[32];
|
||||
num_to_bytebits(fc, 8, wiegand);
|
||||
num_to_bytebits(cn, 24, wiegand + 8);
|
||||
wiegand_add_parity(pre + 8, wiegand, sizeof(wiegand));
|
||||
break;
|
||||
}
|
||||
case 37: {
|
||||
uint8_t wiegand[31];
|
||||
num_to_bytebits(fc, 13, wiegand);
|
||||
num_to_bytebits(cn, 18, wiegand + 13);
|
||||
wiegand_add_parity(pre + 8, wiegand, sizeof(wiegand));
|
||||
break;
|
||||
}
|
||||
case 50: {
|
||||
uint8_t wiegand[48];
|
||||
num_to_bytebits(fc, 16, wiegand);
|
||||
num_to_bytebits(cn, 32, wiegand + 16);
|
||||
wiegand_add_parity(pre + 8, wiegand, sizeof(wiegand));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// add AWID 4bit parity
|
||||
size_t bitLen = addParity(pre, bits + 8, 66, 4, 1);
|
||||
|
||||
if (bitLen != 88) return 0;
|
||||
|
||||
PrintAndLogEx(SUCCESS, "awid raw bits:\n %s \n", sprint_bin(bits, bitLen));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void verify_values(uint8_t *fmtlen, uint32_t *fc, uint32_t *cn) {
|
||||
switch (*fmtlen) {
|
||||
case 50:
|
||||
|
@ -218,15 +164,10 @@ static void verify_values(uint8_t *fmtlen, uint32_t *fc, uint32_t *cn) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// this read is the "normal" read, which download lf signal and tries to demod here.
|
||||
int CmdAWIDRead(const char *Cmd) {
|
||||
lf_read(true, 12000);
|
||||
return CmdAWIDDemod(Cmd);
|
||||
}
|
||||
/*
|
||||
// this read loops on device side.
|
||||
// uses the demod in lfops.c
|
||||
int CmdAWIDRead_device(const char *Cmd) {
|
||||
static int CmdAWIDRead_device(const char *Cmd) {
|
||||
|
||||
if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_awid_read();
|
||||
uint8_t findone = (Cmd[0] == '1') ? 1 : 0;
|
||||
|
@ -235,11 +176,11 @@ int CmdAWIDRead_device(const char *Cmd) {
|
|||
SendCommand(&c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*/
|
||||
//by marshmellow
|
||||
//AWID Prox demod - FSK2a RF/50 with preamble of 00000001 (always a 96 bit data stream)
|
||||
//print full AWID Prox ID and some bit format details if found
|
||||
int CmdAWIDDemod(const char *Cmd) {
|
||||
static int CmdAWIDDemod(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0};
|
||||
size_t size = getFromGraphBuf(bits);
|
||||
|
@ -370,7 +311,13 @@ int CmdAWIDDemod(const char *Cmd) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int CmdAWIDSim(const char *Cmd) {
|
||||
// this read is the "normal" read, which download lf signal and tries to demod here.
|
||||
static int CmdAWIDRead(const char *Cmd) {
|
||||
lf_read(true, 12000);
|
||||
return CmdAWIDDemod(Cmd);
|
||||
}
|
||||
|
||||
static int CmdAWIDSim(const char *Cmd) {
|
||||
uint32_t fc = 0, cn = 0;
|
||||
uint8_t fmtlen = 0;
|
||||
uint8_t bits[96];
|
||||
|
@ -410,7 +357,7 @@ int CmdAWIDSim(const char *Cmd) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int CmdAWIDClone(const char *Cmd) {
|
||||
static int CmdAWIDClone(const char *Cmd) {
|
||||
uint32_t blocks[4] = {T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_50 | 3 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0};
|
||||
uint32_t fc = 0, cn = 0;
|
||||
uint8_t fmtlen = 0;
|
||||
|
@ -461,7 +408,7 @@ int CmdAWIDClone(const char *Cmd) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int CmdAWIDBrute(const char *Cmd) {
|
||||
static int CmdAWIDBrute(const char *Cmd) {
|
||||
|
||||
bool errors = false, verbose = false;
|
||||
uint32_t fc = 0, cn = 0, delay = 1000;
|
||||
|
@ -567,14 +514,72 @@ static command_t CommandTable[] = {
|
|||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
static int CmdHelp(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdLFAWID(const char *Cmd) {
|
||||
clearCommandBuffer();
|
||||
CmdsParse(CommandTable, Cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHelp(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
//refactored by marshmellow
|
||||
int getAWIDBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *bits) {
|
||||
|
||||
// the return bits, preamble 0000 0001
|
||||
bits[7] = 1;
|
||||
|
||||
uint8_t pre[66];
|
||||
memset(pre, 0, sizeof(pre));
|
||||
|
||||
// add formatlength
|
||||
num_to_bytebits(fmtlen, 8, pre);
|
||||
|
||||
// add facilitycode, cardnumber and wiegand parity bits
|
||||
switch (fmtlen) {
|
||||
case 26: {
|
||||
uint8_t wiegand[24];
|
||||
num_to_bytebits(fc, 8, wiegand);
|
||||
num_to_bytebits(cn, 16, wiegand + 8);
|
||||
wiegand_add_parity(pre + 8, wiegand, sizeof(wiegand));
|
||||
break;
|
||||
}
|
||||
case 34: {
|
||||
uint8_t wiegand[32];
|
||||
num_to_bytebits(fc, 8, wiegand);
|
||||
num_to_bytebits(cn, 24, wiegand + 8);
|
||||
wiegand_add_parity(pre + 8, wiegand, sizeof(wiegand));
|
||||
break;
|
||||
}
|
||||
case 37: {
|
||||
uint8_t wiegand[31];
|
||||
num_to_bytebits(fc, 13, wiegand);
|
||||
num_to_bytebits(cn, 18, wiegand + 13);
|
||||
wiegand_add_parity(pre + 8, wiegand, sizeof(wiegand));
|
||||
break;
|
||||
}
|
||||
case 50: {
|
||||
uint8_t wiegand[48];
|
||||
num_to_bytebits(fc, 16, wiegand);
|
||||
num_to_bytebits(cn, 32, wiegand + 16);
|
||||
wiegand_add_parity(pre + 8, wiegand, sizeof(wiegand));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// add AWID 4bit parity
|
||||
size_t bitLen = addParity(pre, bits + 8, 66, 4, 1);
|
||||
|
||||
if (bitLen != 88) return 0;
|
||||
|
||||
PrintAndLogEx(SUCCESS, "awid raw bits:\n %s \n", sprint_bin(bits, bitLen));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int demodAWID(void) {
|
||||
return CmdAWIDDemod("");
|
||||
}
|
||||
|
|
|
@ -25,11 +25,8 @@
|
|||
|
||||
|
||||
int CmdLFAWID(const char *Cmd);
|
||||
int CmdAWIDDemod(const char *Cmd);
|
||||
int CmdAWIDRead(const char *Cmd);
|
||||
int CmdAWIDSim(const char *Cmd);
|
||||
int CmdAWIDClone(const char *Cmd);
|
||||
int CmdAWIDBrute(const char *Cmd);
|
||||
|
||||
int demodAWID(void);
|
||||
int getAWIDBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *bits);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -27,7 +27,7 @@ static int usage_lf_cotag_read(void) {
|
|||
|
||||
// COTAG demod should be able to use GraphBuffer,
|
||||
// when data load samples
|
||||
int CmdCOTAGDemod(const char *Cmd) {
|
||||
static int CmdCOTAGDemod(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
|
||||
uint8_t bits[COTAG_BITS] = {0};
|
||||
|
@ -67,7 +67,7 @@ int CmdCOTAGDemod(const char *Cmd) {
|
|||
// 0 = HIGH/LOW signal - maxlength bigbuff
|
||||
// 1 = translation for HI/LO into bytes with manchester 0,1 - length 300
|
||||
// 2 = raw signal - maxlength bigbuff
|
||||
int CmdCOTAGRead(const char *Cmd) {
|
||||
static int CmdCOTAGRead(const char *Cmd) {
|
||||
|
||||
if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_cotag_read();
|
||||
|
||||
|
@ -110,14 +110,22 @@ static command_t CommandTable[] = {
|
|||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
static int CmdHelp(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdLFCOTAG(const char *Cmd) {
|
||||
clearCommandBuffer();
|
||||
CmdsParse(CommandTable, Cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHelp(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
int demodCOTAG(void) {
|
||||
return CmdCOTAGDemod("");
|
||||
}
|
||||
|
||||
int readCOTAGUid(void) {
|
||||
return CmdCOTAGRead > 0;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#endif
|
||||
|
||||
int CmdLFCOTAG(const char *Cmd);
|
||||
int CmdCOTAGRead(const char *Cmd);
|
||||
int CmdCOTAGDemod(const char *Cmd);
|
||||
|
||||
int demodCOTAG(void);
|
||||
int readCOTAGUid(void);
|
||||
#endif
|
||||
|
|
|
@ -188,7 +188,7 @@ static int usage_lf_em4x05_info(void) {
|
|||
*/
|
||||
|
||||
// Construct the graph for emulating an EM410X tag
|
||||
void ConstructEM410xEmulGraph(const char *uid, const uint8_t clock) {
|
||||
static void ConstructEM410xEmulGraph(const char *uid, const uint8_t clock) {
|
||||
|
||||
int i, j, binary[4], parity[4];
|
||||
uint32_t n;
|
||||
|
@ -383,28 +383,22 @@ int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo, bool verbose) {
|
|||
if (!ASKDemod_ext(Cmd, false, false, 1, &st)) return 0;
|
||||
return AskEm410xDecode(verbose, hi, lo);
|
||||
}
|
||||
|
||||
// this read is the "normal" read, which download lf signal and tries to demod here.
|
||||
int CmdEM410xRead(const char *Cmd) {
|
||||
lf_read(true, 8192);
|
||||
return CmdEM410xDemod(Cmd);
|
||||
}
|
||||
|
||||
/*
|
||||
// this read loops on device side.
|
||||
// uses the demod in lfops.c
|
||||
int CmdEM410xRead_device(const char *Cmd) {
|
||||
static int CmdEM410xRead_device(const char *Cmd) {
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
uint8_t findone = (cmdp == '1') ? 1 : 0;
|
||||
UsbCommand c = {CMD_EM410X_DEMOD, {findone, 0, 0}, {{0}}};
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*/
|
||||
//by marshmellow
|
||||
//takes 3 arguments - clock, invert and maxErr as integers
|
||||
//attempts to demodulate ask while decoding manchester
|
||||
//prints binary found and saves in graphbuffer for further commands
|
||||
int CmdEM410xDemod(const char *Cmd) {
|
||||
static int CmdEM410xDemod(const char *Cmd) {
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (strlen(Cmd) > 10 || cmdp == 'h') return usage_lf_em410x_demod();
|
||||
|
||||
|
@ -417,8 +411,14 @@ int CmdEM410xDemod(const char *Cmd) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
// this read is the "normal" read, which download lf signal and tries to demod here.
|
||||
static int CmdEM410xRead(const char *Cmd) {
|
||||
lf_read(true, 8192);
|
||||
return CmdEM410xDemod(Cmd);
|
||||
}
|
||||
|
||||
// emulate an EM410X tag
|
||||
int CmdEM410xSim(const char *Cmd) {
|
||||
static int CmdEM410xSim(const char *Cmd) {
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (cmdp == 'h') return usage_lf_em410x_sim();
|
||||
|
||||
|
@ -443,7 +443,7 @@ int CmdEM410xSim(const char *Cmd) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int CmdEM410xBrute(const char *Cmd) {
|
||||
static int CmdEM410xBrute(const char *Cmd) {
|
||||
char filename[FILE_PATH_SIZE] = {0};
|
||||
FILE *f = NULL;
|
||||
char buf[11];
|
||||
|
@ -565,7 +565,7 @@ int CmdEM410xBrute(const char *Cmd) {
|
|||
*
|
||||
* EDIT -- capture enough to get 2 complete preambles at the slowest data rate known to be used (rf/64) (64*64*2+9 = 8201) marshmellow
|
||||
*/
|
||||
int CmdEM410xWatch(const char *Cmd) {
|
||||
static int CmdEM410xWatch(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
do {
|
||||
if (ukbhit()) {
|
||||
|
@ -581,7 +581,7 @@ int CmdEM410xWatch(const char *Cmd) {
|
|||
}
|
||||
|
||||
//currently only supports manchester modulations
|
||||
int CmdEM410xWatchnSpoof(const char *Cmd) {
|
||||
static int CmdEM410xWatchnSpoof(const char *Cmd) {
|
||||
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (cmdp == 'h') return usage_lf_em410x_ws();
|
||||
|
@ -593,7 +593,7 @@ int CmdEM410xWatchnSpoof(const char *Cmd) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int CmdEM410xWrite(const char *Cmd) {
|
||||
static int CmdEM410xWrite(const char *Cmd) {
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (cmdp == 0x00 || cmdp == 'h') return usage_lf_em410x_write();
|
||||
|
||||
|
@ -956,18 +956,18 @@ int EM4x50Read(const char *Cmd, bool verbose) {
|
|||
return (int)AllPTest;
|
||||
}
|
||||
|
||||
int CmdEM4x50Read(const char *Cmd) {
|
||||
static int CmdEM4x50Read(const char *Cmd) {
|
||||
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
|
||||
if (ctmp == 'h') return usage_lf_em4x50_read();
|
||||
return EM4x50Read(Cmd, true);
|
||||
}
|
||||
int CmdEM4x50Write(const char *Cmd) {
|
||||
static int CmdEM4x50Write(const char *Cmd) {
|
||||
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
|
||||
if (ctmp == 'h') return usage_lf_em4x50_write();
|
||||
PrintAndLogEx(NORMAL, "no implemented yet");
|
||||
return 0;
|
||||
}
|
||||
int CmdEM4x50Dump(const char *Cmd) {
|
||||
static int CmdEM4x50Dump(const char *Cmd) {
|
||||
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
|
||||
if (ctmp == 'h') return usage_lf_em4x50_dump();
|
||||
PrintAndLogEx(NORMAL, "no implemented yet");
|
||||
|
@ -1143,7 +1143,7 @@ int EM4x05ReadWord_ext(uint8_t addr, uint32_t pwd, bool usePwd, uint32_t *word)
|
|||
return demodEM4x05resp(word);
|
||||
}
|
||||
|
||||
int CmdEM4x05Dump(const char *Cmd) {
|
||||
static int CmdEM4x05Dump(const char *Cmd) {
|
||||
uint8_t addr = 0;
|
||||
uint32_t pwd = 0;
|
||||
bool usePwd = false;
|
||||
|
@ -1176,7 +1176,7 @@ int CmdEM4x05Dump(const char *Cmd) {
|
|||
return success;
|
||||
}
|
||||
|
||||
int CmdEM4x05Read(const char *Cmd) {
|
||||
static int CmdEM4x05Read(const char *Cmd) {
|
||||
uint8_t addr;
|
||||
uint32_t pwd;
|
||||
bool usePwd = false;
|
||||
|
@ -1206,7 +1206,7 @@ int CmdEM4x05Read(const char *Cmd) {
|
|||
return isOk;
|
||||
}
|
||||
|
||||
int CmdEM4x05Write(const char *Cmd) {
|
||||
static int CmdEM4x05Write(const char *Cmd) {
|
||||
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
|
||||
if (strlen(Cmd) == 0 || ctmp == 'h') return usage_lf_em4x05_write();
|
||||
|
||||
|
@ -1419,7 +1419,7 @@ bool EM4x05IsBlock0(uint32_t *word) {
|
|||
return (res > 0) ? true : false;
|
||||
}
|
||||
|
||||
int CmdEM4x05Info(const char *Cmd) {
|
||||
static int CmdEM4x05Info(const char *Cmd) {
|
||||
#define EM_SERIAL_BLOCK 1
|
||||
#define EM_CONFIG_BLOCK 4
|
||||
#define EM_PROT1_BLOCK 14
|
||||
|
@ -1488,14 +1488,18 @@ static command_t CommandTable[] = {
|
|||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
static int CmdHelp(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdLFEM4X(const char *Cmd) {
|
||||
clearCommandBuffer();
|
||||
CmdsParse(CommandTable, Cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHelp(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
int demodEM410x(void) {
|
||||
return CmdEM410xDemod("");
|
||||
}
|
||||
|
|
|
@ -27,21 +27,7 @@
|
|||
|
||||
int CmdLFEM4X(const char *Cmd);
|
||||
|
||||
int CmdEM410xDemod(const char *Cmd);
|
||||
int CmdEM410xRead(const char *Cmd);
|
||||
int CmdEM410xSim(const char *Cmd);
|
||||
int CmdEM410xBrute(const char *Cmd);
|
||||
int CmdEM410xWatch(const char *Cmd);
|
||||
int CmdEM410xWatchnSpoof(const char *Cmd);
|
||||
int CmdEM410xWrite(const char *Cmd);
|
||||
int CmdEM4x05Dump(const char *Cmd);
|
||||
int CmdEM4x05Info(const char *Cmd);
|
||||
int CmdEM4x05Read(const char *Cmd);
|
||||
int CmdEM4x05Write(const char *Cmd);
|
||||
int CmdEM4x50Read(const char *Cmd);
|
||||
int CmdEM4x50Write(const char *Cmd);
|
||||
int CmdEM4x50Dump(const char *Cmd);
|
||||
|
||||
int demodEM410x(void);
|
||||
int EM4x50Read(const char *Cmd, bool verbose);
|
||||
bool EM4x05IsBlock0(uint32_t *word);
|
||||
|
||||
|
|
|
@ -64,20 +64,6 @@ static int usage_lf_fdx_sim(void) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Ask/Biphase Demod then try to locate an ISO 11784/85 ID
|
||||
// BitStream must contain previously askrawdemod and biphasedemoded data
|
||||
int detectFDXB(uint8_t *dest, size_t *size) {
|
||||
//make sure buffer has enough data
|
||||
if (*size < 128 * 2) return -1;
|
||||
size_t startIdx = 0;
|
||||
uint8_t preamble[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
|
||||
if (!preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx))
|
||||
return -2; //preamble not found
|
||||
if (*size != 128) return -3; //wrong demoded size
|
||||
//return start position
|
||||
return (int)startIdx;
|
||||
}
|
||||
|
||||
// clearing the topbit needed for the preambl detection.
|
||||
static void verify_values(uint32_t countryid, uint64_t animalid) {
|
||||
if ((animalid & 0x3FFFFFFFFF) != animalid) {
|
||||
|
@ -90,56 +76,6 @@ static void verify_values(uint32_t countryid, uint64_t animalid) {
|
|||
}
|
||||
}
|
||||
|
||||
int getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t isextended, uint32_t extended, uint8_t *bits) {
|
||||
|
||||
// add preamble ten 0x00 and one 0x01
|
||||
memset(bits, 0x00, 10);
|
||||
bits[10] = 1;
|
||||
|
||||
// 128bits
|
||||
// every 9th bit is 0x01, but we can just fill the rest with 0x01 and overwrite
|
||||
memset(bits, 0x01, 128);
|
||||
|
||||
// add preamble ten 0x00 and one 0x01
|
||||
memset(bits, 0x00, 10);
|
||||
|
||||
// add reserved
|
||||
num_to_bytebitsLSBF(0x00, 7, bits + 66);
|
||||
num_to_bytebitsLSBF(0x00 >> 7, 7, bits + 74);
|
||||
|
||||
// add animal flag - OK
|
||||
bits[65] = isanimal;
|
||||
|
||||
// add extended flag - OK
|
||||
bits[81] = isextended;
|
||||
|
||||
// add national code 40bits - OK
|
||||
num_to_bytebitsLSBF(national_id >> 0, 8, bits + 11);
|
||||
num_to_bytebitsLSBF(national_id >> 8, 8, bits + 20);
|
||||
num_to_bytebitsLSBF(national_id >> 16, 8, bits + 29);
|
||||
num_to_bytebitsLSBF(national_id >> 24, 8, bits + 38);
|
||||
num_to_bytebitsLSBF(national_id >> 32, 6, bits + 47);
|
||||
|
||||
// add country code - OK
|
||||
num_to_bytebitsLSBF(country >> 0, 2, bits + 53);
|
||||
num_to_bytebitsLSBF(country >> 2, 8, bits + 56);
|
||||
|
||||
// add crc-16 - OK
|
||||
uint8_t raw[8];
|
||||
for (uint8_t i = 0; i < 8; ++i)
|
||||
raw[i] = bytebits_to_byte(bits + 11 + i * 9, 8);
|
||||
|
||||
uint16_t crc = crc16_kermit(raw, 8);
|
||||
num_to_bytebitsLSBF(crc >> 0, 8, bits + 83);
|
||||
num_to_bytebitsLSBF(crc >> 8, 8, bits + 92);
|
||||
|
||||
// extended data - OK
|
||||
num_to_bytebitsLSBF(extended >> 0, 8, bits + 101);
|
||||
num_to_bytebitsLSBF(extended >> 8, 8, bits + 110);
|
||||
num_to_bytebitsLSBF(extended >> 16, 8, bits + 119);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// FDX-B ISO11784/85 demod (aka animal tag) BIPHASE, inverted, rf/32, with preamble of 00000000001 (128bits)
|
||||
// 8 databits + 1 parity (1)
|
||||
// CIITT 16 chksum
|
||||
|
@ -157,7 +93,8 @@ int getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t
|
|||
|
||||
-- sample: 985121004515220 [ 37FF65B88EF94 ]
|
||||
*/
|
||||
int CmdFDXBdemodBI(const char *Cmd) {
|
||||
/*
|
||||
static int CmdFDXBdemodBI(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
|
||||
int clk = 32;
|
||||
|
@ -229,11 +166,11 @@ int CmdFDXBdemodBI(const char *Cmd) {
|
|||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
//see ASKDemod for what args are accepted
|
||||
//almost the same demod as cmddata.c/CmdFDXBdemodBI
|
||||
int CmdFdxDemod(const char *Cmd) {
|
||||
static int CmdFdxDemod(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
|
||||
//Differential Biphase / di-phase (inverted biphase)
|
||||
|
@ -303,12 +240,12 @@ int CmdFdxDemod(const char *Cmd) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int CmdFdxRead(const char *Cmd) {
|
||||
static int CmdFdxRead(const char *Cmd) {
|
||||
lf_read(true, 10000);
|
||||
return CmdFdxDemod(Cmd);
|
||||
}
|
||||
|
||||
int CmdFdxClone(const char *Cmd) {
|
||||
static int CmdFdxClone(const char *Cmd) {
|
||||
|
||||
uint32_t countryid = 0;
|
||||
uint64_t animalid = 0;
|
||||
|
@ -360,7 +297,7 @@ int CmdFdxClone(const char *Cmd) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int CmdFdxSim(const char *Cmd) {
|
||||
static int CmdFdxSim(const char *Cmd) {
|
||||
uint32_t countryid = 0;
|
||||
uint64_t animalid = 0;
|
||||
|
||||
|
@ -399,14 +336,83 @@ static command_t CommandTable[] = {
|
|||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
static int CmdHelp(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdLFFdx(const char *Cmd) {
|
||||
clearCommandBuffer();
|
||||
CmdsParse(CommandTable, Cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHelp(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
// Ask/Biphase Demod then try to locate an ISO 11784/85 ID
|
||||
// BitStream must contain previously askrawdemod and biphasedemoded data
|
||||
int detectFDXB(uint8_t *dest, size_t *size) {
|
||||
//make sure buffer has enough data
|
||||
if (*size < 128 * 2) return -1;
|
||||
size_t startIdx = 0;
|
||||
uint8_t preamble[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
|
||||
if (!preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx))
|
||||
return -2; //preamble not found
|
||||
if (*size != 128) return -3; //wrong demoded size
|
||||
//return start position
|
||||
return (int)startIdx;
|
||||
}
|
||||
|
||||
int demodFDX(void) {
|
||||
return CmdFdxDemod("");
|
||||
}
|
||||
|
||||
int getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t isextended, uint32_t extended, uint8_t *bits) {
|
||||
|
||||
// add preamble ten 0x00 and one 0x01
|
||||
memset(bits, 0x00, 10);
|
||||
bits[10] = 1;
|
||||
|
||||
// 128bits
|
||||
// every 9th bit is 0x01, but we can just fill the rest with 0x01 and overwrite
|
||||
memset(bits, 0x01, 128);
|
||||
|
||||
// add preamble ten 0x00 and one 0x01
|
||||
memset(bits, 0x00, 10);
|
||||
|
||||
// add reserved
|
||||
num_to_bytebitsLSBF(0x00, 7, bits + 66);
|
||||
num_to_bytebitsLSBF(0x00 >> 7, 7, bits + 74);
|
||||
|
||||
// add animal flag - OK
|
||||
bits[65] = isanimal;
|
||||
|
||||
// add extended flag - OK
|
||||
bits[81] = isextended;
|
||||
|
||||
// add national code 40bits - OK
|
||||
num_to_bytebitsLSBF(national_id >> 0, 8, bits + 11);
|
||||
num_to_bytebitsLSBF(national_id >> 8, 8, bits + 20);
|
||||
num_to_bytebitsLSBF(national_id >> 16, 8, bits + 29);
|
||||
num_to_bytebitsLSBF(national_id >> 24, 8, bits + 38);
|
||||
num_to_bytebitsLSBF(national_id >> 32, 6, bits + 47);
|
||||
|
||||
// add country code - OK
|
||||
num_to_bytebitsLSBF(country >> 0, 2, bits + 53);
|
||||
num_to_bytebitsLSBF(country >> 2, 8, bits + 56);
|
||||
|
||||
// add crc-16 - OK
|
||||
uint8_t raw[8];
|
||||
for (uint8_t i = 0; i < 8; ++i)
|
||||
raw[i] = bytebits_to_byte(bits + 11 + i * 9, 8);
|
||||
|
||||
uint16_t crc = crc16_kermit(raw, 8);
|
||||
num_to_bytebitsLSBF(crc >> 0, 8, bits + 83);
|
||||
num_to_bytebitsLSBF(crc >> 8, 8, bits + 92);
|
||||
|
||||
// extended data - OK
|
||||
num_to_bytebitsLSBF(extended >> 0, 8, bits + 101);
|
||||
num_to_bytebitsLSBF(extended >> 8, 8, bits + 110);
|
||||
num_to_bytebitsLSBF(extended >> 16, 8, bits + 119);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,11 +20,8 @@
|
|||
#include "lfdemod.h" // parityTest
|
||||
|
||||
int CmdLFFdx(const char *Cmd);
|
||||
int CmdFdxClone(const char *Cmd);
|
||||
int CmdFdxSim(const char *Cmd);
|
||||
int CmdFdxRead(const char *Cmd);
|
||||
int CmdFdxDemod(const char *Cmd);
|
||||
|
||||
int detectFDXB(uint8_t *dest, size_t *size);
|
||||
int demodFDX(void);
|
||||
int getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t isextended, uint32_t extended, uint8_t *bits);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -44,8 +44,241 @@ static int usage_lf_guard_sim(void) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
//by marshmellow
|
||||
//attempts to demodulate and identify a G_Prox_II verex/chubb card
|
||||
//WARNING: if it fails during some points it will destroy the DemodBuffer data
|
||||
// but will leave the GraphBuffer intact.
|
||||
//if successful it will push askraw data back to demod buffer ready for emulation
|
||||
static int CmdGuardDemod(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
|
||||
//Differential Biphase
|
||||
//get binary from ask wave
|
||||
if (!ASKbiphaseDemod("0 64 0 0", false)) {
|
||||
PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII ASKbiphaseDemod failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t size = DemodBufferLen;
|
||||
|
||||
int preambleIndex = detectGProxII(DemodBuffer, &size);
|
||||
if (preambleIndex < 0) {
|
||||
|
||||
if (preambleIndex == -1)
|
||||
PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII too few bits found");
|
||||
else if (preambleIndex == -2)
|
||||
PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII preamble not found");
|
||||
else if (preambleIndex == -3)
|
||||
PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII size not correct: %d", size);
|
||||
else if (preambleIndex == -5)
|
||||
PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII wrong spacerbits");
|
||||
else
|
||||
PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII ans: %d", preambleIndex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//got a good demod of 96 bits
|
||||
uint8_t ByteStream[8] = {0x00};
|
||||
uint8_t xorKey = 0;
|
||||
size_t startIdx = preambleIndex + 6; //start after 6 bit preamble
|
||||
|
||||
uint8_t bits_no_spacer[90];
|
||||
//so as to not mess with raw DemodBuffer copy to a new sample array
|
||||
memcpy(bits_no_spacer, DemodBuffer + startIdx, 90);
|
||||
// remove the 18 (90/5=18) parity bits (down to 72 bits (96-6-18=72))
|
||||
size_t len = removeParity(bits_no_spacer, 0, 5, 3, 90); //source, startloc, paritylen, ptype, length_to_run
|
||||
if (len != 72) {
|
||||
PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII spacer removal did not produce 72 bits: %u, start: %u", len, startIdx);
|
||||
return 0;
|
||||
}
|
||||
// get key and then get all 8 bytes of payload decoded
|
||||
xorKey = (uint8_t)bytebits_to_byteLSBF(bits_no_spacer, 8);
|
||||
for (size_t idx = 0; idx < 8; idx++) {
|
||||
ByteStream[idx] = ((uint8_t)bytebits_to_byteLSBF(bits_no_spacer + 8 + (idx * 8), 8)) ^ xorKey;
|
||||
PrintAndLogEx(DEBUG, "DEBUG: gProxII byte %u after xor: %02x", (unsigned int)idx, ByteStream[idx]);
|
||||
}
|
||||
|
||||
setDemodBuff(DemodBuffer, 96, preambleIndex);
|
||||
setClockGrid(g_DemodClock, g_DemodStartIdx + (preambleIndex * g_DemodClock));
|
||||
|
||||
//ByteStream contains 8 Bytes (64 bits) of decrypted raw tag data
|
||||
uint8_t fmtLen = ByteStream[0] >> 2;
|
||||
uint32_t FC = 0;
|
||||
uint32_t Card = 0;
|
||||
//get raw 96 bits to print
|
||||
uint32_t raw1 = bytebits_to_byte(DemodBuffer, 32);
|
||||
uint32_t raw2 = bytebits_to_byte(DemodBuffer + 32, 32);
|
||||
uint32_t raw3 = bytebits_to_byte(DemodBuffer + 64, 32);
|
||||
bool unknown = false;
|
||||
switch (fmtLen) {
|
||||
case 36:
|
||||
FC = ((ByteStream[3] & 0x7F) << 7) | (ByteStream[4] >> 1);
|
||||
Card = ((ByteStream[4] & 1) << 19) | (ByteStream[5] << 11) | (ByteStream[6] << 3) | (ByteStream[7] >> 5);
|
||||
break;
|
||||
case 26:
|
||||
FC = ((ByteStream[3] & 0x7F) << 1) | (ByteStream[4] >> 7);
|
||||
Card = ((ByteStream[4] & 0x7F) << 9) | (ByteStream[5] << 1) | (ByteStream[6] >> 7);
|
||||
break;
|
||||
default :
|
||||
unknown = true;
|
||||
break;
|
||||
}
|
||||
if (!unknown)
|
||||
PrintAndLogEx(SUCCESS, "G-Prox-II Found: Format Len: %ubit - FC: %u - Card: %u, Raw: %08x%08x%08x", fmtLen, FC, Card, raw1, raw2, raw3);
|
||||
else
|
||||
PrintAndLogEx(SUCCESS, "Unknown G-Prox-II Fmt Found: Format Len: %u, Raw: %08x%08x%08x", fmtLen, raw1, raw2, raw3);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int CmdGuardRead(const char *Cmd) {
|
||||
lf_read(true, 10000);
|
||||
return CmdGuardDemod(Cmd);
|
||||
}
|
||||
|
||||
static int CmdGuardClone(const char *Cmd) {
|
||||
|
||||
char cmdp = param_getchar(Cmd, 0);
|
||||
if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_guard_clone();
|
||||
|
||||
uint32_t facilitycode = 0, cardnumber = 0, fc = 0, cn = 0, fmtlen = 0;
|
||||
uint8_t i;
|
||||
uint8_t bs[96];
|
||||
memset(bs, 0x00, sizeof(bs));
|
||||
|
||||
//GuardProxII - compat mode, ASK/Biphase, data rate 64, 3 data blocks
|
||||
uint32_t blocks[4] = {T55x7_MODULATION_BIPHASE | T55x7_BITRATE_RF_64 | 3 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0};
|
||||
|
||||
if (sscanf(Cmd, "%u %u %u", &fmtlen, &fc, &cn) != 3) return usage_lf_guard_clone();
|
||||
|
||||
fmtlen &= 0x7f;
|
||||
facilitycode = (fc & 0x000000FF);
|
||||
cardnumber = (cn & 0x0000FFFF);
|
||||
|
||||
if (!getGuardBits(fmtlen, facilitycode, cardnumber, bs)) {
|
||||
PrintAndLogEx(WARNING, "Error with tag bitstream generation.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Q5
|
||||
if (param_getchar(Cmd, 3) == 'Q' || param_getchar(Cmd, 3) == 'q')
|
||||
blocks[0] = T5555_MODULATION_FSK2 | T5555_SET_BITRATE(50) | 3 << T5555_MAXBLOCK_SHIFT;
|
||||
|
||||
blocks[1] = bytebits_to_byte(bs, 32);
|
||||
blocks[2] = bytebits_to_byte(bs + 32, 32);
|
||||
blocks[3] = bytebits_to_byte(bs + 64, 32);
|
||||
|
||||
PrintAndLogEx(INFO, "Preparing to clone Guardall to T55x7 with Facility Code: %u, Card Number: %u", facilitycode, cardnumber);
|
||||
print_blocks(blocks, 4);
|
||||
|
||||
UsbCommand resp;
|
||||
UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {0, 0, 0}, {{0}}};
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
c.arg[0] = blocks[i];
|
||||
c.arg[1] = i;
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, T55XX_WRITE_TIMEOUT)) {
|
||||
PrintAndLogEx(WARNING, "Error occurred, device did not respond during write operation.");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int CmdGuardSim(const char *Cmd) {
|
||||
|
||||
// Guard uses: clk: 64, invert: 0, encoding: 2 (ASK Biphase)
|
||||
uint8_t clock1 = 64, encoding = 2, separator = 0, invert = 0;
|
||||
uint32_t facilitycode = 0, cardnumber = 0, fc = 0, cn = 0, fmtlen = 0;
|
||||
|
||||
char cmdp = param_getchar(Cmd, 0);
|
||||
if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_guard_sim();
|
||||
|
||||
if (sscanf(Cmd, "%u %u %u", &fmtlen, &fc, &cn) != 3) return usage_lf_guard_sim();
|
||||
|
||||
uint8_t bs[96];
|
||||
size_t size = sizeof(bs);
|
||||
memset(bs, 0x00, size);
|
||||
|
||||
fmtlen &= 0x7F;
|
||||
facilitycode = (fc & 0x000000FF);
|
||||
cardnumber = (cn & 0x0000FFFF);
|
||||
|
||||
if (!getGuardBits(fmtlen, facilitycode, cardnumber, bs)) {
|
||||
PrintAndLogEx(WARNING, "Error with tag bitstream generation.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
PrintAndLogEx(SUCCESS, "Simulating Guardall - Facility Code: %u, CardNumber: %u", facilitycode, cardnumber);
|
||||
|
||||
uint64_t arg1, arg2;
|
||||
arg1 = (clock1 << 8) | encoding;
|
||||
arg2 = (invert << 8) | separator;
|
||||
|
||||
UsbCommand c = {CMD_ASK_SIM_TAG, {arg1, arg2, size}, {{0}}};
|
||||
memcpy(c.d.asBytes, bs, size);
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, 1, "this help"},
|
||||
{"demod", CmdGuardDemod, 1, "demodulate a G Prox II tag from the GraphBuffer"},
|
||||
{"read", CmdGuardRead, 0, "attempt to read and extract tag data from the antenna"},
|
||||
{"clone", CmdGuardClone, 0, "clone Guardall tag"},
|
||||
{"sim", CmdGuardSim, 0, "simulate Guardall tag"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
static int CmdHelp(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdLFGuard(const char *Cmd) {
|
||||
clearCommandBuffer();
|
||||
CmdsParse(CommandTable, Cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// by marshmellow
|
||||
// demod gProxIIDemod
|
||||
// error returns as -x
|
||||
// success returns start position in bitstream
|
||||
// Bitstream must contain previously askrawdemod and biphasedemoded data
|
||||
int detectGProxII(uint8_t *bits, size_t *size) {
|
||||
|
||||
size_t startIdx = 0;
|
||||
uint8_t preamble[] = {1, 1, 1, 1, 1, 0};
|
||||
|
||||
// sanity check
|
||||
if (*size < sizeof(preamble)) return -1;
|
||||
|
||||
if (!preambleSearch(bits, preamble, sizeof(preamble), size, &startIdx))
|
||||
return -2; //preamble not found
|
||||
|
||||
//gProxII should be 96 bits
|
||||
if (*size != 96) return -3;
|
||||
|
||||
//check first 6 spacer bits to verify format
|
||||
if (!bits[startIdx + 5] && !bits[startIdx + 10] && !bits[startIdx + 15] && !bits[startIdx + 20] && !bits[startIdx + 25] && !bits[startIdx + 30]) {
|
||||
//confirmed proper separator bits found
|
||||
//return start position
|
||||
return (int) startIdx;
|
||||
}
|
||||
return -5; //spacer bits not found - not a valid gproxII
|
||||
}
|
||||
|
||||
int demodGuard(void) {
|
||||
return CmdGuardDemod("");
|
||||
}
|
||||
|
||||
// Works for 26bits.
|
||||
int GetGuardBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits) {
|
||||
int getGuardBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits) {
|
||||
|
||||
uint8_t xorKey = 0x66;
|
||||
uint8_t i;
|
||||
|
@ -139,231 +372,3 @@ int GetGuardBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
// by marshmellow
|
||||
// demod gProxIIDemod
|
||||
// error returns as -x
|
||||
// success returns start position in bitstream
|
||||
// Bitstream must contain previously askrawdemod and biphasedemoded data
|
||||
int detectGProxII(uint8_t *bits, size_t *size) {
|
||||
|
||||
size_t startIdx = 0;
|
||||
uint8_t preamble[] = {1, 1, 1, 1, 1, 0};
|
||||
|
||||
// sanity check
|
||||
if (*size < sizeof(preamble)) return -1;
|
||||
|
||||
if (!preambleSearch(bits, preamble, sizeof(preamble), size, &startIdx))
|
||||
return -2; //preamble not found
|
||||
|
||||
//gProxII should be 96 bits
|
||||
if (*size != 96) return -3;
|
||||
|
||||
//check first 6 spacer bits to verify format
|
||||
if (!bits[startIdx + 5] && !bits[startIdx + 10] && !bits[startIdx + 15] && !bits[startIdx + 20] && !bits[startIdx + 25] && !bits[startIdx + 30]) {
|
||||
//confirmed proper separator bits found
|
||||
//return start position
|
||||
return (int) startIdx;
|
||||
}
|
||||
return -5; //spacer bits not found - not a valid gproxII
|
||||
}
|
||||
|
||||
//by marshmellow
|
||||
//attempts to demodulate and identify a G_Prox_II verex/chubb card
|
||||
//WARNING: if it fails during some points it will destroy the DemodBuffer data
|
||||
// but will leave the GraphBuffer intact.
|
||||
//if successful it will push askraw data back to demod buffer ready for emulation
|
||||
int CmdGuardDemod(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
|
||||
//Differential Biphase
|
||||
//get binary from ask wave
|
||||
if (!ASKbiphaseDemod("0 64 0 0", false)) {
|
||||
PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII ASKbiphaseDemod failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t size = DemodBufferLen;
|
||||
|
||||
int preambleIndex = detectGProxII(DemodBuffer, &size);
|
||||
if (preambleIndex < 0) {
|
||||
|
||||
if (preambleIndex == -1)
|
||||
PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII too few bits found");
|
||||
else if (preambleIndex == -2)
|
||||
PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII preamble not found");
|
||||
else if (preambleIndex == -3)
|
||||
PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII size not correct: %d", size);
|
||||
else if (preambleIndex == -5)
|
||||
PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII wrong spacerbits");
|
||||
else
|
||||
PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII ans: %d", preambleIndex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//got a good demod of 96 bits
|
||||
uint8_t ByteStream[8] = {0x00};
|
||||
uint8_t xorKey = 0;
|
||||
size_t startIdx = preambleIndex + 6; //start after 6 bit preamble
|
||||
|
||||
uint8_t bits_no_spacer[90];
|
||||
//so as to not mess with raw DemodBuffer copy to a new sample array
|
||||
memcpy(bits_no_spacer, DemodBuffer + startIdx, 90);
|
||||
// remove the 18 (90/5=18) parity bits (down to 72 bits (96-6-18=72))
|
||||
size_t len = removeParity(bits_no_spacer, 0, 5, 3, 90); //source, startloc, paritylen, ptype, length_to_run
|
||||
if (len != 72) {
|
||||
PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII spacer removal did not produce 72 bits: %u, start: %u", len, startIdx);
|
||||
return 0;
|
||||
}
|
||||
// get key and then get all 8 bytes of payload decoded
|
||||
xorKey = (uint8_t)bytebits_to_byteLSBF(bits_no_spacer, 8);
|
||||
for (size_t idx = 0; idx < 8; idx++) {
|
||||
ByteStream[idx] = ((uint8_t)bytebits_to_byteLSBF(bits_no_spacer + 8 + (idx * 8), 8)) ^ xorKey;
|
||||
PrintAndLogEx(DEBUG, "DEBUG: gProxII byte %u after xor: %02x", (unsigned int)idx, ByteStream[idx]);
|
||||
}
|
||||
|
||||
setDemodBuff(DemodBuffer, 96, preambleIndex);
|
||||
setClockGrid(g_DemodClock, g_DemodStartIdx + (preambleIndex * g_DemodClock));
|
||||
|
||||
//ByteStream contains 8 Bytes (64 bits) of decrypted raw tag data
|
||||
uint8_t fmtLen = ByteStream[0] >> 2;
|
||||
uint32_t FC = 0;
|
||||
uint32_t Card = 0;
|
||||
//get raw 96 bits to print
|
||||
uint32_t raw1 = bytebits_to_byte(DemodBuffer, 32);
|
||||
uint32_t raw2 = bytebits_to_byte(DemodBuffer + 32, 32);
|
||||
uint32_t raw3 = bytebits_to_byte(DemodBuffer + 64, 32);
|
||||
bool unknown = false;
|
||||
switch (fmtLen) {
|
||||
case 36:
|
||||
FC = ((ByteStream[3] & 0x7F) << 7) | (ByteStream[4] >> 1);
|
||||
Card = ((ByteStream[4] & 1) << 19) | (ByteStream[5] << 11) | (ByteStream[6] << 3) | (ByteStream[7] >> 5);
|
||||
break;
|
||||
case 26:
|
||||
FC = ((ByteStream[3] & 0x7F) << 1) | (ByteStream[4] >> 7);
|
||||
Card = ((ByteStream[4] & 0x7F) << 9) | (ByteStream[5] << 1) | (ByteStream[6] >> 7);
|
||||
break;
|
||||
default :
|
||||
unknown = true;
|
||||
break;
|
||||
}
|
||||
if (!unknown)
|
||||
PrintAndLogEx(SUCCESS, "G-Prox-II Found: Format Len: %ubit - FC: %u - Card: %u, Raw: %08x%08x%08x", fmtLen, FC, Card, raw1, raw2, raw3);
|
||||
else
|
||||
PrintAndLogEx(SUCCESS, "Unknown G-Prox-II Fmt Found: Format Len: %u, Raw: %08x%08x%08x", fmtLen, raw1, raw2, raw3);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CmdGuardRead(const char *Cmd) {
|
||||
lf_read(true, 10000);
|
||||
return CmdGuardDemod(Cmd);
|
||||
}
|
||||
|
||||
int CmdGuardClone(const char *Cmd) {
|
||||
|
||||
char cmdp = param_getchar(Cmd, 0);
|
||||
if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_guard_clone();
|
||||
|
||||
uint32_t facilitycode = 0, cardnumber = 0, fc = 0, cn = 0, fmtlen = 0;
|
||||
uint8_t i;
|
||||
uint8_t bs[96];
|
||||
memset(bs, 0x00, sizeof(bs));
|
||||
|
||||
//GuardProxII - compat mode, ASK/Biphase, data rate 64, 3 data blocks
|
||||
uint32_t blocks[4] = {T55x7_MODULATION_BIPHASE | T55x7_BITRATE_RF_64 | 3 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0};
|
||||
|
||||
if (sscanf(Cmd, "%u %u %u", &fmtlen, &fc, &cn) != 3) return usage_lf_guard_clone();
|
||||
|
||||
fmtlen &= 0x7f;
|
||||
facilitycode = (fc & 0x000000FF);
|
||||
cardnumber = (cn & 0x0000FFFF);
|
||||
|
||||
if (!GetGuardBits(fmtlen, facilitycode, cardnumber, bs)) {
|
||||
PrintAndLogEx(WARNING, "Error with tag bitstream generation.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Q5
|
||||
if (param_getchar(Cmd, 3) == 'Q' || param_getchar(Cmd, 3) == 'q')
|
||||
blocks[0] = T5555_MODULATION_FSK2 | T5555_SET_BITRATE(50) | 3 << T5555_MAXBLOCK_SHIFT;
|
||||
|
||||
blocks[1] = bytebits_to_byte(bs, 32);
|
||||
blocks[2] = bytebits_to_byte(bs + 32, 32);
|
||||
blocks[3] = bytebits_to_byte(bs + 64, 32);
|
||||
|
||||
PrintAndLogEx(INFO, "Preparing to clone Guardall to T55x7 with Facility Code: %u, Card Number: %u", facilitycode, cardnumber);
|
||||
print_blocks(blocks, 4);
|
||||
|
||||
UsbCommand resp;
|
||||
UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {0, 0, 0}, {{0}}};
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
c.arg[0] = blocks[i];
|
||||
c.arg[1] = i;
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, T55XX_WRITE_TIMEOUT)) {
|
||||
PrintAndLogEx(WARNING, "Error occurred, device did not respond during write operation.");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdGuardSim(const char *Cmd) {
|
||||
|
||||
// Guard uses: clk: 64, invert: 0, encoding: 2 (ASK Biphase)
|
||||
uint8_t clock1 = 64, encoding = 2, separator = 0, invert = 0;
|
||||
uint32_t facilitycode = 0, cardnumber = 0, fc = 0, cn = 0, fmtlen = 0;
|
||||
|
||||
char cmdp = param_getchar(Cmd, 0);
|
||||
if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_guard_sim();
|
||||
|
||||
if (sscanf(Cmd, "%u %u %u", &fmtlen, &fc, &cn) != 3) return usage_lf_guard_sim();
|
||||
|
||||
uint8_t bs[96];
|
||||
size_t size = sizeof(bs);
|
||||
memset(bs, 0x00, size);
|
||||
|
||||
fmtlen &= 0x7F;
|
||||
facilitycode = (fc & 0x000000FF);
|
||||
cardnumber = (cn & 0x0000FFFF);
|
||||
|
||||
if (!GetGuardBits(fmtlen, facilitycode, cardnumber, bs)) {
|
||||
PrintAndLogEx(WARNING, "Error with tag bitstream generation.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
PrintAndLogEx(SUCCESS, "Simulating Guardall - Facility Code: %u, CardNumber: %u", facilitycode, cardnumber);
|
||||
|
||||
uint64_t arg1, arg2;
|
||||
arg1 = (clock1 << 8) | encoding;
|
||||
arg2 = (invert << 8) | separator;
|
||||
|
||||
UsbCommand c = {CMD_ASK_SIM_TAG, {arg1, arg2, size}, {{0}}};
|
||||
memcpy(c.d.asBytes, bs, size);
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, 1, "this help"},
|
||||
{"demod", CmdGuardDemod, 1, "demodulate a G Prox II tag from the GraphBuffer"},
|
||||
{"read", CmdGuardRead, 0, "attempt to read and extract tag data from the antenna"},
|
||||
{"clone", CmdGuardClone, 0, "clone Guardall tag"},
|
||||
{"sim", CmdGuardSim, 0, "simulate Guardall tag"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
int CmdLFGuard(const char *Cmd) {
|
||||
clearCommandBuffer();
|
||||
CmdsParse(CommandTable, Cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHelp(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -23,9 +23,7 @@
|
|||
#include "crc.h"
|
||||
|
||||
int CmdLFGuard(const char *Cmd);
|
||||
int CmdGuardDemod(const char *Cmd);
|
||||
int CmdGuardRead(const char *Cmd);
|
||||
int CmdGuardClone(const char *Cmd);
|
||||
int CmdGuardSim(const char *Cmd);
|
||||
|
||||
int detectGProxII(uint8_t *bits, size_t *size);
|
||||
int demodGuard(void);
|
||||
int getGuardBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits);
|
||||
#endif
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#endif
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
/*
|
||||
static int usage_lf_hid_read(void) {
|
||||
PrintAndLogEx(NORMAL, "Enables HID compatible reader mode printing details.");
|
||||
PrintAndLogEx(NORMAL, "By default, values are printed and logged until the button is pressed or another USB command is issued.");
|
||||
|
@ -31,6 +31,7 @@ static int usage_lf_hid_read(void) {
|
|||
PrintAndLogEx(NORMAL, " lf hid read 1");
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
static int usage_lf_hid_wiegand(void) {
|
||||
PrintAndLogEx(NORMAL, "This command converts facility code/card number to Wiegand code");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
|
@ -124,7 +125,7 @@ static bool sendTry(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint32_t delay, ui
|
|||
//by marshmellow (based on existing demod + holiman's refactor)
|
||||
//HID Prox demod - FSK RF/50 with preamble of 00011101 (then manchester encoded)
|
||||
//print full HID Prox ID and some bit format details if found
|
||||
int CmdHIDDemod(const char *Cmd) {
|
||||
static int CmdHIDDemod(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
//raw fsk demod no manchester decoding no start bit finding just get binary from wave
|
||||
uint32_t hi2 = 0, hi = 0, lo = 0;
|
||||
|
@ -230,14 +231,14 @@ int CmdHIDDemod(const char *Cmd) {
|
|||
}
|
||||
|
||||
// this read is the "normal" read, which download lf signal and tries to demod here.
|
||||
int CmdHIDRead(const char *Cmd) {
|
||||
static int CmdHIDRead(const char *Cmd) {
|
||||
lf_read(true, 12000);
|
||||
return CmdHIDDemod(Cmd);
|
||||
}
|
||||
|
||||
/*
|
||||
// this read loops on device side.
|
||||
// uses the demod in lfops.c
|
||||
int CmdHIDRead_device(const char *Cmd) {
|
||||
static int CmdHIDRead_device(const char *Cmd) {
|
||||
|
||||
if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_hid_read();
|
||||
uint8_t findone = (Cmd[0] == '1') ? 1 : 0;
|
||||
|
@ -246,8 +247,8 @@ int CmdHIDRead_device(const char *Cmd) {
|
|||
SendCommand(&c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHIDSim(const char *Cmd) {
|
||||
*/
|
||||
static int CmdHIDSim(const char *Cmd) {
|
||||
uint32_t hi = 0, lo = 0;
|
||||
uint32_t n = 0, i = 0;
|
||||
|
||||
|
@ -268,7 +269,7 @@ int CmdHIDSim(const char *Cmd) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int CmdHIDClone(const char *Cmd) {
|
||||
static int CmdHIDClone(const char *Cmd) {
|
||||
|
||||
uint32_t hi2 = 0, hi = 0, lo = 0;
|
||||
uint32_t n = 0, i = 0;
|
||||
|
@ -473,7 +474,7 @@ void calcWiegand(uint8_t fmtlen, uint16_t fc, uint64_t cardno, uint8_t *bits, ui
|
|||
}
|
||||
}
|
||||
|
||||
int CmdHIDWiegand(const char *Cmd) {
|
||||
static int CmdHIDWiegand(const char *Cmd) {
|
||||
uint32_t oem = 0, fc = 0;
|
||||
uint64_t cardnum = 0;
|
||||
uint8_t bits[BITS] = {0};
|
||||
|
@ -515,7 +516,7 @@ int CmdHIDWiegand(const char *Cmd) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int CmdHIDBrute(const char *Cmd) {
|
||||
static int CmdHIDBrute(const char *Cmd) {
|
||||
|
||||
bool errors = false, verbose = false;
|
||||
uint32_t fc = 0, cn = 0, delay = 1000;
|
||||
|
@ -615,14 +616,18 @@ static command_t CommandTable[] = {
|
|||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
static int CmdHelp(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdLFHID(const char *Cmd) {
|
||||
clearCommandBuffer();
|
||||
CmdsParse(CommandTable, Cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHelp(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
int demodHID(void) {
|
||||
return CmdHIDDemod("");
|
||||
}
|
||||
|
|
|
@ -25,13 +25,8 @@
|
|||
#include "lfdemod.h"
|
||||
|
||||
int CmdLFHID(const char *Cmd);
|
||||
int CmdHIDDemod(const char *Cmd);
|
||||
int CmdHIDRead(const char *Cmd);
|
||||
int CmdHIDSim(const char *Cmd);
|
||||
int CmdHIDClone(const char *Cmd);
|
||||
int CmdHIDWiegand(const char *Cmd);
|
||||
int CmdHIDBrute(const char *Cmd);
|
||||
|
||||
int demodHID(void);
|
||||
//void calc26(uint16_t fc, uint32_t cardno, uint8_t *out);
|
||||
void calcWiegand(uint8_t fmtlen, uint16_t fc, uint64_t cardno, uint8_t *bits, uint8_t oem);
|
||||
#endif
|
||||
|
|
|
@ -64,6 +64,7 @@ static int usage_hitag_info(void) {
|
|||
PrintAndLogEx(NORMAL, " lf hitag info");
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
static int usage_hitag_dump(void) {
|
||||
PrintAndLogEx(NORMAL, "Usage: lf hitag dump [h] p <pwd> f <name>");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
|
@ -76,6 +77,7 @@ static int usage_hitag_dump(void) {
|
|||
PrintAndLogEx(NORMAL, " lf hitag dump p 4D494B52 f mydump");
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
static int usage_hitag_reader(void) {
|
||||
PrintAndLogEx(NORMAL, "Hitag reader functions");
|
||||
PrintAndLogEx(NORMAL, "Usage: lf hitag reader [h] <reader function #>");
|
||||
|
@ -120,7 +122,7 @@ static int usage_hitag_checkchallenges(void) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int CmdLFHitagList(const char *Cmd) {
|
||||
static int CmdLFHitagList(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CmdTraceList("hitag");
|
||||
return 0;
|
||||
|
@ -253,7 +255,7 @@ int CmdLFHitagList(const char *Cmd) {
|
|||
*/
|
||||
}
|
||||
|
||||
int CmdLFHitagSniff(const char *Cmd) {
|
||||
static int CmdLFHitagSniff(const char *Cmd) {
|
||||
|
||||
char ctmp = tolower(param_getchar(Cmd, 0));
|
||||
if (ctmp == 'h') return usage_hitag_sniff();
|
||||
|
@ -264,7 +266,7 @@ int CmdLFHitagSniff(const char *Cmd) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int CmdLFHitagSim(const char *Cmd) {
|
||||
static int CmdLFHitagSim(const char *Cmd) {
|
||||
|
||||
bool errors = false;
|
||||
bool tag_mem_supplied = false;
|
||||
|
@ -476,7 +478,7 @@ static bool getHitagUid(uint32_t *uid) {
|
|||
return true;
|
||||
}
|
||||
|
||||
int CmdLFHitagInfo(const char *Cmd) {
|
||||
static int CmdLFHitagInfo(const char *Cmd) {
|
||||
PrintAndLogEx(INFO, "Hitag2 tag information ");
|
||||
PrintAndLogEx(INFO, "To be done!");
|
||||
PrintAndLogEx(INFO, "------------------------------------");
|
||||
|
@ -509,7 +511,7 @@ int CmdLFHitagInfo(const char *Cmd) {
|
|||
// TODO: iceman
|
||||
// Hitag2 reader, problem is that this command mixes up stuff. So 26 give uid. 21 etc will also give you a memory dump !?
|
||||
//
|
||||
int CmdLFHitagReader(const char *Cmd) {
|
||||
static int CmdLFHitagReader(const char *Cmd) {
|
||||
|
||||
UsbCommand c = {CMD_READER_HITAG, {0, 0, 0}, {{0}}};
|
||||
hitag_data *htd = (hitag_data *)c.d.asBytes;
|
||||
|
@ -590,7 +592,7 @@ int CmdLFHitagReader(const char *Cmd) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int CmdLFHitagCheckChallenges(const char *Cmd) {
|
||||
static int CmdLFHitagCheckChallenges(const char *Cmd) {
|
||||
|
||||
UsbCommand c = { CMD_TEST_HITAGS_TRACES, {0, 0, 0}, {{0}}};
|
||||
char filename[FILE_PATH_SIZE] = { 0x00 };
|
||||
|
@ -640,7 +642,7 @@ int CmdLFHitagCheckChallenges(const char *Cmd) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int CmdLFHitagWriter(const char *Cmd) {
|
||||
static int CmdLFHitagWriter(const char *Cmd) {
|
||||
UsbCommand c = { CMD_WR_HITAG_S, {0, 0, 0}, {{0}}};
|
||||
hitag_data *htd = (hitag_data *)c.d.asBytes;
|
||||
hitag_function htf = param_get32ex(Cmd, 0, 0, 10);
|
||||
|
@ -681,7 +683,8 @@ int CmdLFHitagWriter(const char *Cmd) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int CmdLFHitagDump(const char *Cmd) {
|
||||
/*
|
||||
static int CmdLFHitagDump(const char *Cmd) {
|
||||
PrintAndLogEx(INFO, "Dumping of tag memory");
|
||||
PrintAndLogEx(INFO, "To be done!");
|
||||
|
||||
|
@ -689,6 +692,7 @@ int CmdLFHitagDump(const char *Cmd) {
|
|||
if (ctmp == 'h') return usage_hitag_dump();
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, 1, "This help" },
|
||||
|
@ -702,14 +706,18 @@ static command_t CommandTable[] = {
|
|||
{ NULL, NULL, 0, NULL }
|
||||
};
|
||||
|
||||
static int CmdHelp(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdLFHitag(const char *Cmd) {
|
||||
clearCommandBuffer();
|
||||
CmdsParse(CommandTable, Cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHelp(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
int readHitagUid(void) {
|
||||
return CmdLFHitagReader("26") == 0;
|
||||
}
|
||||
|
|
|
@ -13,13 +13,6 @@
|
|||
|
||||
int CmdLFHitag(const char *Cmd);
|
||||
|
||||
int CmdLFHitagList(const char *Cmd);
|
||||
int CmdLFHitagSniff(const char *Cmd);
|
||||
int CmdLFHitagSim(const char *Cmd);
|
||||
int CmdLFHitagInfo(const char *Cmd);
|
||||
int CmdLFHitagReader(const char *Cmd);
|
||||
int CmdLFHitagCheckChallenges(const char *Cmd);
|
||||
int CmdLFHitagWriter(const char *Cmd);
|
||||
int CmdLFHitagDump(const char *Cmd);
|
||||
int readHitagUid(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -50,126 +50,10 @@ static int usage_lf_indala_sim(void) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
// redesigned by marshmellow adjusted from existing decode functions
|
||||
// indala id decoding
|
||||
static int detectIndala(uint8_t *dest, size_t *size, uint8_t *invert) {
|
||||
|
||||
uint8_t preamble64_i[] = {0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0};
|
||||
uint8_t preamble224_i[] = {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0};
|
||||
|
||||
size_t idx = 0;
|
||||
size_t found_size = *size;
|
||||
|
||||
// PSK1
|
||||
bool res = preambleSearch(dest, preamble64, sizeof(preamble64), &found_size, &idx);
|
||||
if (res) {
|
||||
PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK1 found 64");
|
||||
goto out;
|
||||
}
|
||||
idx = 0;
|
||||
found_size = *size;
|
||||
res = preambleSearch(dest, preamble64_i, sizeof(preamble64_i), &found_size, &idx);
|
||||
if (res) {
|
||||
PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK1 found 64 inverted preamble");
|
||||
goto inv;
|
||||
}
|
||||
|
||||
/*
|
||||
idx = 0;
|
||||
found_size = *size;
|
||||
res = preambleSearch(dest, preamble224, sizeof(preamble224), &found_size, &idx);
|
||||
if ( res ) {
|
||||
PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK1 found 224");
|
||||
goto out;
|
||||
}
|
||||
|
||||
idx = 0;
|
||||
found_size = *size;
|
||||
res = preambleSearch(dest, preamble224_i, sizeof(preamble224_i), &found_size, &idx);
|
||||
if ( res ) {
|
||||
PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK1 found 224 inverted preamble");
|
||||
goto inv;
|
||||
}
|
||||
*/
|
||||
|
||||
// PSK2
|
||||
psk1TOpsk2(dest, *size);
|
||||
PrintAndLogEx(DEBUG, "DEBUG: detectindala Converting PSK1 -> PSK2");
|
||||
|
||||
idx = 0;
|
||||
found_size = *size;
|
||||
res = preambleSearch(dest, preamble64, sizeof(preamble64), &found_size, &idx);
|
||||
if (res) {
|
||||
PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK2 found 64 preamble");
|
||||
goto out;
|
||||
}
|
||||
|
||||
idx = 0;
|
||||
found_size = *size;
|
||||
res = preambleSearch(dest, preamble224, sizeof(preamble224), &found_size, &idx);
|
||||
if (res) {
|
||||
PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK2 found 224 preamble");
|
||||
goto out;
|
||||
}
|
||||
|
||||
idx = 0;
|
||||
found_size = *size;
|
||||
res = preambleSearch(dest, preamble64_i, sizeof(preamble64_i), &found_size, &idx);
|
||||
if (res) {
|
||||
PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK2 found 64 inverted preamble");
|
||||
goto inv;
|
||||
}
|
||||
|
||||
idx = 0;
|
||||
found_size = *size;
|
||||
res = preambleSearch(dest, preamble224_i, sizeof(preamble224_i), &found_size, &idx);
|
||||
if (res) {
|
||||
PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK2 found 224 inverted preamble");
|
||||
goto inv;
|
||||
}
|
||||
|
||||
inv:
|
||||
if (res == 0) {
|
||||
return -4;
|
||||
}
|
||||
|
||||
*invert ^= 1;
|
||||
|
||||
if (*invert && idx > 0) {
|
||||
for (size_t i = idx - 1; i < found_size + idx + 2; i++) {
|
||||
dest[i] ^= 1;
|
||||
}
|
||||
}
|
||||
|
||||
PrintAndLogEx(DEBUG, "DEBUG: Warning - Indala had to invert bits");
|
||||
|
||||
out:
|
||||
|
||||
*size = found_size;
|
||||
|
||||
//PrintAndLogEx(INFO, "DEBUG: detectindala RES = %d | %d | %d", res, found_size, idx);
|
||||
|
||||
if (found_size != 224 && found_size != 64) {
|
||||
PrintAndLogEx(INFO, "DEBUG: detectindala | %d", found_size);
|
||||
return -5;
|
||||
}
|
||||
|
||||
// 224 formats are typically PSK2 (afaik 2017 Marshmellow)
|
||||
// note loses 1 bit at beginning of transformation...
|
||||
return (int) idx;
|
||||
|
||||
}
|
||||
|
||||
// this read is the "normal" read, which download lf signal and tries to demod here.
|
||||
int CmdIndalaRead(const char *Cmd) {
|
||||
lf_read(true, 30000);
|
||||
return CmdIndalaDemod(Cmd);
|
||||
}
|
||||
|
||||
// Indala 26 bit decode
|
||||
// by marshmellow
|
||||
// optional arguments - same as PSKDemod (clock & invert & maxerr)
|
||||
int CmdIndalaDemod(const char *Cmd) {
|
||||
static int CmdIndalaDemod(const char *Cmd) {
|
||||
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (cmdp == 'h') return usage_lf_indala_demod();
|
||||
|
@ -283,7 +167,7 @@ int CmdIndalaDemod(const char *Cmd) {
|
|||
// returns false positives more often - but runs against more sets of samples
|
||||
// poor psk signal can be difficult to demod this approach might succeed when the other fails
|
||||
// but the other appears to currently be more accurate than this approach most of the time.
|
||||
int CmdIndalaDemodAlt(const char *Cmd) {
|
||||
static int CmdIndalaDemodAlt(const char *Cmd) {
|
||||
// Usage: recover 64bit UID by default, specify "224" as arg to recover a 224bit UID
|
||||
int state = -1;
|
||||
int count = 0;
|
||||
|
@ -477,7 +361,13 @@ int CmdIndalaDemodAlt(const char *Cmd) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int CmdIndalaSim(const char *Cmd) {
|
||||
// this read is the "normal" read, which download lf signal and tries to demod here.
|
||||
static int CmdIndalaRead(const char *Cmd) {
|
||||
lf_read(true, 30000);
|
||||
return CmdIndalaDemod(Cmd);
|
||||
}
|
||||
|
||||
static int CmdIndalaSim(const char *Cmd) {
|
||||
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_indala_sim();
|
||||
|
@ -522,7 +412,7 @@ int CmdIndalaSim(const char *Cmd) {
|
|||
}
|
||||
|
||||
// iceman - needs refactoring
|
||||
int CmdIndalaClone(const char *Cmd) {
|
||||
static int CmdIndalaClone(const char *Cmd) {
|
||||
|
||||
bool isLongUid = false;
|
||||
uint8_t data[7 * 4];
|
||||
|
@ -582,14 +472,128 @@ static command_t CommandTable[] = {
|
|||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
static int CmdHelp(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdLFINDALA(const char *Cmd) {
|
||||
clearCommandBuffer();
|
||||
CmdsParse(CommandTable, Cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHelp(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
// redesigned by marshmellow adjusted from existing decode functions
|
||||
// indala id decoding
|
||||
int detectIndala(uint8_t *dest, size_t *size, uint8_t *invert) {
|
||||
|
||||
uint8_t preamble64_i[] = {0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0};
|
||||
uint8_t preamble224_i[] = {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0};
|
||||
|
||||
size_t idx = 0;
|
||||
size_t found_size = *size;
|
||||
|
||||
// PSK1
|
||||
bool res = preambleSearch(dest, preamble64, sizeof(preamble64), &found_size, &idx);
|
||||
if (res) {
|
||||
PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK1 found 64");
|
||||
goto out;
|
||||
}
|
||||
idx = 0;
|
||||
found_size = *size;
|
||||
res = preambleSearch(dest, preamble64_i, sizeof(preamble64_i), &found_size, &idx);
|
||||
if (res) {
|
||||
PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK1 found 64 inverted preamble");
|
||||
goto inv;
|
||||
}
|
||||
|
||||
/*
|
||||
idx = 0;
|
||||
found_size = *size;
|
||||
res = preambleSearch(dest, preamble224, sizeof(preamble224), &found_size, &idx);
|
||||
if ( res ) {
|
||||
PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK1 found 224");
|
||||
goto out;
|
||||
}
|
||||
|
||||
idx = 0;
|
||||
found_size = *size;
|
||||
res = preambleSearch(dest, preamble224_i, sizeof(preamble224_i), &found_size, &idx);
|
||||
if ( res ) {
|
||||
PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK1 found 224 inverted preamble");
|
||||
goto inv;
|
||||
}
|
||||
*/
|
||||
|
||||
// PSK2
|
||||
psk1TOpsk2(dest, *size);
|
||||
PrintAndLogEx(DEBUG, "DEBUG: detectindala Converting PSK1 -> PSK2");
|
||||
|
||||
idx = 0;
|
||||
found_size = *size;
|
||||
res = preambleSearch(dest, preamble64, sizeof(preamble64), &found_size, &idx);
|
||||
if (res) {
|
||||
PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK2 found 64 preamble");
|
||||
goto out;
|
||||
}
|
||||
|
||||
idx = 0;
|
||||
found_size = *size;
|
||||
res = preambleSearch(dest, preamble224, sizeof(preamble224), &found_size, &idx);
|
||||
if (res) {
|
||||
PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK2 found 224 preamble");
|
||||
goto out;
|
||||
}
|
||||
|
||||
idx = 0;
|
||||
found_size = *size;
|
||||
res = preambleSearch(dest, preamble64_i, sizeof(preamble64_i), &found_size, &idx);
|
||||
if (res) {
|
||||
PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK2 found 64 inverted preamble");
|
||||
goto inv;
|
||||
}
|
||||
|
||||
idx = 0;
|
||||
found_size = *size;
|
||||
res = preambleSearch(dest, preamble224_i, sizeof(preamble224_i), &found_size, &idx);
|
||||
if (res) {
|
||||
PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK2 found 224 inverted preamble");
|
||||
goto inv;
|
||||
}
|
||||
|
||||
inv:
|
||||
if (res == 0) {
|
||||
return -4;
|
||||
}
|
||||
|
||||
*invert ^= 1;
|
||||
|
||||
if (*invert && idx > 0) {
|
||||
for (size_t i = idx - 1; i < found_size + idx + 2; i++) {
|
||||
dest[i] ^= 1;
|
||||
}
|
||||
}
|
||||
|
||||
PrintAndLogEx(DEBUG, "DEBUG: Warning - Indala had to invert bits");
|
||||
|
||||
out:
|
||||
|
||||
*size = found_size;
|
||||
|
||||
//PrintAndLogEx(INFO, "DEBUG: detectindala RES = %d | %d | %d", res, found_size, idx);
|
||||
|
||||
if (found_size != 224 && found_size != 64) {
|
||||
PrintAndLogEx(INFO, "DEBUG: detectindala | %d", found_size);
|
||||
return -5;
|
||||
}
|
||||
|
||||
// 224 formats are typically PSK2 (afaik 2017 Marshmellow)
|
||||
// note loses 1 bit at beginning of transformation...
|
||||
return (int) idx;
|
||||
|
||||
}
|
||||
|
||||
int demodIndala(void) {
|
||||
return CmdIndalaDemod("");
|
||||
}
|
||||
|
|
|
@ -25,14 +25,10 @@
|
|||
|
||||
int CmdLFINDALA(const char *Cmd);
|
||||
|
||||
int CmdIndalaDemod(const char *Cmd);
|
||||
int CmdIndalaDemodAlt(const char *Cmd);
|
||||
int CmdIndalaRead(const char *Cmd);
|
||||
int CmdIndalaClone(const char *Cmd);
|
||||
int CmdIndalaSim(const char *Cmd);
|
||||
|
||||
int detectIndala(uint8_t *dest, size_t *size, uint8_t *invert);
|
||||
int detectIndala26(uint8_t *bitStream, size_t *size, uint8_t *invert);
|
||||
int detectIndala64(uint8_t *bitStream, size_t *size, uint8_t *invert);
|
||||
int detectIndala224(uint8_t *bitStream, size_t *size, uint8_t *invert);
|
||||
int demodIndala(void);
|
||||
|
||||
#endif
|
||||
|
|
243
client/cmdlfio.c
243
client/cmdlfio.c
|
@ -11,7 +11,7 @@
|
|||
#include "cmdlfio.h"
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
/*
|
||||
static int usage_lf_io_read(void) {
|
||||
PrintAndLogEx(NORMAL, "Enables IOProx compatible reader mode printing details of scanned tags.");
|
||||
PrintAndLogEx(NORMAL, "By default, values are printed and logged until the button is pressed or another USB command is issued.");
|
||||
|
@ -27,7 +27,7 @@ static int usage_lf_io_read(void) {
|
|||
PrintAndLogEx(NORMAL, " lf io read 1");
|
||||
return 0;
|
||||
}
|
||||
|
||||
*/
|
||||
static int usage_lf_io_sim(void) {
|
||||
PrintAndLogEx(NORMAL, "Enables simulation of IOProx card with specified facility-code and card number.");
|
||||
PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued.");
|
||||
|
@ -60,15 +60,10 @@ static int usage_lf_io_clone(void) {
|
|||
PrintAndLogEx(NORMAL, " lf io clone 26 101 1337");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// this read is the "normal" read, which download lf signal and tries to demod here.
|
||||
int CmdIOProxRead(const char *Cmd) {
|
||||
lf_read(true, 12000);
|
||||
return CmdIOProxDemod(Cmd);
|
||||
}
|
||||
/*
|
||||
// this read loops on device side.
|
||||
// uses the demod in lfops.c
|
||||
int CmdIOProxRead_device(const char *Cmd) {
|
||||
static int CmdIOProxRead_device(const char *Cmd) {
|
||||
if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_io_read();
|
||||
int findone = (Cmd[0] == '1') ? 1 : 0;
|
||||
UsbCommand c = {CMD_IO_DEMOD_FSK, {findone, 0, 0}, {{0}}};
|
||||
|
@ -76,11 +71,11 @@ int CmdIOProxRead_device(const char *Cmd) {
|
|||
SendCommand(&c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*/
|
||||
//by marshmellow
|
||||
//IO-Prox demod - FSK RF/64 with preamble of 000000001
|
||||
//print ioprox ID and some format details
|
||||
int CmdIOProxDemod(const char *Cmd) {
|
||||
static int CmdIOProxDemod(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
int retval = 0;
|
||||
int idx = 0;
|
||||
|
@ -177,6 +172,124 @@ int CmdIOProxDemod(const char *Cmd) {
|
|||
return retval;
|
||||
}
|
||||
|
||||
// this read is the "normal" read, which download lf signal and tries to demod here.
|
||||
static int CmdIOProxRead(const char *Cmd) {
|
||||
lf_read(true, 12000);
|
||||
return CmdIOProxDemod(Cmd);
|
||||
}
|
||||
static int CmdIOProxSim(const char *Cmd) {
|
||||
uint16_t cn = 0;
|
||||
uint8_t version = 0, fc = 0;
|
||||
uint8_t bits[64];
|
||||
size_t size = sizeof(bits);
|
||||
memset(bits, 0x00, size);
|
||||
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_io_sim();
|
||||
|
||||
version = param_get8(Cmd, 0);
|
||||
fc = param_get8(Cmd, 1);
|
||||
cn = param_get32ex(Cmd, 2, 0, 10);
|
||||
|
||||
if (!version || !fc || !cn) return usage_lf_io_sim();
|
||||
|
||||
if ((cn & 0xFFFF) != cn) {
|
||||
cn &= 0xFFFF;
|
||||
PrintAndLogEx(INFO, "Card Number Truncated to 16-bits (IOProx): %u", cn);
|
||||
}
|
||||
|
||||
// clock 64, FSK2a fcHIGH 10 | fcLOW 8
|
||||
uint8_t clk = 64, invert = 1, high = 10, low = 8;
|
||||
uint16_t arg1, arg2;
|
||||
arg1 = high << 8 | low;
|
||||
arg2 = invert << 8 | clk;
|
||||
|
||||
PrintAndLogEx(SUCCESS, "Simulating IOProx version: %u FC: %u; CN: %u\n", version, fc, cn);
|
||||
PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation or run another command");
|
||||
|
||||
if (!getIOProxBits(version, fc, cn, bits)) {
|
||||
PrintAndLogEx(WARNING, "Error with tag bitstream generation.");
|
||||
return 1;
|
||||
}
|
||||
// IOProx uses: fcHigh: 10, fcLow: 8, clk: 64, invert: 1
|
||||
// arg1 --- fcHigh<<8 + fcLow
|
||||
// arg2 --- Invert and clk setting
|
||||
// size --- 64 bits == 8 bytes
|
||||
UsbCommand c = {CMD_FSK_SIM_TAG, {arg1, arg2, size}, {{0}}};
|
||||
memcpy(c.d.asBytes, bits, size);
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int CmdIOProxClone(const char *Cmd) {
|
||||
|
||||
uint32_t blocks[3] = {T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_64 | 2 << T55x7_MAXBLOCK_SHIFT, 0, 0};
|
||||
uint16_t cn = 0;
|
||||
uint8_t version = 0, fc = 0;
|
||||
uint8_t bits[64];
|
||||
memset(bits, 0, sizeof(bits));
|
||||
|
||||
char cmdp = param_getchar(Cmd, 0);
|
||||
if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_io_clone();
|
||||
|
||||
version = param_get8(Cmd, 0);
|
||||
fc = param_get8(Cmd, 1);
|
||||
cn = param_get32ex(Cmd, 2, 0, 10);
|
||||
|
||||
if (!version || !fc || !cn) return usage_lf_io_clone();
|
||||
|
||||
if ((cn & 0xFFFF) != cn) {
|
||||
cn &= 0xFFFF;
|
||||
PrintAndLogEx(INFO, "Card Number Truncated to 16-bits (IOProx): %u", cn);
|
||||
}
|
||||
|
||||
if (!getIOProxBits(version, fc, cn, bits)) {
|
||||
PrintAndLogEx(WARNING, "Error with tag bitstream generation.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (param_getchar(Cmd, 3) == 'Q' || param_getchar(Cmd, 3) == 'q')
|
||||
blocks[0] = T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | T5555_SET_BITRATE(64) | 2 << T5555_MAXBLOCK_SHIFT;
|
||||
|
||||
blocks[1] = bytebits_to_byte(bits, 32);
|
||||
blocks[2] = bytebits_to_byte(bits + 32, 32);
|
||||
|
||||
PrintAndLogEx(INFO, "Preparing to clone IOProx to T55x7 with Version: %u FC: %u, CN: %u", version, fc, cn);
|
||||
print_blocks(blocks, 3);
|
||||
|
||||
//UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {0,0,0}, {{0}}};
|
||||
UsbCommand c = {CMD_IO_CLONE_TAG, {blocks[1], blocks[2], 0}, {{0}}};
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, 1, "this help"},
|
||||
{"demod", CmdIOProxDemod, 1, "demodulate an IOProx tag from the GraphBuffer"},
|
||||
{"read", CmdIOProxRead, 1, "attempt to read and extract tag data"},
|
||||
{"clone", CmdIOProxClone, 0, "clone IOProx to T55x7"},
|
||||
{"sim", CmdIOProxSim, 0, "simulate IOProx tag"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
static int CmdHelp(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdLFIO(const char *Cmd) {
|
||||
clearCommandBuffer();
|
||||
CmdsParse(CommandTable, Cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int demodIOProx(void) {
|
||||
return CmdIOProxDemod("");
|
||||
}
|
||||
|
||||
//Index map
|
||||
//0 10 20 30 40 50 60
|
||||
//| | | | | | |
|
||||
|
@ -244,111 +357,3 @@ int getIOProxBits(uint8_t version, uint8_t fc, uint16_t cn, uint8_t *bits) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int CmdIOProxSim(const char *Cmd) {
|
||||
uint16_t cn = 0;
|
||||
uint8_t version = 0, fc = 0;
|
||||
uint8_t bits[64];
|
||||
size_t size = sizeof(bits);
|
||||
memset(bits, 0x00, size);
|
||||
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_io_sim();
|
||||
|
||||
version = param_get8(Cmd, 0);
|
||||
fc = param_get8(Cmd, 1);
|
||||
cn = param_get32ex(Cmd, 2, 0, 10);
|
||||
|
||||
if (!version || !fc || !cn) return usage_lf_io_sim();
|
||||
|
||||
if ((cn & 0xFFFF) != cn) {
|
||||
cn &= 0xFFFF;
|
||||
PrintAndLogEx(INFO, "Card Number Truncated to 16-bits (IOProx): %u", cn);
|
||||
}
|
||||
|
||||
// clock 64, FSK2a fcHIGH 10 | fcLOW 8
|
||||
uint8_t clk = 64, invert = 1, high = 10, low = 8;
|
||||
uint16_t arg1, arg2;
|
||||
arg1 = high << 8 | low;
|
||||
arg2 = invert << 8 | clk;
|
||||
|
||||
PrintAndLogEx(SUCCESS, "Simulating IOProx version: %u FC: %u; CN: %u\n", version, fc, cn);
|
||||
PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation or run another command");
|
||||
|
||||
if (!getIOProxBits(version, fc, cn, bits)) {
|
||||
PrintAndLogEx(WARNING, "Error with tag bitstream generation.");
|
||||
return 1;
|
||||
}
|
||||
// IOProx uses: fcHigh: 10, fcLow: 8, clk: 64, invert: 1
|
||||
// arg1 --- fcHigh<<8 + fcLow
|
||||
// arg2 --- Invert and clk setting
|
||||
// size --- 64 bits == 8 bytes
|
||||
UsbCommand c = {CMD_FSK_SIM_TAG, {arg1, arg2, size}, {{0}}};
|
||||
memcpy(c.d.asBytes, bits, size);
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdIOProxClone(const char *Cmd) {
|
||||
|
||||
uint32_t blocks[3] = {T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_64 | 2 << T55x7_MAXBLOCK_SHIFT, 0, 0};
|
||||
uint16_t cn = 0;
|
||||
uint8_t version = 0, fc = 0;
|
||||
uint8_t bits[64];
|
||||
memset(bits, 0, sizeof(bits));
|
||||
|
||||
char cmdp = param_getchar(Cmd, 0);
|
||||
if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_io_clone();
|
||||
|
||||
version = param_get8(Cmd, 0);
|
||||
fc = param_get8(Cmd, 1);
|
||||
cn = param_get32ex(Cmd, 2, 0, 10);
|
||||
|
||||
if (!version || !fc || !cn) return usage_lf_io_clone();
|
||||
|
||||
if ((cn & 0xFFFF) != cn) {
|
||||
cn &= 0xFFFF;
|
||||
PrintAndLogEx(INFO, "Card Number Truncated to 16-bits (IOProx): %u", cn);
|
||||
}
|
||||
|
||||
if (!getIOProxBits(version, fc, cn, bits)) {
|
||||
PrintAndLogEx(WARNING, "Error with tag bitstream generation.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (param_getchar(Cmd, 3) == 'Q' || param_getchar(Cmd, 3) == 'q')
|
||||
blocks[0] = T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | T5555_SET_BITRATE(64) | 2 << T5555_MAXBLOCK_SHIFT;
|
||||
|
||||
blocks[1] = bytebits_to_byte(bits, 32);
|
||||
blocks[2] = bytebits_to_byte(bits + 32, 32);
|
||||
|
||||
PrintAndLogEx(INFO, "Preparing to clone IOProx to T55x7 with Version: %u FC: %u, CN: %u", version, fc, cn);
|
||||
print_blocks(blocks, 3);
|
||||
|
||||
//UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {0,0,0}, {{0}}};
|
||||
UsbCommand c = {CMD_IO_CLONE_TAG, {blocks[1], blocks[2], 0}, {{0}}};
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, 1, "this help"},
|
||||
{"demod", CmdIOProxDemod, 1, "demodulate an IOProx tag from the GraphBuffer"},
|
||||
{"read", CmdIOProxRead, 1, "attempt to read and extract tag data"},
|
||||
{"clone", CmdIOProxClone, 0, "clone IOProx to T55x7"},
|
||||
{"sim", CmdIOProxSim, 0, "simulate IOProx tag"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
int CmdLFIO(const char *Cmd) {
|
||||
clearCommandBuffer();
|
||||
CmdsParse(CommandTable, Cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHelp(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -17,11 +17,8 @@
|
|||
#include "cmddata.h"
|
||||
|
||||
int CmdLFIO(const char *Cmd);
|
||||
int CmdIOProxDemod(const char *Cmd);
|
||||
int CmdIOProxRead(const char *Cmd);
|
||||
int CmdIOProxSim(const char *Cmd);
|
||||
int CmdIOProxClone(const char *Cmd);
|
||||
|
||||
int demodIOProx(void);
|
||||
int getIOProxBits(uint8_t version, uint8_t fc, uint16_t cn, uint8_t *bits);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue