mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
enable tearoff for LF EM 4x50_WRITE & EM_WRITE_PASSWORD
This commit is contained in:
parent
125548a44c
commit
d8b2dc2ebf
2 changed files with 63 additions and 39 deletions
|
@ -14,6 +14,7 @@
|
||||||
#include "lfadc.h"
|
#include "lfadc.h"
|
||||||
#include "commonutil.h"
|
#include "commonutil.h"
|
||||||
#include "em4x50.h"
|
#include "em4x50.h"
|
||||||
|
#include "appmain.h" // tear
|
||||||
|
|
||||||
// 4 data bytes
|
// 4 data bytes
|
||||||
// + byte with row parities
|
// + byte with row parities
|
||||||
|
@ -470,6 +471,8 @@ static bool find_double_listen_window(bool bcommand) {
|
||||||
|
|
||||||
if (bcommand) {
|
if (bcommand) {
|
||||||
|
|
||||||
|
// SpinDelay(10);
|
||||||
|
|
||||||
// data transmission from card has to be stopped, because
|
// data transmission from card has to be stopped, because
|
||||||
// a commamd shall be issued
|
// a commamd shall be issued
|
||||||
|
|
||||||
|
@ -816,7 +819,7 @@ void em4x50_info(em4x50_data_t *etd) {
|
||||||
status = (bsuccess << 1) + blogin;
|
status = (bsuccess << 1) + blogin;
|
||||||
|
|
||||||
lf_finalize();
|
lf_finalize();
|
||||||
reply_ng(CMD_ACK, status, (uint8_t *)tag.sectors, 238);
|
reply_ng(CMD_LF_EM4X50_INFO, status, (uint8_t *)tag.sectors, 238);
|
||||||
}
|
}
|
||||||
|
|
||||||
void em4x50_read(em4x50_data_t *etd) {
|
void em4x50_read(em4x50_data_t *etd) {
|
||||||
|
@ -860,14 +863,13 @@ void em4x50_read(em4x50_data_t *etd) {
|
||||||
status = (now << 2) + (bsuccess << 1) + blogin;
|
status = (now << 2) + (bsuccess << 1) + blogin;
|
||||||
|
|
||||||
lf_finalize();
|
lf_finalize();
|
||||||
reply_ng(CMD_ACK, status, (uint8_t *)tag.sectors, 238);
|
reply_ng(CMD_LF_EM4X50_READ, status, (uint8_t *)tag.sectors, 238);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
// write functions
|
// write functions
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
static int write(uint8_t word[4], uint8_t address) {
|
||||||
static bool write(uint8_t word[4], uint8_t address) {
|
|
||||||
|
|
||||||
// writes <word> to specified <address>
|
// writes <word> to specified <address>
|
||||||
|
|
||||||
|
@ -882,17 +884,23 @@ static bool write(uint8_t word[4], uint8_t address) {
|
||||||
// send data
|
// send data
|
||||||
em4x50_send_word(word);
|
em4x50_send_word(word);
|
||||||
|
|
||||||
// wait for T0 * EM4X50_T_TAG_TWA (write access time)
|
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured
|
||||||
wait_timer(FPGA_TIMER_0, T0 * EM4X50_T_TAG_TWA);
|
reply_ng(CMD_LF_EM4X50_WRITE, PM3_ETEAROFF, NULL, 0);
|
||||||
|
return PM3_ETEAROFF;
|
||||||
|
} else {
|
||||||
|
|
||||||
// look for ACK sequence
|
// wait for T0 * EM4X50_T_TAG_TWA (write access time)
|
||||||
if (check_ack(false)) {
|
wait_timer(FPGA_TIMER_0, T0 * EM4X50_T_TAG_TWA);
|
||||||
|
|
||||||
// now EM4x50 needs T0 * EM4X50_T_TAG_TWEE (EEPROM write time)
|
// look for ACK sequence
|
||||||
// for saving data and should return with ACK
|
if (check_ack(false)) {
|
||||||
if (check_ack(false))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
|
// now EM4x50 needs T0 * EM4X50_T_TAG_TWEE (EEPROM write time)
|
||||||
|
// for saving data and should return with ACK
|
||||||
|
if (check_ack(false))
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -900,10 +908,10 @@ static bool write(uint8_t word[4], uint8_t address) {
|
||||||
Dbprintf("error in command request");
|
Dbprintf("error in command request");
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool write_password(uint8_t password[4], uint8_t new_password[4]) {
|
static int write_password(uint8_t password[4], uint8_t new_password[4]) {
|
||||||
|
|
||||||
// changes password from <password> to <new_password>
|
// changes password from <password> to <new_password>
|
||||||
|
|
||||||
|
@ -915,23 +923,29 @@ static bool write_password(uint8_t password[4], uint8_t new_password[4]) {
|
||||||
// send address data
|
// send address data
|
||||||
em4x50_send_word(password);
|
em4x50_send_word(password);
|
||||||
|
|
||||||
// wait for T0 * EM4x50_T_TAG_TPP (processing pause time)
|
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured
|
||||||
wait_timer(FPGA_TIMER_0, T0 * EM4X50_T_TAG_TPP);
|
reply_ng(CMD_LF_EM4X50_WRITE, PM3_ETEAROFF, NULL, 0);
|
||||||
|
return PM3_ETEAROFF;
|
||||||
|
} else {
|
||||||
|
|
||||||
// look for ACK sequence and send rm request
|
// wait for T0 * EM4x50_T_TAG_TPP (processing pause time)
|
||||||
// during following listen window
|
wait_timer(FPGA_TIMER_0, T0 * EM4X50_T_TAG_TPP);
|
||||||
if (check_ack(true)) {
|
|
||||||
|
|
||||||
// send new password
|
// look for ACK sequence and send rm request
|
||||||
em4x50_send_word(new_password);
|
// during following listen window
|
||||||
|
if (check_ack(true)) {
|
||||||
|
|
||||||
// wait for T0 * EM4X50_T_TAG_TWA (write access time)
|
// send new password
|
||||||
wait_timer(FPGA_TIMER_0, T0 * EM4X50_T_TAG_TWA);
|
em4x50_send_word(new_password);
|
||||||
|
|
||||||
|
// wait for T0 * EM4X50_T_TAG_TWA (write access time)
|
||||||
|
wait_timer(FPGA_TIMER_0, T0 * EM4X50_T_TAG_TWA);
|
||||||
|
|
||||||
if (check_ack(false))
|
|
||||||
if (check_ack(false))
|
if (check_ack(false))
|
||||||
return true;
|
if (check_ack(false))
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -939,7 +953,7 @@ static bool write_password(uint8_t password[4], uint8_t new_password[4]) {
|
||||||
Dbprintf("error in command request");
|
Dbprintf("error in command request");
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void em4x50_write(em4x50_data_t *etd) {
|
void em4x50_write(em4x50_data_t *etd) {
|
||||||
|
@ -966,8 +980,13 @@ void em4x50_write(em4x50_data_t *etd) {
|
||||||
blogin = login(etd->password);
|
blogin = login(etd->password);
|
||||||
|
|
||||||
// write word to given address
|
// write word to given address
|
||||||
if (write(etd->word, etd->address)) {
|
int res = write(etd->word, etd->address);
|
||||||
|
if (res == PM3_ETEAROFF) {
|
||||||
|
lf_finalize();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res == PM3_SUCCESS) {
|
||||||
// to verify result reset EM4x50
|
// to verify result reset EM4x50
|
||||||
if (reset()) {
|
if (reset()) {
|
||||||
|
|
||||||
|
@ -996,9 +1015,8 @@ void em4x50_write(em4x50_data_t *etd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
status = (bsuccess << 1) + blogin;
|
status = (bsuccess << 1) + blogin;
|
||||||
|
|
||||||
lf_finalize();
|
lf_finalize();
|
||||||
reply_ng(CMD_ACK, status, (uint8_t *)tag.sectors, 238);
|
reply_ng(CMD_LF_EM4X50_WRITE, status, (uint8_t *)tag.sectors, 238);
|
||||||
}
|
}
|
||||||
|
|
||||||
void em4x50_write_password(em4x50_data_t *etd) {
|
void em4x50_write_password(em4x50_data_t *etd) {
|
||||||
|
@ -1015,12 +1033,18 @@ void em4x50_write_password(em4x50_data_t *etd) {
|
||||||
|
|
||||||
// login and change password
|
// login and change password
|
||||||
if (login(etd->password)) {
|
if (login(etd->password)) {
|
||||||
bsuccess = write_password(etd->password, etd->new_password);
|
|
||||||
|
int res = write_password(etd->password, etd->new_password);
|
||||||
|
if (res == PM3_ETEAROFF) {
|
||||||
|
lf_finalize();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bsuccess = (res == PM3_SUCCESS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lf_finalize();
|
lf_finalize();
|
||||||
reply_ng(CMD_ACK, bsuccess, 0, 0);
|
reply_ng(CMD_LF_EM4X50_WRITE_PASSWORD, bsuccess, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void em4x50_wipe(em4x50_data_t *etd) {
|
void em4x50_wipe(em4x50_data_t *etd) {
|
||||||
|
@ -1078,5 +1102,5 @@ void em4x50_wipe(em4x50_data_t *etd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
lf_finalize();
|
lf_finalize();
|
||||||
reply_ng(CMD_ACK, bsuccess, (uint8_t *)tag.sectors, 238);
|
reply_ng(CMD_LF_EM4X50_WIPE, bsuccess, (uint8_t *)tag.sectors, 238);
|
||||||
}
|
}
|
||||||
|
|
|
@ -315,7 +315,7 @@ int CmdEM4x50Info(const char *Cmd) {
|
||||||
SendCommandNG(CMD_LF_EM4X50_INFO, (uint8_t *)&etd, sizeof(etd));
|
SendCommandNG(CMD_LF_EM4X50_INFO, (uint8_t *)&etd, sizeof(etd));
|
||||||
|
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, TIMEOUT)) {
|
if (!WaitForResponseTimeout(CMD_LF_EM4X50_INFO, &resp, TIMEOUT)) {
|
||||||
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
|
@ -388,7 +388,7 @@ int CmdEM4x50Write(const char *Cmd) {
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandNG(CMD_LF_EM4X50_WRITE, (uint8_t *)&etd, sizeof(etd));
|
SendCommandNG(CMD_LF_EM4X50_WRITE, (uint8_t *)&etd, sizeof(etd));
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, TIMEOUT)) {
|
if (!WaitForResponseTimeout(CMD_LF_EM4X50_WRITE, &resp, TIMEOUT)) {
|
||||||
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
|
@ -483,7 +483,7 @@ int CmdEM4x50WritePassword(const char *Cmd) {
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandNG(CMD_LF_EM4X50_WRITE_PASSWORD, (uint8_t *)&etd, sizeof(etd));
|
SendCommandNG(CMD_LF_EM4X50_WRITE_PASSWORD, (uint8_t *)&etd, sizeof(etd));
|
||||||
|
|
||||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, TIMEOUT)) {
|
if (!WaitForResponseTimeout(CMD_LF_EM4X50_WRITE_PASSWORD, &resp, TIMEOUT)) {
|
||||||
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
|
@ -515,7 +515,7 @@ int em4x50_read(em4x50_data_t *etd, em4x50_word_t *out, bool verbose) {
|
||||||
SendCommandNG(CMD_LF_EM4X50_READ, (uint8_t *)&edata, sizeof(edata));
|
SendCommandNG(CMD_LF_EM4X50_READ, (uint8_t *)&edata, sizeof(edata));
|
||||||
|
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, TIMEOUT)) {
|
if (!WaitForResponseTimeout(CMD_LF_EM4X50_READ, &resp, TIMEOUT)) {
|
||||||
PrintAndLogEx(WARNING, "(em4x50) timeout while waiting for reply.");
|
PrintAndLogEx(WARNING, "(em4x50) timeout while waiting for reply.");
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
|
@ -651,7 +651,7 @@ int CmdEM4x50Dump(const char *Cmd) {
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandNG(CMD_LF_EM4X50_INFO, (uint8_t *)&etd, sizeof(etd));
|
SendCommandNG(CMD_LF_EM4X50_INFO, (uint8_t *)&etd, sizeof(etd));
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, TIMEOUT)) {
|
if (!WaitForResponseTimeout(CMD_LF_EM4X50_INFO, &resp, TIMEOUT)) {
|
||||||
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
|
@ -726,7 +726,7 @@ int CmdEM4x50Wipe(const char *Cmd) {
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandNG(CMD_LF_EM4X50_WIPE, (uint8_t *)&etd, sizeof(etd));
|
SendCommandNG(CMD_LF_EM4X50_WIPE, (uint8_t *)&etd, sizeof(etd));
|
||||||
|
|
||||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2 * TIMEOUT)) {
|
if (!WaitForResponseTimeout(CMD_LF_EM4X50_WIPE, &resp, 2 * TIMEOUT)) {
|
||||||
PrintAndLogEx(WARNING, "\ntimeout while waiting for reply.\n");
|
PrintAndLogEx(WARNING, "\ntimeout while waiting for reply.\n");
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue