From 61e96805add5df3ceade89eaafed4695fa31a422 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Fri, 9 Feb 2018 15:49:55 -0500 Subject: [PATCH 1/3] add bitbang option to lf cmdread by setting delay to 0 we can use cmd binary to bitbang the antenna. note that the timing isn't perfect (especially on the off periods) but is fairly close. worst i've seen it off is 8us on a large off period. but i don't have the best test equipment... --- armsrc/lfops.c | 79 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 63 insertions(+), 16 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 4344742b..5e9fb193 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -29,6 +29,7 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint32_t period_1, uint8_t *command) { + StartTicks(); int divisor_used = 95; // 125 KHz // see if 'h' was specified @@ -43,36 +44,82 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint /* Make sure the tag is reset */ FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelay(2500); + WaitMS(2500); + //power on LFSetupFPGAForADC(sc.divisor, 1); // And a little more time for the tag to fully power up - SpinDelay(2000); - + WaitMS(2000); + // if delay_off = 0 then just bitbang 1 = antenna on 0 = off for respective periods. + bool bitbang = delay_off == 0; // now modulate the reader field - while(*command != '\0' && *command != ' ') { + + if (bitbang) { + //HACK it appears my loop and if statements take up about 7 us so adjust waits accordingly... + uint8_t hack_cnt = 7; + if (period_0 < hack_cnt || period_1 < hack_cnt) { + DbpString("Warning periods cannot be less than 7 in bit bang mode"); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LED_D_OFF(); + return; + } + //prime cmd_len to save time comparing strings while modulating + int cmd_len = 0; + while(command[cmd_len] != '\0' && command[cmd_len] != ' ') + cmd_len++; + + int counter = 0; + bool off = false; + for (counter = 0; counter < cmd_len; counter++) { + //while(*command != '\0' && *command != ' ') { + // if cmd = 0 then turn field off + if (command[counter] == '0') { + // if field already off leave alone (affects timing otherwise) + if (off == false) { + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LED_D_OFF(); + off = true; + } + // note we appear to take about 6us to switch over (or run the if statements/loop...) + WaitUS(period_0-hack_cnt); + // else if cmd = 1 then turn field on + } else { + // if field already on leave alone (affects timing otherwise) + if (off) { + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + LED_D_ON(); + off = false; + } + // note we appear to take about 6us to switch over (or run the if statements/loop...) + WaitUS(period_1-hack_cnt); + } + } + } else { // old mode of cmd read using delay as off period + while(*command != '\0' && *command != ' ') { + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LED_D_OFF(); + WaitUS(delay_off); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc.divisor); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + LED_D_ON(); + if(*(command++) == '0') { + WaitUS(period_0); + } else { + WaitUS(period_1); + } + } FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LED_D_OFF(); - SpinDelayUs(delay_off); + WaitUS(delay_off); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc.divisor); - - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - LED_D_ON(); - if(*(command++) == '0') - SpinDelayUs(period_0); - else - SpinDelayUs(period_1); } - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LED_D_OFF(); - SpinDelayUs(delay_off); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc.divisor); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); // now do the read DoAcquisition_config(false, 0); + // note leaves field on... (for future commands?) } /* blank r/w tag data stream From 779d9a0e90a20392785adbaa4974cafaa27005a8 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sat, 10 Feb 2018 17:30:32 -0500 Subject: [PATCH 2/3] reconfigure lf cmdread ... to use lf config settings instead of it's own settings. (now allows full options of lf config...) also it will now run `data samples` when the command completes making it not necessary to run manually... note: adjusted client wait message as it was confusing. --- armsrc/lfops.c | 48 ++++++++++++++++++++++++++---------------------- client/cmdlf.c | 30 +++++++++++------------------- client/cmdmain.c | 2 +- 3 files changed, 38 insertions(+), 42 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 5e9fb193..c7a7a59d 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -4,7 +4,7 @@ // the license. //----------------------------------------------------------------------------- // Miscellaneous routines for low frequency tag operations. -// Tags supported here so far are Texas Instruments (TI), HID +// Tags supported here so far are Texas Instruments (TI), HID, EM4x05, EM410x // Also routines for raw mode reading/simulating of LF waveform //----------------------------------------------------------------------------- @@ -28,17 +28,12 @@ */ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint32_t period_1, uint8_t *command) { - + // start timer StartTicks(); - int divisor_used = 95; // 125 KHz - // see if 'h' was specified - if (command[strlen((char *) command) - 1] == 'h') - divisor_used = 88; // 134.8 KHz - - sample_config sc = { 0,0,1, divisor_used, 0}; - setSamplingConfig(&sc); - //clear read buffer + // use lf config settings + sample_config *sc = getSamplingConfig(); + // clear read buffer BigBuf_Clear_keep_EM(); /* Make sure the tag is reset */ @@ -46,8 +41,8 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitMS(2500); - //power on - LFSetupFPGAForADC(sc.divisor, 1); + // power on + LFSetupFPGAForADC(sc->divisor, 1); // And a little more time for the tag to fully power up WaitMS(2000); @@ -56,15 +51,21 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint // now modulate the reader field if (bitbang) { - //HACK it appears my loop and if statements take up about 7 us so adjust waits accordingly... + // HACK it appears the loop and if statements take up about 7us so adjust waits accordingly... uint8_t hack_cnt = 7; if (period_0 < hack_cnt || period_1 < hack_cnt) { - DbpString("Warning periods cannot be less than 7 in bit bang mode"); + DbpString("Warning periods cannot be less than 7us in bit bang mode"); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LED_D_OFF(); return; } - //prime cmd_len to save time comparing strings while modulating + + // hack2 needed--- it appears to take about 8-16us to turn the antenna back on + // leading to ~ 1 to 2 125khz samples extra in every off period + // so we should test for last 0 before next 1 and reduce period_0 by this extra amount... + // but is this time different for every antenna or other hw builds??? more testing needed + + // prime cmd_len to save time comparing strings while modulating int cmd_len = 0; while(command[cmd_len] != '\0' && command[cmd_len] != ' ') cmd_len++; @@ -72,7 +73,6 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint int counter = 0; bool off = false; for (counter = 0; counter < cmd_len; counter++) { - //while(*command != '\0' && *command != ' ') { // if cmd = 0 then turn field off if (command[counter] == '0') { // if field already off leave alone (affects timing otherwise) @@ -81,17 +81,17 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint LED_D_OFF(); off = true; } - // note we appear to take about 6us to switch over (or run the if statements/loop...) + // note we appear to take about 7us to switch over (or run the if statements/loop...) WaitUS(period_0-hack_cnt); // else if cmd = 1 then turn field on } else { // if field already on leave alone (affects timing otherwise) if (off) { - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); LED_D_ON(); off = false; } - // note we appear to take about 6us to switch over (or run the if statements/loop...) + // note we appear to take about 7us to switch over (or run the if statements/loop...) WaitUS(period_1-hack_cnt); } } @@ -100,7 +100,7 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LED_D_OFF(); WaitUS(delay_off); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc.divisor); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc->divisor); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); LED_D_ON(); if(*(command++) == '0') { @@ -112,14 +112,18 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LED_D_OFF(); WaitUS(delay_off); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc.divisor); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc->divisor); } FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); // now do the read DoAcquisition_config(false, 0); - // note leaves field on... (for future commands?) + + // Turn off antenna + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + // tell client we are done + cmd_send(CMD_ACK,0,0,0,0,0); } /* blank r/w tag data stream diff --git a/client/cmdlf.c b/client/cmdlf.c index ef9c3cbb..42f73fa1 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -54,26 +54,24 @@ static int CmdHelp(const char *Cmd); int usage_lf_cmdread(void) { - PrintAndLog("Usage: lf cmdread d z o c [H] "); + PrintAndLog("Usage: lf cmdread d z o c "); PrintAndLog("Options: "); PrintAndLog(" h This help"); - PrintAndLog(" L Low frequency (125 KHz)"); - PrintAndLog(" H High frequency (134 KHz)"); - PrintAndLog(" d delay OFF period"); - PrintAndLog(" z time period ZERO"); - PrintAndLog(" o time period ONE"); + PrintAndLog(" d delay OFF period between bits (0 for bitbang mode)"); + PrintAndLog(" z time period ZERO (antenna off in bitbang mode)"); + PrintAndLog(" o time period ONE (antenna on in bitbang mode)"); PrintAndLog(" c Command bytes"); PrintAndLog(" ************* All periods in microseconds"); + PrintAndLog(" ************* Use lf config to configure options."); PrintAndLog("Examples:"); PrintAndLog(" lf cmdread d 80 z 100 o 200 c 11000"); - PrintAndLog(" lf cmdread d 80 z 100 o 100 c 11000 H"); + PrintAndLog(" lf cmdread d 80 z 100 o 100 c 11000"); return 0; } /* send a command before reading */ int CmdLFCommandRead(const char *Cmd) { - static char dummy[3] = {0x20,0x00,0x00}; UsbCommand c = {CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K}; bool errors = false; //uint8_t divisor = 95; //125khz @@ -84,14 +82,6 @@ int CmdLFCommandRead(const char *Cmd) { case 'h': return usage_lf_cmdread(); - case 'H': - //divisor = 88; - dummy[1]='h'; - cmdp++; - break; - case 'L': - cmdp++; - break; case 'c': param_getstr(Cmd, cmdp+1, (char *)&c.d.asBytes, sizeof(c.d.asBytes)); cmdp+=2; @@ -121,11 +111,13 @@ int CmdLFCommandRead(const char *Cmd) //Validations if(errors) return usage_lf_cmdread(); - // in case they specified 'H' - strcpy((char *)&c.d.asBytes + strlen((char *)c.d.asBytes), dummy); - clearCommandBuffer(); SendCommand(&c); + + WaitForResponse(CMD_ACK,NULL); + getSamples(0, true); + + return 0; } diff --git a/client/cmdmain.c b/client/cmdmain.c index 719617fd..8d9313f9 100644 --- a/client/cmdmain.c +++ b/client/cmdmain.c @@ -162,7 +162,7 @@ bool WaitForResponseTimeoutW(uint32_t cmd, UsbCommand* response, size_t ms_timeo } if (msclock() - start_time > 2000 && show_warning) { PrintAndLog("Waiting for a response from the proxmark..."); - PrintAndLog("Don't forget to cancel its operation first by pressing on the button"); + PrintAndLog("You can cancel this operation by pressing the pm3 button"); show_warning = false; } } From 2896e490d9851053666f6b83c0ec3ffe7eb686ab Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Wed, 14 Feb 2018 15:41:39 -0500 Subject: [PATCH 3/3] update changelog +fix a comment typo + move clear bigbuf after fpgadownloadandgo... --- CHANGELOG.md | 2 ++ armsrc/lfops.c | 7 ++++--- armsrc/lfsampling.c | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4162c638..36e57b5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ## [unreleased][unreleased] ### Changed +- Adjusted `lf cmdread` to respond to client when complete and the client will then automatically call `data samples` - Improved backdoor detection missbehaving magic s50/1k tag (Fl0-0) - Deleted wipe functionality from `hf mf csetuid` (Merlok) - Changed `hf mf nested` logic (Merlok) @@ -21,6 +22,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Changed start sequence in Qt mode (fix: short commands hangs main Qt thread) (Merlok) ### Added +- Added a bitbang mode to `lf cmdread` if delay is 0 the cmd bits turn off and on the antenna with 0 and 1 respectively (marshmellow) - Added PAC/Stanley detection to lf search (marshmellow) - Added lf pac demod and lf pac read - extracts the raw blocks from a PAC/Stanley tag (marshmellow) - Added hf mf c* commands compatibity for 4k and gen1b backdoor (Fl0-0) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index c7a7a59d..f3bbbf84 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -33,14 +33,15 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint // use lf config settings sample_config *sc = getSamplingConfig(); - // clear read buffer - BigBuf_Clear_keep_EM(); - /* Make sure the tag is reset */ + // Make sure the tag is reset FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitMS(2500); + // clear read buffer (after fpga bitstream loaded...) + BigBuf_Clear_keep_EM(); + // power on LFSetupFPGAForADC(sc->divisor, 1); diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 084201a5..3b076265 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -266,7 +266,7 @@ uint32_t SnoopLF() } /** -* acquisition of Cotag LF signal. Similart to other LF, since the Cotag has such long datarate RF/384 +* acquisition of Cotag LF signal. Similar to other LF, since the Cotag has such long datarate RF/384 * and is Manchester?, we directly gather the manchester data into bigbuff **/ #define COTAG_T1 384