From 75ba4e97b194d9d7a5cb06cdf2d6d6aef1c45cf6 Mon Sep 17 00:00:00 2001 From: Jakub Kramarz Date: Tue, 23 Sep 2025 00:51:51 +0200 Subject: [PATCH] cmdwiegand: add option to brute-force hex input length --- client/src/cmdwiegand.c | 9 +++++++++ client/src/wiegand_formats.c | 22 +++++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/client/src/cmdwiegand.c b/client/src/cmdwiegand.c index c2d6bb3b1..1a329383f 100644 --- a/client/src/cmdwiegand.c +++ b/client/src/cmdwiegand.c @@ -165,6 +165,7 @@ int CmdWiegandDecode(const char *Cmd) { arg_str0("r", "raw", "", "raw hex to be decoded"), arg_str0("b", "bin", "", "binary string to be decoded"), arg_str0("n", "new", "", "new padded pacs as raw hex to be decoded"), + arg_lit0("f", "force", "skip preabmle checking, brute force all possible lengths for raw hex input"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); @@ -180,6 +181,8 @@ int CmdWiegandDecode(const char *Cmd) { uint8_t phex[8] = {0}; res = CLIParamHexToBuf(arg_get_str(ctx, 3), phex, sizeof(phex), &plen); + bool no_preamble = arg_get_lit(ctx, 4); + CLIParserFree(ctx); if (res) { @@ -195,6 +198,12 @@ int CmdWiegandDecode(const char *Cmd) { PrintAndLogEx(ERR, "Hex string contains none hex chars"); return PM3_EINVARG; } + + if(no_preamble){ + // pass hex input length as is and brute force all possible lengths + blen = -hlen; + } + } else if (blen) { int n = binarray_to_u96(&top, &mid, &bot, binarr, blen); if (n != blen) { diff --git a/client/src/wiegand_formats.c b/client/src/wiegand_formats.c index 29ee46d93..2aa1ea3f1 100644 --- a/client/src/wiegand_formats.c +++ b/client/src/wiegand_formats.c @@ -1716,8 +1716,28 @@ bool decode_wiegand(uint32_t top, uint32_t mid, uint32_t bot, int n) { if (n > 0) { wiegand_message_t packed = initialize_message_object(top, mid, bot, n); res = HIDTryUnpack(&packed); + } else if(n < 0) { + PrintAndLogEx(INFO, "Brute forcing all possible lengths..."); + int scan_end = (-n)*4; + int scan_start = scan_end-3; + + wiegand_message_t packed = initialize_message_object(top, mid, bot, scan_end); + + // find the first bit set in the first nibble + for(int i = 0; i < 4; i++) { + if (get_bit_by_position(&packed, i) == 1) { + scan_start = scan_end-i; + break; + } + } + + PrintAndLogEx(INFO, "Scanning from bit %d to %d...", scan_start, scan_end); + for(int i = scan_start; i <= scan_end; i++) { + packed.Length = i; + res |= HIDTryUnpack(&packed); + } } else { - wiegand_message_t packed = initialize_message_object(top, mid, bot, n); // 26-37 bits + wiegand_message_t packed = initialize_message_object(top, mid, bot, 0); // 26-37 bits res = HIDTryUnpack(&packed); PrintAndLogEx(INFO, "Trying with a preamble bit...");