diff --git a/armsrc/BigBuf.c b/armsrc/BigBuf.c index 97c2ef5c4..9ba400ff9 100644 --- a/armsrc/BigBuf.c +++ b/armsrc/BigBuf.c @@ -13,6 +13,7 @@ #include "string.h" #include "dbprint.h" #include "pm3_cmd.h" +#include "util.h" // nbytes extern uint32_t _stack_start[], __bss_end__[]; @@ -289,6 +290,13 @@ bool LogTrace_ISO15693(const uint8_t *bytes, uint16_t len, uint32_t ts_start, ui return LogTrace(bytes, len, ts_start, ts_end, parity, reader2tag); } +// specific LogTrace function for bitstreams: the partial byte size is stored in first parity byte. E.g. bitstream "1100 00100010" -> partial byte: 4 bits +bool RAMFUNC LogTraceBits(const uint8_t *btBytes, uint16_t bitLen, uint32_t timestamp_start, uint32_t timestamp_end, bool readerToTag) { + uint8_t parity[(nbytes(bitLen) - 1) / 8 + 1]; + memset(parity, 0x00, sizeof(parity)); + parity[0] = ((bitLen - 1) % 8) + 1; + return LogTrace(btBytes, nbytes(bitLen), timestamp_start, timestamp_end, parity, readerToTag); +} // Emulator memory uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length) { diff --git a/armsrc/BigBuf.h b/armsrc/BigBuf.h index 6bdf4e331..435aeb80d 100644 --- a/armsrc/BigBuf.h +++ b/armsrc/BigBuf.h @@ -45,6 +45,7 @@ void set_tracelen(uint32_t value); bool get_tracing(void); bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag); +bool RAMFUNC LogTraceBits(const uint8_t *btBytes, uint16_t bitLen, uint32_t timestamp_start, uint32_t timestamp_end, bool readerToTag); bool LogTrace_ISO15693(const uint8_t *bytes, uint16_t len, uint32_t ts_start, uint32_t ts_end, uint8_t *parity, bool reader2tag); uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length); diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 693a5f9d2..70f048bab 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -314,8 +314,8 @@ static void hitag2_handle_reader_command(uint8_t *rx, const size_t rxlen, uint8_ break; } - // LogTrace(rx, nbytes(rxlen), 0, 0, NULL, false); - // LogTrace(tx, nbytes(txlen), 0, 0, NULL, true); + // LogTraceBits(rx, rxlen, 0, 0, false); + // LogTraceBits(tx, txlen, 0, 0, true); if (tag.crypto_active) { hitag2_cipher_transcrypt(&(tag.cs), tx, *txlen / 8, *txlen % 8); @@ -1100,7 +1100,7 @@ void SniffHitag2(bool ledcontrol) { if (rxlen == 0) continue; - LogTrace(rx, nbytes(rxlen), 0, 0, NULL, false); + LogTraceBits(rx, rxlen, 0, 0, false); total_count += nbytes(rxlen); } else { // decode reader comms @@ -1108,7 +1108,7 @@ void SniffHitag2(bool ledcontrol) { total_count += rxlen; // Pack the response into a byte array - // LogTrace(rx, nbytes(rdr), 0, 0, NULL, true); + // LogTraceBits(rx, rdr, 0, 0, true); // total_count += nbytes(rdr); } if (ledcontrol) LED_A_INV(); @@ -1265,7 +1265,7 @@ void SniffHitag2(bool ledcontrol) { // Check if frame was captured if (rxlen) { frame_count++; - LogTrace(rx, nbytes(rxlen), response, 0, NULL, reader_frame); + LogTraceBits(rx, rxlen, response, 0, reader_frame); // Check if we recognize a valid authentication attempt if (nbytes(rxlen) == 8) { @@ -1495,7 +1495,7 @@ void SimulateHitag2(bool ledcontrol) { // Check if frame was captured if (rxlen > 4) { - LogTrace(rx, nbytes(rxlen), response, response, NULL, true); + LogTraceBits(rx, rxlen, response, response, true); // Process the incoming frame (rx) and prepare the outgoing frame (tx) hitag2_handle_reader_command(rx, rxlen, tx, &txlen); @@ -1514,7 +1514,7 @@ void SimulateHitag2(bool ledcontrol) { lf_manchester_send_bytes(tx, txlen, ledcontrol); // Store the frame in the trace - LogTrace(tx, nbytes(txlen), 0, 0, NULL, false); + LogTraceBits(tx, txlen, 0, 0, false); } // Reset the received frame and response timing info @@ -1844,7 +1844,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd, bool ledcontrol) { // and to be able to overwrite the first samples with the trace (since they currently // still use the same memory space) if (txlen > 0) { - LogTrace(tx, nbytes(txlen), command_start, command_start + command_duration, NULL, true); + LogTraceBits(tx, txlen, command_start, command_start + command_duration, true); } // Reset values for receiving frames @@ -1904,7 +1904,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd, bool ledcontrol) { // Check if frame was captured and store it if (rxlen > 0) { - LogTrace(rx, nbytes(rxlen), response_start, response_start + response_duration, NULL, false); + LogTraceBits(rx, rxlen, response_start, response_start + response_duration, false); // TODO when using cumulative time for command_start, pm3 doesn't reply anymore, e.g. on lf hitag reader --23 -k 4F4E4D494B52 // Use delta time? @@ -2167,7 +2167,7 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page, bool ledcontrol) // and to be able to overwrite the first samples with the trace (since they currently // still use the same memory space) if (txlen > 0) { - LogTrace(tx, nbytes(txlen), command_start, command_start + command_duration, NULL, true); + LogTraceBits(tx, txlen, command_start, command_start + command_duration, true); } // Reset values for receiving frames @@ -2225,7 +2225,7 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page, bool ledcontrol) // Check if frame was captured and store it if (rxlen > 0) { - LogTrace(rx, nbytes(rxlen), response_start, response_start + response_duration, NULL, false); + LogTraceBits(rx, rxlen, response_start, response_start + response_duration, false); command_start = 0; } } diff --git a/armsrc/hitagS.c b/armsrc/hitagS.c index 5ff3d9589..462a18277 100644 --- a/armsrc/hitagS.c +++ b/armsrc/hitagS.c @@ -1036,7 +1036,7 @@ void SimulateHitagSTag(bool tag_mem_supplied, uint8_t *data, bool ledcontrol) { // Check if frame was captured if (rxlen > 0) { // frame_count++; - LogTrace(rx, nbytes(rxlen), response, response, NULL, true); + LogTraceBits(rx, rxlen, response, response, true); // Disable timer 1 with external trigger to avoid triggers during our own modulation AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; @@ -1055,7 +1055,7 @@ void SimulateHitagSTag(bool tag_mem_supplied, uint8_t *data, bool ledcontrol) { if (txlen > 0) { // Transmit the tag frame hitag_send_frame(tx, txlen, ledcontrol); - LogTrace(tx, nbytes(txlen), 0, 0, NULL, false); + LogTraceBits(tx, txlen, 0, 0, false); } // Enable and reset external trigger in timer for capturing future frames @@ -1278,7 +1278,7 @@ void ReadHitagS(hitag_function htf, hitag_data *htd, bool ledcontrol) { // Check if frame was captured and store it if (rxlen > 0) { // frame_count++; - LogTrace(rx, nbytes(rxlen), response, response, NULL, false); + LogTraceBits(rx, rxlen, response, response, false); } // By default reset the transmission buffer @@ -1407,7 +1407,7 @@ void ReadHitagS(hitag_function htf, hitag_data *htd, bool ledcontrol) { // Add transmitted frame to total count if (txlen > 0) { // frame_count++; - LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, HITAG_T_WAIT_2, NULL, true); + LogTraceBits(tx, txlen, HITAG_T_WAIT_2, HITAG_T_WAIT_2, true); } hitagS_receive_frame(rx, &rxlen, &response, ledcontrol); @@ -1535,7 +1535,7 @@ void WritePageHitagS(hitag_function htf, hitag_data *htd, int page, bool ledcont // Check if frame was captured and store it if (rxlen > 0) { // frame_count++; - LogTrace(rx, nbytes(rxlen), response, response, NULL, false); + LogTraceBits(rx, rxlen, response, response, false); } //check for valid input @@ -1622,7 +1622,7 @@ void WritePageHitagS(hitag_function htf, hitag_data *htd, int page, bool ledcont // Add transmitted frame to total count if (txlen > 0) { // frame_count++; - LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, HITAG_T_WAIT_2, NULL, true); + LogTraceBits(tx, txlen, HITAG_T_WAIT_2, HITAG_T_WAIT_2, true); } hitagS_receive_frame(rx, &rxlen, &response, ledcontrol); @@ -1729,7 +1729,7 @@ void check_challenges(bool file_given, uint8_t *data, bool ledcontrol) { // Check if frame was captured and store it if (rxlen > 0) { // frame_count++; - LogTrace(rx, nbytes(rxlen), response, response, NULL, false); + LogTraceBits(rx, rxlen, response, response, false); } uint8_t *tx = txbuf; @@ -1861,7 +1861,7 @@ void check_challenges(bool file_given, uint8_t *data, bool ledcontrol) { // Add transmitted frame to total count if (txlen > 0) { // frame_count++; - LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, HITAG_T_WAIT_2, NULL, true); + LogTraceBits(tx, txlen, HITAG_T_WAIT_2, HITAG_T_WAIT_2, true); } hitagS_receive_frame(rx, &rxlen, &response, ledcontrol); diff --git a/client/src/cmdtrace.c b/client/src/cmdtrace.c index 1e49ca64c..17ddacfdd 100644 --- a/client/src/cmdtrace.c +++ b/client/src/cmdtrace.c @@ -240,7 +240,8 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr sprintf(line[0], ""); } } - + uint8_t partialbytebuff = 0; + uint8_t offset = 0; for (int j = 0; j < data_len && j / 18 < 18; j++) { uint8_t parityBits = parityBytes[j >> 3]; if (protocol != LEGIC @@ -270,6 +271,18 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr snprintf(line[j / 18] + ((j % 18) * 4), 120, "%02x! ", frame[j]); } + } else if (((protocol == PROTO_HITAG1) || (protocol == PROTO_HITAG2) || (protocol == PROTO_HITAGS)) && (parityBytes[0] > 0)){ + // handle partial bytes + uint8_t nbits = parityBytes[0]; + if (j==0) { + partialbytebuff = frame[0] << nbits; + snprintf(line[0], 120, "%02x(%i) ", frame[0] >> (8 - nbits), nbits); + offset = 2; + } else { + uint8_t byte = partialbytebuff | (frame[j] >> (8 - nbits)); + partialbytebuff = frame[j] << nbits; + snprintf(line[j / 18] + ((j % 18) * 4) + offset, 120, "%02x ", byte); + } } else { snprintf(line[j / 18] + ((j % 18) * 4), 120, "%02x ", frame[j]); } @@ -278,11 +291,23 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr if (markCRCBytes) { //CRC-command - if (crcStatus == 0 || crcStatus == 1) { - char *pos1 = line[(data_len - 2) / 18] + (((data_len - 2) % 18) * 4) - 1; + if (((protocol == PROTO_HITAG1) || (protocol == PROTO_HITAGS)) && (data_len > 1)) { + // notes hitag S: + // pm3 is using UID REQUEST Adv -> SOF is 111(AC) then 111111(MC) + // first tag response is AC encoded Currently, recorded trace is garbage + // for unknown reason, recorded SOF in trace is 1111 instead of 111111 (or should be even skipped) + // CRC on tag response is SOF excluded + char *pos1 = line[(data_len - 1) / 18] + (((data_len - 1) % 18) * 4) + offset - 1; (*pos1) = '['; - char *pos2 = line[(data_len) / 18] + (((data_len) % 18) * 4) - 1; + char *pos2 = line[(data_len) / 18] + (((data_len) % 18) * 4) + offset - 2; sprintf(pos2, "%c", ']'); + } else { + if (crcStatus == 0 || crcStatus == 1) { + char *pos1 = line[(data_len - 2) / 18] + (((data_len - 2) % 18) * 4) - 1; + (*pos1) = '['; + char *pos2 = line[(data_len) / 18] + (((data_len) % 18) * 4) - 1; + sprintf(pos2, "%c", ']'); + } } } diff --git a/traces/lf_HitagS256_dump.trace b/traces/lf_HitagS256_dump.trace index 255abb56d..b1036b1c4 100644 Binary files a/traces/lf_HitagS256_dump.trace and b/traces/lf_HitagS256_dump.trace differ