Skip to content

Commit bbce619

Browse files
authored
Merge pull request #2990 from jkramarz/cmdwiegand-bf
add option to brute-force hex input length in wiegand decode command
2 parents 128af38 + b65797b commit bbce619

File tree

2 files changed

+35
-4
lines changed

2 files changed

+35
-4
lines changed

client/src/cmdwiegand.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ int CmdWiegandDecode(const char *Cmd) {
165165
arg_str0("r", "raw", "<hex>", "raw hex to be decoded"),
166166
arg_str0("b", "bin", "<bin>", "binary string to be decoded"),
167167
arg_str0("n", "new", "<hex>", "new padded pacs as raw hex to be decoded"),
168+
arg_lit0("f", "force", "skip preabmle checking, brute force all possible lengths for raw hex input"),
168169
arg_param_end
169170
};
170171
CLIExecWithReturn(ctx, Cmd, argtable, false);
@@ -180,6 +181,8 @@ int CmdWiegandDecode(const char *Cmd) {
180181
uint8_t phex[8] = {0};
181182
res = CLIParamHexToBuf(arg_get_str(ctx, 3), phex, sizeof(phex), &plen);
182183

184+
bool no_preamble = arg_get_lit(ctx, 4);
185+
183186
CLIParserFree(ctx);
184187

185188
if (res) {
@@ -195,6 +198,12 @@ int CmdWiegandDecode(const char *Cmd) {
195198
PrintAndLogEx(ERR, "Hex string contains none hex chars");
196199
return PM3_EINVARG;
197200
}
201+
202+
if(no_preamble){
203+
// pass hex input length as is and brute force all possible lengths
204+
blen = -hlen;
205+
}
206+
198207
} else if (blen) {
199208
int n = binarray_to_u96(&top, &mid, &bot, binarr, blen);
200209
if (n != blen) {

client/src/wiegand_formats.c

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1688,10 +1688,12 @@ bool HIDTryUnpack(wiegand_message_t *packed) {
16881688
);
16891689
}
16901690

1691-
if (packed->Length && ((found_cnt - found_invalid_par) == 0)) { // if length > 0 and no valid parity matches
1692-
PrintAndLogEx(FAILED, "Parity tests failed");
1691+
if(found_cnt > 0){
1692+
if (packed->Length && ((found_cnt - found_invalid_par) == 0)) { // if length > 0 and no valid parity matches
1693+
PrintAndLogEx(FAILED, "Parity tests failed");
1694+
}
1695+
PrintAndLogEx(NORMAL, "");
16931696
}
1694-
PrintAndLogEx(NORMAL, "");
16951697

16961698
return ((found_cnt - found_invalid_par) > 0);
16971699
}
@@ -1716,8 +1718,28 @@ bool decode_wiegand(uint32_t top, uint32_t mid, uint32_t bot, int n) {
17161718
if (n > 0) {
17171719
wiegand_message_t packed = initialize_message_object(top, mid, bot, n);
17181720
res = HIDTryUnpack(&packed);
1721+
} else if(n < 0) {
1722+
PrintAndLogEx(INFO, "Brute forcing all possible lengths...");
1723+
int scan_end = (-n)*4;
1724+
int scan_start = scan_end-3;
1725+
1726+
wiegand_message_t packed = initialize_message_object(top, mid, bot, scan_end);
1727+
1728+
// find the first bit set in the first nibble
1729+
for(int i = 0; i < 4; i++) {
1730+
if (get_bit_by_position(&packed, i) == 1) {
1731+
scan_start = scan_end-i;
1732+
break;
1733+
}
1734+
}
1735+
1736+
PrintAndLogEx(INFO, "Scanning from bit %d to %d...", scan_start, scan_end);
1737+
for(int i = scan_start; i <= scan_end; i++) {
1738+
packed.Length = i;
1739+
res |= HIDTryUnpack(&packed);
1740+
}
17191741
} else {
1720-
wiegand_message_t packed = initialize_message_object(top, mid, bot, n); // 26-37 bits
1742+
wiegand_message_t packed = initialize_message_object(top, mid, bot, 0); // 26-37 bits
17211743
res = HIDTryUnpack(&packed);
17221744

17231745
PrintAndLogEx(INFO, "Trying with a preamble bit...");

0 commit comments

Comments
 (0)