added @marshmellows new viking demod.

adjusted it to fit with the clone/demod  that is under  "lf viking" commands.

did some code clean up,  3spaces into tab.
This commit is contained in:
iceman1001
2015-11-10 11:42:59 +01:00
parent 4db2af08cd
commit 70459879e9
10 changed files with 273 additions and 300 deletions

View File

@@ -1250,7 +1250,7 @@ int CmdFSKdemodAWID(const char *Cmd)
// | | | | | | |
// 01234567 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 - to 96
// -----------------------------------------------------------------------------
// 00000001 000 1 110 1 101 1 011 1 1 d01 1 010 0 000 1 000 1 010 0 001 0 110 1 100 0 000 1 000 1
// 00000001 000 1 110 1 101 1 011 1 101 1 010 0 000 1 000 1 010 0 001 0 110 1 100 0 000 1 000 1
// premable bbb o bbb o bbw o fff o fff o ffc o ccc o ccc o ccc o ccc o ccc o wxx o xxx o xxx o - to 96
// |---26 bit---| |-----117----||-------------142-------------|
// b = format bit len, o = odd parity of last 3 bits
@@ -1419,7 +1419,6 @@ int CmdFSKdemodPyramid(const char *Cmd)
uint32_t fc = 0;
uint32_t cardnum = 0;
uint32_t code1 = 0;
//uint32_t code2 = 0;
if (fmtLen==26){
fc = bytebits_to_byte(BitStream+73, 8);
cardnum = bytebits_to_byte(BitStream+81, 16);
@@ -1878,54 +1877,6 @@ int CmdRawDemod(const char *Cmd)
return ans;
}
int AmVikingDecode(const uint8_t *id){
// searching the buffer for the id
//uint8_t id_bits[32];
// convert 4 bytes of id to 32 bits present in 32 bytes data;
//bytes_to_bits(id,4,id_bits,sizeof(id_bits));
//print_arraybinary(id_bits,sizeof(id_bits));
PrintAndLog(" binary: %s", printBits(4, id) );
//size_t idx = 0;
size_t BitLen = DemodBufferLen;
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
memcpy(BitStream, DemodBuffer, BitLen);
// if (VikingDecode(BitStream,BitLen,&idx,id_bits,sizeof(id_bits)) == 1)
// {
// setDemodBuf(BitStream,64, idx);
// PrintAndLog("Found Viking tag\n");
// CmdPrintDemodBuff("x");
// }
// else
// {
// PrintAndLog("Not found Viking tag\n");
// }
return 0;
}
int AMVikingDemod(const uint8_t *id){
// demod am clock 32 fail
if (!ASKDemod("32",g_debugMode,false,1))
return 0;
// search for the card id from bitstream.
return AmVikingDecode(id);
}
//by Gusto
// takes 1 argument <8 bytes of Hex number on the card
// print binary found and saves in grapbuffer for further commands
int CmdAMVikingDemod(const char *Cmd){
uint8_t id[4];
if (param_gethex(Cmd,0,id,8) == 1)
{
PrintAndLog("Usage: data vikingdemod CardID 8 bytes of hex number");
return 0;
}
PrintAndLog("Card ID : %02X%02X%02X%02X\n",id[0],id[1],id[2],id[3]);
// try to demod AMViking
return AMVikingDemod(id);
}
int CmdGrid(const char *Cmd)
{
sscanf(Cmd, "%i %i", &PlotGridX, &PlotGridY);
@@ -2415,6 +2366,7 @@ static command_t CommandTable[] =
{"askedgedetect", CmdAskEdgeDetect, 1, "[threshold] Adjust Graph for manual ask demod using the length of sample differences to detect the edge of a wave (use 20-45, def:25)"},
{"askem410xdemod", CmdAskEM410xDemod, 1, "[clock] [invert<0|1>] [maxErr] -- Demodulate an EM410x tag from GraphBuffer (args optional)"},
{"askgproxiidemod", CmdG_Prox_II_Demod, 1, "Demodulate a G Prox II tag from GraphBuffer"},
{"askvikingdemod", CmdVikingDemod, 1, "Demodulate a Viking AM tag from GraphBuffer"},
{"autocorr", CmdAutoCorr, 1, "[window length] [g] -- Autocorrelation over window - g to save back to GraphBuffer (overwrite)"},
{"biphaserawdecode",CmdBiphaseDecodeRaw,1, "[offset] [invert<0|1>] [maxErr] -- Biphase decode bin stream in DemodBuffer (offset = 0|1 bits to shift the decode start)"},
{"bin2hex", Cmdbin2hex, 1, "bin2hex <digits> -- Converts binary to hexadecimal"},
@@ -2424,7 +2376,6 @@ static command_t CommandTable[] =
{"detectclock", CmdDetectClockRate, 1, "[modulation] Detect clock rate of wave in GraphBuffer (options: 'a','f','n','p' for ask, fsk, nrz, psk respectively)"},
{"fdxbdemod", CmdFDXBdemodBI , 1, "Demodulate a FDX-B ISO11784/85 Biphase tag from GraphBuffer"},
{"fskawiddemod", CmdFSKdemodAWID, 1, "Demodulate an AWID FSK tag from GraphBuffer"},
{"vikingdemod", CmdAMVikingDemod, 1, "Demodulate a Viking AM tag from GraphBuffer"},
//{"fskfcdetect", CmdFSKfcDetect, 1, "Try to detect the Field Clock of an FSK wave"},
{"fskhiddemod", CmdFSKdemodHID, 1, "Demodulate a HID FSK tag from GraphBuffer"},
{"fskiodemod", CmdFSKdemodIO, 1, "Demodulate an IO Prox FSK tag from GraphBuffer"},

View File

@@ -17,6 +17,7 @@ int CmdData(const char *Cmd);
void printDemodBuff(void);
void setDemodBuf(uint8_t *buff, size_t size, size_t startIdx);
int CmdAskEM410xDemod(const char *Cmd);
int CmdVikingDemod(const char *Cmd);
int CmdG_Prox_II_Demod(const char *Cmd);
int Cmdaskrawdemod(const char *Cmd);
int Cmdaskmandemod(const char *Cmd);
@@ -67,8 +68,7 @@ int PSKDemod(const char *Cmd, bool verbose);
int NRZrawDemod(const char *Cmd, bool verbose);
void printEM410x(uint32_t hi, uint64_t id);
int getSamples(const char *Cmd, bool silent);
int AMVikingDemod(const uint8_t *cardid);
int CmdAMVikingDemod(const char *cmd);
#define MAX_DEMOD_BUF_LEN (1024*128)
extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];

