From a60612db65bd92709d6807406c52453b0f931ee6 Mon Sep 17 00:00:00 2001 From: "edouard@lafargue.name" Date: Thu, 9 Apr 2009 09:37:34 +0000 Subject: [PATCH] Added indala demodulation command (indalademod) as well as offline mode for the Linux client: if no proxmark is detected, the Linux client will go on. Of course, do not issue Proxmark3 commands in this mode, the client does not discriminate at this point... --- Changelog | 4 ++ linux/proxmark3.c | 25 ++++++-- winsrc/command.cpp | 142 ++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 164 insertions(+), 7 deletions(-) create mode 100644 Changelog diff --git a/Changelog b/Changelog new file mode 100644 index 00000000..3bfe5a9a --- /dev/null +++ b/Changelog @@ -0,0 +1,4 @@ +2009-04-09 : Initial SVN commit plus: + - Added indala demodulation algorithm - full documentation on https://www.lafargue.name/proxmark3/ + - losim should also be able to simulate an indala tag after indalademod + diff --git a/linux/proxmark3.c b/linux/proxmark3.c index 5a3d6f2d..b3621af0 100644 --- a/linux/proxmark3.c +++ b/linux/proxmark3.c @@ -18,6 +18,10 @@ struct usb_receiver_arg { int run; }; +struct main_loop_arg { + int usb_present; +}; + static void *usb_receiver(void *targ) { struct usb_receiver_arg *arg = (struct usb_receiver_arg*)targ; UsbCommand cmdbuf; @@ -40,6 +44,7 @@ static void *usb_receiver(void *targ) { static void *main_loop(void *targ) { + struct main_loop_arg *arg = (struct main_loop_arg*)targ; char *cmd = NULL; while(1) { @@ -47,11 +52,14 @@ static void *main_loop(void *targ) pthread_t reader_thread; rarg.run=1; - pthread_create(&reader_thread, NULL, &usb_receiver, &rarg); - + if (arg->usb_present == 1) { + pthread_create(&reader_thread, NULL, &usb_receiver, &rarg); + } cmd = readline(PROXPROMPT); rarg.run=0; - pthread_join(reader_thread, NULL); + if (arg->usb_present == 1) { + pthread_join(reader_thread, NULL); + } if (cmd) { if (cmd[0] != 0x00) { @@ -71,21 +79,26 @@ static void *main_loop(void *targ) int main(int argc, char **argv) { + struct main_loop_arg marg; pthread_t main_loop_t; usb_init(); if (!(devh = OpenProxmark(1))) { fprintf(stderr,"PROXMARK3: NOT FOUND!\n"); - exit(1); + marg.usb_present = 0; + } else { + marg.usb_present = 1; } - pthread_create(&main_loop_t, NULL, &main_loop, NULL); + pthread_create(&main_loop_t, NULL, &main_loop, &marg); InitGraphics(argc, argv); MainGraphics(); pthread_join(main_loop_t, NULL); - CloseProxmark(); + if (marg.usb_present == 1) { + CloseProxmark(); + } return 0; } diff --git a/winsrc/command.cpp b/winsrc/command.cpp index 1da1e1c2..43a8e2ac 100644 --- a/winsrc/command.cpp +++ b/winsrc/command.cpp @@ -1302,6 +1302,146 @@ static void CmdVchdemod(char *str) } } +static void CmdIndalademod(char *str) +{ + // Usage: recover 64bit UID by default, specify "224" as arg to recover a 224bit UID + + int state = -1; + int count = 0; + int i, j; + // worst case with GraphTraceLen=64000 is < 4096 + // under normal conditions it's < 2048 + BYTE rawbits[4096]; + int rawbit = 0; + int worst = 0, worstPos = 0; + PrintToScrollback("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; + } + } + PrintToScrollback("Recovered %d raw bits", rawbit); + PrintToScrollback("worst metric (0=best..7=worst): %d at pos %d", worst, worstPos); + + // Finding the start of a UID + int uidlen, long_wait; + if(strcmp(str, "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; + } + } + if(start == rawbit - uidlen + 1) { + PrintToScrollback("nothing to wait for"); + return; + } + + // Inverting signal if needed + if(first == 1) { + for(i = start; i < rawbit; i++) { + rawbits[i] = !rawbits[i]; + } + } + + // Dumping UID + BYTE bits[224]; + char showbits[225]; + showbits[uidlen]='\0'; + int bit; + i = start; + int times = 0; + if(uidlen > rawbit) { + PrintToScrollback("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'; + PrintToScrollback("Partial UID=%s", showbits); + return; + } else { + for(bit = 0; bit < uidlen; bit++) { + bits[bit] = rawbits[i++]; + showbits[bit] = '0' + bits[bit]; + } + times = 1; + } + PrintToScrollback("UID=%s", showbits); + + // Checking UID against next occurences + for(; i + uidlen <= rawbit;) { + int failed = 0; + for(bit = 0; bit < uidlen; bit++) { + if(bits[bit] != rawbits[i++]) { + failed = 1; + break; + } + } + if (failed == 1) { + break; + } + times += 1; + } + PrintToScrollback("Occurences: %d (expected %d)", times, (rawbit - start) / uidlen); + + // Remodulating for tag cloning + 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; + } + } + + RepaintGraphWindow(); +} + static void CmdFlexdemod(char *str) { int i; @@ -1462,7 +1602,6 @@ static void Cmdaskdemod(char *str) { static void Cmdmanchesterdemod(char *str) { int i; int clock; - int grouping=16; int lastval; int lc = 0; int bitidx = 0; @@ -1705,6 +1844,7 @@ static struct { "ltrim", CmdLtrim, "trim from left of trace", "scale", CmdScale, "set cursor display scale", "flexdemod", CmdFlexdemod, "demod samples for FlexPass", + "indalademod", CmdIndalademod, "demod samples for Indala", "save", CmdSave, "save trace (from graph window)", "load", CmdLoad, "load trace (to graph window", "hisimlisten", CmdHisimlisten, "get HF samples as fake tag", -- 2.39.2