chg: 'lf cmdread' @marshmellow42 improvements from https://github.com/Proxmark/proxmark3/pull/570

chg:  and some adaptations..
This commit is contained in:
iceman1001 2018-02-14 21:40:52 +01:00
commit b2a3b0f72a
3 changed files with 94 additions and 52 deletions

View file

@ -4,7 +4,7 @@
// the license. // the license.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Miscellaneous routines for low frequency tag operations. // 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 // Also routines for raw mode reading/simulating of LF waveform
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -55,47 +55,101 @@
/** /**
* Function to do a modulation and then get samples. * Function to do a modulation and then get samples.
* @param delay_off * @param delay_off
* @param periods 0xFFFF0000 is period_0, 0x0000FFFF is period_1 * @param period_0
* @param useHighFreg * @param period_1
* @param command * @param command (in binary char array)
*/ */
void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t periods, uint32_t useHighFreq, uint8_t *command) { void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint32_t period_1, uint8_t *command) {
uint16_t period_0 = periods >> 16;
uint16_t period_1 = periods & 0xFFFF; // start timer
StartTicks();
// 95 == 125 KHz 88 == 134.8 KHz
int divisor_used = (useHighFreq) ? 88 : 95; // use lf config settings
sample_config sc = { 0,0,1, divisor_used, 0}; sample_config *sc = getSamplingConfig();
setSamplingConfig(&sc);
//clear read buffer //clear read buffer
BigBuf_Clear_keep_EM(); BigBuf_Clear_keep_EM();
LFSetupFPGAForADC(sc.divisor, 1); LFSetupFPGAForADC(sc->divisor, 1);
// Trigger T55x7 in mode. // Trigger T55x7 in mode.
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
WaitUS(START_GAP);
// And a little more time for the tag to fully power up
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 // now modulate the reader field
while (*command != '\0' && *command != ' ') { if (bitbang) {
LED_D_ON(); // HACK it appears the loop and if statements take up about 7us so adjust waits accordingly...
if (*(command++) == '0') uint8_t hack_cnt = 7;
TurnReadLFOn(period_0); if (period_0 < hack_cnt || period_1 < hack_cnt) {
else DbpString("[!] Warning periods cannot be less than 7us in bit bang mode");
TurnReadLFOn(period_1); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LED_D_OFF();
return;
}
LED_D_OFF(); // hack2 needed--- it appears to take about 8-16us to turn the antenna back on
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // leading to ~ 1 to 2 125khz samples extra in every off period
WaitUS(delay_off); // 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++;
int counter = 0;
bool off = false;
for (counter = 0; counter < cmd_len; counter++) {
// 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 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);
LED_D_ON();
off = false;
}
// note we appear to take about 7us 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 != ' ') {
LED_D_ON();
if (*(command++) == '0')
TurnReadLFOn(period_0);
else
TurnReadLFOn(period_1);
LED_D_OFF();
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
WaitUS(delay_off);
}
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc->divisor);
} }
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
// now do the read // now do the read
DoAcquisition_config(false, 0); DoAcquisition_config(false, 0);
// Turn off antenna
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
// tell client we are done
cmd_send(CMD_ACK,0,0,0,0,0); cmd_send(CMD_ACK,0,0,0,0,0);
} }

View file

@ -14,19 +14,18 @@ bool g_lf_threshold_set = false;
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
int usage_lf_cmdread(void) { int usage_lf_cmdread(void) {
PrintAndLog("Usage: lf cmdread d <delay period> z <zero period> o <one period> c <cmdbytes> [H]"); PrintAndLog("Usage: lf cmdread d <delay period> z <zero period> o <one period> c <cmdbytes>");
PrintAndLog("Options:"); PrintAndLog("Options:");
PrintAndLog(" h This help"); PrintAndLog(" h This help");
PrintAndLog(" L Low frequency (125 KHz)"); PrintAndLog(" d <delay> delay OFF period, (0 for bitbang mode) (decimal)");
PrintAndLog(" H High frequency (134 KHz)");
PrintAndLog(" d <delay> delay OFF period, (decimal)");
PrintAndLog(" z <zero> time period ZERO, (decimal)"); PrintAndLog(" z <zero> time period ZERO, (decimal)");
PrintAndLog(" o <one> time period ONE, (decimal)"); PrintAndLog(" o <one> time period ONE, (decimal)");
PrintAndLog(" c <cmd> Command bytes (in ones and zeros)"); PrintAndLog(" c <cmd> Command bytes (in ones and zeros)");
PrintAndLog("");
PrintAndLog(" ************* All periods in microseconds (ms)"); PrintAndLog(" ************* All periods in microseconds (ms)");
PrintAndLog(" ************* Use lf config to configure options.");
PrintAndLog("Examples:"); PrintAndLog("Examples:");
PrintAndLog(" lf cmdread d 80 z 100 o 200 c 11000"); PrintAndLog(" lf cmdread d 80 z 100 o 200 c 11000");
PrintAndLog(" lf cmdread d 80 z 100 o 100 c 11000 H");
return 0; return 0;
} }
int usage_lf_read(void){ int usage_lf_read(void){
@ -144,23 +143,15 @@ int usage_lf_find(void){
/* send a LF command before reading */ /* send a LF command before reading */
int CmdLFCommandRead(const char *Cmd) { int CmdLFCommandRead(const char *Cmd) {
bool errors = false;
bool useHighFreq = false;
uint16_t one = 0, zero = 0;
uint8_t cmdp = 0;
UsbCommand c = {CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K, {0,0,0}}; UsbCommand c = {CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K, {0,0,0}};
bool errors = false;
uint8_t cmdp = 0;
while(param_getchar(Cmd, cmdp) != 0x00 && !errors) { while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch(param_getchar(Cmd, cmdp)) { switch(param_getchar(Cmd, cmdp)) {
case 'h': case 'h':
return usage_lf_cmdread();
case 'H': case 'H':
useHighFreq = true; return usage_lf_cmdread();
cmdp++;
break;
case 'L':
cmdp++;
break;
case 'c': case 'c':
param_getstr(Cmd, cmdp+1, (char *)&c.d.asBytes, sizeof(c.d.asBytes)); param_getstr(Cmd, cmdp+1, (char *)&c.d.asBytes, sizeof(c.d.asBytes));
cmdp += 2; cmdp += 2;
@ -170,16 +161,16 @@ int CmdLFCommandRead(const char *Cmd) {
cmdp += 2; cmdp += 2;
break; break;
case 'z': case 'z':
zero = param_get32ex(Cmd, cmdp+1, 0, 10) & 0xFFFF; c.arg[1] = param_get32ex(Cmd, cmdp+1, 0, 10) & 0xFFFF;
cmdp += 2; cmdp += 2;
break; break;
case 'o': case 'o':
one = param_get32ex(Cmd, cmdp+1, 0, 10) & 0xFFFF; c.arg[2] = param_get32ex(Cmd, cmdp+1, 0, 10) & 0xFFFF;
cmdp += 2; cmdp += 2;
break; break;
default: default:
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = 1; errors = true;
break; break;
} }
} }
@ -187,14 +178,11 @@ int CmdLFCommandRead(const char *Cmd) {
//Validations //Validations
if (errors || cmdp == 0) return usage_lf_cmdread(); if (errors || cmdp == 0) return usage_lf_cmdread();
// zero and one lengths
c.arg[1] = (uint32_t)(zero << 16 | one);
// add frequency 125 or 134
c.arg[2] = useHighFreq;
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommand(&c);
WaitForResponse(CMD_ACK, NULL);
getSamples(0, true);
return 0; return 0;
} }

View file

@ -165,7 +165,7 @@ bool WaitForResponseTimeoutW(uint32_t cmd, UsbCommand* response, size_t ms_timeo
if (msclock() - start_time > 3000 && show_warning) { if (msclock() - start_time > 3000 && show_warning) {
PrintAndLog("Waiting for a response from the proxmark..."); 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; show_warning = false;
} }
} }