From 8573695134ea61b7f042e6149e7f2160ab06e7ed Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 23 Mar 2021 11:06:09 +0100 Subject: [PATCH] data bin2hex - now uses cliparser\n added a binary string input parser --- client/deps/cliparser/cliparser.c | 25 +++++++++ client/deps/cliparser/cliparser.h | 1 + client/src/cmddata.c | 54 ++++++++++++-------- client/src/util.c | 84 ++++++++++++++++++++++--------- client/src/util.h | 1 + 5 files changed, 121 insertions(+), 44 deletions(-) diff --git a/client/deps/cliparser/cliparser.c b/client/deps/cliparser/cliparser.c index f3f3c581e..174a540fc 100644 --- a/client/deps/cliparser/cliparser.c +++ b/client/deps/cliparser/cliparser.c @@ -231,6 +231,31 @@ int CLIParamHexToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int return res; } +int CLIParamBinToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen) { + *datalen = 0; + + 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 || tmplen == 0) { + return res; + } + + res = param_getbin_to_eol((char *)tmpstr, 0, data, maxdatalen, datalen); + switch (res) { + case 1: + PrintAndLogEx(ERR, "Parameter error: Invalid BINARY value\n"); + break; + case 2: + PrintAndLogEx(ERR, "Parameter error: parameter too large\n"); + break; + } + return res; +} + int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen) { *datalen = 0; if (!argstr->count) diff --git a/client/deps/cliparser/cliparser.h b/client/deps/cliparser/cliparser.h index 78bb59f32..0213d1917 100644 --- a/client/deps/cliparser/cliparser.h +++ b/client/deps/cliparser/cliparser.h @@ -66,6 +66,7 @@ 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); +int CLIParamBinToBuf(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); int arg_get_u64_hexstr_def_nlen(CLIParserContext *ctx, uint8_t paramnum, uint64_t def, uint64_t *out, uint8_t nlen, bool optional); diff --git a/client/src/cmddata.c b/client/src/cmddata.c index ba3d2b5f1..2809fbecb 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -224,12 +224,6 @@ static int usage_data_detectclock(void) { return PM3_SUCCESS; } -static int usage_data_bin2hex(void) { - PrintAndLogEx(NORMAL, "Usage: data bin2hex "); - PrintAndLogEx(NORMAL, " This function will ignore all characters not 1 or 0 (but stop reading on whitespace)"); - return PM3_SUCCESS; -} - //set the demod buffer with given array of binary (one bit per byte) //by marshmellow void setDemodBuff(uint8_t *buff, size_t size, size_t start_idx) { @@ -2224,31 +2218,49 @@ static int CmdZerocrossings(const char *Cmd) { * @return */ static 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; + CLIParserContext *ctx; + CLIParserInit(&ctx, "data bin2hex", + "This function converts binary to hexadecimal. It will ignore all\n" + "characters not 1 or 0 but stop reading on whitespace", + "data bin2hex -d 0101111001010" + ); + void *argtable[] = { + arg_param_begin, + arg_strx0("d", "data", "", "binary string to convert"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + int blen = 0; + uint8_t binarr[400] = {0x00}; + int res = CLIParamBinToBuf(arg_get_str(ctx, 1), binarr, sizeof(binarr), &blen); + CLIParserFree(ctx); + + if (res) { + PrintAndLogEx(FAILED, "Error parsing binary string"); + return PM3_EINVARG; + } + + // Number of digits supplied as argument + size_t bytelen = (blen + 7) / 8; uint8_t *arr = (uint8_t *) calloc(bytelen, sizeof(uint8_t)); memset(arr, 0, bytelen); BitstreamOut bout = { arr, 0, 0 }; - for (; bg <= en; bg++) { - char c = Cmd[bg]; - if (c == '1') + for (int i = 0; i < blen; i++) { + uint8_t c = binarr[i]; + if (c == 1) pushBit(&bout, 1); - else if (c == '0') + else if (c == 0) pushBit(&bout, 0); else - PrintAndLogEx(NORMAL, "Ignoring '%c'", c); + PrintAndLogEx(INFO, "Ignoring '%d' at pos %d", c, i); } if (bout.numbits % 8 != 0) - PrintAndLogEx(NORMAL, "[padded with %d zeroes]", 8 - (bout.numbits % 8)); + PrintAndLogEx(INFO, "[right padded with %d zeroes]", 8 - (bout.numbits % 8)); - PrintAndLogEx(NORMAL, "%s", sprint_hex(arr, bytelen)); + PrintAndLogEx(SUCCESS, _YELLOW_("%s"), sprint_hex(arr, bytelen)); free(arr); return PM3_SUCCESS; } @@ -2256,8 +2268,8 @@ static int Cmdbin2hex(const char *Cmd) { static int Cmdhex2bin(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "data hex2bin", - "This function will ignore all non-hexadecimal characters\n" - "but stop reading on whitespace", + "This function converts hexadecimal to binary. It will ignore all\n" + "non-hexadecimal characters but stop reading on whitespace", "data hex2bin -d 01020304" ); void *argtable[] = { diff --git a/client/src/util.c b/client/src/util.c index 978cb4b45..bcebabfa0 100644 --- a/client/src/util.c +++ b/client/src/util.c @@ -285,36 +285,33 @@ char *sprint_hex_inrow_spaces(const uint8_t *data, const size_t len, size_t spac char *sprint_bin_break(const uint8_t *data, const size_t len, const uint8_t breaks) { // make sure we don't go beyond our char array memory - size_t in_index = 0, out_index = 0; - size_t rowlen = (len > MAX_BIN_BREAK_LENGTH) ? MAX_BIN_BREAK_LENGTH : len; - if (breaks > 0 && len % breaks != 0) - rowlen = (len + (len / breaks) > MAX_BIN_BREAK_LENGTH) ? MAX_BIN_BREAK_LENGTH : len + (len / breaks); - - //PrintAndLogEx(NORMAL, "(sprint_bin_break) rowlen %d", rowlen); - - static char buf[MAX_BIN_BREAK_LENGTH]; // 3072 + end of line characters if broken at 8 bits - //clear memory + // 3072 + end of line characters if broken at 8 bits + static char buf[MAX_BIN_BREAK_LENGTH]; memset(buf, 0x00, sizeof(buf)); char *tmp = buf; // loop through the out_index to make sure we don't go too far - for (out_index = 0; out_index < rowlen; out_index++) { - // set character - if (data[in_index] == 7) // Manchester wrong bit marker - sprintf(tmp++, "."); - else - sprintf(tmp++, "%u", data[in_index]); + for (int i = 0; i < rowlen; i++) { + + char c = data[i]; + // manchester wrong bit marker + if (c == 7) + c = '.'; + else + c += '0'; + + *(tmp++) = c; // check if a line break is needed and we have room to print it in our array - if ((breaks > 0) && !((in_index + 1) % breaks) && (out_index + 1 != rowlen)) { - sprintf(tmp++, "%s", "\n"); + if (breaks) { + if (((i + 1) % breaks) == 0) { + + *(tmp++) = '\n'; + } } - - in_index++; } - return buf; } /* @@ -714,6 +711,48 @@ int param_gethex_to_eol(const char *line, int paramnum, uint8_t *data, int maxda return 0; } +int param_getbin_to_eol(const char *line, int paramnum, uint8_t *data, int maxdatalen, int *datalen) { + int bg, en; + if (param_getptr(line, &bg, &en, paramnum)) { + return 1; + } + + *datalen = 0; + char buf[5] = {0}; + int indx = bg; + while (line[indx]) { + if (line[indx] == '\t' || line[indx] == ' ') { + indx++; + continue; + } + + if (line[indx] == '0' || line[indx] == '1') { + buf[strlen(buf) + 1] = 0x00; + buf[strlen(buf)] = line[indx]; + } else { + // if we have symbols other than spaces and 0/1 + return 1; + } + + if (*datalen >= maxdatalen) { + // if we dont have space in buffer and have symbols to translate + return 2; + } + + if (strlen(buf) > 0) { + uint32_t temp = 0; + sscanf(buf, "%d", &temp); + data[*datalen] = (uint8_t)(temp & 0xff); + *buf = 0; + (*datalen)++; + } + + indx++; + } + return 0; +} + + int param_getstr(const char *line, int paramnum, char *str, size_t buffersize) { int bg, en; @@ -768,9 +807,8 @@ int hextobinarray(char *target, char *source) { // convert hex to human readable binary string int hextobinstring(char *target, char *source) { - int length; - - if (!(length = hextobinarray(target, source))) + int length = hextobinarray(target, source); + if (length == 0) return 0; binarraytobinstring(target, target, length); return length; diff --git a/client/src/util.h b/client/src/util.h index 7577c216e..6a2933d5a 100644 --- a/client/src/util.h +++ b/client/src/util.h @@ -77,6 +77,7 @@ uint8_t param_isdec(const char *line, int paramnum); int param_gethex(const char *line, int paramnum, uint8_t *data, int hexcnt); int param_gethex_ex(const char *line, int paramnum, uint8_t *data, int *hexcnt); int param_gethex_to_eol(const char *line, int paramnum, uint8_t *data, int maxdatalen, int *datalen); +int param_getbin_to_eol(const char *line, int paramnum, uint8_t *data, int maxdatalen, int *datalen); int param_getstr(const char *line, int paramnum, char *str, size_t buffersize); int hextobinarray(char *target, char *source);