diff --git a/client/src/cmdlfhid.c b/client/src/cmdlfhid.c index 47eeca45b..319fbc9e6 100644 --- a/client/src/cmdlfhid.c +++ b/client/src/cmdlfhid.c @@ -356,11 +356,9 @@ static int CmdHIDClone(const char *Cmd) { bool q5 = arg_get_lit(ctx, 7); bool em = arg_get_lit(ctx, 8); - int bin_len = 63; uint8_t bin[70] = {0}; CLIGetStrWithReturn(ctx, 9, bin, &bin_len); - CLIParserFree(ctx); if (q5 && em) { @@ -383,12 +381,21 @@ static int CmdHIDClone(const char *Cmd) { return PM3_EINVARG; } + uint32_t top = 0, mid = 0, bot = 0; if (raw_len) { - uint32_t top = 0, mid = 0, bot = 0; hexstring_to_u96(&top, &mid, &bot, raw); packed.Top = top; packed.Mid = mid; packed.Bot = bot; + } else if (bin_len) { + int res = binstring_to_u96(&top, &mid, &bot, bin); + if (res != bin_len) { + PrintAndLogEx(ERR, "Binary string contains none <0|1> chars"); + return PM3_EINVARG; + } + packed.Top = top; + packed.Mid = mid; + packed.Bot = bot; } else { if (HIDPack(format_idx, &card, &packed, true) == false) { PrintAndLogEx(WARNING, "The card data could not be encoded in the selected format."); diff --git a/client/src/util.c b/client/src/util.c index 03a1e68f8..53825f28b 100644 --- a/client/src/util.c +++ b/client/src/util.c @@ -951,13 +951,13 @@ char *str_ndup(const char *src, size_t len) { } /** - * Converts a hex string to component "hi2", "hi" and "lo" 32-bit integers, one nibble - * at a time. + * Converts a hex string to component "hi2", "hi" and "lo" 32-bit integers + * one nibble at a time. * * Returns the number of nibbles (4 bits) entered. */ int hexstring_to_u96(uint32_t *hi2, uint32_t *hi, uint32_t *lo, const char *str) { - unsigned int n = 0, i = 0; + uint32_t n = 0, i = 0; while (sscanf(&str[i++], "%1x", &n) == 1) { *hi2 = (*hi2 << 4) | (*hi >> 28); @@ -967,6 +967,30 @@ int hexstring_to_u96(uint32_t *hi2, uint32_t *hi, uint32_t *lo, const char *str) return i - 1; } +/** + * Converts a binary string to component "hi2", "hi" and "lo" 32-bit integers, + * one bit at a time. + * + * Returns the number of bits entered. + */ +int binstring_to_u96(uint32_t *hi2, uint32_t *hi, uint32_t *lo, const char *str) { + uint32_t n = 0, i = 0; + + for(;;) { + + int res = sscanf(&str[i], "%1u", &n); + if ((res != 1) || (n > 1)) + break; + + *hi2 = (*hi2 << 1) | (*hi >> 31); + *hi = (*hi << 1) | (*lo >> 31); + *lo = (*lo << 1) | (n & 0x1); + + i++; + } + return i; +} + inline uint32_t bitcount32(uint32_t a) { #if defined __GNUC__ return __builtin_popcountl(a); diff --git a/client/src/util.h b/client/src/util.h index 4d86553c2..7577c216e 100644 --- a/client/src/util.h +++ b/client/src/util.h @@ -105,6 +105,7 @@ void strcreplace(char *buf, size_t len, char from, char to); char *str_dup(const char *src); char *str_ndup(const char *src, size_t len); int hexstring_to_u96(uint32_t *hi2, uint32_t *hi, uint32_t *lo, const char *str); +int binstring_to_u96(uint32_t *hi2, uint32_t *hi, uint32_t *lo, const char *str); uint32_t bitcount32(uint32_t a); uint64_t bitcount64(uint64_t a);