mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 13:53:55 -07:00
commit
8e13d44b8b
20 changed files with 413 additions and 361 deletions
|
@ -52,18 +52,17 @@ void RunMod() {
|
||||||
int playing = 0;
|
int playing = 0;
|
||||||
int cardRead = 0;
|
int cardRead = 0;
|
||||||
|
|
||||||
// Turn on selected LED
|
|
||||||
LED(selected + 1, 0);
|
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
// exit from SamyRun, send a usbcommand.
|
// exit from SamyRun, send a usbcommand.
|
||||||
if (data_available()) break;
|
if (data_available()) break;
|
||||||
|
|
||||||
// Was our button held down or pressed?
|
// Was our button held down or pressed?
|
||||||
int button_pressed = BUTTON_HELD(1000);
|
int button_pressed = BUTTON_HELD(280);
|
||||||
SpinDelay(300);
|
if (button_pressed != BUTTON_HOLD)
|
||||||
|
continue;
|
||||||
|
|
||||||
// Button was held for a second, begin recording
|
// Button was held for a second, begin recording
|
||||||
if (button_pressed > 0 && cardRead == 0) {
|
if (button_pressed > 0 && cardRead == 0) {
|
||||||
|
@ -71,16 +70,11 @@ void RunMod() {
|
||||||
LED(selected + 1, 0);
|
LED(selected + 1, 0);
|
||||||
LED(LED_D, 0);
|
LED(LED_D, 0);
|
||||||
|
|
||||||
|
WAIT_BUTTON_RELEASED();
|
||||||
|
|
||||||
// record
|
// record
|
||||||
DbpString("[=] starting recording");
|
DbpString("[=] starting recording");
|
||||||
|
|
||||||
// wait for button to be released
|
|
||||||
while (BUTTON_PRESS())
|
|
||||||
WDT_HIT();
|
|
||||||
|
|
||||||
/* need this delay to prevent catching some weird data */
|
|
||||||
SpinDelay(500);
|
|
||||||
|
|
||||||
CmdHIDdemodFSK(1, &high[selected], &low[selected], 0);
|
CmdHIDdemodFSK(1, &high[selected], &low[selected], 0);
|
||||||
Dbprintf("[=] recorded %x %x %08x", selected, high[selected], low[selected]);
|
Dbprintf("[=] recorded %x %x %08x", selected, high[selected], low[selected]);
|
||||||
|
|
||||||
|
@ -99,12 +93,7 @@ void RunMod() {
|
||||||
// record
|
// record
|
||||||
Dbprintf("[=] cloning %x %x %08x", selected, high[selected], low[selected]);
|
Dbprintf("[=] cloning %x %x %08x", selected, high[selected], low[selected]);
|
||||||
|
|
||||||
// wait for button to be released
|
WAIT_BUTTON_RELEASED();
|
||||||
while (BUTTON_PRESS())
|
|
||||||
WDT_HIT();
|
|
||||||
|
|
||||||
/* need this delay to prevent catching some weird data */
|
|
||||||
SpinDelay(500);
|
|
||||||
|
|
||||||
CopyHIDtoT55x7(0, high[selected], low[selected], 0);
|
CopyHIDtoT55x7(0, high[selected], low[selected], 0);
|
||||||
Dbprintf("[=] cloned %x %x %08x", selected, high[selected], low[selected]);
|
Dbprintf("[=] cloned %x %x %08x", selected, high[selected], low[selected]);
|
||||||
|
@ -136,9 +125,7 @@ void RunMod() {
|
||||||
LED(LED_B, 0);
|
LED(LED_B, 0);
|
||||||
DbpString("[=] playing");
|
DbpString("[=] playing");
|
||||||
|
|
||||||
// wait for button to be released
|
WAIT_BUTTON_RELEASED();
|
||||||
while (BUTTON_PRESS())
|
|
||||||
WDT_HIT();
|
|
||||||
|
|
||||||
Dbprintf("[=] %x %x %08x", selected, high[selected], low[selected]);
|
Dbprintf("[=] %x %x %08x", selected, high[selected], low[selected]);
|
||||||
CmdHIDsimTAG(high[selected], low[selected], 0);
|
CmdHIDsimTAG(high[selected], low[selected], 0);
|
||||||
|
@ -168,16 +155,15 @@ void RunMod() {
|
||||||
|
|
||||||
LED(LED_B, 0);
|
LED(LED_B, 0);
|
||||||
DbpString("[=] entering bruteforce mode");
|
DbpString("[=] entering bruteforce mode");
|
||||||
// wait for button to be released
|
|
||||||
while (BUTTON_PRESS())
|
WAIT_BUTTON_RELEASED();
|
||||||
WDT_HIT();
|
|
||||||
|
|
||||||
// Calculate Facility Code and Card Number from high and low
|
// Calculate Facility Code and Card Number from high and low
|
||||||
uint32_t cardnum = (low[selected] >> 1) & 0xFFFFF;
|
uint32_t cardnum = (low[selected] >> 1) & 0xFFFFF;
|
||||||
uint32_t fc = ((high[selected] & 1) << 11) | (low[selected] >> 21);
|
uint32_t fc = ((high[selected] & 1) << 11) | (low[selected] >> 21);
|
||||||
uint32_t original_cardnum = cardnum;
|
uint32_t original_cardnum = cardnum;
|
||||||
|
|
||||||
Dbprintf("[=] Proxbrute - starting decrementing card number");
|
Dbprintf("[=] HID brute - starting decrementing card number");
|
||||||
|
|
||||||
while (cardnum > 0) {
|
while (cardnum > 0) {
|
||||||
|
|
||||||
|
@ -207,7 +193,7 @@ void RunMod() {
|
||||||
|
|
||||||
cardnum = original_cardnum;
|
cardnum = original_cardnum;
|
||||||
|
|
||||||
Dbprintf("[=] Proxbrute - starting incrementing card number");
|
Dbprintf("[=] HID brute - starting incrementing card number");
|
||||||
|
|
||||||
while (cardnum <= 0xFFFFF) {
|
while (cardnum <= 0xFFFFF) {
|
||||||
|
|
||||||
|
@ -247,13 +233,13 @@ void RunMod() {
|
||||||
LED(selected + 1, 0);
|
LED(selected + 1, 0);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
while (BUTTON_PRESS())
|
WAIT_BUTTON_RELEASED();
|
||||||
WDT_HIT();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
SpinErr((LED_A | LED_B | LED_C | LED_D), 250, 5);
|
||||||
DbpString("[=] exiting");
|
DbpString("[=] exiting");
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,6 @@
|
||||||
#include "ticks.h"
|
#include "ticks.h"
|
||||||
#include "lfops.h"
|
#include "lfops.h"
|
||||||
|
|
||||||
#define OPTS 2
|
|
||||||
|
|
||||||
void ModInfo(void) {
|
void ModInfo(void) {
|
||||||
DbpString(" LF HID ProxII bruteforce - aka Proxbrute (Brad Antoniewicz)");
|
DbpString(" LF HID ProxII bruteforce - aka Proxbrute (Brad Antoniewicz)");
|
||||||
}
|
}
|
||||||
|
@ -30,97 +28,56 @@ void RunMod() {
|
||||||
Dbprintf(">> LF HID proxII bruteforce a.k.a ProxBrute Started (Brad Antoniewicz) <<");
|
Dbprintf(">> LF HID proxII bruteforce a.k.a ProxBrute Started (Brad Antoniewicz) <<");
|
||||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||||
|
|
||||||
uint32_t high[OPTS], low[OPTS];
|
uint32_t high, low;
|
||||||
int selected = 0;
|
|
||||||
int playing = 0;
|
|
||||||
int cardRead = 0;
|
|
||||||
|
|
||||||
// Turn on selected LED
|
#define STATE_READ 0
|
||||||
LED(selected + 1, 0);
|
#define STATE_BRUTE 1
|
||||||
|
|
||||||
|
uint8_t state = STATE_READ;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
// exit from SamyRun, send a usbcommand.
|
// exit from SamyRun, send a usbcommand.
|
||||||
if (data_available()) break;
|
if (data_available()) break;
|
||||||
|
|
||||||
// Was our button held down or pressed?
|
// Was our button held down or pressed?
|
||||||
int button_pressed = BUTTON_HELD(1000);
|
int button_pressed = BUTTON_HELD(280);
|
||||||
SpinDelay(300);
|
if (button_pressed != BUTTON_HOLD)
|
||||||
|
continue;
|
||||||
|
|
||||||
// Button was held for a second, begin recording
|
// Button was held for a second, begin recording
|
||||||
if (button_pressed > 0 && cardRead == 0) {
|
if (state == STATE_READ) {
|
||||||
LEDsoff();
|
|
||||||
LED(selected + 1, 0);
|
LEDsoff();
|
||||||
LED(LED_D, 0);
|
LED_A_ON();
|
||||||
|
WAIT_BUTTON_RELEASED();
|
||||||
|
|
||||||
// record
|
|
||||||
DbpString("[=] starting recording");
|
DbpString("[=] starting recording");
|
||||||
|
|
||||||
// wait for button to be released
|
|
||||||
while (BUTTON_PRESS())
|
|
||||||
WDT_HIT();
|
|
||||||
|
|
||||||
/* need this delay to prevent catching some weird data */
|
// findone, high, low, no ledcontrol (A)
|
||||||
SpinDelay(500);
|
CmdHIDdemodFSK(1, &high, &low, 0);
|
||||||
|
|
||||||
CmdHIDdemodFSK(1, &high[selected], &low[selected], 0);
|
Dbprintf("[=] recorded | %x%08x", high, low);
|
||||||
Dbprintf("[=] recorded %x %x %08x", selected, high[selected], low[selected]);
|
|
||||||
|
|
||||||
LEDsoff();
|
// got nothing. blink and loop.
|
||||||
LED(selected + 1, 0);
|
if (high == 0 && low == 0) {
|
||||||
// Finished recording
|
SpinErr(LED_A, 100, 12);
|
||||||
// If we were previously playing, set playing off
|
DbpString("[=] only got zeros, retry recording after click");
|
||||||
// so next button push begins playing what we recorded
|
continue;
|
||||||
playing = 0;
|
|
||||||
cardRead = 1;
|
|
||||||
} else if (button_pressed > 0 && cardRead == 1) {
|
|
||||||
LEDsoff();
|
|
||||||
LED(selected + 1, 0);
|
|
||||||
LED(LED_A, 0);
|
|
||||||
|
|
||||||
// record
|
|
||||||
Dbprintf("[=] cloning %x %x %08x", selected, high[selected], low[selected]);
|
|
||||||
|
|
||||||
// wait for button to be released
|
|
||||||
while (BUTTON_PRESS())
|
|
||||||
WDT_HIT();
|
|
||||||
|
|
||||||
/* need this delay to prevent catching some weird data */
|
|
||||||
SpinDelay(500);
|
|
||||||
|
|
||||||
CopyHIDtoT55x7(0, high[selected], low[selected], 0);
|
|
||||||
Dbprintf("[=] cloned %x %x %08x", selected, high[selected], low[selected]);
|
|
||||||
|
|
||||||
LEDsoff();
|
|
||||||
LED(selected + 1, 0);
|
|
||||||
// Finished recording
|
|
||||||
|
|
||||||
// If we were previously playing, set playing off
|
|
||||||
// so next button push begins playing what we recorded
|
|
||||||
playing = 0;
|
|
||||||
cardRead = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change where to record (or begin playing)
|
SpinErr(LED_A, 250, 2);
|
||||||
else if (button_pressed) {
|
state = STATE_BRUTE;
|
||||||
// Next option if we were previously playing
|
continue;
|
||||||
if (playing)
|
|
||||||
selected = (selected + 1) % OPTS;
|
|
||||||
playing = !playing;
|
|
||||||
|
|
||||||
LEDsoff();
|
} else if (state == STATE_BRUTE) {
|
||||||
LED(selected + 1, 0);
|
|
||||||
|
|
||||||
// Begin transmitting
|
LED_C_ON(); // Simulate
|
||||||
if (playing) {
|
WAIT_BUTTON_RELEASED();
|
||||||
LED(LED_B, 0);
|
|
||||||
DbpString("[=] playing");
|
|
||||||
// wait for button to be released
|
|
||||||
while (BUTTON_PRESS())
|
|
||||||
WDT_HIT();
|
|
||||||
|
|
||||||
/* START PROXBRUTE */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ProxBrute - brad a. - foundstone
|
ProxBrute - brad a. - foundstone
|
||||||
|
@ -131,50 +88,32 @@ void RunMod() {
|
||||||
worked or not, so its a crap shoot. One option is to time how long
|
worked or not, so its a crap shoot. One option is to time how long
|
||||||
it takes to get a valid ID then start from scratch every time.
|
it takes to get a valid ID then start from scratch every time.
|
||||||
*/
|
*/
|
||||||
if (selected == 1) {
|
DbpString("[=] entering ProxBrute mode");
|
||||||
DbpString("[=] entering ProxBrute Mode");
|
Dbprintf("[=] simulating | %08x%08x", high, low);
|
||||||
Dbprintf("[=] current Tag: Selected = %x Facility = %08x ID = %08x", selected, high[selected], low[selected]);
|
|
||||||
LED(LED_A, 0);
|
for (uint16_t i = low - 1; i > 0; i--) {
|
||||||
LED(LED_C, 0);
|
|
||||||
for (uint16_t i = low[selected] - 1; i > 0; i--) {
|
if (data_available()) break;
|
||||||
if (BUTTON_PRESS()) {
|
|
||||||
DbpString("[-] told to stop");
|
// Was our button held down or pressed?
|
||||||
break;
|
int button_pressed = BUTTON_HELD(280);
|
||||||
|
if (button_pressed != BUTTON_HOLD) break;
|
||||||
|
|
||||||
|
Dbprintf("[=] trying Facility = %08x ID %08x", high, i);
|
||||||
|
|
||||||
|
// high, i, ledcontrol, timelimit 20000
|
||||||
|
CmdHIDsimTAGEx(high, i, false, 20000);
|
||||||
|
|
||||||
|
SpinDelay(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
Dbprintf("[=] trying Facility = %08x ID %08x", high[selected], i);
|
state = STATE_READ;
|
||||||
CmdHIDsimTAGEx(high[selected], i, 0, 20000);
|
SpinErr((LED_A | LED_C), 250, 2);
|
||||||
SpinDelay(500);
|
LEDsoff();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
|
||||||
DbpString("[=] RED is lit, not entering ProxBrute Mode");
|
SpinErr((LED_A | LED_B | LED_C | LED_D), 250, 5);
|
||||||
Dbprintf("[=] %x %x %x", selected, high[selected], low[selected]);
|
DbpString("[=] You can take the shell back :) ...");
|
||||||
CmdHIDsimTAGEx(high[selected], low[selected], 0, 20000);
|
|
||||||
DbpString("[=] done playing");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* END PROXBRUTE */
|
|
||||||
|
|
||||||
|
|
||||||
if (BUTTON_HELD(1000) > 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
/* We pressed a button so ignore it here with a delay */
|
|
||||||
SpinDelay(300);
|
|
||||||
|
|
||||||
// when done, we're done playing, move to next option
|
|
||||||
selected = (selected + 1) % OPTS;
|
|
||||||
playing = !playing;
|
|
||||||
LEDsoff();
|
|
||||||
LED(selected + 1, 0);
|
|
||||||
} else {
|
|
||||||
while (BUTTON_PRESS())
|
|
||||||
WDT_HIT();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out:
|
|
||||||
DbpString("[=] exiting");
|
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,6 +138,7 @@ void RunMod() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SpinErr((LED_A | LED_B | LED_C | LED_D), 250, 5);
|
||||||
DbpString("[=] You can take shell back :) ...");
|
DbpString("[=] You can take shell back :) ...");
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,6 +102,14 @@ static int usage_lf_em410x_brute(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////// 4050 / 4450 commands
|
//////////////// 4050 / 4450 commands
|
||||||
|
static int usage_lf_em4x50_demod(void) {
|
||||||
|
PrintAndLogEx(NORMAL, "Usage: lf em 4x50_demod [h]");
|
||||||
|
PrintAndLogEx(NORMAL, "Options:");
|
||||||
|
PrintAndLogEx(NORMAL, " h - this help");
|
||||||
|
PrintAndLogEx(NORMAL, "Examples:");
|
||||||
|
PrintAndLogEx(NORMAL, " lf em 4x50_demod");
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
static int usage_lf_em4x50_dump(void) {
|
static int usage_lf_em4x50_dump(void) {
|
||||||
PrintAndLogEx(NORMAL, "Dump EM4x50/EM4x69. Tag must be on antenna. ");
|
PrintAndLogEx(NORMAL, "Dump EM4x50/EM4x69. Tag must be on antenna. ");
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
@ -979,17 +987,25 @@ int EM4x50Read(const char *Cmd, bool verbose) {
|
||||||
return AllPTest ? PM3_SUCCESS : PM3_ESOFT;
|
return AllPTest ? PM3_SUCCESS : PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int CmdEM4x50Demod(const char *Cmd) {
|
||||||
|
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
|
||||||
|
if (ctmp == 'h') return usage_lf_em4x50_demod();
|
||||||
|
return EM4x50Read(Cmd, true);
|
||||||
|
}
|
||||||
|
|
||||||
static int CmdEM4x50Read(const char *Cmd) {
|
static int CmdEM4x50Read(const char *Cmd) {
|
||||||
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
|
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
|
||||||
if (ctmp == 'h') return usage_lf_em4x50_read();
|
if (ctmp == 'h') return usage_lf_em4x50_read();
|
||||||
return EM4x50Read(Cmd, true);
|
return EM4x50Read(Cmd, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CmdEM4x50Write(const char *Cmd) {
|
static int CmdEM4x50Write(const char *Cmd) {
|
||||||
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
|
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
|
||||||
if (ctmp == 'h') return usage_lf_em4x50_write();
|
if (ctmp == 'h') return usage_lf_em4x50_write();
|
||||||
PrintAndLogEx(NORMAL, "no implemented yet");
|
PrintAndLogEx(NORMAL, "no implemented yet");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CmdEM4x50Dump(const char *Cmd) {
|
static int CmdEM4x50Dump(const char *Cmd) {
|
||||||
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
|
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
|
||||||
if (ctmp == 'h') return usage_lf_em4x50_dump();
|
if (ctmp == 'h') return usage_lf_em4x50_dump();
|
||||||
|
@ -1531,6 +1547,7 @@ static command_t CommandTable[] = {
|
||||||
{"4x05_info", CmdEM4x05Info, IfPm3Lf, "tag information EM4x05/EM4x69"},
|
{"4x05_info", CmdEM4x05Info, IfPm3Lf, "tag information EM4x05/EM4x69"},
|
||||||
{"4x05_read", CmdEM4x05Read, IfPm3Lf, "read word data from EM4x05/EM4x69"},
|
{"4x05_read", CmdEM4x05Read, IfPm3Lf, "read word data from EM4x05/EM4x69"},
|
||||||
{"4x05_write", CmdEM4x05Write, IfPm3Lf, "write word data to EM4x05/EM4x69"},
|
{"4x05_write", CmdEM4x05Write, IfPm3Lf, "write word data to EM4x05/EM4x69"},
|
||||||
|
{"4x50_demod", CmdEM4x50Demod, AlwaysAvailable, "demodulate a EM4x50 tag from the GraphBuffer"},
|
||||||
{"4x50_dump", CmdEM4x50Dump, IfPm3Lf, "dump EM4x50 tag"},
|
{"4x50_dump", CmdEM4x50Dump, IfPm3Lf, "dump EM4x50 tag"},
|
||||||
{"4x50_read", CmdEM4x50Read, IfPm3Lf, "read word data from EM4x50"},
|
{"4x50_read", CmdEM4x50Read, IfPm3Lf, "read word data from EM4x50"},
|
||||||
{"4x50_write", CmdEM4x50Write, IfPm3Lf, "write word data to EM4x50"},
|
{"4x50_write", CmdEM4x50Write, IfPm3Lf, "write word data to EM4x50"},
|
||||||
|
|
|
@ -36,8 +36,17 @@
|
||||||
#define T55XX_DLMODE_1OF4 3 // 1 of 4
|
#define T55XX_DLMODE_1OF4 3 // 1 of 4
|
||||||
#define T55XX_LONGLEADINGREFERENCE 4 // Value to tell Write Bit to send long reference
|
#define T55XX_LONGLEADINGREFERENCE 4 // Value to tell Write Bit to send long reference
|
||||||
|
|
||||||
|
//static uint8_t bit_rates[9] = {8, 16, 32, 40, 50, 64, 100, 128, 0};
|
||||||
|
|
||||||
// Default configuration
|
// Default configuration
|
||||||
t55xx_conf_block_t config = { .modulation = DEMOD_ASK, .inverted = false, .offset = 0x00, .block0 = 0x00, .Q5 = false };
|
t55xx_conf_block_t config = {
|
||||||
|
.modulation = DEMOD_ASK,
|
||||||
|
.inverted = false,
|
||||||
|
.offset = 0x00,
|
||||||
|
.block0 = 0x00,
|
||||||
|
.Q5 = false,
|
||||||
|
.usepwd = false
|
||||||
|
};
|
||||||
|
|
||||||
t55xx_conf_block_t Get_t55xx_Config() {
|
t55xx_conf_block_t Get_t55xx_Config() {
|
||||||
return config;
|
return config;
|
||||||
|
@ -55,9 +64,10 @@ static void print_usage_t55xx_downloadlink(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int usage_t55xx_config() {
|
static int usage_t55xx_config() {
|
||||||
PrintAndLogEx(NORMAL, "Usage: lf t55xx config [d <demodulation>] [i [0/1]] [o <offset>] [Q5 [0/1]] [ST [0/1]]");
|
PrintAndLogEx(NORMAL, "Usage: lf t55xx config [c <blk0>] [d <demodulation>] [i [0/1]] [o <offset>] [Q5 [0/1]] [ST [0/1]]");
|
||||||
PrintAndLogEx(NORMAL, "Options:");
|
PrintAndLogEx(NORMAL, "Options:");
|
||||||
PrintAndLogEx(NORMAL, " h - This help");
|
PrintAndLogEx(NORMAL, " h - This help");
|
||||||
|
PrintAndLogEx(NORMAL, " c <block0> - set configuration from a block0");
|
||||||
PrintAndLogEx(NORMAL, " b <8|16|32|40|50|64|100|128> - Set bitrate");
|
PrintAndLogEx(NORMAL, " b <8|16|32|40|50|64|100|128> - Set bitrate");
|
||||||
PrintAndLogEx(NORMAL, " d <FSK|FSK1|FSK1a|FSK2|FSK2a|ASK|PSK1|PSK2|NRZ|BI|BIa> - Set demodulation FSK / ASK / PSK / NRZ / Biphase / Biphase A");
|
PrintAndLogEx(NORMAL, " d <FSK|FSK1|FSK1a|FSK2|FSK2a|ASK|PSK1|PSK2|NRZ|BI|BIa> - Set demodulation FSK / ASK / PSK / NRZ / Biphase / Biphase A");
|
||||||
PrintAndLogEx(NORMAL, " i [0/1] - Set/reset data signal inversion");
|
PrintAndLogEx(NORMAL, " i [0/1] - Set/reset data signal inversion");
|
||||||
|
@ -103,18 +113,20 @@ static int usage_t55xx_resetread() {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
static int usage_t55xx_write() {
|
static int usage_t55xx_write() {
|
||||||
PrintAndLogEx(NORMAL, "Usage: lf t55xx write [r <mode>] b <block> d <data> [p <password>] [1] [t]");
|
PrintAndLogEx(NORMAL, "Usage: lf t55xx write [r <mode>] b <block> d <data> [p <password>] [1] [t] [v]");
|
||||||
PrintAndLogEx(NORMAL, "Options:");
|
PrintAndLogEx(NORMAL, "Options:");
|
||||||
PrintAndLogEx(NORMAL, " b <block> - block number to write. Between 0-7");
|
PrintAndLogEx(NORMAL, " b <block> - block number to write. Between 0-7");
|
||||||
PrintAndLogEx(NORMAL, " d <data> - 4 bytes of data to write (8 hex characters)");
|
PrintAndLogEx(NORMAL, " d <data> - 4 bytes of data to write (8 hex characters)");
|
||||||
PrintAndLogEx(NORMAL, " p <password> - OPTIONAL password 4bytes (8 hex characters)");
|
PrintAndLogEx(NORMAL, " p <password> - OPTIONAL password 4bytes (8 hex characters)");
|
||||||
PrintAndLogEx(NORMAL, " 1 - OPTIONAL write Page 1 instead of Page 0");
|
PrintAndLogEx(NORMAL, " 1 - OPTIONAL write Page 1 instead of Page 0");
|
||||||
PrintAndLogEx(NORMAL, " t - OPTIONAL test mode write - ****DANGER****");
|
PrintAndLogEx(NORMAL, " t - OPTIONAL test mode write - ****DANGER****");
|
||||||
|
PrintAndLogEx(NORMAL, " v - OPTIONAL validate data afterwards");
|
||||||
print_usage_t55xx_downloadlink();
|
print_usage_t55xx_downloadlink();
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(NORMAL, "Examples:");
|
PrintAndLogEx(NORMAL, "Examples:");
|
||||||
PrintAndLogEx(NORMAL, " lf t55xx write b 3 d 11223344 - write 11223344 to block 3");
|
PrintAndLogEx(NORMAL, " lf t55xx write b 3 d 11223344 - write 11223344 to block 3");
|
||||||
PrintAndLogEx(NORMAL, " lf t55xx write b 3 d 11223344 p feedbeef - write 11223344 to block 3 password feedbeef");
|
PrintAndLogEx(NORMAL, " lf t55xx write b 3 d 11223344 p feedbeef - write 11223344 to block 3 password feedbeef");
|
||||||
|
PrintAndLogEx(NORMAL, " lf t55xx write b 3 d 11223344 v - write 11223344 to block 3 and try to validate data");
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -131,12 +143,12 @@ static int usage_t55xx_trace() {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
static int usage_t55xx_info() {
|
static int usage_t55xx_info() {
|
||||||
PrintAndLogEx(NORMAL, "Usage: lf t55xx info [1] [r <mode>] [d <data> [q]]");
|
PrintAndLogEx(NORMAL, "Usage: lf t55xx info [1] [r <mode>] [c <blk0> [q]]");
|
||||||
PrintAndLogEx(NORMAL, "Options:");
|
PrintAndLogEx(NORMAL, "Options:");
|
||||||
PrintAndLogEx(NORMAL, " (default) - read data from tag.");
|
PrintAndLogEx(NORMAL, " (default) - read data from tag.");
|
||||||
PrintAndLogEx(NORMAL, " p <password> - OPTIONAL password 4bytes (8 hex symbols)");
|
PrintAndLogEx(NORMAL, " p <password> - OPTIONAL password 4bytes (8 hex symbols)");
|
||||||
PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer instead of reading tag.");
|
PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer instead of reading tag.");
|
||||||
PrintAndLogEx(NORMAL, " d <data> - 4 bytes of data (8 hex characters)");
|
PrintAndLogEx(NORMAL, " c <block0> - set configuration from a block0");
|
||||||
PrintAndLogEx(NORMAL, " if set, use these data instead of reading tag.");
|
PrintAndLogEx(NORMAL, " if set, use these data instead of reading tag.");
|
||||||
PrintAndLogEx(NORMAL, " q - if set, provided data are interpreted as Q5 config.");
|
PrintAndLogEx(NORMAL, " q - if set, provided data are interpreted as Q5 config.");
|
||||||
print_usage_t55xx_downloadlink();
|
print_usage_t55xx_downloadlink();
|
||||||
|
@ -296,6 +308,48 @@ static int usage_lf_deviceconfig() {
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
|
static bool t55xxVerifyWrite( uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, uint32_t data) {
|
||||||
|
|
||||||
|
//Password mode
|
||||||
|
if (usepwd) {
|
||||||
|
// try reading the config block and verify that PWD bit is set before doing this!
|
||||||
|
if (override == 0) {
|
||||||
|
if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0, downlink_mode) == false)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (tryDetectModulation() == false) {
|
||||||
|
PrintAndLogEx(NORMAL, "Safety Check: Could not detect if PWD bit is set in config block. Exits.");
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(NORMAL, "Safety Check: PWD bit is NOT set in config block. Reading without password...");
|
||||||
|
usepwd = false;
|
||||||
|
}
|
||||||
|
} else if (override == 1) {
|
||||||
|
PrintAndLogEx(NORMAL, "Safety Check Overriden - proceeding despite risk");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AquireData(page1, block, usepwd, password, downlink_mode) == false)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (block == 0 && page1 == false) {
|
||||||
|
if (tryDetectModulation() == false) {
|
||||||
|
PrintAndLogEx(WARNING, "Could not detect modulation automatically. Try setting it manually with \'lf t55xx config\'");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DecodeT55xxBlock() == false)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// compare...
|
||||||
|
uint32_t readblock = 0;
|
||||||
|
if (GetT55xxBlockData(&readblock) == false)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return (readblock == data);
|
||||||
|
}
|
||||||
|
|
||||||
void printT5xxHeader(uint8_t page) {
|
void printT5xxHeader(uint8_t page) {
|
||||||
PrintAndLogEx(NORMAL, "Reading Page %d:", page);
|
PrintAndLogEx(NORMAL, "Reading Page %d:", page);
|
||||||
PrintAndLogEx(NORMAL, "blk | hex data | binary | ascii");
|
PrintAndLogEx(NORMAL, "blk | hex data | binary | ascii");
|
||||||
|
@ -312,6 +366,9 @@ static int CmdT55xxSetConfig(const char *Cmd) {
|
||||||
uint8_t rates[9] = {8, 16, 32, 40, 50, 64, 100, 128, 0};
|
uint8_t rates[9] = {8, 16, 32, 40, 50, 64, 100, 128, 0};
|
||||||
uint8_t cmdp = 0;
|
uint8_t cmdp = 0;
|
||||||
bool errors = false;
|
bool errors = false;
|
||||||
|
uint32_t block0 = 0;
|
||||||
|
bool gotconf = false;
|
||||||
|
|
||||||
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||||
char tmp = tolower(param_getchar(Cmd, cmdp));
|
char tmp = tolower(param_getchar(Cmd, cmdp));
|
||||||
switch (tmp) {
|
switch (tmp) {
|
||||||
|
@ -331,6 +388,11 @@ static int CmdT55xxSetConfig(const char *Cmd) {
|
||||||
}
|
}
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
break;
|
break;
|
||||||
|
case 'c':
|
||||||
|
block0 = param_get32ex(Cmd, cmdp + 1, 0, 16);
|
||||||
|
gotconf = true;
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
param_getstr(Cmd, cmdp + 1, modulation, sizeof(modulation));
|
param_getstr(Cmd, cmdp + 1, modulation, sizeof(modulation));
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
|
@ -413,7 +475,36 @@ static int CmdT55xxSetConfig(const char *Cmd) {
|
||||||
//Validations
|
//Validations
|
||||||
if (errors) return usage_t55xx_config();
|
if (errors) return usage_t55xx_config();
|
||||||
|
|
||||||
|
if ( gotconf ) {
|
||||||
|
|
||||||
|
// Q5
|
||||||
|
|
||||||
|
|
||||||
|
// T55x7
|
||||||
|
uint32_t extend = (block0 >> (32 - 15)) & 0x01;
|
||||||
|
uint32_t dbr;
|
||||||
|
if (extend)
|
||||||
|
dbr = (block0 >> (32 - 14)) & 0x3F;
|
||||||
|
else
|
||||||
|
dbr = (block0 >> (32 - 14)) & 0x07;
|
||||||
|
|
||||||
|
uint32_t datamod = (block0 >> (32 - 20)) & 0x1F;
|
||||||
|
bool pwd = (bool)((block0 >> (32 - 28)) & 0x01);
|
||||||
|
bool sst = (bool)((block0 >> (32 - 29)) & 0x01);
|
||||||
|
bool inv = (bool)((block0 >> (32 - 31)) & 0x01);
|
||||||
|
|
||||||
|
config.modulation = datamod;
|
||||||
|
config.bitrate = dbr;
|
||||||
|
config.inverted = inv;
|
||||||
|
config.Q5 = 0;
|
||||||
|
config.ST = sst;
|
||||||
|
config.usepwd = pwd;
|
||||||
|
config.offset = 0;
|
||||||
|
config.block0 = block0;
|
||||||
|
} else {
|
||||||
config.block0 = 0;
|
config.block0 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return printConfiguration(config);
|
return printConfiguration(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1014,11 +1105,14 @@ static bool testQ5(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk)
|
||||||
si += 3;
|
si += 3;
|
||||||
//uint8_t ST = PackBits(si, 1, DemodBuffer); si += 1;
|
//uint8_t ST = PackBits(si, 1, DemodBuffer); si += 1;
|
||||||
if (maxBlk == 0) continue;
|
if (maxBlk == 0) continue;
|
||||||
|
|
||||||
//test modulation
|
//test modulation
|
||||||
if (!testQ5Modulation(mode, modread)) continue;
|
if (!testQ5Modulation(mode, modread)) continue;
|
||||||
if (bitRate != clk) continue;
|
if (bitRate != clk) continue;
|
||||||
|
|
||||||
*fndBitRate = convertQ5bitRate(bitRate);
|
*fndBitRate = convertQ5bitRate(bitRate);
|
||||||
if (*fndBitRate < 0) continue;
|
if (*fndBitRate < 0) continue;
|
||||||
|
|
||||||
*offset = idx;
|
*offset = idx;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1174,6 +1268,7 @@ static int CmdT55xxWriteBlock(const char *Cmd) {
|
||||||
bool gotdata = false;
|
bool gotdata = false;
|
||||||
bool testMode = false;
|
bool testMode = false;
|
||||||
bool errors = false;
|
bool errors = false;
|
||||||
|
bool validate = false;
|
||||||
uint8_t cmdp = 0;
|
uint8_t cmdp = 0;
|
||||||
uint32_t downlink_mode = 0;
|
uint32_t downlink_mode = 0;
|
||||||
|
|
||||||
|
@ -1215,6 +1310,10 @@ static int CmdT55xxWriteBlock(const char *Cmd) {
|
||||||
|
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
break;
|
break;
|
||||||
|
case 'v':
|
||||||
|
validate = true;
|
||||||
|
cmdp++;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||||
errors = true;
|
errors = true;
|
||||||
|
@ -1235,8 +1334,6 @@ static int CmdT55xxWriteBlock(const char *Cmd) {
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "Writing page %d block: %02d data: 0x%08X %s", page1, block, data, (usepwd) ? pwdStr : "");
|
PrintAndLogEx(INFO, "Writing page %d block: %02d data: 0x%08X %s", page1, block, data, (usepwd) ? pwdStr : "");
|
||||||
|
|
||||||
clearCommandBuffer();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
OLD style
|
OLD style
|
||||||
arg0 = data, (4 bytes)
|
arg0 = data, (4 bytes)
|
||||||
|
@ -1253,11 +1350,22 @@ static int CmdT55xxWriteBlock(const char *Cmd) {
|
||||||
ng.blockno = block;
|
ng.blockno = block;
|
||||||
ng.flags = flags;
|
ng.flags = flags;
|
||||||
|
|
||||||
|
clearCommandBuffer();
|
||||||
SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng));
|
SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng));
|
||||||
if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, 2000)) {
|
if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, 2000)) {
|
||||||
PrintAndLogEx(ERR, "Error occurred, device did not ACK write operation. (May be due to old firmware)");
|
PrintAndLogEx(ERR, "Error occurred, device did not ACK write operation. (May be due to old firmware)");
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (validate) {
|
||||||
|
//t55xxVerifyWrite( uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, uint32_t data) {
|
||||||
|
bool isOK = t55xxVerifyWrite(block, page1, usepwd, 1, password, downlink_mode, data);
|
||||||
|
if (isOK)
|
||||||
|
PrintAndLogEx(SUCCESS, "Write OK, validation succesful");
|
||||||
|
else
|
||||||
|
PrintAndLogEx(WARNING, "Write could not validate the written data");
|
||||||
|
}
|
||||||
|
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1550,7 +1658,7 @@ static int CmdT55xxInfo(const char *Cmd) {
|
||||||
switch (tolower(param_getchar(Cmd, cmdp))) {
|
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||||
case 'h':
|
case 'h':
|
||||||
return usage_t55xx_info();
|
return usage_t55xx_info();
|
||||||
case 'd':
|
case 'c':
|
||||||
block0 = param_get32ex(Cmd, cmdp + 1, 0, 16);
|
block0 = param_get32ex(Cmd, cmdp + 1, 0, 16);
|
||||||
gotdata = true;
|
gotdata = true;
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
|
|
|
@ -116,6 +116,7 @@ typedef struct {
|
||||||
} bitrate;
|
} bitrate;
|
||||||
bool Q5;
|
bool Q5;
|
||||||
bool ST;
|
bool ST;
|
||||||
|
bool usepwd;
|
||||||
} t55xx_conf_block_t;
|
} t55xx_conf_block_t;
|
||||||
|
|
||||||
t55xx_conf_block_t Get_t55xx_Config(void);
|
t55xx_conf_block_t Get_t55xx_Config(void);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue