mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-07-10 15:32:41 -07:00
commit
f69f1de80c
5 changed files with 97 additions and 51 deletions
|
@ -6,6 +6,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
||||||
## [unreleased][unreleased]
|
## [unreleased][unreleased]
|
||||||
|
|
||||||
### Changed
|
### 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)
|
- Improved backdoor detection missbehaving magic s50/1k tag (Fl0-0)
|
||||||
- Deleted wipe functionality from `hf mf csetuid` (Merlok)
|
- Deleted wipe functionality from `hf mf csetuid` (Merlok)
|
||||||
- Changed `hf mf nested` logic (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)
|
- Changed start sequence in Qt mode (fix: short commands hangs main Qt thread) (Merlok)
|
||||||
|
|
||||||
### Added
|
### 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 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 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)
|
- Added hf mf c* commands compatibity for 4k and gen1b backdoor (Fl0-0)
|
||||||
|
|
112
armsrc/lfops.c
112
armsrc/lfops.c
|
@ -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
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -28,51 +28,103 @@
|
||||||
*/
|
*/
|
||||||
void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint32_t period_1, uint8_t *command)
|
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
|
// use lf config settings
|
||||||
// see if 'h' was specified
|
sample_config *sc = getSamplingConfig();
|
||||||
|
|
||||||
if (command[strlen((char *) command) - 1] == 'h')
|
// Make sure the tag is reset
|
||||||
divisor_used = 88; // 134.8 KHz
|
|
||||||
|
|
||||||
sample_config sc = { 0,0,1, divisor_used, 0};
|
|
||||||
setSamplingConfig(&sc);
|
|
||||||
//clear read buffer
|
|
||||||
BigBuf_Clear_keep_EM();
|
|
||||||
|
|
||||||
/* Make sure the tag is reset */
|
|
||||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
SpinDelay(2500);
|
WaitMS(2500);
|
||||||
|
|
||||||
LFSetupFPGAForADC(sc.divisor, 1);
|
// clear read buffer (after fpga bitstream loaded...)
|
||||||
|
BigBuf_Clear_keep_EM();
|
||||||
|
|
||||||
|
// power on
|
||||||
|
LFSetupFPGAForADC(sc->divisor, 1);
|
||||||
|
|
||||||
// And a little more time for the tag to fully power up
|
// 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
|
// now modulate the reader field
|
||||||
while(*command != '\0' && *command != ' ') {
|
|
||||||
|
if (bitbang) {
|
||||||
|
// 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 7us in bit bang mode");
|
||||||
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
|
LED_D_OFF();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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++;
|
||||||
|
|
||||||
|
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 != ' ') {
|
||||||
|
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);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
LED_D_OFF();
|
LED_D_OFF();
|
||||||
SpinDelayUs(delay_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')
|
|
||||||
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);
|
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);
|
||||||
|
// tell client we are done
|
||||||
|
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* blank r/w tag data stream
|
/* blank r/w tag data stream
|
||||||
|
|
|
@ -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
|
* and is Manchester?, we directly gather the manchester data into bigbuff
|
||||||
**/
|
**/
|
||||||
#define COTAG_T1 384
|
#define COTAG_T1 384
|
||||||
|
|
|
@ -54,26 +54,24 @@ 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 between bits (0 for bitbang mode)");
|
||||||
PrintAndLog(" H High frequency (134 KHz)");
|
PrintAndLog(" z <zero> time period ZERO (antenna off in bitbang mode)");
|
||||||
PrintAndLog(" d <delay> delay OFF period");
|
PrintAndLog(" o <one> time period ONE (antenna on in bitbang mode)");
|
||||||
PrintAndLog(" z <zero> time period ZERO");
|
|
||||||
PrintAndLog(" o <one> time period ONE");
|
|
||||||
PrintAndLog(" c <cmd> Command bytes");
|
PrintAndLog(" c <cmd> Command bytes");
|
||||||
PrintAndLog(" ************* All periods in microseconds");
|
PrintAndLog(" ************* All periods in microseconds");
|
||||||
|
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");
|
PrintAndLog(" lf cmdread d 80 z 100 o 100 c 11000");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* send a command before reading */
|
/* send a command before reading */
|
||||||
int CmdLFCommandRead(const char *Cmd)
|
int CmdLFCommandRead(const char *Cmd)
|
||||||
{
|
{
|
||||||
static char dummy[3] = {0x20,0x00,0x00};
|
|
||||||
UsbCommand c = {CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K};
|
UsbCommand c = {CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K};
|
||||||
bool errors = false;
|
bool errors = false;
|
||||||
//uint8_t divisor = 95; //125khz
|
//uint8_t divisor = 95; //125khz
|
||||||
|
@ -84,14 +82,6 @@ int CmdLFCommandRead(const char *Cmd)
|
||||||
{
|
{
|
||||||
case 'h':
|
case 'h':
|
||||||
return usage_lf_cmdread();
|
return usage_lf_cmdread();
|
||||||
case 'H':
|
|
||||||
//divisor = 88;
|
|
||||||
dummy[1]='h';
|
|
||||||
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;
|
||||||
|
@ -121,11 +111,13 @@ int CmdLFCommandRead(const char *Cmd)
|
||||||
//Validations
|
//Validations
|
||||||
if(errors) return usage_lf_cmdread();
|
if(errors) return usage_lf_cmdread();
|
||||||
|
|
||||||
// in case they specified 'H'
|
|
||||||
strcpy((char *)&c.d.asBytes + strlen((char *)c.d.asBytes), dummy);
|
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
|
|
||||||
|
WaitForResponse(CMD_ACK,NULL);
|
||||||
|
getSamples(0, true);
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -162,7 +162,7 @@ bool WaitForResponseTimeoutW(uint32_t cmd, UsbCommand* response, size_t ms_timeo
|
||||||
}
|
}
|
||||||
if (msclock() - start_time > 2000 && show_warning) {
|
if (msclock() - start_time > 2000 && 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue