Uninformed: Informative Information for the Uninformed

Vol 1» 2005.May


Decoding Data

For decoding the data, we simply record bits to an input buffer when the clock is in one state, and to an output buffer when the clock is in the other. Then dump all of the bytes and reset our counter whenever there's a reset. This should give us a dump of the data that's being transferred between the two devices.

/*
 * Synchronous Smart Card Log Analyzer v1.0 [analyze.c]
 * by h1kari <h1kari@dachb0den.com>
 */
#include <stdio.h>

#ifdef PRINTBITS
#define BYTESPERROW 8
#else
#define BYTESPERROW 16
#endif

void
pushbit(u_char *byte, u_char bit, u_char n)
{
    /* add specified bit to their byte */
    *byte &= ~(1 << (7 - n));
    *byte |= (bit << (7 - n));
}

void
printbuf(u_char *buf, int len, char *io)
{
    int i, b;

    printf("%s:\n", io);

    for(i = 0; i < len; i++) {
#ifdef PRINTBITS
        int j;

        for(j = 7; j >= 0; j--)
            printf("%d", (buf[i] >> j) & 1);
        putchar(' ');
#else
        printf("%02x ", buf[i]);
#endif
        if((i % BYTESPERROW) == BYTESPERROW - 1)
            printf("\n");
    }

    if((i % BYTESPERROW) != 0) {
        printf("\n");
    }
}

int
main(int argc, char *argv[])
{
    u_char ibit, obit;
    u_char ibyte, obyte;
    u_char clk, rst, bit;
    u_char lclk;
    u_char ibuf[1024 * 1024], obuf[1024 * 1024];
    int ii = 0, oi = 0;
    char line[1024];
    FILE *fh;

    if(argc < 2) {
        fprintf(stderr, "usage: %s <file>\n", argv[0]);
        exit(1);
    }

    if((fh = fopen(argv[1], "r")) == NULL) {
        perror("unable to open lpt log\n");
        exit(1);
    }

    lclk = 2;
    while(fgets(line, 1024, fh) != NULL) {
        bit = line[0] - 48;
        rst = line[2] - 48;
        clk = line[3] - 48;
        bit = bit ? 0 : 1;

        if(lclk == 2) lclk = clk;

        /* print out buffers when we get a reset */
        if(rst) {
            if(ii > 0 && oi > 0) {
                printbuf(ibuf, ii, "input");
                printbuf(obuf, oi, "output");
            }
            ibit = obit = 0;
            ibyte = obyte = 0;
            ii = oi = 0;
        }

        /* if clock high input */
        if(clk) {
            /* incr on clock change */
            if(lclk != clk) obit++;
            pushbit(&ibyte, bit, ibit);
        /* otherwise output */
        } else {
            /* incr on clock change */
            if(lclk != clk) ibit++;
            pushbit(&obyte, bit, obit);
        }

        /* next byte */
        if(ibit == 8) {
            ibuf[ii++] = ibyte;
            ibit = 0;
        }

        if(obit == 8) {
            obuf[oi++] = obyte;
            obit = 0;
        }

        /* save last clock */
        lclk = clk;
    }
}