// Low frequency EM4x commands
//-----------------------------------------------------------------------------
+#include "cmdlfem4x.h"
+
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
-#include "cmdlfem4x.h"
-#include "proxmark3.h"
+#include "comms.h"
#include "ui.h"
#include "util.h"
-#include "data.h"
#include "graph.h"
#include "cmdparser.h"
#include "cmddata.h"
}
int usage_lf_em410x_brute(void) {
- PrintAndLog("Bruteforcing by emulating EM410x tag");
- PrintAndLog("");
- PrintAndLog("Usage: lf em 410xbrute [h] ids.txt [d 2000] [clock]");
- PrintAndLog("Options:");
- PrintAndLog(" h - this help");
- PrintAndLog(" ids.txt - file with UIDs in HEX format one per line");
- PrintAndLog(" d (2000) - pause delay in milliseonds between UIDs simulation, default 1000ms (optional)");
- PrintAndLog(" clock - clock (32|64), default 64 (optional)");
- PrintAndLog("samples:");
- PrintAndLog(" lf em 410xbrute ids.txt");
- PrintAndLog(" lf em 410xbrute ids.txt 32");
- PrintAndLog(" lf em 410xbrute ids.txt d 3000 32");
+ PrintAndLog("Bruteforcing by emulating EM410x tag");
+ PrintAndLog("");
+ PrintAndLog("Usage: lf em 410xbrute [h] ids.txt [d 2000] [c clock]");
+ PrintAndLog("Options:");
+ PrintAndLog(" h - this help");
+ PrintAndLog(" ids.txt - file with UIDs in HEX format, one per line");
+ PrintAndLog(" d (2000) - pause delay in milliseconds between UIDs simulation, default 1000 ms (optional)");
+ PrintAndLog(" c (32) - clock (32|64), default 64 (optional)");
+ PrintAndLog("samples:");
+ PrintAndLog(" lf em 410xbrute ids.txt");
+ PrintAndLog(" lf em 410xbrute ids.txt c 32");
+ PrintAndLog(" lf em 410xbrute ids.txt d 3000");
+ PrintAndLog(" lf em 410xbrute ids.txt d 3000 c 32");
return 0;
}
uint8_t clock = 64;
/* default pause time: 1 second */
uint32_t delay = 1000;
- char delaystr[32] = {0x00};
char cmdp = param_getchar(Cmd, 0);
cmdp = param_getchar(Cmd, 1);
if (cmdp == 'd' || cmdp == 'D') {
- param_getstr(Cmd,2, delaystr);
- if (strlen(delaystr) > 0) delay = (uint32_t) atoi(delaystr);
- param_getdec(Cmd,3, &clock);
- } else {
- param_getdec(Cmd,1, &clock);
+ delay = param_get32ex(Cmd, 2, 1000, 10);
+ param_getdec(Cmd, 4, &clock);
+ } else if (cmdp == 'c' || cmdp == 'C') {
+ param_getdec(Cmd, 2, &clock);
+ delay = param_get32ex(Cmd, 4, 1000, 10);
}
- param_getstr(Cmd, 0, filename);
+ param_getstr(Cmd, 0, filename, sizeof(filename));
uidBlock = calloc(stUidBlock, 5);
if (uidBlock == NULL) return 1;
return 0;
}
- sprintf(testuid, "%010lX", bytes_to_num(uidBlock + 5*c, 5));
+ sprintf(testuid, "%010" PRIX64, bytes_to_num(uidBlock + 5*c, 5));
PrintAndLog("Bruteforce %d / %d: simulating UID %s, clock %d", c + 1, uidcnt, testuid, clock);
ConstructEM410xEmulGraph(testuid, clock);
char tmp2[20];
int phaseoff;
high = low = 0;
- memset(tmpbuff, 0, MAX_GRAPH_TRACE_LEN / 64);
+ memset(tmpbuff, 0, sizeof(tmpbuff));
// get user entry if any
sscanf(Cmd, "%i %i", &clk, &invert);
bool downloadSamplesEM() {
// 8 bit preamble + 32 bit word response (max clock (128) * 40bits = 5120 samples)
uint8_t got[6000];
- GetFromBigBuf(got, sizeof(got), 0);
- if ( !WaitForResponseTimeout(CMD_ACK, NULL, 4000) ) {
+ if (!GetFromBigBuf(got, sizeof(got), 0, NULL, 4000, true)) {
PrintAndLog("command execution time out");
return false;
}
}
int testLen = (GraphTraceLen < 1000) ? GraphTraceLen : 1000;
if (graphJustNoise(GraphBuffer, testLen)) {
- PrintAndLog("no tag not found");
return -1;
}
//attempt demod:
return EM4x05WriteWord(addr, data, pwd, usePwd, swap, invert);
}
+int usage_lf_em_protect(void) {
+ PrintAndLog("Protect EM4x05. Tag must be on antenna. ");
+ PrintAndLog("");
+ PrintAndLog("Usage: lf em 4x05protect [h] d <data> p <pwd> [s] [i]");
+ PrintAndLog("Options:");
+ PrintAndLog(" h - this help");
+ PrintAndLog(" d <data> - data to write (hex)");
+ PrintAndLog(" p <pwd> - password (hex) (optional)");
+ PrintAndLog(" s - swap the data bit order before write");
+ PrintAndLog(" i - invert the data bits before write");
+ PrintAndLog("samples:");
+ PrintAndLog(" lf em 4x05protect d 11223344");
+ PrintAndLog(" lf em 4x05protect p deadc0de d 11223344 s i");
+ return 0;
+}
+
+int EM4x05Protect(uint32_t data, uint32_t pwd, bool usePwd, bool swap, bool invert) {
+ if (swap) data = SwapBits(data, 32);
+
+ if (invert) data ^= 0xFFFFFFFF;
+
+ if ( !usePwd ) {
+ PrintAndLog("Writing Protect data %08X", data);
+ } else {
+ PrintAndLog("Writing Protect data %08X using password %08X", data, pwd);
+ }
+
+ uint16_t flag = usePwd;
+
+ UsbCommand c = {CMD_EM4X_PROTECT, {flag, data, pwd}};
+ clearCommandBuffer();
+ SendCommand(&c);
+ UsbCommand resp;
+ if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)){
+ PrintAndLog("Error occurred, device did not respond during protect operation.");
+ return -1;
+ }
+ if ( !downloadSamplesEM() ) {
+ return -1;
+ }
+ //check response for 00001010 for write confirmation!
+ //attempt demod:
+ uint32_t dummy = 0;
+ int result = demodEM4x05resp(&dummy,false);
+ if (result == 1) {
+ PrintAndLog("Protect Verified");
+ } else {
+ PrintAndLog("Protect could not be verified");
+ }
+ return result;
+}
+
+int CmdEM4x05ProtectWrite(const char *Cmd) {
+ bool errors = false;
+ bool usePwd = false;
+ uint32_t data = 0xFFFFFFFF;
+ uint32_t pwd = 0xFFFFFFFF;
+ bool swap = false;
+ bool invert = false;
+ bool gotData = false;
+ char cmdp = 0;
+ while(param_getchar(Cmd, cmdp) != 0x00)
+ {
+ switch(param_getchar(Cmd, cmdp))
+ {
+ case 'h':
+ case 'H':
+ return usage_lf_em_write();
+ case 'd':
+ case 'D':
+ data = param_get32ex(Cmd, cmdp+1, 0, 16);
+ gotData = true;
+ cmdp += 2;
+ break;
+ case 'i':
+ case 'I':
+ invert = true;
+ cmdp++;
+ break;
+ case 'p':
+ case 'P':
+ pwd = param_get32ex(Cmd, cmdp+1, 1, 16);
+ if (pwd == 1) {
+ PrintAndLog("invalid pwd");
+ errors = true;
+ }
+ usePwd = true;
+ cmdp += 2;
+ break;
+ case 's':
+ case 'S':
+ swap = true;
+ cmdp++;
+ break;
+ default:
+ PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
+ errors = true;
+ break;
+ }
+ if(errors) break;
+ }
+ //Validations
+ if(errors) return usage_lf_em_protect();
+
+ if ( strlen(Cmd) == 0 ) return usage_lf_em_protect();
+
+ if (!gotData) {
+ PrintAndLog("You must enter the data you want to write");
+ return usage_lf_em_protect();
+ }
+ return EM4x05Protect(data, pwd, usePwd, swap, invert);
+}
+
void printEM4x05config(uint32_t wordData) {
uint16_t datarate = EM4x05_GET_BITRATE(wordData);
uint8_t encoder = ((wordData >> 6) & 0xF);
{"410xread", CmdEMdemodASK, 0, "[findone] -- Extract ID from EM410x tag (option 0 for continuous loop, 1 for only 1 tag)"},
{"410xdemod", CmdAskEM410xDemod, 1, "[clock] [invert<0|1>] [maxErr] -- Demodulate an EM410x tag from GraphBuffer (args optional)"},
{"410xsim", CmdEM410xSim, 0, "<UID> [clock rate] -- Simulate EM410x tag"},
- {"410xbrute", CmdEM410xBrute, 0, "ids.txt [d (delay in ms)] [clock rate] -- Bruteforcing by simulating EM410x tags (1 UID/s)"},
+ {"410xbrute", CmdEM410xBrute, 0, "ids.txt [d (delay in ms)] [c (clock rate)] -- Reader bruteforce attack by simulating EM410x tags"},
{"410xwatch", CmdEM410xWatch, 0, "['h'] -- Watches for EM410x 125/134 kHz tags (option 'h' for 134)"},
{"410xspoof", CmdEM410xWatchnSpoof, 0, "['h'] --- Watches for EM410x 125/134 kHz tags, and replays them. (option 'h' for 134)" },
{"410xwrite", CmdEM410xWrite, 0, "<UID> <'0' T5555> <'1' T55x7> [clock rate] -- Write EM410x UID to T5555(Q5) or T55x7 tag, optionally setting clock rate"},
{"4x05info", CmdEM4x05info, 0, "(pwd) -- Get info from EM4x05/EM4x69 tag"},
{"4x05readword", CmdEM4x05ReadWord, 0, "<Word> (pwd) -- Read EM4x05/EM4x69 word data"},
{"4x05writeword", CmdEM4x05WriteWord, 0, "<Word> <data> (pwd) -- Write EM4x05/EM4x69 word data"},
+ {"4x05protect", CmdEM4x05ProtectWrite, 0, "<data> (pwd) -- Write Protection to EM4x05"},
{"4x50read", CmdEM4x50Read, 1, "demod data from EM4x50 tag from the graph buffer"},
{NULL, NULL, 0, NULL}
};