diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..d3d86ee80 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,55 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "(gdb) Attach", + "type": "cppdbg", + "request": "attach", + "program": "${cwd}/client/proxmark3", + //"processId": "${command:pickProcess}", + "processId": "${input:ProcessID}", + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + },{ + "name": "(gdb) Build & Launch", + "type": "cppdbg", + "request": "launch", + "program": "${cwd}/client/proxmark3", + "args": ["/dev/ttyACM0"], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ], + "preLaunchTask": "client: Debug: clean & make", + "miDebuggerPath": "/usr/bin/gdb" + } + ], + "inputs": [ + { + // Using Extension "Tasks Shell Input" https://marketplace.visualstudio.com/items?itemName=augustocdias.tasks-shell-input + "id": "ProcessID", + "type": "command", + "command": "shellCommand.execute", + "args": { + "command": "pgrep -n proxmark3", + } + } + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 20b68be0e..155aa80cd 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -4,24 +4,82 @@ "version": "2.0.0", "tasks": [ { - "label": "build", + "label": "all: Make & run", "type": "shell", - "command": "make clean && make all -j$(nproc --all)", + "command": "make -j && ./pm3", "problemMatcher": [ "$gcc" - ] + ], + "group": { + "kind": "build", + "isDefault": true + } }, { - "label": "flash fullimage", + "label": "choose: Make", "type": "shell", - "command": "sudo ./pm3-flash-fullimage", + "command": "make ${input:componentType} -j", + "problemMatcher": [ + "$gcc" + ], + "group": "build", + }, + { + "label": "client: Debug: make", + "type": "shell", + "command": "make client -j DEBUG=1", + "problemMatcher": [ + "$gcc" + ], + "group": "build", + }, + { + "label": "client: Debug: clean & make", + "type": "shell", + "command": "make client/clean && make client -j DEBUG=1", + "problemMatcher": [ + "$gcc" + ], + "group": "build", + }, + { + "label": "fullimage: Make & Flash", + "type": "shell", + "command": "make fullimage && ./pm3-flash-fullimage", "problemMatcher": [] }, { - "label": "FLASH BOOTROM", + "label": "BOOTROM: Make & Flash", "type": "shell", - "command": "sudo ./pm3-flash-bootrom", + "command": "make bootrom && ./pm3-flash-bootrom", "problemMatcher": [] + }, + { + "label": "Run client", + "type": "shell", + "command": "./pm3", + "problemMatcher": [] + } + ], + "inputs": [ + { + "type": "pickString", + "id": "componentType", + "description": "What Makefile target do you want to execute?", + "options": [ + "all", + "client", + "bootrom", + "fullimage", + "recovery", + "clean", + "install", + "uninstall", + "style", + "miscchecks", + "check", + ], + "default": "all" } ] } \ No newline at end of file diff --git a/Makefile.defs b/Makefile.defs index 06eb2e36f..a06cbb31e 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -27,6 +27,9 @@ LD = g++ SH = sh BASH = bash PERL = perl +CCC =foo +CC_VERSION = $(shell $(CC) -dumpversion 2>/dev/null|sed 's/\..*//') +CC_VERSION := $(or $(strip $(CC_VERSION)),0) PATHSEP=/ PREFIX ?= /usr/local @@ -48,9 +51,15 @@ else RANLIB= ranlib endif -DEFCXXFLAGS = -Wall -Werror -O3 -pipe -DEFCFLAGS = -Wall -Werror -O3 -fstrict-aliasing -pipe -DEFLDFLAGS = +ifeq ($(DEBUG),1) + DEFCXXFLAGS = -g -O0 -pipe + DEFCFLAGS = -g -O0 -fstrict-aliasing -pipe + DEFLDFLAGS = +else + DEFCXXFLAGS = -Wall -Werror -O3 -pipe + DEFCFLAGS = -Wall -Werror -O3 -fstrict-aliasing -pipe + DEFLDFLAGS = +endif # Next ones are activated only if SANITIZE=1 ifeq ($(SANITIZE),1) DEFCFLAGS += -g -fsanitize=address -fno-omit-frame-pointer @@ -62,7 +71,11 @@ DEFCFLAGS += -Wbad-function-cast -Wredundant-decls -Wmissing-prototypes -Wchar-s # Some more warnings we need first to eliminate, so temporarely tolerated: DEFCFLAGS += -Wcast-align -Wno-error=cast-align DEFCFLAGS += -Wswitch-enum -Wno-error=switch-enum - +# GCC 10 has issues with false positives on stringop-overflow, let's disable them for now (cf https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92955, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94335) +# beware these flags didn't exist for GCC < 7 +ifeq ($(shell expr $(CC_VERSION) \>= 10), 1) + DEFCFLAGS += -Wno-stringop-overflow -Wno-error=stringop-overflow +endif ifeq ($(platform),Darwin) # their readline has strict-prototype issues DEFCFLAGS += -Wno-strict-prototypes diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 02d6f1d23..f5eacc363 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -978,6 +978,15 @@ static void PacketReceived(PacketCommandNG *packet) { EM4xLogin(payload->password); break; } + case CMD_LF_EM4X_BF: { + struct p { + uint32_t start_pwd; + uint32_t n; + } PACKED; + struct p *payload = (struct p *) packet->data.asBytes; + EM4xBruteforce(payload->start_pwd, payload->n); + break; + } case CMD_LF_EM4X_READWORD: { struct p { uint32_t password; @@ -1250,7 +1259,11 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_HF_ISO14443A_ANTIFUZZ: { - iso14443a_antifuzz(packet->oldarg[0]); + struct p { + uint8_t flag; + } PACKED; + struct p *payload = (struct p *) packet->data.asBytes; + iso14443a_antifuzz(payload->flag); break; } case CMD_HF_EPA_COLLECT_NONCE: { @@ -1481,12 +1494,12 @@ static void PacketReceived(PacketCommandNG *packet) { MifareU_Otp_Tearoff(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes); break; } - case CMD_HF_MFU_COUNTER_TEAROFF: { + case CMD_HF_MFU_COUNTER_TEAROFF: { struct p { uint8_t counter; uint32_t tearoff_time; } PACKED; - struct p *payload = (struct p *) packet->data.asBytes; + struct p *payload = (struct p *) packet->data.asBytes; MifareU_Counter_Tearoff(payload->counter, payload->tearoff_time); break; } @@ -1520,13 +1533,13 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_HF_ICLASS_SIMULATE: { -/* - struct p { - uint8_t reader[4]; - uint8_t mac[4]; - } PACKED; - struct p *payload = (struct p *) packet->data.asBytes; -*/ + /* + struct p { + uint8_t reader[4]; + uint8_t mac[4]; + } PACKED; + struct p *payload = (struct p *) packet->data.asBytes; + */ SimulateIClass(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2], packet->data.asBytes); break; @@ -1562,7 +1575,7 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_HF_ICLASS_RESTORE: { - iClass_Restore( (iclass_restore_req_t *)packet->data.asBytes); + iClass_Restore((iclass_restore_req_t *)packet->data.asBytes); break; } #endif @@ -1604,7 +1617,11 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_SMART_SETCLOCK: { - SmartCardSetClock(packet->oldarg[0]); + struct p { + uint32_t new_clk; + } PACKED; + struct p *payload = (struct p *)packet->data.asBytes; + SmartCardSetClock(payload->new_clk); break; } case CMD_SMART_RAW: { diff --git a/armsrc/em4x50.c b/armsrc/em4x50.c index bce422908..9ab8dcf35 100644 --- a/armsrc/em4x50.c +++ b/armsrc/em4x50.c @@ -889,18 +889,18 @@ static int write(uint8_t word[4], uint8_t address) { return PM3_ETEAROFF; } else { - // wait for T0 * EM4X50_T_TAG_TWA (write access time) - wait_timer(FPGA_TIMER_0, T0 * EM4X50_T_TAG_TWA); + // wait for T0 * EM4X50_T_TAG_TWA (write access time) + wait_timer(FPGA_TIMER_0, T0 * EM4X50_T_TAG_TWA); - // look for ACK sequence - if (check_ack(false)) { + // look for ACK sequence + if (check_ack(false)) { - // 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; + // 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 { @@ -985,7 +985,7 @@ void em4x50_write(em4x50_data_t *etd) { lf_finalize(); return; } - + if (res == PM3_SUCCESS) { // to verify result reset EM4x50 if (reset()) { @@ -1033,7 +1033,7 @@ void em4x50_write_password(em4x50_data_t *etd) { // login and change password if (login(etd->password)) { - + int res = write_password(etd->password, etd->new_password); if (res == PM3_ETEAROFF) { lf_finalize(); diff --git a/armsrc/i2c.c b/armsrc/i2c.c index 1ca742893..7b858dd36 100644 --- a/armsrc/i2c.c +++ b/armsrc/i2c.c @@ -47,12 +47,6 @@ static void __attribute__((optimize("O0"))) I2CSpinDelayClk(uint16_t delay) { #define I2C_DELAY_2CLK I2CSpinDelayClk(2) #define I2C_DELAY_XCLK(x) I2CSpinDelayClk((x)) -#define I2C_DELAY_100us I2CSpinDelayClk( 100 / 3) -#define I2C_DELAY_600us I2CSpinDelayClk( 600 / 3) -#define I2C_DELAY_10ms I2CSpinDelayClk( 10 * 1000 / 3 ) -#define I2C_DELAY_30ms I2CSpinDelayClk( 30 * 1000 / 3 ) -#define I2C_DELAY_100ms I2CSpinDelayClk( 100 * 1000 / 3) - #define ISO7618_MAX_FRAME 255 // try i2c bus recovery at 100kHz = 5us high, 5us low @@ -134,11 +128,11 @@ void I2C_Reset_EnterMainProgram(void) { StartTicks(); I2C_init(); I2C_SetResetStatus(0, 0, 0); - I2C_DELAY_30ms; + WaitMS(30); I2C_SetResetStatus(1, 0, 0); - I2C_DELAY_30ms; + WaitMS(30); I2C_SetResetStatus(1, 1, 1); - I2C_DELAY_10ms; + WaitMS(10); } // Reset the SIM_Adapter, then enter the bootloader program @@ -147,9 +141,9 @@ void I2C_Reset_EnterBootloader(void) { StartTicks(); I2C_init(); I2C_SetResetStatus(0, 1, 1); - I2C_DELAY_100ms; + WaitMS(100); I2C_SetResetStatus(1, 1, 1); - I2C_DELAY_10ms; + WaitMS(10); } // Wait for the clock to go High. @@ -193,7 +187,7 @@ static bool WaitSCL_L_timeout(void) { if (!SCL_read) return true; - I2C_DELAY_100us; + WaitMS(1); } return (delay == 0); } @@ -440,8 +434,7 @@ int16_t I2C_BufferRead(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t d // extra wait 500us (514us measured) // 200us (xx measured) -// WaitUS(600); - I2C_DELAY_600us; + WaitUS(600); bool bBreak = true; uint16_t readcount = 0; @@ -811,8 +804,7 @@ void SmartCardUpgrade(uint64_t arg0) { } // writing takes time. -// WaitMS(50); - I2C_DELAY_100ms; + WaitMS(100); // read res = I2C_ReadFW(verfiydata, size, msb, lsb, I2C_DEVICE_ADDRESS_BOOT); @@ -844,12 +836,10 @@ void SmartCardSetClock(uint64_t arg0) { LED_D_ON(); set_tracing(true); I2C_Reset_EnterMainProgram(); - // Send SIM CLC // start [C0 05 xx] stop I2C_WriteByte(arg0, I2C_DEVICE_CMD_SIM_CLC, I2C_DEVICE_ADDRESS_MAIN); - - reply_mix(CMD_ACK, 1, 0, 0, 0, 0); + reply_ng(CMD_SMART_SETCLOCK, PM3_SUCCESS, NULL, 0); set_tracing(false); LEDsoff(); } diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 204cd9ea1..03f7dcbba 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -1367,7 +1367,7 @@ static bool select_iclass_tag_ex(picopass_hdr *hdr, bool use_credit_key, uint32_ *status |= FLAG_ICLASS_CC; } else { - + // on NON_SECURE_PAGEMODE cards, AIA is on block2.. // read App Issuer Area block 2 @@ -1443,7 +1443,7 @@ void ReaderIClass(uint8_t flags) { // with 0xFF:s in block 3 and 4. LED_B_ON(); - reply_mix(CMD_ACK, result_status, 0, 0, (uint8_t*)&hdr, sizeof(hdr)); + reply_mix(CMD_ACK, result_status, 0, 0, (uint8_t *)&hdr, sizeof(hdr)); //Send back to client, but don't bother if we already sent this - // only useful if looping in arm (not try_once && not abort_after_read) @@ -1489,9 +1489,9 @@ bool authenticate_iclass_tag(iclass_auth_req_t *payload, picopass_hdr *hdr, uint memcpy(ccnr, hdr->epurse, sizeof(hdr->epurse)); - if ( payload->use_replay) { + if (payload->use_replay) { - memcpy(pmac, payload->key + 4, 4); + memcpy(pmac, payload->key + 4, 4); memcpy(cmd_check + 1, payload->key, 8); } else { @@ -1780,7 +1780,7 @@ static bool iclass_writeblock_ext(uint8_t blockno, uint8_t *data, uint8_t *mac) // write command: cmd, 1 blockno, 8 data, 4 mac uint8_t write[16] = { 0x80 | ICLASS_CMD_UPDATE, blockno }; - memcpy(write + 2, data, 8); + memcpy(write + 2, data, 8); memcpy(write + 10, mac, 4); AddCrc(write + 1, 13); @@ -1872,11 +1872,11 @@ void iClass_WriteBlock(uint8_t *msg) { iclass_send_as_reader(write, sizeof(write), &start_time, &eof_time); if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured - res = false; - switch_off(); - if (payload->req.send_reply) - reply_ng(CMD_HF_ICLASS_WRITEBL, PM3_ETEAROFF, (uint8_t *)&res, sizeof(uint8_t)); - return; + res = false; + switch_off(); + if (payload->req.send_reply) + reply_ng(CMD_HF_ICLASS_WRITEBL, PM3_ETEAROFF, (uint8_t *)&res, sizeof(uint8_t)); + return; } else { if (GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_UPDATE, &eof_time) == 10) { @@ -1885,7 +1885,7 @@ void iClass_WriteBlock(uint8_t *msg) { } } } - + if (tries == 0) { res = false; goto out; @@ -1932,7 +1932,7 @@ void iClass_Restore(iclass_restore_req_t *msg) { if (msg->req.send_reply) { reply_ng(CMD_HF_ICLASS_RESTORE, PM3_ESOFT, NULL, 0); } - return; + return; } LED_A_ON(); @@ -1942,7 +1942,7 @@ void iClass_Restore(iclass_restore_req_t *msg) { uint32_t eof_time = 0; picopass_hdr hdr = {0}; - // select + // select bool res = select_iclass_tag(&hdr, msg->req.use_credit_key, &eof_time); if (res == false) { goto out; @@ -1974,7 +1974,7 @@ void iClass_Restore(iclass_restore_req_t *msg) { doMAC_N(wb, sizeof(wb), hdr.key_c, mac); else doMAC_N(wb, sizeof(wb), hdr.key_d, mac); - + // data + mac if (iclass_writeblock_ext(item.blockno, item.data, mac)) { Dbprintf("Write block [%02x] " _GREEN_("successful"), item.blockno); @@ -1983,7 +1983,7 @@ void iClass_Restore(iclass_restore_req_t *msg) { Dbprintf("Write block [%02x] " _RED_("failed"), item.blockno); } } - + out: switch_off(); diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index d40080ae1..cf0bce153 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -2390,7 +2390,7 @@ void iso14443a_antifuzz(uint32_t flags) { } } - reply_old(CMD_ACK, 1, 0, 0, 0, 0); + reply_ng(CMD_HF_ISO14443A_ANTIFUZZ, PM3_SUCCESS, NULL, 0); switch_off(); BigBuf_free_keep_EM(); } @@ -2629,7 +2629,7 @@ int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint32 AddCrc14A(rats, 2); ReaderTransmit(rats, sizeof(rats), NULL); int len = ReaderReceive(resp, resp_par); - if (len == 0) + if (len == 0) return 0; if (p_card) { diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index 00af14c4f..bacceb165 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -1474,13 +1474,13 @@ int SendDataTag(uint8_t *send, int sendlen, bool init, bool speed_fast, uint8_t int res = 0; tosend_t *ts = get_tosend(); TransmitTo15693Tag(ts->buf, ts->max, &start_time); - + if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured res = PM3_ETEAROFF; } else { - + *eof_time = start_time + 32 * ((8 * ts->max) - 4); // substract the 4 padding bits after EOF LogTrace_ISO15693(send, sendlen, (start_time * 4), (*eof_time * 4), NULL, true); if (recv != NULL) { @@ -1595,11 +1595,11 @@ void ReaderIso15693(uint32_t parameter) { uint32_t start_time = 0; uint32_t eof_time; int recvlen = SendDataTag(cmd, sizeof(cmd), true, true, answer, ISO15693_MAX_RESPONSE_LENGTH, start_time, ISO15693_READER_TIMEOUT, &eof_time); - + if (recvlen == PM3_ETEAROFF) { // tearoff occured reply_mix(CMD_ACK, recvlen, 0, 0, NULL, 0); } else { - + start_time = eof_time + DELAY_ISO15693_VICC_TO_VCD_READER; // we should do a better check than this @@ -1634,7 +1634,7 @@ void ReaderIso15693(uint32_t parameter) { } } else { DbpString("Failed to select card"); - reply_mix(CMD_ACK, 0, 0, 0, NULL, 0); + reply_mix(CMD_ACK, 0, 0, 0, NULL, 0); } } switch_off(); @@ -1869,7 +1869,7 @@ void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint } if (recv) { - recvlen = MIN(recvlen,ISO15693_MAX_RESPONSE_LENGTH); + recvlen = MIN(recvlen, ISO15693_MAX_RESPONSE_LENGTH); reply_mix(CMD_ACK, recvlen, 0, 0, recvbuf, recvlen); } else { reply_mix(CMD_ACK, 1, 0, 0, NULL, 0); diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 4d25bd314..a6fbb7bba 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -2467,7 +2467,7 @@ static uint8_t Prepare_Data(uint16_t data_low, uint16_t data_hi) { // Requires: forwarLink_data filled with valid bits (1 bit per byte) // fwd_bit_count set with number of bits to be sent //==================================================================== -static void SendForward(uint8_t fwd_bit_count) { +static void SendForward(uint8_t fwd_bit_count, bool fast) { // iceman, 21.3us increments for the USclock verification. // 55FC * 8us == 440us / 21.3 === 20.65 steps. could be too short. Go for 56FC instead @@ -2480,9 +2480,10 @@ static void SendForward(uint8_t fwd_bit_count) { fwd_write_ptr = forwardLink_data; fwd_bit_sz = fwd_bit_count; - // Set up FPGA, 125kHz or 95 divisor - LFSetupFPGAForADC(LF_DIVISOR_125, true); - + if (! fast) { + // Set up FPGA, 125kHz or 95 divisor + LFSetupFPGAForADC(LF_DIVISOR_125, true); + } // force 1st mod pulse (start gap must be longer for 4305) fwd_bit_sz--; //prepare next bit modulation fwd_write_ptr++; @@ -2490,13 +2491,13 @@ static void SendForward(uint8_t fwd_bit_count) { TurnReadLF_off(EM_START_GAP); TurnReadLFOn(18 * 8); - // now start writting with bitbanging the antenna. (each bit should be 32*8 total length) + // now start writing with bitbanging the antenna. (each bit should be 32*8 total length) while (fwd_bit_sz-- > 0) { //prepare next bit modulation if (((*fwd_write_ptr++) & 1) == 1) { WaitUS(32 * 8); } else { TurnReadLF_off(23 * 8); - TurnReadLFOn((32 - 23) * 8); + TurnReadLFOn(18 * 8); } } } @@ -2505,13 +2506,60 @@ static void EM4xLoginEx(uint32_t pwd) { forward_ptr = forwardLink_data; uint8_t len = Prepare_Cmd(FWD_CMD_LOGIN); len += Prepare_Data(pwd & 0xFFFF, pwd >> 16); - SendForward(len); + SendForward(len, false); //WaitUS(20); // no wait for login command. // should receive // 0000 1010 ok // 0000 0001 fail } +void EM4xBruteforce(uint32_t start_pwd, uint32_t n) { + // With current timing, 18.6 ms per test = 53.8 pwds/s + reply_ng(CMD_LF_EM4X_BF, PM3_SUCCESS, NULL, 0); + StartTicks(); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + WaitMS(20); + LED_A_ON(); + LFSetupFPGAForADC(LF_DIVISOR_125, true); + uint32_t candidates_found = 0; + for (uint32_t pwd = start_pwd; pwd < 0xFFFFFFFF; pwd++) { + if (((pwd - start_pwd) & 0x3F) == 0x00) { + WDT_HIT(); + if (BUTTON_PRESS() || data_available()) { + Dbprintf("EM4x05 Bruteforce Interrupted"); + break; + } + } + // Report progress every 256 attempts + if (((pwd - start_pwd) & 0xFF) == 0x00) { + Dbprintf("Trying: %06Xxx", pwd >> 8); + } + clear_trace(); + + forward_ptr = forwardLink_data; + uint8_t len = Prepare_Cmd(FWD_CMD_LOGIN); + len += Prepare_Data(pwd & 0xFFFF, pwd >> 16); + SendForward(len, true); + + WaitUS(400); + DoPartialAcquisition(0, false, 350, 1000); + uint8_t *mem = BigBuf_get_addr(); + if (mem[334] < 128) { + candidates_found++; + Dbprintf("Password candidate: " _GREEN_("%08X"), pwd); + if ((n != 0) && (candidates_found == n)) { + Dbprintf("EM4x05 Bruteforce Stopped. %i candidate%s found", candidates_found, candidates_found > 1 ? "s" : ""); + break; + } + } + // Beware: if smaller, tag might not have time to be back in listening state yet + WaitMS(1); + } + StopTicks(); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); +} + void EM4xLogin(uint32_t pwd) { StartTicks(); @@ -2558,7 +2606,7 @@ void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd) { uint8_t len = Prepare_Cmd(FWD_CMD_READ); len += Prepare_Addr(addr); - SendForward(len); + SendForward(len, false); WaitUS(400); @@ -2594,7 +2642,7 @@ void EM4xWriteWord(uint8_t addr, uint32_t data, uint32_t pwd, uint8_t usepwd) { len += Prepare_Addr(addr); len += Prepare_Data(data & 0xFFFF, data >> 16); - SendForward(len); + SendForward(len, false); if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured StopTicks(); @@ -2636,7 +2684,7 @@ void EM4xProtectWord(uint32_t data, uint32_t pwd, uint8_t usepwd) { uint8_t len = Prepare_Cmd(FWD_CMD_PROTECT); len += Prepare_Data(data & 0xFFFF, data >> 16); - SendForward(len); + SendForward(len, false); if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured StopTicks(); diff --git a/armsrc/lfops.h b/armsrc/lfops.h index bf251ac85..0ec050158 100644 --- a/armsrc/lfops.h +++ b/armsrc/lfops.h @@ -57,6 +57,7 @@ void T55xxDangerousRawTest(uint8_t *data); void TurnReadLFOn(uint32_t delay); void EM4xLogin(uint32_t pwd); +void EM4xBruteforce(uint32_t start_pwd, uint32_t n); void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd); void EM4xWriteWord(uint8_t addr, uint32_t data, uint32_t pwd, uint8_t usepwd); void EM4xProtectWord(uint32_t data, uint32_t pwd, uint8_t usepwd); diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index f442166f4..11c89a98b 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -2752,15 +2752,15 @@ void MifareU_Counter_Tearoff(uint8_t counter, uint32_t tearoff_time) { // Send MFU counter increase cmd uint8_t cmd[] = { - MIFARE_ULEV1_INCR_CNT, - counter, - 0, // lsb - 0, - 0, // msb - 0, // rfu - 0, - 0, - }; + MIFARE_ULEV1_INCR_CNT, + counter, + 0, // lsb + 0, + 0, // msb + 0, // rfu + 0, + 0, + }; AddCrc14A(cmd, sizeof(cmd) - 2); // anticollision / select card diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 46e77a14f..6d4abf82d 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -18,6 +18,7 @@ # -DANDROID_NATIVE_API_LEVEL=android-19 \ # -DSKIPBT=1 -DSKIPPYTHON=1 -DSKIPPTHREAD=1 .. +message(STATUS "CMake ${CMAKE_VERSION}") cmake_minimum_required(VERSION 3.10) project(proxmark3) SET (PM3_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/..) @@ -496,20 +497,10 @@ if (NOT APPLE) set(ADDITIONAL_LNK ${ADDITIONAL_LNK} -Wl,--as-needed -latomic -Wl,--no-as-needed) endif (NOT APPLE) - -find_library(pm3rrg_rdv4_cliparser REQUIRED) -find_library(pm3rrg_rdv4_tinycbor REQUIRED) -find_library(pm3rrg_rdv4_lua REQUIRED) -find_library(pm3rrg_rdv4_mbedtls REQUIRED) -find_library(pm3rrg_rdv4_reveng REQUIRED) -find_library(pm3rrg_rdv4_hardnested REQUIRED) - if (NOT JANSSON_FOUND) - find_library(pm3rrg_rdv4_jansson REQUIRED) set(ADDITIONAL_LNK pm3rrg_rdv4_jansson ${ADDITIONAL_LNK}) endif (NOT JANSSON_FOUND) if (NOT WHEREAMI_FOUND) - find_library(pm3rrg_rdv4_whereami REQUIRED) set(ADDITIONAL_LNK pm3rrg_rdv4_whereami ${ADDITIONAL_LNK}) endif (NOT WHEREAMI_FOUND) diff --git a/client/android/CMakeLists.txt b/client/android/CMakeLists.txt index b3f432c6c..69e71d5d5 100644 --- a/client/android/CMakeLists.txt +++ b/client/android/CMakeLists.txt @@ -1,4 +1,5 @@ # version +message(STATUS "CMake ${CMAKE_VERSION}") cmake_minimum_required(VERSION 3.4.1) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -fvisibility=hidden -w") @@ -12,7 +13,6 @@ add_subdirectory(../deps deps) if (CMAKE_MAKE_PROGRAM MATCHES ".*ninja.*") set(BZIP2_INCLUDE_DIRS ${BZIP2_ROOT}) set(BZIP2_LIBRARIES pm3rrg_rdv4_bzip2) - find_library(pm3rrg_rdv4_bzip2 REQUIRED) elseif (UNIX) # Cross compile at Unix Makefile System. # bzip2 dep. include(ExternalProject) @@ -190,15 +190,6 @@ target_include_directories(pm3rrg_rdv4 PRIVATE ${PM3_ROOT}/common_fpga ${PM3_ROOT}/client/src) -find_library(pm3rrg_rdv4_cliparser REQUIRED) -find_library(pm3rrg_rdv4_jansson REQUIRED) -find_library(pm3rrg_rdv4_tinycbor REQUIRED) -find_library(pm3rrg_rdv4_lua REQUIRED) -find_library(pm3rrg_rdv4_mbedtls REQUIRED) -find_library(pm3rrg_rdv4_reveng REQUIRED) -find_library(pm3rrg_rdv4_hardnested REQUIRED) -find_library(pm3rrg_rdv4_whereami REQUIRED) - target_link_libraries(pm3rrg_rdv4 ${BZIP2_LIBRARIES} pm3rrg_rdv4_hardnested diff --git a/client/deps/amiibo.cmake b/client/deps/amiibo.cmake index 234547cd1..491d90d60 100644 --- a/client/deps/amiibo.cmake +++ b/client/deps/amiibo.cmake @@ -14,7 +14,6 @@ add_library(pm3rrg_rdv4_amiibo STATIC if (NOT TARGET pm3rrg_rdv4_mbedtls) include(mbedtls.cmake) endif() -find_library(pm3rrg_rdv4_mbedtls REQUIRED) target_link_libraries(pm3rrg_rdv4_amiibo PRIVATE m pm3rrg_rdv4_mbedtls) diff --git a/client/deps/cliparser.cmake b/client/deps/cliparser.cmake index b16451c07..fccae33b7 100644 --- a/client/deps/cliparser.cmake +++ b/client/deps/cliparser.cmake @@ -3,6 +3,7 @@ add_library(pm3rrg_rdv4_cliparser STATIC cliparser/cliparser.c ) +target_compile_definitions(pm3rrg_rdv4_cliparser PRIVATE _ISOC99_SOURCE) target_include_directories(pm3rrg_rdv4_cliparser PRIVATE ../../common ../../include diff --git a/client/deps/cliparser/Makefile b/client/deps/cliparser/Makefile index 4873372c4..1994992f9 100644 --- a/client/deps/cliparser/Makefile +++ b/client/deps/cliparser/Makefile @@ -9,3 +9,12 @@ MYSRCS = \ LIB_A = libcliparser.a include ../../../Makefile.host + +$(info PLATFORM $(platform)) +ifneq (,$(findstring MINGW,$(platform))) + # Mingw uses by default Microsoft printf, we want the GNU printf (e.g. for %z) + # and setting _ISOC99_SOURCE sets internally __USE_MINGW_ANSI_STDIO=1 + # FTR __USE_MINGW_ANSI_STDIO seems deprecated in Mingw32 + # but not Mingw64 https://fr.osdn.net/projects/mingw/lists/archive/users/2019-January/000199.html + CFLAGS += -D_ISOC99_SOURCE +endif diff --git a/client/deps/cliparser/cliparser.c b/client/deps/cliparser/cliparser.c index a601e6490..ca119ac14 100644 --- a/client/deps/cliparser/cliparser.c +++ b/client/deps/cliparser/cliparser.c @@ -11,8 +11,10 @@ #include "cliparser.h" #include #include -#include // Get color constants -#include // get PrintAndLogEx +#include // Get color constants +#include // get PrintAndLogEx +#include // tolower +#include // PRIu64 #ifndef ARRAYLEN # define ARRAYLEN(x) (sizeof(x)/sizeof((x)[0])) @@ -125,7 +127,6 @@ int CLIParserParseArg(CLIParserContext *ctx, int argc, char **argv, void *vargta return 0; } - enum ParserState { PS_FIRST, PS_ARGUMENT, @@ -205,9 +206,9 @@ int CLIParamHexToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int int tmplen = 0; uint8_t tmpstr[(256 * 2) + 1] = {0}; - + // concat all strings in argstr into tmpstr[] - // + // int res = CLIParamStrToBuf(argstr, tmpstr, sizeof(tmpstr), &tmplen); if (res) { return res; @@ -216,7 +217,7 @@ int CLIParamHexToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int return res; } - res = param_gethex_to_eol((char*)tmpstr, 0, data, maxdatalen, datalen); + res = param_gethex_to_eol((char *)tmpstr, 0, data, maxdatalen, datalen); switch (res) { case 1: printf("Parameter error: Invalid HEX value\n"); @@ -241,20 +242,20 @@ int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int int ibuf = 0; for (int i = 0; i < argstr->count; i++) { - + int len = strlen(argstr->sval[i]); - - if (len > ( (sizeof(tmpstr) / 2 ) - ibuf)) { + + if (len > ((sizeof(tmpstr) / 2) - ibuf)) { printf("Parameter error: string too long (%i chars), expect MAX %zu chars\n", len + ibuf, (sizeof(tmpstr) / 2)); fflush(stdout); return 2; } - + memcpy(&tmpstr[ibuf], argstr->sval[i], len); ibuf += len; } - + ibuf = MIN(ibuf, (sizeof(tmpstr) / 2)); tmpstr[ibuf] = 0; @@ -272,4 +273,20 @@ int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int return 0; } +uint64_t arg_get_u64_hexstr_def(CLIParserContext *ctx, uint8_t paramnum, uint64_t def) { + uint64_t rv = 0; + uint8_t data[8]; + int datalen = 0; + int res = CLIParamHexToBuf(arg_get_str(ctx, paramnum), data, sizeof(data), &datalen); + if (res == 0) { + for (uint8_t i = 0; i < datalen; i++) { + rv <<= 8; + rv |= data[i]; + } + } else { + rv = def; + } + return rv; +} + diff --git a/client/deps/cliparser/cliparser.h b/client/deps/cliparser/cliparser.h index 89c9e00ca..996ad81ef 100644 --- a/client/deps/cliparser/cliparser.h +++ b/client/deps/cliparser/cliparser.h @@ -66,4 +66,6 @@ int CLIParserParseArg(CLIParserContext *ctx, int argc, char **argv, void *vargta int CLIParamHexToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen); int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen); + +uint64_t arg_get_u64_hexstr_def(CLIParserContext *ctx, uint8_t paramnum, uint64_t def); #endif diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 58c2c40bc..cf40e63fd 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1203,3 +1203,9 @@ FEE2A3FBC5B6 # taurus avm # 005078565703 +# +# Ving? +# +0602721E8F06 +FC0B50AF8700 +F7BA51A9434E \ No newline at end of file diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index e9ddbf6c5..00b7d9484 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -1338,7 +1338,7 @@ static int CmdHF14ACmdRaw(const char *Cmd) { if (!res && datalen > 0) waitCmd(0, timeout); } - return 0; + return PM3_SUCCESS; } static int waitCmd(uint8_t iSelect, uint32_t timeout) { @@ -1398,16 +1398,20 @@ static int CmdHF14AAntiFuzz(const char *Cmd) { }; CLIExecWithReturn(ctx, Cmd, argtable, false); - uint8_t arg0 = FLAG_4B_UID_IN_DATA; + struct { + uint8_t flag; + } PACKED param; + param.flag = FLAG_4B_UID_IN_DATA; + if (arg_get_lit(ctx, 2)) - arg0 = FLAG_7B_UID_IN_DATA; + param.flag = FLAG_7B_UID_IN_DATA; if (arg_get_lit(ctx, 3)) - arg0 = FLAG_10B_UID_IN_DATA; + param.flag = FLAG_10B_UID_IN_DATA; CLIParserFree(ctx); clearCommandBuffer(); - SendCommandMIX(CMD_HF_ISO14443A_ANTIFUZZ, arg0, 0, 0, NULL, 0); - return 0; + SendCommandNG(CMD_HF_ISO14443A_ANTIFUZZ, (uint8_t*)¶m, sizeof(param)); + return PM3_SUCCESS; } static int CmdHF14AChaining(const char *Cmd) { @@ -1438,7 +1442,7 @@ static int CmdHF14AChaining(const char *Cmd) { PrintAndLogEx(INFO, "\nISO 14443-4 input chaining %s.\n", APDUInFramingEnable ? "enabled" : "disabled"); - return 0; + return PM3_SUCCESS; } static void printTag(const char *tag) { @@ -1681,10 +1685,16 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { } getTagLabel(card.uid[0], card.uid[1]); break; - case 0x57: // Qualcomm + case 0x46: + if (memcmp(card.uid, "FSTN10m", 7) == 0) { + isMifareClassic = false; + printTag("Waveshare NFC-Powered e-Paper 1.54\" (please disregard MANUFACTURER mapping above)"); + } + break; + case 0x57: if (memcmp(card.uid, "WSDZ10m", 7) == 0) { isMifareClassic = false; - printTag("Waveshare NFC-Powered e-Paper"); + printTag("Waveshare NFC-Powered e-Paper (please disregard MANUFACTURER mapping above)"); } break; default: @@ -1837,30 +1847,30 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { if (memcmp(card.ats + pos, "\xC1\x05\x2F\x2F\x01\xBC\xD6", 7) == 0) { tip = "-> MIFARE Plus X 2K/4K (SL3)"; } else if (memcmp(card.ats + pos, "\xC1\x05\x2F\x2F\x00\x35\xC7", 7) == 0) { - + if ((card.atqa[0] & 0x02) == 0x02) tip = "-> MIFARE Plus S 2K (SL3)"; else if ((card.atqa[0] & 0x04) == 0x04) tip = "-> MIFARE Plus S 4K (SL3)"; - + } else if (memcmp(card.ats + pos, "\xC1\x05\x21\x30\x00\xF6\xD1", 7) == 0) { tip = "-> MIFARE Plus SE 1K (17pF)"; - } else if (memcmp(card.ats + pos, "\xC1\x05\x21\x30\x10\xF6\xD1", 7) == 0) { + } else if (memcmp(card.ats + pos, "\xC1\x05\x21\x30\x10\xF6\xD1", 7) == 0) { tip = "-> MIFARE Plus SE 1K (70pF)"; } - - } else { //SAK B4,5,6 - - if ((card.sak & 0x20) == 0x20) { // and no GetVersion().. - - + + } else { //SAK B4,5,6 + + if ((card.sak & 0x20) == 0x20) { // and no GetVersion().. + + if (memcmp(card.ats + pos, "\xC1\x05\x2F\x2F\x01\xBC\xD6", 7) == 0) { tip = "-> MIFARE Plus X 2K (SL1)"; } else if (memcmp(card.ats + pos, "\xC1\x05\x2F\x2F\x00\x35\xC7", 7) == 0) { tip = "-> MIFARE Plus S 2K (SL1)"; } else if (memcmp(card.ats + pos, "\xC1\x05\x21\x30\x00\xF6\xD1", 7) == 0) { tip = "-> MIFARE Plus SE 1K (17pF)"; - } else if (memcmp(card.ats + pos, "\xC1\x05\x21\x30\x10\xF6\xD1", 7) == 0) { + } else if (memcmp(card.ats + pos, "\xC1\x05\x21\x30\x10\xF6\xD1", 7) == 0) { tip = "-> MIFARE Plus SE 1K (70pF)"; } } else { @@ -1868,7 +1878,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { tip = "-> MIFARE Plus X 4K (SL1)"; } else if (memcmp(card.ats + pos, "\xC1\x05\x2F\x2F\x00\x35\xC7", 7) == 0) { tip = "-> MIFARE Plus S 4K (SL1)"; - } + } } } diff --git a/client/src/cmdhf14b.c b/client/src/cmdhf14b.c index 85898fe04..73f8c2a8f 100644 --- a/client/src/cmdhf14b.c +++ b/client/src/cmdhf14b.c @@ -149,7 +149,7 @@ static int CmdHF14BSim(const char *Cmd) { PrintAndLogEx(FAILED, "failed to read pupi"); return PM3_EINVARG; } - + PrintAndLogEx(INFO, "Simulate with PUPI : " _GREEN_("%s"), sprint_hex_inrow(pupi, sizeof(pupi))); PrintAndLogEx(INFO, "Press pm3-button to abort simulation"); clearCommandBuffer(); diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index b4cde234f..6d276617c 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -656,13 +656,13 @@ static int CmdHF15Demod(const char *Cmd) { }; CLIExecWithReturn(ctx, Cmd, argtable, true); CLIParserFree(ctx); - + // The sampling rate is 106.353 ksps/s, for T = 18.8 us int i, j; int max = 0, maxPos = 0; int skip = 4; - if (GraphTraceLen < 1000) { + if (GraphTraceLen < 1000) { PrintAndLogEx(FAILED, "Too few samples in GraphBuffer. Need more than 1000"); PrintAndLogEx(HINT, "Run " _YELLOW_("`hf 15 samples`") " to collect and download data"); return PM3_ESOFT; @@ -733,8 +733,8 @@ static int CmdHF15Demod(const char *Cmd) { PrintAndLogEx(WARNING, "Warning, uneven octet! (discard extra bits!)"); PrintAndLogEx(INFO, " mask = %02x", mask); } - - if ( k == 0 ) { + + if (k == 0) { return PM3_SUCCESS; } @@ -744,7 +744,7 @@ static int CmdHF15Demod(const char *Cmd) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(SUCCESS, " idx | data"); PrintAndLogEx(SUCCESS, "-----+-------------------------------------------------"); - if ( k / 16 > 0) { + if (k / 16 > 0) { for (; i < k; i += 16) { PrintAndLogEx(SUCCESS, " %3i | %s", i, sprint_hex(outBuf + i, 16)); } @@ -824,7 +824,7 @@ static int NxpSysInfo(uint8_t *uid) { if (status == PM3_ETEAROFF) { return status; } - + if (status < 2) { PrintAndLogEx(WARNING, "iso15693 card doesn't answer to NXP systeminfo command"); return PM3_EWRONGANSWER; @@ -1058,7 +1058,7 @@ static int CmdHF15Sniff(const char *Cmd) { }; CLIExecWithReturn(ctx, Cmd, argtable, true); CLIParserFree(ctx); - + PacketResponseNG resp; clearCommandBuffer(); SendCommandNG(CMD_HF_ISO15693_SNIFF, NULL, 0); @@ -1111,7 +1111,7 @@ static int CmdHF15Sim(const char *Cmd) { struct { uint8_t uid[8]; } PACKED payload; - + int uidlen = 0; CLIGetHexWithReturn(ctx, 1, payload.uid, &uidlen); CLIParserFree(ctx); @@ -1904,11 +1904,11 @@ static int CmdHF15CSetUID(const char *Cmd) { struct { uint8_t uid[8]; } PACKED payload; - + int uidlen = 0; CLIGetHexWithReturn(ctx, 1, payload.uid, &uidlen); CLIParserFree(ctx); - + if (uidlen != 8) { PrintAndLogEx(WARNING, "UID must include 16 HEX symbols got "); return PM3_EINVARG; @@ -1936,7 +1936,7 @@ static int CmdHF15CSetUID(const char *Cmd) { if (WaitForResponseTimeout(CMD_HF_ISO15693_CSETUID, &resp, 2000) == false) { PrintAndLogEx(WARNING, "timeout while waiting for reply"); DropField(); - return PM3_ESOFT; + return PM3_ESOFT; } PrintAndLogEx(INFO, "getting updated card details..."); diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index dd025852f..75c77559c 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -427,52 +427,52 @@ static void fuse_config(const picopass_hdr *hdr) { uint16_t otp = (hdr->conf.otp[1] << 8 | hdr->conf.otp[0]); - PrintAndLogEx(INFO, " Raw: " _YELLOW_("%s"), sprint_hex((uint8_t*)&hdr->conf, 8)); - PrintAndLogEx(INFO, " " _YELLOW_("%02X") "..................... App limit", hdr->conf.app_limit); + PrintAndLogEx(INFO, " Raw: " _YELLOW_("%s"), sprint_hex((uint8_t *)&hdr->conf, 8)); + PrintAndLogEx(INFO, " " _YELLOW_("%02X") "..................... app limit", hdr->conf.app_limit); PrintAndLogEx(INFO, " " _YELLOW_("%04X") " ( %5u )...... OTP", otp, otp); - PrintAndLogEx(INFO, " " _YELLOW_("%02X") "............ Block write lock", hdr->conf.block_writelock); - PrintAndLogEx(INFO, " " _YELLOW_("%02X") "......... Chip", hdr->conf.chip_config); - PrintAndLogEx(INFO, " " _YELLOW_("%02X") "...... Mem", hdr->conf.mem_config); + PrintAndLogEx(INFO, " " _YELLOW_("%02X") "............ block write lock", hdr->conf.block_writelock); + PrintAndLogEx(INFO, " " _YELLOW_("%02X") "......... chip", hdr->conf.chip_config); + PrintAndLogEx(INFO, " " _YELLOW_("%02X") "...... mem", hdr->conf.mem_config); PrintAndLogEx(INFO, " " _YELLOW_("%02X") "... EAS", hdr->conf.eas); - PrintAndLogEx(INFO, " " _YELLOW_("%02X") " Fuses", hdr->conf.fuses); + PrintAndLogEx(INFO, " " _YELLOW_("%02X") " fuses", hdr->conf.fuses); uint8_t fuses = hdr->conf.fuses; PrintAndLogEx(INFO, " Fuses:"); if (isset(fuses, FUSE_FPERS)) - PrintAndLogEx(SUCCESS, " mode..... " _GREEN_("Personalization (programmable)")); + PrintAndLogEx(SUCCESS, " mode......... " _GREEN_("Personalization (programmable)")); else - PrintAndLogEx(SUCCESS, " mode..... " _YELLOW_("Application (locked)")); + PrintAndLogEx(SUCCESS, " mode......... " _YELLOW_("Application (locked)")); if (isset(fuses, FUSE_CODING1)) { - PrintAndLogEx(SUCCESS, " coding.. RFU"); + PrintAndLogEx(SUCCESS, " coding...... RFU"); } else { if (isset(fuses, FUSE_CODING0)) - PrintAndLogEx(SUCCESS, " coding... " _YELLOW_("ISO 14443-2 B / 15693")); + PrintAndLogEx(SUCCESS, " coding....... " _YELLOW_("ISO 14443-2 B / 15693")); else - PrintAndLogEx(SUCCESS, " coding... " _YELLOW_("ISO 14443-B only")); + PrintAndLogEx(SUCCESS, " coding....... " _YELLOW_("ISO 14443-B only")); } uint8_t pagemap = get_pagemap(hdr); switch (pagemap) { case 0x0: - PrintAndLogEx(INFO, " crypt.... No auth possible. Read only if RA is enabled"); + PrintAndLogEx(INFO, " crypt........ No auth possible. Read only if RA is enabled"); break; case 0x1: - PrintAndLogEx(SUCCESS, " crypt.... Non secured page"); + PrintAndLogEx(SUCCESS, " crypt........ Non secured page"); break; case 0x2: - PrintAndLogEx(INFO, " crypt.... Secured page, keys locked"); + PrintAndLogEx(INFO, " crypt........ Secured page, keys locked"); break; case 0x03: - PrintAndLogEx(SUCCESS, " crypt.... Secured page, " _GREEN_("keys not locked")); + PrintAndLogEx(SUCCESS, " crypt........ Secured page, " _GREEN_("keys not locked")); break; } if (isset(fuses, FUSE_RA)) - PrintAndLogEx(SUCCESS, " RA....... Read access enabled (non-secure mode)"); + PrintAndLogEx(SUCCESS, " RA........... Read access enabled (non-secure mode)"); else - PrintAndLogEx(INFO, " RA....... Read access not enabled"); + PrintAndLogEx(INFO, " RA........... Read access not enabled"); } static void getMemConfig(uint8_t mem_cfg, uint8_t chip_cfg, uint8_t *app_areas, uint8_t *kb) { @@ -545,23 +545,23 @@ static void mem_app_config(const picopass_hdr *hdr) { PrintAndLogEx(INFO, " AA1 blocks %u { 0x06 - 0x%02X (06 - %02d) }", app1_limit, app1_limit + 5, app1_limit + 5); PrintAndLogEx(INFO, " AA2 blocks %u { 0x%02X - 0x%02X (%02d - %02d) }", app2_limit - app1_limit, app1_limit + 5 + 1, app2_limit, app1_limit + 5 + 1, app2_limit); - PrintAndLogEx(INFO, "------------------------ " _CYAN_("KeyAccess") " -------------------------"); - PrintAndLogEx(INFO, " Kd = Debit key (AA1), Kc = Credit key (AA2)"); + PrintAndLogEx(INFO, "------------------------- " _CYAN_("KeyAccess") " ------------------------"); + PrintAndLogEx(INFO, " * Kd, Debit key, AA1 Kc, Credit key, AA2 *"); uint8_t book = isset(mem, 0x20); if (book) { - PrintAndLogEx(INFO, " Read A - Kd"); - PrintAndLogEx(INFO, " Read B - Kc"); - PrintAndLogEx(INFO, " Write A - Kd"); - PrintAndLogEx(INFO, " Write B - Kc"); - PrintAndLogEx(INFO, " Debit - Kd or Kc"); - PrintAndLogEx(INFO, " Credit - Kc"); + PrintAndLogEx(INFO, " Read A....... debit"); + PrintAndLogEx(INFO, " Read B....... credit"); + PrintAndLogEx(INFO, " Write A...... debit"); + PrintAndLogEx(INFO, " Write B...... credit"); + PrintAndLogEx(INFO, " Debit........ debit or credit"); + PrintAndLogEx(INFO, " Credit....... credit"); } else { - PrintAndLogEx(INFO, " Read A - Kd or Kc"); - PrintAndLogEx(INFO, " Read B - Kd or Kc"); - PrintAndLogEx(INFO, " Write A - Kc"); - PrintAndLogEx(INFO, " Write B - Kc"); - PrintAndLogEx(INFO, " Debit - Kd or Kc"); - PrintAndLogEx(INFO, " Credit - Kc"); + PrintAndLogEx(INFO, " Read A....... debit or credit"); + PrintAndLogEx(INFO, " Read B....... debit or credit"); + PrintAndLogEx(INFO, " Write A...... credit"); + PrintAndLogEx(INFO, " Write B...... credit"); + PrintAndLogEx(INFO, " Debit........ debit or credit"); + PrintAndLogEx(INFO, " redit........ credit"); } } @@ -1540,7 +1540,7 @@ static int CmdHFiClassDump(const char *Cmd) { PrintAndLogEx(SUCCESS, "Using " _YELLOW_("replay NR/MAC mode")); use_replay = true; cmdp++; - break; + break; default: PrintAndLogEx(WARNING, "Unknown parameter '%c'\n", param_getchar(Cmd, cmdp)); errors = true; @@ -1552,7 +1552,7 @@ static int CmdHFiClassDump(const char *Cmd) { PrintAndLogEx(FAILED, "Can not use a combo of 'e', 'r', 'n'"); errors = true; } - + if (errors) return usage_hf_iclass_dump(); uint32_t flags = (FLAG_ICLASS_READER_INIT | FLAG_ICLASS_READER_CLEARTRACE); @@ -1788,7 +1788,7 @@ write_dump: } static int iclass_write_block(uint8_t blockno, uint8_t *bldata, uint8_t *KEY, bool use_credit_key, bool elite, bool rawkey, bool replay, bool verbose) { - + iclass_writeblock_req_t payload = { .req.use_raw = rawkey, .req.use_elite = elite, @@ -1882,13 +1882,13 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) { rawkey = true; cmdp++; break; -/* - case 'n': - PrintAndLogEx(SUCCESS, "Using " _YELLOW_("replay NR/MAC mode")); - use_replay = true; - cmdp++; - break; -*/ + /* + case 'n': + PrintAndLogEx(SUCCESS, "Using " _YELLOW_("replay NR/MAC mode")); + use_replay = true; + cmdp++; + break; + */ case 'v': verbose = true; cmdp++; @@ -1910,7 +1910,7 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) { if (errors || cmdp < 6) return usage_hf_iclass_writeblock(); int isok = iclass_write_block(blockno, bldata, KEY, use_credit_key, elite, rawkey, use_replay, verbose); - switch(isok) { + switch (isok) { case PM3_SUCCESS: PrintAndLogEx(SUCCESS, "Wrote block %02X successful", blockno); break; @@ -2043,24 +2043,24 @@ static int CmdHFiClassRestore(const char *Cmd) { return PM3_EFILE; } - if (bytes_read < ((endblock - startblock + 1) * 8 )) { + if (bytes_read < ((endblock - startblock + 1) * 8)) { PrintAndLogEx(ERR, "file is smaller than your suggested block range ( " _RED_("0x%02x..0x%02x")" )", - startblock, endblock - ); + startblock, endblock + ); free(dump); return PM3_EFILE; } iclass_restore_req_t *payload = calloc(1, payload_size); - payload->req.use_raw = rawkey, - payload->req.use_elite = elite, - payload->req.use_credit_key = use_credit_key, - payload->req.use_replay = false, - payload->req.blockno = startblock, - payload->req.send_reply = true, - payload->req.do_auth = true, + payload->req.use_raw = rawkey; + payload->req.use_elite = elite; + payload->req.use_credit_key = use_credit_key; + payload->req.use_replay = false; + payload->req.blockno = startblock; + payload->req.send_reply = true; + payload->req.do_auth = true; memcpy(payload->req.key, KEY, 8); - + payload->item_cnt = (endblock - startblock + 1); // read data from file from block 6 --- 19 @@ -2068,21 +2068,21 @@ static int CmdHFiClassRestore(const char *Cmd) { // then copy to usbcommand->asbytes; // max is 32 - 6 = 28 block. 28 x 12 bytes gives 336 bytes - for (uint8_t i = 0; i < payload->item_cnt; i++) { + for (uint8_t i = 0; i < payload->item_cnt; i++) { payload->blocks[i].blockno = startblock + i; - memcpy(payload->blocks[i].data, dump + (startblock * 8) + (i * 8) , sizeof(payload->blocks[i].data)); + memcpy(payload->blocks[i].data, dump + (startblock * 8) + (i * 8), sizeof(payload->blocks[i].data)); } free(dump); if (verbose) { PrintAndLogEx(INFO, "Preparing to restore block range 0x%02x..0x%02x", startblock, endblock); - + PrintAndLogEx(INFO, "------+----------------------"); PrintAndLogEx(INFO, "block | data"); PrintAndLogEx(INFO, "------+----------------------"); - for (uint8_t i = 0; i < payload->item_cnt; i++) { + for (uint8_t i = 0; i < payload->item_cnt; i++) { iclass_restore_item_t item = payload->blocks[i]; PrintAndLogEx(INFO, " %02X | %s", item.blockno, sprint_hex_inrow(item.data, sizeof(item.data))); } @@ -2233,7 +2233,7 @@ static int CmdHFiClass_ReadBlock(const char *Cmd) { } if (got_blockno == false) errors = true; - + if ((use_replay + rawkey + elite) > 1) { PrintAndLogEx(FAILED, "Can not use a combo of 'e', 'r', 'n'"); errors = true; @@ -2405,7 +2405,7 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e PrintAndLogEx(INFO, " blk| data | ascii |lck| info"); PrintAndLogEx(INFO, "----+-------------------------+----------+---+--------------"); PrintAndLogEx(INFO, "0x00| " _GREEN_("%s") " | | CSN ", sprint_hex_ascii(iclass_dump, 8)); - + if (i != 1) PrintAndLogEx(INFO, "...."); @@ -2455,8 +2455,8 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e const char *s = info_nonks[3]; if (i < 3) { s = info_nonks[i]; - } - + } + PrintAndLogEx(INFO, "0x%02X| %s | %s | %s ", i, sprint_hex_ascii(blk, 8), lockstr, s); } else { const char *info_ks[] = {"CSN", "Config", "E-purse", "Debit", "Credit", "AIA", "User"}; @@ -2978,8 +2978,8 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { free(keyBlock); return res; } - - // Get CSN / UID and CCNR + + // Get CSN / UID and CCNR PrintAndLogEx(SUCCESS, "Reading tag CSN / CCNR..."); for (uint8_t i = 0; i < ICLASS_AUTH_RETRY && !got_csn; i++) { got_csn = select_only(CSN, CCNR, false); @@ -2993,7 +2993,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { DropField(); return PM3_ESOFT; } - + iclass_premac_t *pre = calloc(keycount, sizeof(iclass_premac_t)); if (pre == NULL) { return PM3_EMALLOC; @@ -3449,7 +3449,7 @@ static int CmdHFiClassAutopwn(const char *Cmd) { }; CLIExecWithReturn(ctx, Cmd, argtable, true); CLIParserFree(ctx); - + // Check keys. // dump @@ -3539,33 +3539,33 @@ int info_iclass(void) { picopass_ns_hdr *ns_hdr = (picopass_ns_hdr *)resp.data.asBytes; PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") " --------------------------"); - PrintAndLogEx(INFO, "-------------------------------------------------------------"); + PrintAndLogEx(INFO, "--------------------- " _CYAN_("Tag Information") " ----------------------"); + PrintAndLogEx(INFO, "------------------------------------------------------------"); if (readStatus & FLAG_ICLASS_CSN) { - PrintAndLogEx(SUCCESS, " CSN: " _GREEN_("%s") " (uid)", sprint_hex(hdr->csn, sizeof(hdr->csn))); + PrintAndLogEx(SUCCESS, " CSN: " _GREEN_("%s") " uid", sprint_hex(hdr->csn, sizeof(hdr->csn))); } if (readStatus & FLAG_ICLASS_CONF) { - PrintAndLogEx(SUCCESS, " Config: %s (Card configuration)", sprint_hex((uint8_t *)&hdr->conf, sizeof(hdr->conf))); + PrintAndLogEx(SUCCESS, " Config: %s card configuration", sprint_hex((uint8_t *)&hdr->conf, sizeof(hdr->conf))); } // page mapping. If fuse0|1 == 0x01, card is in non-secure mode, with CSN, CONF, AIA as top 3 blocks. // page9 in http://www.proxmark.org/files/Documents/13.56%20MHz%20-%20iClass/DS%20Picopass%202KS%20V1-0.pdf uint8_t pagemap = get_pagemap(hdr); if (pagemap == PICOPASS_NON_SECURE_PAGEMODE) { - PrintAndLogEx(SUCCESS, " AIA: %s (Application Issuer area)", sprint_hex(ns_hdr->app_issuer_area, sizeof(ns_hdr->app_issuer_area))); + PrintAndLogEx(SUCCESS, " AIA: %s application issuer area", sprint_hex(ns_hdr->app_issuer_area, sizeof(ns_hdr->app_issuer_area))); } else { if (readStatus & FLAG_ICLASS_CC) { - PrintAndLogEx(SUCCESS, "E-purse: %s (Card challenge, CC)", sprint_hex(hdr->epurse, sizeof(hdr->epurse))); + PrintAndLogEx(SUCCESS, "E-purse: %s Card challenge, CC", sprint_hex(hdr->epurse, sizeof(hdr->epurse))); } - PrintAndLogEx(SUCCESS, " Kd: %s (Debit key, hidden)", sprint_hex(hdr->key_d, sizeof(hdr->key_d))); - PrintAndLogEx(SUCCESS, " Kc: %s (Credit key, hidden)", sprint_hex(hdr->key_c, sizeof(hdr->key_c))); + PrintAndLogEx(SUCCESS, " Kd: %s debit key, hidden", sprint_hex(hdr->key_d, sizeof(hdr->key_d))); + PrintAndLogEx(SUCCESS, " Kc: %s credit key, hidden", sprint_hex(hdr->key_c, sizeof(hdr->key_c))); if (readStatus & FLAG_ICLASS_AIA) { - PrintAndLogEx(SUCCESS, " AIA: %s (Application Issuer area)", sprint_hex(hdr->app_issuer_area, sizeof(hdr->app_issuer_area))); + PrintAndLogEx(SUCCESS, " AIA: %s application issuer area", sprint_hex(hdr->app_issuer_area, sizeof(hdr->app_issuer_area))); } } @@ -3573,7 +3573,7 @@ int info_iclass(void) { print_picopass_info(hdr); } - PrintAndLogEx(INFO, "------ " _CYAN_("Fingerprint") " ------"); + PrintAndLogEx(INFO, "------------------------ " _CYAN_("Fingerprint") " -----------------------"); uint8_t aia[8]; if (pagemap == PICOPASS_NON_SECURE_PAGEMODE) @@ -3588,18 +3588,17 @@ int info_iclass(void) { bool se_enabled = (memcmp(aia, "\xff\xff\xff\x00\x06\xff\xff\xff", 8) == 0); if (isHidRange) { - PrintAndLogEx(SUCCESS, "CSN is in HID range"); + PrintAndLogEx(SUCCESS, " CSN.......... " _YELLOW_("HID range")); if (legacy) - PrintAndLogEx(SUCCESS, "Credential : " _GREEN_("iCLASS legacy")); + PrintAndLogEx(SUCCESS, " Credential... " _GREEN_("iCLASS legacy")); if (se_enabled) - PrintAndLogEx(SUCCESS, "Credential : " _GREEN_("iCLASS SE")); - + PrintAndLogEx(SUCCESS, " Credential... " _GREEN_("iCLASS SE")); } else { - PrintAndLogEx(SUCCESS, _YELLOW_("PicoPass")" (CSN is not in HID range)"); + PrintAndLogEx(SUCCESS, " CSN..-....... " _YELLOW_("outside HID range")); } uint8_t cardtype = get_mem_config(hdr); - PrintAndLogEx(SUCCESS, " Card type : " _GREEN_("%s"), card_types[cardtype]); + PrintAndLogEx(SUCCESS, " Card type.... " _GREEN_("%s"), card_types[cardtype]); } DropField(); diff --git a/client/src/cmdhfmfp.c b/client/src/cmdhfmfp.c index 7d9c077fb..fd0f6c93a 100644 --- a/client/src/cmdhfmfp.c +++ b/client/src/cmdhfmfp.c @@ -294,9 +294,9 @@ static int CmdHFMFPInfo(const char *Cmd) { } else { // info about 14a part infoHF14A(false, false, false); - + // Historical bytes. - + } diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index c472b8d59..55e03a848 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -242,7 +242,7 @@ static int usage_hf_mfu_otp_tearoff(void) { PrintAndLogEx(NORMAL, " s