X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/98b2a3a1e9829f85f1df6afa59a0803bfdca37ed..6063655a3ca719d224c61ece09645cedd5b4818c:/client/cmddata.c diff --git a/client/cmddata.c b/client/cmddata.c index 44bc42c0..902a6363 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -8,23 +8,22 @@ // Data and Graph commands //----------------------------------------------------------------------------- -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <limits.h> -#include "proxmark3.h" -#include "data.h" -#include "ui.h" -#include "graph.h" -#include "cmdparser.h" +#include <stdio.h> // also included in util.h +#include <string.h> // also included in util.h +#include <limits.h> // for CmdNorm INT_MIN && INT_MAX +#include "data.h" // also included in util.h +#include "cmddata.h" #include "util.h" #include "cmdmain.h" -#include "cmddata.h" -#include "lfdemod.h" -#include "usb_cmd.h" -#include "crc.h" -#include "crc16.h" -#include "loclass/cipherutils.h" +#include "proxmark3.h" +#include "ui.h" // for show graph controls +#include "graph.h" // for graph data +#include "cmdparser.h"// already included in cmdmain.h +#include "usb_cmd.h" // already included in cmdmain.h and proxmark3.h +#include "lfdemod.h" // for demod code +#include "crc.h" // for pyramid checksum maxim +#include "crc16.h" // for FDXB demod checksum +#include "loclass/cipherutils.h" // for decimating samples in getsamples uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN]; uint8_t g_debugMode=0; @@ -277,7 +276,8 @@ int AskEm410xDecode(bool verbose, uint32_t *hi, uint64_t *lo ) int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo, bool verbose) { - if (!ASKDemod(Cmd, FALSE, FALSE, 1)) return 0; + bool st = TRUE; + if (!ASKDemod_ext(Cmd, FALSE, FALSE, 1, &st)) return 0; return AskEm410xDecode(verbose, hi, lo); } @@ -312,8 +312,7 @@ int CmdAskEM410xDemod(const char *Cmd) //verbose will print results and demoding messages //emSearch will auto search for EM410x format in bitstream //askType switches decode: ask/raw = 0, ask/manchester = 1 -int ASKDemod(const char *Cmd, bool verbose, bool emSearch, uint8_t askType) -{ +int ASKDemod_ext(const char *Cmd, bool verbose, bool emSearch, uint8_t askType, bool *stCheck) { int invert=0; int clk=0; int maxErr=100; @@ -336,7 +335,14 @@ int ASKDemod(const char *Cmd, bool verbose, bool emSearch, uint8_t askType) if (g_debugMode) PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen); if (BitLen<255) return 0; if (maxLen<BitLen && maxLen != 0) BitLen = maxLen; - + int foundclk = 0; + bool st = false; + if (*stCheck) st = DetectST(BitStream, &BitLen, &foundclk); + if (st) { + *stCheck = st; + clk = (clk == 0) ? foundclk : clk; + if (verbose || g_debugMode) PrintAndLog("\nFound Sequence Terminator"); + } int errCnt = askdemod(BitStream, &BitLen, &clk, &invert, maxErr, askAmp, askType); if (errCnt<0 || BitLen<16){ //if fatal error (or -1) if (g_debugMode) PrintAndLog("DEBUG: no data found %d, errors:%d, bitlen:%d, clock:%d",errCnt,invert,BitLen,clk); @@ -365,6 +371,10 @@ int ASKDemod(const char *Cmd, bool verbose, bool emSearch, uint8_t askType) } return 1; } +int ASKDemod(const char *Cmd, bool verbose, bool emSearch, uint8_t askType) { + bool st = false; + return ASKDemod_ext(Cmd, verbose, emSearch, askType, &st); +} //by marshmellow //takes 5 arguments - clock, invert, maxErr, maxLen as integers and amplify as char == 'a' @@ -374,7 +384,8 @@ int Cmdaskmandemod(const char *Cmd) { char cmdp = param_getchar(Cmd, 0); if (strlen(Cmd) > 25 || cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: data rawdemod am [clock] <invert> [maxError] [maxLen] [amplify]"); + PrintAndLog("Usage: data rawdemod am <s> [clock] <invert> [maxError] [maxLen] [amplify]"); + PrintAndLog(" ['s'] optional, check for Sequence Terminator"); PrintAndLog(" [set clock as integer] optional, if not set, autodetect"); PrintAndLog(" <invert>, 1 to invert output"); PrintAndLog(" [set maximum allowed errors], default = 100"); @@ -388,6 +399,12 @@ int Cmdaskmandemod(const char *Cmd) PrintAndLog(" : data rawdemod am 64 1 0 = demod an ask/manchester tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); return 0; } + bool st = TRUE; + if (Cmd[0]=='s') + return ASKDemod_ext(Cmd++, TRUE, TRUE, 1, &st); + else if (Cmd[1] == 's') + return ASKDemod_ext(Cmd+=2, TRUE, TRUE, 1, &st); + else return ASKDemod(Cmd, TRUE, TRUE, 1); } @@ -574,7 +591,7 @@ int Cmdaskbiphdemod(const char *Cmd) int CmdG_Prox_II_Demod(const char *Cmd) { if (!ASKbiphaseDemod(Cmd, FALSE)){ - if (g_debugMode) PrintAndLog("ASKbiphaseDemod failed 1st try"); + if (g_debugMode) PrintAndLog("Error gProxII: ASKbiphaseDemod failed 1st try"); return 0; } size_t size = DemodBufferLen; @@ -584,46 +601,32 @@ int CmdG_Prox_II_Demod(const char *Cmd) if (g_debugMode) PrintAndLog("Error gProxII_Demod"); return 0; } - //got a good demod - uint32_t ByteStream[65] = {0x00}; + //got a good demod of 96 bits + uint8_t ByteStream[8] = {0x00}; uint8_t xorKey=0; - uint8_t keyCnt=0; - uint8_t bitCnt=0; - uint8_t ByteCnt=0; - size_t startIdx = ans + 6; //start after preamble - for (size_t idx = 0; idx<size-6; idx++){ - if ((idx+1) % 5 == 0){ - //spacer bit - should be 0 - if (DemodBuffer[startIdx+idx] != 0) { - if (g_debugMode) PrintAndLog("Error spacer not 0: %d, pos: %d",DemodBuffer[startIdx+idx],startIdx+idx); + size_t startIdx = ans + 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 bitLen = removeParity(bits_no_spacer, 0, 5, 3, 90); //source, startloc, paritylen, ptype, length_to_run + if (bitLen != 72) { + if (g_debugMode) PrintAndLog("Error gProxII: spacer removal did not produce 72 bits: %u, start: %u", bitLen, startIdx); return 0; } - continue; - } - if (keyCnt<8){ //lsb first - xorKey = xorKey | (DemodBuffer[startIdx+idx]<<keyCnt); - keyCnt++; - if (keyCnt==8 && g_debugMode) PrintAndLog("xorKey Found: %02x", xorKey); - continue; - } - //lsb first - ByteStream[ByteCnt] = ByteStream[ByteCnt] | (DemodBuffer[startIdx+idx]<<bitCnt); - bitCnt++; - if (bitCnt % 8 == 0){ - if (g_debugMode) PrintAndLog("byte %d: %02x",ByteCnt,ByteStream[ByteCnt]); - bitCnt=0; - ByteCnt++; - } + // 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; + if (g_debugMode) PrintAndLog("byte %u after xor: %02x", (unsigned int)idx, ByteStream[idx]); } - for (uint8_t i = 0; i < ByteCnt; i++){ - ByteStream[i] ^= xorKey; //xor - if (g_debugMode) PrintAndLog("byte %d after xor: %02x", i, ByteStream[i]); - } - //now ByteStream contains 64 bytes of decrypted raw tag data + //now 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+ans,32); uint32_t raw2 = bytebits_to_byte(DemodBuffer+ans+32, 32); uint32_t raw3 = bytebits_to_byte(DemodBuffer+ans+64, 32); @@ -631,13 +634,14 @@ int CmdG_Prox_II_Demod(const char *Cmd) if (fmtLen==36){ FC = ((ByteStream[3] & 0x7F)<<7) | (ByteStream[4]>>1); Card = ((ByteStream[4]&1)<<19) | (ByteStream[5]<<11) | (ByteStream[6]<<3) | (ByteStream[7]>>5); - PrintAndLog("G-Prox-II Found: FmtLen %d, FC %d, Card %d",fmtLen,FC,Card); + PrintAndLog("G-Prox-II Found: FmtLen %d, FC %u, Card %u", (int)fmtLen, FC, Card); } else if(fmtLen==26){ FC = ((ByteStream[3] & 0x7F)<<1) | (ByteStream[4]>>7); Card = ((ByteStream[4]&0x7F)<<9) | (ByteStream[5]<<1) | (ByteStream[6]>>7); - PrintAndLog("G-Prox-II Found: FmtLen %d, FC %d, Card %d",fmtLen,FC,Card); + PrintAndLog("G-Prox-II Found: FmtLen %d, FC %u, Card %u", (int)fmtLen, FC, Card); } else { - PrintAndLog("Unknown G-Prox-II Fmt Found: FmtLen %d",fmtLen); + PrintAndLog("Unknown G-Prox-II Fmt Found: FmtLen %d",(int)fmtLen); + PrintAndLog("Decoded Raw: %s", sprint_hex(ByteStream, 8)); } PrintAndLog("Raw: %08x%08x%08x", raw1,raw2,raw3); setDemodBuf(DemodBuffer+ans, 96, 0); @@ -925,16 +929,16 @@ char *GetFSKType(uint8_t fchigh, uint8_t fclow, uint8_t invert) char *fskType = fType; if (fchigh==10 && fclow==8){ if (invert) //fsk2a - fskType = "FSK2a"; + memcpy(fskType, "FSK2a", 5); else //fsk2 - fskType = "FSK2"; + memcpy(fskType, "FSK2", 4); } else if (fchigh == 8 && fclow == 5) { if (invert) - fskType = "FSK1"; + memcpy(fskType, "FSK1", 4); else - fskType = "FSK1a"; + memcpy(fskType, "FSK1a", 5); } else { - fskType = "FSK??"; + memcpy(fskType, "FSK??", 5); } return fskType; } @@ -964,7 +968,6 @@ int FSKrawDemod(const char *Cmd, bool verbose) uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; size_t BitLen = getFromGraphBuf(BitStream); if (BitLen==0) return 0; - if (g_debugMode==2) PrintAndLog("DEBUG: Got samples"); //get field clock lengths uint16_t fcs=0; if (!fchigh || !fclow) { @@ -1261,7 +1264,7 @@ int CmdFSKdemodAWID(const char *Cmd) //get binary from fsk wave int idx = AWIDdemodFSK(BitStream, &size); if (idx<=0){ - if (g_debugMode==1){ + if (g_debugMode){ if (idx == -1) PrintAndLog("DEBUG: Error - not enough samples"); else if (idx == -2) @@ -1299,7 +1302,7 @@ int CmdFSKdemodAWID(const char *Cmd) size = removeParity(BitStream, idx+8, 4, 1, 88); if (size != 66){ - if (g_debugMode==1) PrintAndLog("DEBUG: Error - at parity check-tag size does not match AWID format"); + if (g_debugMode) PrintAndLog("DEBUG: Error - at parity check-tag size does not match AWID format"); return 0; } // ok valid card found! @@ -1359,7 +1362,7 @@ int CmdFSKdemodPyramid(const char *Cmd) //get binary from fsk wave int idx = PyramiddemodFSK(BitStream, &size); if (idx < 0){ - if (g_debugMode==1){ + if (g_debugMode){ if (idx == -5) PrintAndLog("DEBUG: Error - not enough samples"); else if (idx == -1) @@ -1393,7 +1396,7 @@ int CmdFSKdemodPyramid(const char *Cmd) // s = format start bit, o = odd parity of last 7 bits // f = facility code, c = card number // w = wiegand parity, x = extra space for other formats - // p = unknown checksum + // p = CRC8maxim checksum // (26 bit format shown) //get bytes for checksum calc @@ -1415,7 +1418,7 @@ int CmdFSKdemodPyramid(const char *Cmd) size = removeParity(BitStream, idx+8, 8, 1, 120); if (size != 105){ - if (g_debugMode==1) + if (g_debugMode) PrintAndLog("DEBUG: Error at parity check - tag size does not match Pyramid format, SIZE: %d, IDX: %d, hi3: %x",size, idx, rawHi3); return 0; } @@ -1440,38 +1443,33 @@ int CmdFSKdemodPyramid(const char *Cmd) // s = format start bit, o = odd parity of last 7 bits // f = facility code, c = card number // w = wiegand parity, x = extra space for other formats - // p = unknown checksum + // p = CRC8-Maxim checksum // (26 bit format shown) //find start bit to get fmtLen int j; - for (j=0; j<size; j++){ + for (j=0; j < size; ++j){ if(BitStream[j]) break; } + uint8_t fmtLen = size-j-8; uint32_t fc = 0; uint32_t cardnum = 0; uint32_t code1 = 0; - if (fmtLen==26){ + + if ( fmtLen == 26 ){ fc = bytebits_to_byte(BitStream+73, 8); cardnum = bytebits_to_byte(BitStream+81, 16); code1 = bytebits_to_byte(BitStream+72,fmtLen); PrintAndLog("Pyramid ID Found - BitLength: %d, FC: %d, Card: %d - Wiegand: %x, Raw: %08x%08x%08x%08x", fmtLen, fc, cardnum, code1, rawHi3, rawHi2, rawHi, rawLo); - } else if (fmtLen==45){ - fmtLen=42; //end = 10 bits not 7 like 26 bit fmt + } else if (fmtLen == 45) { + fmtLen = 42; //end = 10 bits not 7 like 26 bit fmt fc = bytebits_to_byte(BitStream+53, 10); cardnum = bytebits_to_byte(BitStream+63, 32); PrintAndLog("Pyramid ID Found - BitLength: %d, FC: %d, Card: %d - Raw: %08x%08x%08x%08x", fmtLen, fc, cardnum, rawHi3, rawHi2, rawHi, rawLo); } else { cardnum = bytebits_to_byte(BitStream+81, 16); - if (fmtLen>32){ - //code1 = bytebits_to_byte(BitStream+(size-fmtLen),fmtLen-32); - //code2 = bytebits_to_byte(BitStream+(size-32),32); - PrintAndLog("Pyramid ID Found - BitLength: %d -unknown BitLength- (%d), Raw: %08x%08x%08x%08x", fmtLen, cardnum, rawHi3, rawHi2, rawHi, rawLo); - } else{ - //code1 = bytebits_to_byte(BitStream+(size-fmtLen),fmtLen); - PrintAndLog("Pyramid ID Found - BitLength: %d -unknown BitLength- (%d), Raw: %08x%08x%08x%08x", fmtLen, cardnum, rawHi3, rawHi2, rawHi, rawLo); - } + PrintAndLog("Pyramid ID Found - BitLength: %d -unknown BitLength- (%d), Raw: %08x%08x%08x%08x", fmtLen, cardnum, rawHi3, rawHi2, rawHi, rawLo); } if (checksum == checkCS) PrintAndLog("Checksum %02x passed", checksum); @@ -1638,21 +1636,21 @@ int CmdIndalaDecode(const char *Cmd) } if (!ans){ - if (g_debugMode==1) + if (g_debugMode) PrintAndLog("Error1: %d",ans); return 0; } uint8_t invert=0; size_t size = DemodBufferLen; - size_t startIdx = indala26decode(DemodBuffer, &size, &invert); - if (startIdx < 1 || size > 224) { - if (g_debugMode==1) + int startIdx = indala26decode(DemodBuffer, &size, &invert); + if (startIdx < 0 || size > 224) { + if (g_debugMode) PrintAndLog("Error2: %d",ans); return -1; } - setDemodBuf(DemodBuffer, size, startIdx); + setDemodBuf(DemodBuffer, size, (size_t)startIdx); if (invert) - if (g_debugMode==1) + if (g_debugMode) PrintAndLog("Had to invert bits"); PrintAndLog("BitLen: %d",DemodBufferLen);