diff --git a/client/graph.c b/client/graph.c index b872f26a3..ac3934018 100644 --- a/client/graph.c +++ b/client/graph.c @@ -14,9 +14,13 @@ #include "ui.h" #include "graph.h" #include "lfdemod.h" +#include "cmddata.h" //for g_debugmode int GraphBuffer[MAX_GRAPH_TRACE_LEN]; int GraphTraceLen; + +int s_Buff[MAX_GRAPH_TRACE_LEN]; + /* write a manchester bit to the graph */ void AppendGraph(int redraw, int clock, int bit) { @@ -46,16 +50,19 @@ int ClearGraph(int redraw) void save_restoreGB(uint8_t saveOpt) { static int SavedGB[MAX_GRAPH_TRACE_LEN]; - static int SavedGBlen; + static int SavedGBlen=0; static bool GB_Saved = false; + static int SavedGridOffsetAdj=0; - if (saveOpt==1) { //save + if (saveOpt == GRAPH_SAVE) { //save memcpy(SavedGB, GraphBuffer, sizeof(GraphBuffer)); SavedGBlen = GraphTraceLen; GB_Saved=true; + SavedGridOffsetAdj = GridOffset; } else if (GB_Saved){ //restore memcpy(GraphBuffer, SavedGB, sizeof(GraphBuffer)); GraphTraceLen = SavedGBlen; + GridOffset = SavedGridOffsetAdj; RepaintGraphWindow(); } return; @@ -147,7 +154,6 @@ int GetAskClock(const char str[], bool printAns, bool verbose) if (printAns) PrintAndLog("Auto-detected clock rate: %d, Best Starting Position: %d", clock, start); - SetGraphClock(clock, start); return clock; } @@ -190,7 +196,6 @@ int GetPskClock(const char str[], bool printAns, bool verbose) if (printAns) PrintAndLog("Auto-detected clock rate: %d, Best Starting Position: %d", clock, start); - SetGraphClock(clock, start); return clock; } @@ -217,7 +222,6 @@ uint8_t GetNrzClock(const char str[], bool printAns, bool verbose) if (printAns) PrintAndLog("Auto-detected clock rate: %d, Best Starting Position: %d", clock, start); - SetGraphClock(clock, start); return clock; } //by marshmellow @@ -263,9 +267,6 @@ uint8_t fskClocks(uint8_t *fc1, uint8_t *fc2, uint8_t *rf1, bool verbose) if (verbose || g_debugMode) PrintAndLog("DEBUG: Clock detect error"); return 0; } - if (verbose || g_debugMode) - PrintAndLog("Detected Field Clocks: FC/%d, FC/%d - Bit Clock: RF/%d | Best Starting Position: %d", *fc1, *fc2, *rf1, start); - SetGraphClock(*rf1, start); return 1; } diff --git a/client/graph.h b/client/graph.h index 6f3f600d9..d26e1909c 100644 --- a/client/graph.h +++ b/client/graph.h @@ -31,7 +31,11 @@ void DetectHighLowInGraph(int *high, int *low, bool addFuzz); // Max graph trace len: 40000 (bigbuf) * 8 (at 1 bit per sample) #define MAX_GRAPH_TRACE_LEN (40000 * 8 ) +#define GRAPH_SAVE 1 +#define GRAPH_RESTORE 0 extern int GraphBuffer[MAX_GRAPH_TRACE_LEN]; extern int GraphTraceLen; +extern int s_Buff[MAX_GRAPH_TRACE_LEN]; + #endif diff --git a/client/ui.c b/client/ui.c index 0bab2eb3d..5365a8938 100644 --- a/client/ui.c +++ b/client/ui.c @@ -11,13 +11,14 @@ #include "ui.h" -// set QT vars -double CursorScaleFactor; -int PlotGridX, PlotGridY, PlotGridXdefault = 64, PlotGridYdefault = 64, CursorCPos = 0, CursorDPos = 0; -int PlotClock = 0, PlockClockStartIndex = 0; - +double CursorScaleFactor = 1; +int PlotGridX=0, PlotGridY=0, PlotGridXdefault= 64, PlotGridYdefault= 64, CursorCPos= 0, CursorDPos= 0; int offline; -int flushAfterWrite = 0; +int flushAfterWrite = 0; //buzzy +int GridOffset = 0; +bool GridLocked = false; +bool showDemod = true; + extern pthread_mutex_t print_lock; static char *logfilename = "proxmark3.log"; @@ -29,9 +30,6 @@ void PrintAndLog(char *fmt, ...) va_list argptr, argptr2; static FILE *logfile = NULL; static int logging = 1; - // time_t current_time; - // struct tm* tm_info; - // char buffer[26] = {0}; // lock this section to avoid interlacing prints from different threads pthread_mutex_lock(&print_lock); @@ -44,6 +42,8 @@ void PrintAndLog(char *fmt, ...) } } +#ifdef RL_STATE_READCMD + // We are using GNU readline. int need_hack = (rl_readline_state & RL_STATE_READCMD) > 0; if (need_hack) { @@ -53,6 +53,10 @@ void PrintAndLog(char *fmt, ...) rl_replace_line("", 0); rl_redisplay(); } +#else + // We are using libedit (OSX), which doesn't support this flag. + int need_hack = 0; +#endif va_start(argptr, fmt); va_copy(argptr2, argptr); @@ -70,16 +74,6 @@ void PrintAndLog(char *fmt, ...) } if (logging && logfile) { - - /* - // Obtain current time. - current_time = time(NULL); - // Convert to local time format. - tm_info = localtime(¤t_time); - strftime(buffer, 26, "%Y-%m-%d %H:%M:%S", tm_info); - fprintf(logfile, "%s ", buffer); - */ - vfprintf(logfile, fmt, argptr2); fprintf(logfile,"\n"); fflush(logfile); diff --git a/client/ui.h b/client/ui.h index 77169cf81..257a91fb6 100644 --- a/client/ui.h +++ b/client/ui.h @@ -16,18 +16,12 @@ #include #include #include +#include #include #include -#include +#include #include -// Handle platform specific includes -#ifndef _WIN32 - #include -#else - #include - #include -#endif #include "loclass/cipherutils.h" #include "util.h" @@ -45,10 +39,11 @@ void PrintAndLog(char *fmt, ...); void SetLogFilename(char *fn); extern double CursorScaleFactor; -extern int PlotGridX, PlotGridY, PlotGridXdefault, PlotGridYdefault, CursorCPos, CursorDPos; -extern int PlotClock, PlockClockStartIndex; +extern int PlotGridX, PlotGridY, PlotGridXdefault, PlotGridYdefault, CursorCPos, CursorDPos, GridOffset; extern int offline; extern int flushAfterWrite; //buzzy +extern bool GridLocked; +extern bool showDemod; void iceIIR_Butterworth(int * data, const size_t len); void iceSimple_Filter(int *data, const size_t len, uint8_t k); diff --git a/common/Makefile.common b/common/Makefile.common index 9221acb60..c223e0858 100644 --- a/common/Makefile.common +++ b/common/Makefile.common @@ -69,7 +69,7 @@ endif #COMMON_FLAGS += -DHAS_512_FLASH # Also search prerequisites in the common directory (for usb.c), the fpga directory (for fpga.bit), and the zlib directory -VPATH = . ../common ../fpga ../zlib --/uart +VPATH = . ../common ../common/crapto1 ../fpga ../zlib --/uart INCLUDES = ../include/proxmark3.h ../include/at91sam7s512.h ../include/config_gpio.h ../include/usb_cmd.h $(APP_INCLUDES) diff --git a/common/lfdemod.c b/common/lfdemod.c index 797bce406..c1a2e8a2f 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -5,28 +5,55 @@ // at your option, any later version. See the LICENSE.txt file for the text of // the license. //----------------------------------------------------------------------------- -// Low frequency demod/decode commands +// Low frequency demod/decode commands - by marshmellow, holiman, iceman and +// many others who came before +// +// NOTES: +// LF Demod functions are placed here to allow the flexability to use client or +// device side. Most BUT NOT ALL of these functions are currenlty safe for +// device side use currently. (DetectST for example...) +// +// There are likely many improvements to the code that could be made, please +// make suggestions... +// +// we tried to include author comments so any questions could be directed to +// the source. +// +// There are 4 main sections of code below: +// Utilities Section: +// for general utilities used by multiple other functions +// Clock / Bitrate Detection Section: +// for clock detection functions for each modulation +// Modulation Demods &/or Decoding Section: +// for main general modulation demodulating and encoding decoding code. +// Tag format detection section: +// for detection of specific tag formats within demodulated data +// +// marshmellow //----------------------------------------------------------------------------- + +#include // for memset, memcmp and size_t #include "lfdemod.h" +#include // for uint_32+ +#include // for bool +#include "parity.h" // for parity test -//un_comment to allow debug print calls when used not on device +//********************************************************************************************** +//---------------------------------Utilities Section-------------------------------------------- +//********************************************************************************************** +#define LOWEST_DEFAULT_CLOCK 32 +#define FSK_PSK_THRESHOLD 123 + +//to allow debug print calls when used not on device void dummy(char *fmt, ...){} -void dummy_sgc (int clock, int startidx) {} - #ifndef ON_DEVICE # include "ui.h" // plotclock, plotclockstartindex # include "cmdparser.h" # include "cmddata.h" # define prnt PrintAndLog -# define sgc SetGraphClock -void SetGraphClock(int clock, int startidx){ - PlotClock = clock; - PlockClockStartIndex = startidx; -} #else uint8_t g_debugMode = 0; # define prnt dummy -# define sgc dummy_sgc #endif //test samples are not just noise @@ -49,7 +76,7 @@ int getHiLo(uint8_t *BitStream, size_t size, int *high, int *low, uint8_t fuzzHi if (BitStream[i] > *high) *high = BitStream[i]; if (BitStream[i] < *low) *low = BitStream[i]; } - if (*high < 123) return -1; // just noise + if (*high < FSK_PSK_THRESHOLD) return -1; // just noise *high = ((*high-128)*fuzzHi + 12800)/100; *low = ((*low-128)*fuzzLo + 12800)/100; return 1; @@ -58,18 +85,12 @@ int getHiLo(uint8_t *BitStream, size_t size, int *high, int *low, uint8_t fuzzHi // by marshmellow // pass bits to be tested in bits, length bits passed in bitLen, and parity type (even=0 | odd=1) in pType // returns 1 if passed -uint8_t parityTest(uint32_t bits, uint8_t bitLen, uint8_t pType) -{ - uint8_t ans = 0; - for (uint8_t i = 0; i < bitLen; i++){ - ans ^= ((bits >> i) & 1); - } - if (g_debugMode) prnt("DEBUG: ans: %d, ptype: %d, bits: %08X",ans,pType,bits); - return (ans == pType); +bool parityTest(uint32_t bits, uint8_t bitLen, uint8_t pType) { + return oddparity32(bits) ^ pType; } //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 - MAX 32), // Parity Type (1 for odd; 0 for even; 2 for Always 1's; 3 for Always 0's), and binary Length (length to run) size_t removeParity(uint8_t *BitStream, size_t startIdx, uint8_t pLen, uint8_t pType, size_t bLen) { @@ -77,6 +98,7 @@ size_t removeParity(uint8_t *BitStream, size_t startIdx, uint8_t pLen, uint8_t p size_t j = 0, bitCnt = 0; for (int word = 0; word < (bLen); word += pLen){ for (int bit=0; bit < pLen; bit++){ + if (word+bit >= bLen) break; parityWd = (parityWd << 1) | BitStream[startIdx+word+bit]; BitStream[j++] = (BitStream[startIdx+word+bit]); } @@ -328,8 +350,6 @@ int askdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr if (*invert != 1) *invert = 0; if (amp==1) askAmp(BinStream, *size); if (g_debugMode==2) prnt("DEBUG ASK: clk %d, beststart %d, amp %d", *clk, start, amp); - - sgc(*clk, start); uint8_t initLoopMax = 255; if (initLoopMax > *size) initLoopMax = *size; @@ -446,16 +466,18 @@ uint32_t manchesterEncode2Bytes(uint16_t datain) { //by marshmellow //encode binary data into binary manchester -int ManchesterEncode(uint8_t *BitStream, size_t size) -{ - size_t modIdx=20000, i=0; - if (size>modIdx) return -1; +//NOTE: BitStream must have triple the size of "size" available in memory to do the swap +int ManchesterEncode(uint8_t *BitStream, size_t size) { + //allow up to 4K out (means BitStream must be at least 2048+4096 to handle the swap) + size = (size>2048) ? 2048 : size; + size_t modIdx = size; + size_t i; for (size_t idx=0; idx < size; idx++){ BitStream[idx+modIdx++] = BitStream[idx]; BitStream[idx+modIdx++] = BitStream[idx]^1; } - for (; i<(size*2); i++){ - BitStream[i] = BitStream[i+20000]; + for (i=0; i<(size*2); i++){ + BitStream[i] = BitStream[i+size]; } return i; } @@ -910,6 +932,11 @@ uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, uint8_t high, uint8_t lo } return allArePeaks; } + +//********************************************************************************************** +//-------------------Clock / Bitrate Detection Section------------------------------------------ +//********************************************************************************************** + // by marshmellow // to help detect clocks on heavily clipped samples // based on count of low to low @@ -1584,6 +1611,7 @@ uint16_t countFC(uint8_t *BitStream, size_t size, uint8_t fskAdj) best3=i; } if (g_debugMode==2) prnt("DEBUG countfc: FC %u, Cnt %u, best fc: %u, best2 fc: %u",fcLens[i],fcCnts[i],fcLens[best1],fcLens[best2]); + if (fcLens[i]==0) break; } if (fcLens[best1]==0) return 0; uint8_t fcH=0, fcL=0; @@ -1602,7 +1630,7 @@ uint16_t countFC(uint8_t *BitStream, size_t size, uint8_t fskAdj) uint16_t fcs = (((uint16_t)fcH)<<8) | fcL; if (fskAdj) return fcs; - return fcLens[best1]; + return (uint16_t)fcLens[best2] << 8 | fcLens[best1]; } //by marshmellow - demodulate PSK1 wave diff --git a/common/lfdemod.h b/common/lfdemod.h index 9bd340fcb..445593314 100644 --- a/common/lfdemod.h +++ b/common/lfdemod.h @@ -19,9 +19,6 @@ #include // for //generic -#ifndef ON_DEVICE -void SetGraphClock(int clock, int startidx); -#endif uint8_t justNoise(uint8_t *bits, size_t size); size_t addParity(uint8_t *BitSource, uint8_t *dest, uint8_t sourceLen, uint8_t pLen, uint8_t pType); int askdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr, uint8_t amp, uint8_t askType); @@ -47,7 +44,7 @@ uint32_t manchesterEncode2Bytes(uint16_t datain); int ManchesterEncode(uint8_t *BitStream, size_t size); int manrawdecode(uint8_t *BitStream, size_t *size, uint8_t invert); int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert); -uint8_t parityTest(uint32_t bits, uint8_t bitLen, uint8_t pType); +extern bool parityTest(uint32_t bits, uint8_t bitLen, uint8_t pType); bool preambleSearch(uint8_t *BitStream, uint8_t *preamble, size_t pLen, size_t *size, size_t *startIdx); bool preambleSearchEx(uint8_t *BitStream, uint8_t *preamble, size_t pLen, size_t *size, size_t *startIdx, bool findone); int pskRawDemod(uint8_t dest[], size_t *size, int *clock, int *invert);