mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
Add generic tear-off hook
This commit is contained in:
parent
f3a3a94fea
commit
7f8a4b4182
5 changed files with 119 additions and 16 deletions
|
@ -68,6 +68,24 @@ extern uint32_t _stack_start, _stack_end;
|
||||||
struct common_area common_area __attribute__((section(".commonarea")));
|
struct common_area common_area __attribute__((section(".commonarea")));
|
||||||
static int button_status = BUTTON_NO_CLICK;
|
static int button_status = BUTTON_NO_CLICK;
|
||||||
static bool allow_send_wtx = false;
|
static bool allow_send_wtx = false;
|
||||||
|
static uint32_t tearoff_delay_us = 0;
|
||||||
|
static bool tearoff_enabled = false;
|
||||||
|
|
||||||
|
int tearoff_hook(void) {
|
||||||
|
if (tearoff_enabled) {
|
||||||
|
if (tearoff_delay_us == 0) {
|
||||||
|
Dbprintf(_RED_("No tear-off delay configured!"));
|
||||||
|
return PM3_SUCCESS; // SUCCESS = the hook didn't do anything
|
||||||
|
}
|
||||||
|
WaitUS(tearoff_delay_us);
|
||||||
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
|
tearoff_enabled = false;
|
||||||
|
Dbprintf(_YELLOW_("Tear-off triggered!"));
|
||||||
|
return PM3_ETEAROFF;
|
||||||
|
} else {
|
||||||
|
return PM3_SUCCESS; // SUCCESS = the hook didn't do anything
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void send_wtx(uint16_t wtx) {
|
void send_wtx(uint16_t wtx) {
|
||||||
if (allow_send_wtx) {
|
if (allow_send_wtx) {
|
||||||
|
@ -731,6 +749,24 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
reply_ng(CMD_SET_DBGMODE, PM3_SUCCESS, NULL, 0);
|
reply_ng(CMD_SET_DBGMODE, PM3_SUCCESS, NULL, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case CMD_SET_TEAROFF: {
|
||||||
|
struct p {
|
||||||
|
uint32_t delay_us;
|
||||||
|
bool on;
|
||||||
|
bool off;
|
||||||
|
} PACKED;
|
||||||
|
struct p *payload = (struct p *)packet->data.asBytes;
|
||||||
|
if (payload->on && payload->off)
|
||||||
|
reply_ng(CMD_SET_TEAROFF, PM3_EINVARG, NULL, 0);
|
||||||
|
if (payload->on)
|
||||||
|
tearoff_enabled = true;
|
||||||
|
if (payload->off)
|
||||||
|
tearoff_enabled = false;
|
||||||
|
if (payload->delay_us > 0)
|
||||||
|
tearoff_delay_us = payload->delay_us;
|
||||||
|
reply_ng(CMD_SET_TEAROFF, PM3_SUCCESS, NULL, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
// always available
|
// always available
|
||||||
case CMD_HF_DROPFIELD: {
|
case CMD_HF_DROPFIELD: {
|
||||||
hf_field_off();
|
hf_field_off();
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
extern int g_rsamples; // = 0;
|
extern int g_rsamples; // = 0;
|
||||||
extern uint8_t g_trigger;
|
extern uint8_t g_trigger;
|
||||||
|
|
||||||
|
int tearoff_hook(void);
|
||||||
|
|
||||||
// ADC Vref = 3300mV, and an (10M+1M):1M voltage divider on the HF input can measure voltages up to 36300 mV
|
// ADC Vref = 3300mV, and an (10M+1M):1M voltage divider on the HF input can measure voltages up to 36300 mV
|
||||||
#define MAX_ADC_HF_VOLTAGE 36300
|
#define MAX_ADC_HF_VOLTAGE 36300
|
||||||
// ADC Vref = 3300mV, (240k-10M):240k voltage divider, 140800 mV
|
// ADC Vref = 3300mV, (240k-10M):240k voltage divider, 140800 mV
|
||||||
|
|
|
@ -2573,15 +2573,20 @@ void EM4xWriteWord(uint8_t addr, uint32_t data, uint32_t pwd, uint8_t usepwd) {
|
||||||
|
|
||||||
SendForward(len);
|
SendForward(len);
|
||||||
|
|
||||||
// Wait 20ms for write to complete?
|
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured
|
||||||
// No, when write is denied, err preamble comes much sooner
|
StopTicks();
|
||||||
//WaitUS(10820); // tPC+tWEE
|
reply_ng(CMD_LF_EM4X_WRITEWORD, PM3_ETEAROFF, NULL, 0);
|
||||||
|
} else {
|
||||||
|
// Wait 20ms for write to complete?
|
||||||
|
// No, when write is denied, err preamble comes much sooner
|
||||||
|
//WaitUS(10820); // tPC+tWEE
|
||||||
|
|
||||||
DoPartialAcquisition(0, false, 6000, 1000);
|
DoPartialAcquisition(0, false, 6000, 1000);
|
||||||
|
|
||||||
StopTicks();
|
StopTicks();
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
reply_ng(CMD_LF_EM4X_WRITEWORD, PM3_SUCCESS, NULL, 0);
|
reply_ng(CMD_LF_EM4X_WRITEWORD, PM3_SUCCESS, NULL, 0);
|
||||||
|
}
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2610,15 +2615,19 @@ void EM4xProtectWord(uint32_t data, uint32_t pwd, uint8_t usepwd) {
|
||||||
|
|
||||||
SendForward(len);
|
SendForward(len);
|
||||||
|
|
||||||
// Wait 20ms for write to complete?
|
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured
|
||||||
// No, when write is denied, err preamble comes much sooner
|
StopTicks();
|
||||||
//WaitUS(13640); // tPC+tPR
|
reply_ng(CMD_LF_EM4X_PROTECTWORD, PM3_ETEAROFF, NULL, 0);
|
||||||
|
} else {
|
||||||
|
// Wait 20ms for write to complete?
|
||||||
|
// No, when write is denied, err preamble comes much sooner
|
||||||
|
//WaitUS(13640); // tPC+tPR
|
||||||
|
|
||||||
DoPartialAcquisition(0, false, 6000, 1000);
|
DoPartialAcquisition(0, false, 6000, 1000);
|
||||||
|
StopTicks();
|
||||||
StopTicks();
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
reply_ng(CMD_LF_EM4X_PROTECTWORD, PM3_SUCCESS, NULL, 0);
|
||||||
reply_ng(CMD_LF_EM4X_PROTECTWORD, PM3_SUCCESS, NULL, 0);
|
}
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "cmdparser.h" // command_t
|
#include "cmdparser.h" // command_t
|
||||||
|
#include "cliparser.h"
|
||||||
#include "comms.h"
|
#include "comms.h"
|
||||||
#include "usart_defs.h"
|
#include "usart_defs.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
|
@ -515,6 +516,57 @@ static int CmdStatus(const char *Cmd) {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int CmdTearoff(const char *Cmd) {
|
||||||
|
CLIParserContext *ctx;
|
||||||
|
CLIParserInit(&ctx, "hw tearoff",
|
||||||
|
"Configure a tear-off hook for the next write command supporting tear-off\n"
|
||||||
|
"After having been triggered by a write command, the tear-off hook is deactivated",
|
||||||
|
"hw tearoff --delay 1200 --> define delay of 1200us\n"
|
||||||
|
"hw tearoff --on --> (re)activate a previously defined delay\n"
|
||||||
|
"hw tearoff --off --> deactivate a previously activated but not yet triggered hook\n");
|
||||||
|
|
||||||
|
void *argtable[] = {
|
||||||
|
arg_param_begin,
|
||||||
|
arg_int0(NULL, "delay", "<decimal>", "Delay in us before triggering tear-off, must be > 0"),
|
||||||
|
arg_lit0(NULL, "on", "Activate tear-off hook"),
|
||||||
|
arg_lit0(NULL, "off", "Deactivate tear-off hook"),
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
struct {
|
||||||
|
uint32_t delay_us;
|
||||||
|
bool on;
|
||||||
|
bool off;
|
||||||
|
} PACKED params;
|
||||||
|
params.delay_us = arg_get_u32_def(ctx, 1, 0);
|
||||||
|
params.on = arg_get_lit(ctx, 2);
|
||||||
|
params.off = arg_get_lit(ctx, 3);
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
if (params.on && params.off) {
|
||||||
|
PrintAndLogEx(WARNING, "You can't set both --on and --off!");
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommandNG(CMD_SET_TEAROFF, (uint8_t *)¶ms, sizeof(params));
|
||||||
|
PacketResponseNG resp;
|
||||||
|
if (WaitForResponseTimeout(CMD_SET_TEAROFF, &resp, 500) == false) {
|
||||||
|
PrintAndLogEx(WARNING, "Tear-off command timeout.");
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
|
if (resp.status == PM3_SUCCESS) {
|
||||||
|
if (params.delay_us > 0)
|
||||||
|
PrintAndLogEx(INFO, "Tear-off hook configured with delay of %ius.", params.delay_us);
|
||||||
|
if (params.on)
|
||||||
|
PrintAndLogEx(INFO, "Tear-off hook enabled.");
|
||||||
|
if (params.off)
|
||||||
|
PrintAndLogEx(INFO, "Tear-off hook disabled.");
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
PrintAndLogEx(WARNING, "Tear-off command failed.");
|
||||||
|
return resp.status;
|
||||||
|
}
|
||||||
|
|
||||||
static int CmdTia(const char *Cmd) {
|
static int CmdTia(const char *Cmd) {
|
||||||
(void)Cmd; // Cmd is not used so far
|
(void)Cmd; // Cmd is not used so far
|
||||||
PrintAndLogEx(INFO, "Triggering new Timing Interval Acquisition (TIA)...");
|
PrintAndLogEx(INFO, "Triggering new Timing Interval Acquisition (TIA)...");
|
||||||
|
@ -621,6 +673,7 @@ static command_t CommandTable[] = {
|
||||||
{"setmux", CmdSetMux, IfPm3Present, "Set the ADC mux to a specific value"},
|
{"setmux", CmdSetMux, IfPm3Present, "Set the ADC mux to a specific value"},
|
||||||
{"standalone", CmdStandalone, IfPm3Present, "Jump to the standalone mode"},
|
{"standalone", CmdStandalone, IfPm3Present, "Jump to the standalone mode"},
|
||||||
{"status", CmdStatus, IfPm3Present, "Show runtime status information about the connected Proxmark3"},
|
{"status", CmdStatus, IfPm3Present, "Show runtime status information about the connected Proxmark3"},
|
||||||
|
{"tearoff", CmdTearoff, IfPm3Present, "Program a tearoff hook for the next command supporting tearoff"},
|
||||||
{"tia", CmdTia, IfPm3Present, "Trigger a Timing Interval Acquisition to re-adjust the RealTimeCounter divider"},
|
{"tia", CmdTia, IfPm3Present, "Trigger a Timing Interval Acquisition to re-adjust the RealTimeCounter divider"},
|
||||||
{"tune", CmdTune, IfPm3Present, "Measure antenna tuning"},
|
{"tune", CmdTune, IfPm3Present, "Measure antenna tuning"},
|
||||||
{"version", CmdVersion, IfPm3Present, "Show version information about the connected Proxmark3"},
|
{"version", CmdVersion, IfPm3Present, "Show version information about the connected Proxmark3"},
|
||||||
|
|
|
@ -401,6 +401,7 @@ typedef struct {
|
||||||
#define CMD_WTX 0x0116
|
#define CMD_WTX 0x0116
|
||||||
#define CMD_TIA 0x0117
|
#define CMD_TIA 0x0117
|
||||||
#define CMD_BREAK_LOOP 0x0118
|
#define CMD_BREAK_LOOP 0x0118
|
||||||
|
#define CMD_SET_TEAROFF 0x0119
|
||||||
|
|
||||||
// RDV40, Flash memory operations
|
// RDV40, Flash memory operations
|
||||||
#define CMD_FLASHMEM_WRITE 0x0121
|
#define CMD_FLASHMEM_WRITE 0x0121
|
||||||
|
@ -774,8 +775,10 @@ typedef struct {
|
||||||
|
|
||||||
// execute pm3 cmd failed client/pm3: when one of our pm3 cmd tries and fails. opposite from PM3_SUCCESS
|
// execute pm3 cmd failed client/pm3: when one of our pm3 cmd tries and fails. opposite from PM3_SUCCESS
|
||||||
#define PM3_EFAILED -21
|
#define PM3_EFAILED -21
|
||||||
// partial success client/pm3: when tring to dump a tag and fails on some blocks. Partial dump.
|
// partial success client/pm3: when trying to dump a tag and fails on some blocks. Partial dump.
|
||||||
#define PM3_EPARTIAL -22
|
#define PM3_EPARTIAL -22
|
||||||
|
// tearoff occured client/pm3: when a tearoff hook was called and a tearoff actually happened
|
||||||
|
#define PM3_ETEAROFF -23
|
||||||
|
|
||||||
// No data pm3: no data available, no host frame available (not really an error)
|
// No data pm3: no data available, no host frame available (not really an error)
|
||||||
#define PM3_ENODATA -98
|
#define PM3_ENODATA -98
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue