Implemented data hex2bin and data bin2hex as per suggestion in http://www.proxmark.org/forum/viewtopic.php?pid=17504

This commit is contained in:
Martin Holst Swende 2015-07-31 23:27:09 +02:00
commit f68211671c
3 changed files with 102 additions and 15 deletions

View file

@ -9,6 +9,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
- AWID26 command context added as 'lf awid' containing realtime demodulation as well as cloning/simulation based on tag numbers (Craig Young)
- Added 'hw status'. This command makes the ARM print out some runtime information. (holiman)
- Added 'hw ping'. This command just sends a usb packets and checks if the pm3 is responsive. Can be used to abort certain operations which supports abort over usb. (holiman)
- Added `data hex2bin` and `data bin2hex` for command line conversion between binary and hexadecimal (holiman)
### Changed
- Revised workflow for StandAloneMode14a (Craig Young)

View file

@ -24,6 +24,7 @@
#include "usb_cmd.h"
#include "crc.h"
#include "crc16.h"
#include "loclass/cipherutils.h"
uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
uint8_t g_debugMode=0;
@ -1943,26 +1944,14 @@ int CmdHpf(const char *Cmd)
RepaintGraphWindow();
return 0;
}
typedef struct {
uint8_t * buffer;
uint32_t numbits;
uint32_t position;
}BitstreamOut;
bool _headBit( BitstreamOut *stream)
{
int bytepos = stream->position >> 3; // divide by 8
int bitpos = (stream->position++) & 7; // mask out 00000111
return (*(stream->buffer + bytepos) >> (7-bitpos)) & 1;
}
uint8_t getByte(uint8_t bits_per_sample, BitstreamOut* b)
uint8_t getByte(uint8_t bits_per_sample, BitstreamIn* b)
{
int i;
uint8_t val = 0;
for(i =0 ; i < bits_per_sample; i++)
{
val |= (_headBit(b) << (7-i));
val |= (headBit(b) << (7-i));
}
return val;
}
@ -2002,7 +1991,7 @@ int getSamples(const char *Cmd, bool silent)
if(bits_per_sample < 8)
{
PrintAndLog("Unpacking...");
BitstreamOut bout = { got, bits_per_sample * n, 0};
BitstreamIn bout = { got, bits_per_sample * n, 0};
int j =0;
for (j = 0; j * bits_per_sample < n * 8 && j < n; j++) {
uint8_t sample = getByte(bits_per_sample, &bout);
@ -2265,6 +2254,99 @@ int CmdZerocrossings(const char *Cmd)
return 0;
}
int usage_data_bin2hex(){
PrintAndLog("Usage: data bin2hex <binary_digits>");
PrintAndLog(" This function will ignore all characters not 1 or 0 (but stop reading on whitespace)");
return 0;
}
/**
* @brief Utility for conversion via cmdline.
* @param Cmd
* @return
*/
int Cmdbin2hex(const char *Cmd)
{
int bg =0, en =0;
if(param_getptr(Cmd, &bg, &en, 0))
{
return usage_data_bin2hex();
}
//Number of digits supplied as argument
size_t length = en - bg +1;
size_t bytelen = (length+7) / 8;
uint8_t* arr = (uint8_t *) malloc(bytelen);
memset(arr, 0, bytelen);
BitstreamOut bout = { arr, 0, 0 };
for(; bg <= en ;bg++)
{
char c = Cmd[bg];
if( c == '1') pushBit(&bout, 1);
else if( c == '0') pushBit(&bout, 0);
else PrintAndLog("Ignoring '%c'", c);
}
if(bout.numbits % 8 != 0)
{
printf("[padded with %d zeroes]\n", 8-(bout.numbits % 8));
}
//Uses printf instead of PrintAndLog since the latter
// adds linebreaks to each printout - this way was more convenient since we don't have to
// allocate a string and write to that first...
for(size_t x = 0; x < bytelen ; x++)
{
printf("%02X", arr[x]);
}
printf("\n");
free(arr);
return 0;
}
int usage_data_hex2bin(){
PrintAndLog("Usage: data bin2hex <binary_digits>");
PrintAndLog(" This function will ignore all non-hexadecimal characters (but stop reading on whitespace)");
return 0;
}
int Cmdhex2bin(const char *Cmd)
{
int bg =0, en =0;
if(param_getptr(Cmd, &bg, &en, 0))
{
return usage_data_hex2bin();
}
while(bg <= en )
{
char x = Cmd[bg++];
// capitalize
if (x >= 'a' && x <= 'f')
x -= 32;
// convert to numeric value
if (x >= '0' && x <= '9')
x -= '0';
else if (x >= 'A' && x <= 'F')
x -= 'A' - 10;
else
continue;
//Uses printf instead of PrintAndLog since the latter
// adds linebreaks to each printout - this way was more convenient since we don't have to
// allocate a string and write to that first...
for(int i= 0 ; i < 4 ; ++i)
printf("%d",(x >> (3 - i)) & 1);
}
printf("\n");
return 0;
}
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
@ -2287,6 +2369,9 @@ static command_t CommandTable[] =
{"getbitstream", CmdGetBitStream, 1, "Convert GraphBuffer's >=1 values to 1 and <1 to 0"},
{"grid", CmdGrid, 1, "<x> <y> -- overlay grid on graph window, use zero value to turn off either"},
{"hexsamples", CmdHexsamples, 0, "<bytes> [<offset>] -- Dump big buffer as hex bytes"},
{"bin2hex", Cmdbin2hex, 1, "bin2hex <digits> -- Converts binary to hexadecimal"},
{"hex2bin", Cmdhex2bin, 1, "hex2bin <hexadecimal> -- Converts hexadecimal to binary"},
{"hexsamples", CmdHexsamples, 0, "<bytes> [<offset>] -- Dump big buffer as hex bytes"},
{"hide", CmdHide, 1, "Hide graph window"},
{"hpf", CmdHpf, 1, "Remove DC offset from trace"},
{"load", CmdLoad, 1, "<filename> -- Load trace (to graph window"},

View file

@ -47,6 +47,7 @@ char * printBits(size_t const size, void const * const ptr);
uint8_t *SwapEndian64(const uint8_t *src, const size_t len, const uint8_t blockSize);
char param_getchar(const char *line, int paramnum);
int param_getptr(const char *line, int *bg, int *en, int paramnum);
uint8_t param_get8(const char *line, int paramnum);
uint8_t param_get8ex(const char *line, int paramnum, int deflt, int base);
uint32_t param_get32ex(const char *line, int paramnum, int deflt, int base);