View File

@@ -127,6 +127,18 @@ int usage_lf_simpsk(void) {
PrintAndLog(" d <hexdata> Data to sim as hex - omit to sim from DemodBuffer");
return 0;
}
int usage_lf_find(void){
PrintAndLog("Usage: lf search <0|1> [u]");
PrintAndLog(" <use data from Graphbuffer> , if not set, try reading data from tag.");
PrintAndLog(" [Search for Unknown tags] , if not set, reads only known tags.");
PrintAndLog("");
PrintAndLog(" sample: lf search = try reading data from tag & search for known tags");
PrintAndLog(" : lf search 1 = use data from GraphBuffer & search for known tags");
PrintAndLog(" : lf search u = try reading data from tag & search for known and unknown tags");
PrintAndLog(" : lf search 1 u = use data from GraphBuffer & search for known and unknown tags");
return 0;
}
/* send a LF command before reading */
int CmdLFCommandRead(const char *Cmd)
@@ -269,191 +281,186 @@ int CmdFlexdemod(const char *Cmd)
int CmdIndalaDemod(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 count = 0;
int i, j;
int state = -1;
int count = 0;
int i, j;
// worst case with GraphTraceLen=64000 is < 4096
// under normal conditions it's < 2048
// worst case with GraphTraceLen=64000 is < 4096
// under normal conditions it's < 2048
uint8_t rawbits[4096];
int rawbit = 0;
int worst = 0, worstPos = 0;
// PrintAndLog("Expecting a bit less than %d raw bits", GraphTraceLen / 32);
for (i = 0; i < GraphTraceLen-1; i += 2) {
count += 1;
if ((GraphBuffer[i] > GraphBuffer[i + 1]) && (state != 1)) {
if (state == 0) {
for (j = 0; j < count - 8; j += 16) {
rawbits[rawbit++] = 0;
}
if ((abs(count - j)) > worst) {
worst = abs(count - j);
worstPos = i;
}
}
state = 1;
count = 0;
} else if ((GraphBuffer[i] < GraphBuffer[i + 1]) && (state != 0)) {
if (state == 1) {
for (j = 0; j < count - 8; j += 16) {
rawbits[rawbit++] = 1;
}
if ((abs(count - j)) > worst) {
worst = abs(count - j);
worstPos = i;
}
}
state = 0;
count = 0;
}
}
if (rawbit>0){
PrintAndLog("Recovered %d raw bits, expected: %d", rawbit, GraphTraceLen/32);
PrintAndLog("worst metric (0=best..7=worst): %d at pos %d", worst, worstPos);
uint8_t rawbits[4096];
int rawbit = 0;
int worst = 0, worstPos = 0;
// PrintAndLog("Expecting a bit less than %d raw bits", GraphTraceLen / 32);
for (i = 0; i < GraphTraceLen-1; i += 2) {
count += 1;
if ((GraphBuffer[i] > GraphBuffer[i + 1]) && (state != 1)) {
if (state == 0) {
for (j = 0; j < count - 8; j += 16) {
rawbits[rawbit++] = 0;
}
if ((abs(count - j)) > worst) {
worst = abs(count - j);
worstPos = i;
}
}
state = 1;
count = 0;
} else if ((GraphBuffer[i] < GraphBuffer[i + 1]) && (state != 0)) {
if (state == 1) {
for (j = 0; j < count - 8; j += 16) {
rawbits[rawbit++] = 1;
}
if ((abs(count - j)) > worst) {
worst = abs(count - j);
worstPos = i;
}
}
state = 0;
count = 0;
}
}
if ( rawbit>0 ){
PrintAndLog("Recovered %d raw bits, expected: %d", rawbit, GraphTraceLen/32);
PrintAndLog("worst metric (0=best..7=worst): %d at pos %d", worst, worstPos);
} else {
return 0;
}
// Finding the start of a UID
int uidlen, long_wait;
if (strcmp(Cmd, "224") == 0) {
uidlen = 224;
long_wait = 30;
} else {
uidlen = 64;
long_wait = 29;
}
// Finding the start of a UID
int uidlen, long_wait;
if (strcmp(Cmd, "224") == 0) {
uidlen = 224;
long_wait = 30;
} else {
uidlen = 64;
long_wait = 29;
}
int start;
int first = 0;
for (start = 0; start <= rawbit - uidlen; start++) {
first = rawbits[start];
for (i = start; i < start + long_wait; i++) {
if (rawbits[i] != first) {
break;
}
}
if (i == (start + long_wait)) {
break;
}
}
int start;
int first = 0;
for (start = 0; start <= rawbit - uidlen; start++) {
first = rawbits[start];
for (i = start; i < start + long_wait; i++) {
if (rawbits[i] != first) {
break;
}
}
if (i == (start + long_wait)) {
break;
}
}
if (start == rawbit - uidlen + 1) {
PrintAndLog("nothing to wait for");
return 0;
}
if (start == rawbit - uidlen + 1) {
PrintAndLog("nothing to wait for");
return 0;
}
// Inverting signal if needed
if (first == 1) {
for (i = start; i < rawbit; i++) {
rawbits[i] = !rawbits[i];
}
}
// Inverting signal if needed
if (first == 1) {
for (i = start; i < rawbit; i++) {
rawbits[i] = !rawbits[i];
}
}
// Dumping UID
// Dumping UID
uint8_t bits[224] = {0x00};
char showbits[225] = {0x00};
int bit;
i = start;
int times = 0;
int bit;
i = start;
int times = 0;
if (uidlen > rawbit) {
PrintAndLog("Warning: not enough raw bits to get a full UID");
for (bit = 0; bit < rawbit; bit++) {
bits[bit] = rawbits[i++];
// As we cannot know the parity, let's use "." and "/"
showbits[bit] = '.' + bits[bit];
}
showbits[bit+1]='\0';
PrintAndLog("Partial UID=%s", showbits);
return 0;
} else {
for (bit = 0; bit < uidlen; bit++) {
bits[bit] = rawbits[i++];
showbits[bit] = '0' + bits[bit];
}
times = 1;
}
if (uidlen > rawbit) {
PrintAndLog("Warning: not enough raw bits to get a full UID");
for (bit = 0; bit < rawbit; bit++) {
bits[bit] = rawbits[i++];
// As we cannot know the parity, let's use "." and "/"
showbits[bit] = '.' + bits[bit];
}
showbits[bit+1]='\0';
PrintAndLog("Partial UID=%s", showbits);
return 0;
} else {
for (bit = 0; bit < uidlen; bit++) {
bits[bit] = rawbits[i++];
showbits[bit] = '0' + bits[bit];
}
times = 1;
}
//convert UID to HEX
uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7;
int idx;
//convert UID to HEX
uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7;
int idx;
uid1 = uid2 = 0;
if (uidlen==64){
for( idx=0; idx<64; idx++) {
if (showbits[idx] == '0') {
uid1=(uid1<<1)|(uid2>>31);
uid2=(uid2<<1)|0;
} else {
uid1=(uid1<<1)|(uid2>>31);
uid2=(uid2<<1)|1;
}
}
PrintAndLog("UID=%s (%x%08x)", showbits, uid1, uid2);
}
else {
if (uidlen==64){
for( idx=0; idx<64; idx++) {
if (showbits[idx] == '0') {
uid1 = (uid1<<1) | (uid2>>31);
uid2 = (uid2<<1) | 0;
} else {
uid1 = (uid1<<1) | (uid2>>31);
uid2 = (uid2<<1) | 1;
}
}
PrintAndLog("UID=%s (%x%08x)", showbits, uid1, uid2);
} else {
uid3 = uid4 = uid5 = uid6 = uid7 = 0;
for( idx=0; idx<224; idx++) {
uid1=(uid1<<1)|(uid2>>31);
uid2=(uid2<<1)|(uid3>>31);
uid3=(uid3<<1)|(uid4>>31);
uid4=(uid4<<1)|(uid5>>31);
uid5=(uid5<<1)|(uid6>>31);
uid6=(uid6<<1)|(uid7>>31);
for( idx=0; idx<224; idx++) {
uid1 = (uid1<<1) | (uid2>>31);
uid2 = (uid2<<1) | (uid3>>31);
uid3 = (uid3<<1) | (uid4>>31);
uid4 = (uid4<<1) | (uid5>>31);
uid5 = (uid5<<1) | (uid6>>31);
uid6 = (uid6<<1) | (uid7>>31);
if (showbits[idx] == '0')
uid7 = (uid7<<1) | 0;
else
uid7 = (uid7<<1) | 1;
}
PrintAndLog("UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7);
}
}
PrintAndLog("UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7);
}
// Checking UID against next occurrences
int failed = 0;
// Checking UID against next occurrences
int failed = 0;
for (; i + uidlen <= rawbit;) {
failed = 0;
for (bit = 0; bit < uidlen; bit++) {
if (bits[bit] != rawbits[i++]) {
failed = 1;
break;
}
}
if (failed == 1) {
break;
}
times += 1;
}
for (bit = 0; bit < uidlen; bit++) {
if (bits[bit] != rawbits[i++]) {
failed = 1;
break;
}
}
if (failed == 1) {
break;
}
times += 1;
}
PrintAndLog("Occurrences: %d (expected %d)", times, (rawbit - start) / uidlen);
PrintAndLog("Occurrences: %d (expected %d)", times, (rawbit - start) / uidlen);
// Remodulating for tag cloning
// Remodulating for tag cloning
// HACK: 2015-01-04 this will have an impact on our new way of seening lf commands (demod)
// since this changes graphbuffer data.
GraphTraceLen = 32*uidlen;
i = 0;
int phase = 0;
for (bit = 0; bit < uidlen; bit++) {
if (bits[bit] == 0) {
phase = 0;
} else {
phase = 1;
}
int j;
for (j = 0; j < 32; j++) {
GraphBuffer[i++] = phase;
phase = !phase;
}
}
GraphTraceLen = 32 * uidlen;
i = 0;
int phase = 0;
for (bit = 0; bit < uidlen; bit++) {
phase = (bits[bit] == 0) ? 0 : 1;
int j;
for (j = 0; j < 32; j++) {
GraphBuffer[i++] = phase;
phase = !phase;
}
}
RepaintGraphWindow();
return 1;
RepaintGraphWindow();
return 1;
}
int CmdIndalaClone(const char *Cmd)
@@ -1043,25 +1050,14 @@ int CmdVchDemod(const char *Cmd)
//by marshmellow
int CmdLFfind(const char *Cmd)
{
int ans=0;
int ans = 0;
char cmdp = param_getchar(Cmd, 0);
char testRaw = param_getchar(Cmd, 1);
if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: lf search <0|1> [u]");
PrintAndLog(" <use data from Graphbuffer> , if not set, try reading data from tag.");
PrintAndLog(" [Search for Unknown tags] , if not set, reads only known tags.");
PrintAndLog("");
PrintAndLog(" sample: lf search = try reading data from tag & search for known tags");
PrintAndLog(" : lf search 1 = use data from GraphBuffer & search for known tags");
PrintAndLog(" : lf search u = try reading data from tag & search for known and unknown tags");
PrintAndLog(" : lf search 1 u = use data from GraphBuffer & search for known and unknown tags");
return 0;
}
if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') return usage_lf_find();
if (!offline && (cmdp != '1')){
CmdLFRead("s");
getSamples("30000",false);
CmdLFRead("s");
getSamples("30000",false);
} else if (GraphTraceLen < 1000) {
PrintAndLog("Data in Graphbuffer was too small.");
return 0;
@@ -1133,6 +1129,12 @@ int CmdLFfind(const char *Cmd)
return 1;
}
ans=CmdVikingDemod("");
if (ans>0) {
PrintAndLog("\nValid Viking ID Found!");
return 1;
}
ans=CmdPSKNexWatch("");
if (ans>0) {
PrintAndLog("\nValid NexWatch ID Found!");
@@ -1171,15 +1173,15 @@ int CmdLFfind(const char *Cmd)
}
}
}
ans=GetFskClock("",FALSE,FALSE);
ans=GetFskClock("",FALSE,FALSE);
if (ans != 0){ //fsk
ans=FSKrawDemod("",TRUE);
if (ans>0) {
PrintAndLog("\nUnknown FSK Modulated Tag Found!");
return 1;
}
ans=FSKrawDemod("",TRUE);
if (ans>0) {
PrintAndLog("\nUnknown FSK Modulated Tag Found!");
return 1;
}
}
ans=ASKDemod("0 0 0",TRUE,FALSE,1);
ans=ASKDemod("0 0 0",TRUE,FALSE,1);
if (ans>0) {
PrintAndLog("\nUnknown ASK Modulated and Manchester encoded Tag Found!");
PrintAndLog("\nif it does not look right it could instead be ASK/Biphase - try 'data rawdemod ab'");
@@ -1187,10 +1189,10 @@ int CmdLFfind(const char *Cmd)
}
ans=CmdPSK1rawDemod("");
if (ans>0) {
PrintAndLog("Possible unknown PSK1 Modulated Tag Found above!\n\nCould also be PSK2 - try 'data rawdemod p2'");
PrintAndLog("\nCould also be PSK3 - [currently not supported]");
PrintAndLog("\nCould also be NRZ - try 'data nrzrawdemod");
return 1;
PrintAndLog("Possible unknown PSK1 Modulated Tag Found above!\n\nCould also be PSK2 - try 'data rawdemod p2'");
PrintAndLog("\nCould also be PSK3 - [currently not supported]");
PrintAndLog("\nCould also be NRZ - try 'data nrzrawdemod");
return 1;
}
PrintAndLog("\nNo Data Found!\n");
}

