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
commit 70459879e9
10 changed files with 273 additions and 300 deletions

View file

@ -7,6 +7,8 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
-- --
### Added ### Added
- Added viking demod to `lf search` (marshmellow)
- `data askvikingdemod` demod viking id tag from graphbuffer (marshmellow)
- `lf t55xx resetread` added reset then read command - should allow determining start - `lf t55xx resetread` added reset then read command - should allow determining start
of stream transmissions (marshmellow) of stream transmissions (marshmellow)
- `lf t55xx wakeup` added wake with password (AOR) to allow lf search or standard lf read after (iceman, marshmellow) - `lf t55xx wakeup` added wake with password (AOR) to allow lf search or standard lf read after (iceman, marshmellow)
@ -22,8 +24,12 @@ of stream transmissions (marshmellow)
- Added 'hw status'. This command makes the ARM print out some runtime information. (holiman) - Added 'hw status'. This command makes the ARM print out some runtime information. (holiman)
- Added 'hw ping'. This command just sends a usb packets and checks if the pm3 is responsive. Can be used to abort certain operations which supports abort over usb. (holiman) - Added 'hw ping'. This command just sends a usb packets and checks if the pm3 is responsive. Can be used to abort certain operations which supports abort over usb. (holiman)
- Added `data hex2bin` and `data bin2hex` for command line conversion between binary and hexadecimal (holiman) - Added `data hex2bin` and `data bin2hex` for command line conversion between binary and hexadecimal (holiman)
- Added 'hf snoop'. This command take digitalized signal from FPGA and put in BigBuffer. (pwpiwi + enio)
- Added Topaz (NFC type 1) protocol support ('hf topaz reader', 'hf list topaz', 'hf 14a raw -T', 'hf topaz snoop'). (piwi)
- Added option c to 'hf list' (mark CRC bytes) (piwi)
### Changed ### Changed
- Adjusted lf em410x em410xsim to accept a clock argument
- Adjusted lf t55xx dump to allow overriding the safety check and warning text (marshmellow) - Adjusted lf t55xx dump to allow overriding the safety check and warning text (marshmellow)
- Adjusted lf t55xx write input variables (marshmellow) - Adjusted lf t55xx write input variables (marshmellow)
- Adjusted lf t55xx read with password safety check and warning text and adjusted the input variables (marshmellow & iceman) - Adjusted lf t55xx read with password safety check and warning text and adjusted the input variables (marshmellow & iceman)

View file

@ -89,7 +89,8 @@ void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo);
void CopyIndala64toT55x7(uint32_t hi, uint32_t lo); // Clone Indala 64-bit tag by UID to T55x7 void CopyIndala64toT55x7(uint32_t hi, uint32_t lo); // Clone Indala 64-bit tag by UID to T55x7
void CopyIndala224toT55x7(uint32_t uid1, uint32_t uid2, uint32_t uid3, uint32_t uid4, uint32_t uid5, uint32_t uid6, uint32_t uid7); // Clone Indala 224-bit tag by UID to T55x7 void CopyIndala224toT55x7(uint32_t uid1, uint32_t uid2, uint32_t uid3, uint32_t uid4, uint32_t uid5, uint32_t uid6, uint32_t uid7); // Clone Indala 224-bit tag by UID to T55x7
void T55xxResetRead(void); void T55xxResetRead(void);
void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode); void T55xxWriteBlock(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg);
void T55xxWriteBlockExt(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg);
void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd); void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd);
void T55xxWakeUp(uint32_t Pwd); void T55xxWakeUp(uint32_t Pwd);
void TurnReadLFOn(); void TurnReadLFOn();

View file

