Merge pull request #2765 from Donny-Guo/wiegand

Correct Bitlen Calculation and Refactor Wiegand Decoding
This commit is contained in:
Iceman 2025-03-01 21:56:49 +01:00 committed by GitHub
commit a75c7cc093
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 15 additions and 43 deletions

View file

@ -69,8 +69,7 @@ static int wiegand_new_pacs(uint8_t *padded_pacs, uint8_t plen) {
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "------------------------- " _CYAN_("SIO - Wiegand") " ---------------------------"); PrintAndLogEx(INFO, "------------------------- " _CYAN_("SIO - Wiegand") " ---------------------------");
wiegand_message_t packed = initialize_message_object(top, mid, bot, strlen(binstr)); decode_wiegand(top, mid, bot, strlen(binstr));
HIDTryUnpack(&packed);
free(binstr); free(binstr);
return PM3_SUCCESS; return PM3_SUCCESS;
} }
@ -215,8 +214,7 @@ int CmdWiegandDecode(const char *Cmd) {
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "Wiegand decode"); PrintAndLogEx(INFO, "Wiegand decode");
wiegand_message_t packed = initialize_message_object(top, mid, bot, blen); decode_wiegand(top, mid, bot, blen);
HIDTryUnpack(&packed);
return PM3_SUCCESS; return PM3_SUCCESS;
} }

View file

@ -1647,24 +1647,16 @@ bool decode_wiegand(uint32_t top, uint32_t mid, uint32_t bot, int n) {
return res; return res;
} }
if (n || ((mid & 0xFFFFFFC0) > 0)) { // if n > 0 or there's more than 38 bits if (n > 0) {
wiegand_message_t packed = initialize_message_object(top, mid, bot, n); wiegand_message_t packed = initialize_message_object(top, mid, bot, n);
res = HIDTryUnpack(&packed); res = HIDTryUnpack(&packed);
} else {
} else { // n <= 0 and 39-64 bits are all 0, try two possible bitlens
wiegand_message_t packed = initialize_message_object(top, mid, bot, n); // 26-37 bits wiegand_message_t packed = initialize_message_object(top, mid, bot, n); // 26-37 bits
res = HIDTryUnpack(&packed); res = HIDTryUnpack(&packed);
n = packed.Length - 1; PrintAndLogEx(INFO, "Trying with a preamble bit...");
PrintAndLogEx(INFO, "Trying without a preamble bit..."); packed.Length += 1;
packed = initialize_message_object(top, mid, bot, n); // iclass has only a preamble bit.
res |= HIDTryUnpack(&packed); res |= HIDTryUnpack(&packed);
if (res == false) {
packed = initialize_message_object(top, mid, bot, 38); // 38 bits
res |= HIDTryUnpack(&packed);
}
} }
if (res == false) { if (res == false) {

View file

@ -132,8 +132,6 @@ static uint8_t get_length_from_header(wiegand_message_t *data) {
/** /**
* detect if message has "preamble" / "sentinel bit" * detect if message has "preamble" / "sentinel bit"
* Right now we just calculate the highest bit set * Right now we just calculate the highest bit set
* 38 bits format is handled by directly setting n=38 in initialize_message_object()
* since it's hard to distinguish 38 bits with formats with preamble bit (26-36 bits)
* *
* (from http://www.proxmark.org/forum/viewtopic.php?pid=5368#p5368) * (from http://www.proxmark.org/forum/viewtopic.php?pid=5368#p5368)
* 0000 0010 0000 0000 01xx xxxx xxxx xxxx xxxx xxxx xxxx 26-bit * 0000 0010 0000 0000 01xx xxxx xxxx xxxx xxxx xxxx xxxx 26-bit
@ -148,7 +146,6 @@ static uint8_t get_length_from_header(wiegand_message_t *data) {
* 0000 0010 1xxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx 35-bit * 0000 0010 1xxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx 35-bit
* 0000 0011 xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx 36-bit * 0000 0011 xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx 36-bit
* 0000 000x xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx 37-bit * 0000 000x xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx 37-bit
* 0000 00xx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx 38-bit
*/ */
uint8_t len = 0; uint8_t len = 0;
uint32_t hfmt = 0; // for calculating card length uint32_t hfmt = 0; // for calculating card length
@ -156,37 +153,22 @@ static uint8_t get_length_from_header(wiegand_message_t *data) {
if ((data->Top & 0x000FFFFF) > 0) { // > 64 bits if ((data->Top & 0x000FFFFF) > 0) { // > 64 bits
hfmt = data->Top & 0x000FFFFF; hfmt = data->Top & 0x000FFFFF;
len = 64; len = 64;
} else if (data->Mid > 0) { } else if (data->Mid & 0xFFFFFFC0) { // handle 38bit and above format
// detect HID format b38 set
if (data->Mid & 0xFFFFFFC0) { // 39-64 bits
hfmt = data->Mid; hfmt = data->Mid;
len = 31; // remove leading 1 (preamble) in 39-64 bits format len = 31; // remove leading 1 (preamble) in 38-64 bits format
} else { // detect card format 26-37 bits using "preamble" / "sentinel bit" } else if (((data->Mid >> 5) & 1) == 1) { // bit 38 is set => 26-36bit format
PrintAndLogEx(DEBUG, "hid preamble detected"); hfmt = (((data->Mid & 31) << 6) | (data->Bot >> 26)); // get bits 27-37 to check for format len bit
len = 25;
// if bit 38 is set: => 26-36 bits } else { // if bit 38 is not set => 37bit format
if (((data->Mid >> 5) & 1) == 1) {
hfmt = (((data->Mid & 31) << 12) | (data->Bot >> 26)); //get bits 27-37 to check for format len bit
len = 19;
} else { // if bit 38 is not set => 37 bits
hfmt = 0; hfmt = 0;
len = 37; len = 37;
} }
}
} else {
hfmt = data->Bot;
len = 0;
}
while (hfmt > 0) { while (hfmt > 0) {
hfmt >>= 1; hfmt >>= 1;
len++; len++;
} }
// everything less than 26 bits found, assume 26 bits
if (len < 26)
len = 26;
return len; return len;
} }