View File

@@ -12,43 +12,68 @@
#include "cmdlfviking.h"
#include "lfdemod.h"
static int CmdHelp(const char *Cmd);
int usage_lf_viking_clone(void){
PrintAndLog("clone a Viking AM tag to a T55x7 tag.");
PrintAndLog("Usage: lf viking clone <Card ID 16 bytes of hex number>");
return 0;
}
//by marshmellow
//see ASKDemod for what args are accepted
int CmdVikingDemod(const char *Cmd)
{
uint8_t id[4];
if (param_gethex(Cmd,0,id,8) == 1)
{
PrintAndLog("Usage: lf viking demod <CardID 8 bytes of hex number>");
return 0;
}
UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, {false,0,0}};
SendCommand(&c);
WaitForResponse(CMD_ACK,NULL);
getSamples("40000",true);
// try to demod AMViking
return AMVikingDemod(id);
CmdLFRead("s");
getSamples("30000",false);
if (!ASKDemod(Cmd, false, false, 1)) {
if (g_debugMode) PrintAndLog("ASKDemod failed");
return 0;
}
size_t size = DemodBufferLen;
int ans = VikingDemod_AM(DemodBuffer, &size);
if (ans < 0) {
if (g_debugMode) PrintAndLog("Error Viking_Demod");
return 0;
}
//got a good demod
uint32_t raw1 = bytebits_to_byte(DemodBuffer+ans, 32);
uint32_t raw2 = bytebits_to_byte(DemodBuffer+ans+32, 32);
uint32_t cardid = bytebits_to_byte(DemodBuffer+ans+24, 32);
uint8_t checksum = bytebits_to_byte(DemodBuffer+ans+32+24, 8);
PrintAndLog("Viking Tag Found: Card ID %08X, Checksum: %02X", cardid, checksum);
PrintAndLog("Raw: %08X%08X", raw1,raw2);
setDemodBuf(DemodBuffer+ans, 64, 0);
return 1;
}
int CmdVikingClone(const char *Cmd)
{
uint32_t b1,b2;
// get the tag number 64 bits (8 bytes) in hex
uint8_t id[8];
if (param_gethex(Cmd,0,id,16) == 1)
{
PrintAndLog("Usage: lf viking clone <Card ID 16 bytes of hex number>");
return 0;
}
b1 = bytes_to_num(id,sizeof(uint32_t));
b2 = bytes_to_num(id + sizeof(uint32_t),sizeof(uint32_t));
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_viking_clone();
if (param_gethex(Cmd, 0, id, 16) == 1)
return usage_lf_viking_clone();
b1 = bytes_to_num(id, sizeof(uint32_t));
b2 = bytes_to_num(id + sizeof(uint32_t), sizeof(uint32_t));
UsbCommand c = {CMD_VIKING_CLONE_TAG,{b1,b2}};
SendCommand(&c);
clearCommandBuffer();
SendCommand(&c);
//check for ACK?
return 0;
}
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
{"demod",CmdVikingDemod ,1, "<8 digits tag id> -- Extract tag data"},
{"clone", CmdVikingClone, 1, "<16 digits card data> clone viking tag"},
{"help", CmdHelp, 1, "This help"},
{"demod", CmdVikingDemod, 1, "Extract tag data"},
{"clone", CmdVikingClone, 1, "<16 digits card data> clone viking tag"},
{NULL, NULL, 0, NULL}
};