@ -1132,7 +1132,7 @@ void T55xxResetRead(void) {
} }
// Write one card block in page 0, no lock // Write one card block in page 0, no lock
void T55xxWriteBlockExt(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t arg) { void T55xxWriteBlockExt(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg) {
LED_A_ON(); LED_A_ON();
bool PwdMode = arg & 0x1; bool PwdMode = arg & 0x1;
uint8_t Page = (arg & 0x2)>>1; uint8_t Page = (arg & 0x2)>>1;
@ -1178,7 +1178,7 @@ void T55xxWriteBlockExt(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t arg
} }
// Write one card block in page 0, no lock // Write one card block in page 0, no lock
void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t arg) { void T55xxWriteBlock(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg) {
T55xxWriteBlockExt(Data, Block, Pwd, arg); T55xxWriteBlockExt(Data, Block, Pwd, arg);
cmd_send(CMD_ACK,0,0,0,0,0); cmd_send(CMD_ACK,0,0,0,0,0);
} }
@ -1260,10 +1260,8 @@ void T55xxWakeUp(uint32_t Pwd){
void WriteT55xx(uint32_t *blockdata, uint8_t startblock, uint8_t numblocks) { void WriteT55xx(uint32_t *blockdata, uint8_t startblock, uint8_t numblocks) {
// write last block first and config block last (if included) // write last block first and config block last (if included)
for (uint8_t i = numblocks+startblock; i > startblock; i--) { for (uint8_t i = numblocks+startblock; i > startblock; i--)
//Dbprintf("write- Blk: %d, d:%08X",i-1,blockdata[i-1]);
T55xxWriteBlockExt(blockdata[i-1],i-1,0,0); T55xxWriteBlockExt(blockdata[i-1],i-1,0,0);
}
} }
// Copy HID id to card and setup block 0 config // Copy HID id to card and setup block 0 config
@ -1652,13 +1650,10 @@ void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode
} }
void CopyViKingtoT55x7(uint32_t block1, uint32_t block2) { void CopyViKingtoT55x7(uint32_t block1, uint32_t block2) {
LED_D_ON();
T55xxWriteBlock(block1,1,0,0); uint32_t data[] = {T55x7_BITRATE_RF_32 | T55x7_MODULATION_MANCHESTER | (2 << T55x7_MAXBLOCK_SHIFT), block1, block2};
T55xxWriteBlock(block2,2,0,0); // Program the data blocks for supplied ID and the block 0 config
T55xxWriteBlock(T55x7_MODULATION_MANCHESTER | T55x7_BITRATE_RF_32 | 2 << T55x7_MAXBLOCK_SHIFT,0,0,0); WriteT55xx(data, 0, 3);
// T55xxWriteBlock(T55x7_MODULATION_MANCHESTER | T55x7_BITRATE_RF_32 | 2 << T5555_MAXBLOCK_SHIFT,0,0,1);
// ICEMAN NOTES:
// Shouldn't this one be: T55x7_MAXBLOCK_SHIFT and 0 in password mode
LED_D_OFF(); LED_D_OFF();
} }

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 // 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 // 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-------------| // |---26 bit---| |-----117----||-------------142-------------|
// b = format bit len, o = odd parity of last 3 bits // 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 fc = 0;
uint32_t cardnum = 0; uint32_t cardnum = 0;
uint32_t code1 = 0; uint32_t code1 = 0;
//uint32_t code2 = 0;
if (fmtLen==26){ if (fmtLen==26){
fc = bytebits_to_byte(BitStream+73, 8); fc = bytebits_to_byte(BitStream+73, 8);
cardnum = bytebits_to_byte(BitStream+81, 16); cardnum = bytebits_to_byte(BitStream+81, 16);
@ -1878,54 +1877,6 @@ int CmdRawDemod(const char *Cmd)
return ans; 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) int CmdGrid(const char *Cmd)
{ {
sscanf(Cmd, "%i %i", &PlotGridX, &PlotGridY); 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)"}, {"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)"}, {"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"}, {"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)"}, {"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)"}, {"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"}, {"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)"}, {"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"}, {"fdxbdemod", CmdFDXBdemodBI , 1, "Demodulate a FDX-B ISO11784/85 Biphase tag from GraphBuffer"},
{"fskawiddemod", CmdFSKdemodAWID, 1, "Demodulate an AWID FSK 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"}, //{"fskfcdetect", CmdFSKfcDetect, 1, "Try to detect the Field Clock of an FSK wave"},
{"fskhiddemod", CmdFSKdemodHID, 1, "Demodulate a HID FSK tag from GraphBuffer"}, {"fskhiddemod", CmdFSKdemodHID, 1, "Demodulate a HID FSK tag from GraphBuffer"},
{"fskiodemod", CmdFSKdemodIO, 1, "Demodulate an IO Prox 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 printDemodBuff(void);
void setDemodBuf(uint8_t *buff, size_t size, size_t startIdx); void setDemodBuf(uint8_t *buff, size_t size, size_t startIdx);
int CmdAskEM410xDemod(const char *Cmd); int CmdAskEM410xDemod(const char *Cmd);
int CmdVikingDemod(const char *Cmd);
int CmdG_Prox_II_Demod(const char *Cmd); int CmdG_Prox_II_Demod(const char *Cmd);
int Cmdaskrawdemod(const char *Cmd); int Cmdaskrawdemod(const char *Cmd);
int Cmdaskmandemod(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); int NRZrawDemod(const char *Cmd, bool verbose);
void printEM410x(uint32_t hi, uint64_t id); void printEM410x(uint32_t hi, uint64_t id);
int getSamples(const char *Cmd, bool silent); 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) #define MAX_DEMOD_BUF_LEN (1024*128)
extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN]; 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"); PrintAndLog(" d <hexdata> Data to sim as hex - omit to sim from DemodBuffer");
return 0; 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 */ /* send a LF command before reading */
int CmdLFCommandRead(const char *Cmd) int CmdLFCommandRead(const char *Cmd)
@ -311,7 +323,7 @@ int CmdIndalaDemod(const char *Cmd)
} }
} }
if (rawbit>0){ if ( rawbit>0 ){
PrintAndLog("Recovered %d raw bits, expected: %d", rawbit, GraphTraceLen/32); PrintAndLog("Recovered %d raw bits, expected: %d", rawbit, GraphTraceLen/32);
PrintAndLog("worst metric (0=best..7=worst): %d at pos %d", worst, worstPos); PrintAndLog("worst metric (0=best..7=worst): %d at pos %d", worst, worstPos);
} else { } else {
@ -387,25 +399,24 @@ int CmdIndalaDemod(const char *Cmd)
if (uidlen==64){ if (uidlen==64){
for( idx=0; idx<64; idx++) { for( idx=0; idx<64; idx++) {
if (showbits[idx] == '0') { if (showbits[idx] == '0') {
uid1=(uid1<<1)|(uid2>>31); uid1 = (uid1<<1) | (uid2>>31);
uid2=(uid2<<1)|0; uid2 = (uid2<<1) | 0;
} else { } else {
uid1=(uid1<<1)|(uid2>>31); uid1 = (uid1<<1) | (uid2>>31);
uid2=(uid2<<1)|1; uid2 = (uid2<<1) | 1;
} }
} }
PrintAndLog("UID=%s (%x%08x)", showbits, uid1, uid2); PrintAndLog("UID=%s (%x%08x)", showbits, uid1, uid2);
} } else {
else {
uid3 = uid4 = uid5 = uid6 = uid7 = 0; uid3 = uid4 = uid5 = uid6 = uid7 = 0;
for( idx=0; idx<224; idx++) { for( idx=0; idx<224; idx++) {
uid1=(uid1<<1)|(uid2>>31); uid1 = (uid1<<1) | (uid2>>31);
uid2=(uid2<<1)|(uid3>>31); uid2 = (uid2<<1) | (uid3>>31);
uid3=(uid3<<1)|(uid4>>31); uid3 = (uid3<<1) | (uid4>>31);
uid4=(uid4<<1)|(uid5>>31); uid4 = (uid4<<1) | (uid5>>31);
uid5=(uid5<<1)|(uid6>>31); uid5 = (uid5<<1) | (uid6>>31);
uid6=(uid6<<1)|(uid7>>31); uid6 = (uid6<<1) | (uid7>>31);
if (showbits[idx] == '0') if (showbits[idx] == '0')
uid7 = (uid7<<1) | 0; uid7 = (uid7<<1) | 0;
@ -436,15 +447,11 @@ int CmdIndalaDemod(const char *Cmd)
// 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) // HACK: 2015-01-04 this will have an impact on our new way of seening lf commands (demod)
// since this changes graphbuffer data. // since this changes graphbuffer data.
GraphTraceLen = 32*uidlen; GraphTraceLen = 32 * uidlen;
i = 0; i = 0;
int phase = 0; int phase = 0;
for (bit = 0; bit < uidlen; bit++) { for (bit = 0; bit < uidlen; bit++) {
if (bits[bit] == 0) { phase = (bits[bit] == 0) ? 0 : 1;
phase = 0;
} else {
phase = 1;
}
int j; int j;
for (j = 0; j < 32; j++) { for (j = 0; j < 32; j++) {
GraphBuffer[i++] = phase; GraphBuffer[i++] = phase;
@ -1043,21 +1050,10 @@ int CmdVchDemod(const char *Cmd)
//by marshmellow //by marshmellow
int CmdLFfind(const char *Cmd) int CmdLFfind(const char *Cmd)
{ {
int ans=0; int ans = 0;
char cmdp = param_getchar(Cmd, 0); char cmdp = param_getchar(Cmd, 0);
char testRaw = param_getchar(Cmd, 1); char testRaw = param_getchar(Cmd, 1);
if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') { if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') return usage_lf_find();
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 (!offline && (cmdp != '1')){ if (!offline && (cmdp != '1')){
CmdLFRead("s"); CmdLFRead("s");
@ -1133,6 +1129,12 @@ int CmdLFfind(const char *Cmd)
return 1; return 1;
} }
ans=CmdVikingDemod("");
if (ans>0) {
PrintAndLog("\nValid Viking ID Found!");
return 1;
}
ans=CmdPSKNexWatch(""); ans=CmdPSKNexWatch("");
if (ans>0) { if (ans>0) {
PrintAndLog("\nValid NexWatch ID Found!"); PrintAndLog("\nValid NexWatch ID Found!");

View file

@ -12,42 +12,67 @@
#include "cmdlfviking.h" #include "cmdlfviking.h"
#include "lfdemod.h" #include "lfdemod.h"
static int CmdHelp(const char *Cmd); 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) int CmdVikingDemod(const char *Cmd)
{ {
uint8_t id[4]; CmdLFRead("s");
if (param_gethex(Cmd,0,id,8) == 1) getSamples("30000",false);
{
PrintAndLog("Usage: lf viking demod <CardID 8 bytes of hex number>"); if (!ASKDemod(Cmd, false, false, 1)) {
if (g_debugMode) PrintAndLog("ASKDemod failed");
return 0; return 0;
} }
UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, {false,0,0}}; size_t size = DemodBufferLen;
SendCommand(&c);
WaitForResponse(CMD_ACK,NULL); int ans = VikingDemod_AM(DemodBuffer, &size);
getSamples("40000",true); if (ans < 0) {
// try to demod AMViking if (g_debugMode) PrintAndLog("Error Viking_Demod");
return AMVikingDemod(id); 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) int CmdVikingClone(const char *Cmd)
{ {
uint32_t b1,b2; uint32_t b1,b2;
// get the tag number 64 bits (8 bytes) in hex // get the tag number 64 bits (8 bytes) in hex
uint8_t id[8]; uint8_t id[8];
if (param_gethex(Cmd,0,id,16) == 1)
{ char cmdp = param_getchar(Cmd, 0);
PrintAndLog("Usage: lf viking clone <Card ID 16 bytes of hex number>"); if (strlen(Cmd) < 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_viking_clone();
return 0;
} if (param_gethex(Cmd, 0, id, 16) == 1)
b1 = bytes_to_num(id,sizeof(uint32_t)); return usage_lf_viking_clone();
b2 = bytes_to_num(id + sizeof(uint32_t),sizeof(uint32_t));
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}}; UsbCommand c = {CMD_VIKING_CLONE_TAG,{b1,b2}};
clearCommandBuffer();
SendCommand(&c); SendCommand(&c);
//check for ACK?
return 0; return 0;
} }
static command_t CommandTable[] = static command_t CommandTable[] =
{ {
{"help", CmdHelp, 1, "This help"}, {"help", CmdHelp, 1, "This help"},
{"demod",CmdVikingDemod ,1, "<8 digits tag id> -- Extract tag data"}, {"demod", CmdVikingDemod, 1, "Extract tag data"},
{"clone", CmdVikingClone, 1, "<16 digits card data> clone viking tag"}, {"clone", CmdVikingClone, 1, "<16 digits card data> clone viking tag"},
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };

View file

@ -599,6 +599,26 @@ int IOdemodFSK(uint8_t *dest, size_t size)
return -5; return -5;
} }
// by marshmellow
// find viking preamble 0xF200 in already demoded data
int VikingDemod_AM(uint8_t *dest, size_t *size) {
if (justNoise(dest, *size)) return -1;
//make sure buffer has data
if (*size < 64*2) return -2;
size_t startIdx = 0;
uint8_t preamble[] = {1,1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
uint8_t errChk = preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx);
if (errChk == 0) return -4; //preamble not found
uint32_t checkCalc = bytebits_to_byte(dest+startIdx,8) ^ bytebits_to_byte(dest+startIdx+8,8) ^ bytebits_to_byte(dest+startIdx+16,8)
^ bytebits_to_byte(dest+startIdx+24,8) ^ bytebits_to_byte(dest+startIdx+32,8) ^ bytebits_to_byte(dest+startIdx+40,8)
^ bytebits_to_byte(dest+startIdx+48,8) ^ bytebits_to_byte(dest+startIdx+56,8);
if ( checkCalc != 0xA8 ) return -5;
if (*size != 64) return -5;
//return start position
return (int) startIdx;
}
// by marshmellow // by marshmellow
// takes a array of binary values, start position, length of bits per parity (includes parity bit), // takes a array of binary values, start position, length of bits per parity (includes parity bit),
// Parity Type (1 for odd; 0 for even; 2 Always 1's), and binary Length (length to run) // Parity Type (1 for odd; 0 for even; 2 Always 1's), and binary Length (length to run)
@ -1505,30 +1525,3 @@ int pskRawDemod(uint8_t dest[], size_t *size, int *clock, int *invert)
*size = numBits; *size = numBits;
return errCnt; return errCnt;
} }
// on successful return 1 otherwise return 0
int VikingDecode(uint8_t *BitStream,
size_t size,
size_t *startIdx,
uint8_t *id_bits,
size_t id_bits_size)
{
//no arguments needed - built this way in case we want this to be a direct call from "data " cmds in the future
// otherwise could be a void with no arguments
//set defaults
uint32_t i = 0;
uint32_t lastcheckindex = size - (id_bits_size * 2);
int found = 0;
while (i < lastcheckindex)
{
if (memcmp(BitStream + i,id_bits,id_bits_size) == 0)
{
*startIdx = i;
found = 1;
break;
}
i++;
}
return found;
}

View file

@ -48,8 +48,8 @@ int gProxII_Demod(uint8_t BitStream[], size_t *size);
int HIDdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo); int HIDdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo);
int IOdemodFSK(uint8_t *dest, size_t size); int IOdemodFSK(uint8_t *dest, size_t size);
int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert); int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert);
int PyramiddemodFSK(uint8_t *dest, size_t *size);
int ParadoxdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo); int ParadoxdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo);
int VikingDecode(uint8_t *BitStream, size_t size, size_t *startIdx,uint8_t *id_bit,size_t id_bits_size); int PyramiddemodFSK(uint8_t *dest, size_t *size);
int VikingDemod_AM(uint8_t *dest, size_t *size);
#endif #endif