mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-14 18:48:13 -07:00
fix: askdemod - enhances which solves some viking demod errors
This commit is contained in:
parent
abc66484e5
commit
37c30c0395
5 changed files with 55 additions and 45 deletions
|
@ -584,7 +584,8 @@ static int Cmdmandecoderaw(const char *Cmd) {
|
|||
size_t size = 0;
|
||||
int high = 0, low = 0;
|
||||
size_t i = 0;
|
||||
int errCnt = 0, invert = 0, maxErr = 20;
|
||||
uint16_t errCnt = 0;
|
||||
int invert = 0, maxErr = 20;
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (strlen(Cmd) > 5 || cmdp == 'h') return usage_data_manrawdecode();
|
||||
|
||||
|
@ -610,7 +611,7 @@ static int Cmdmandecoderaw(const char *Cmd) {
|
|||
uint8_t alignPos = 0;
|
||||
errCnt = manrawdecode(bits, &size, invert, &alignPos);
|
||||
if (errCnt >= maxErr) {
|
||||
PrintAndLogEx(WARNING, "Too many errors: %d", errCnt);
|
||||
PrintAndLogEx(WARNING, "Too many errors: %u", errCnt);
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ static int usage_lf_cotag_read(void) {
|
|||
PrintAndLogEx(NORMAL, "Example:");
|
||||
PrintAndLogEx(NORMAL, " lf cotag read 0");
|
||||
PrintAndLogEx(NORMAL, " lf cotag read 1");
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
// COTAG demod should be able to use GraphBuffer,
|
||||
|
@ -35,10 +35,10 @@ static int CmdCOTAGDemod(const char *Cmd) {
|
|||
memcpy(bits, DemodBuffer, COTAG_BITS);
|
||||
|
||||
uint8_t alignPos = 0;
|
||||
int err = manrawdecode(bits, &bitlen, 1, &alignPos);
|
||||
if (err) {
|
||||
uint16_t err = manrawdecode(bits, &bitlen, 1, &alignPos);
|
||||
if (err == 0xFFFF) {
|
||||
if (g_debugMode) PrintAndLogEx(DEBUG, "DEBUG: Error - COTAG too many errors: %d", err);
|
||||
return -1;
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
setDemodBuff(bits, bitlen, 0);
|
||||
|
@ -60,7 +60,7 @@ static int CmdCOTAGDemod(const char *Cmd) {
|
|||
1001 1100 1100 0001 10000101
|
||||
*/
|
||||
PrintAndLogEx(SUCCESS, "COTAG Found: FC %u, CN: %u Raw: %08X%08X%08X%08X", fc, cn, raw1, raw2, raw3, raw4);
|
||||
return 1;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
// When reading a COTAG.
|
||||
|
@ -78,7 +78,7 @@ static int CmdCOTAGRead(const char *Cmd) {
|
|||
SendCommandMIX(CMD_COTAG, rawsignal, 0, 0, NULL, 0);
|
||||
if (!WaitForResponseTimeout(CMD_ACK, NULL, 7000)) {
|
||||
PrintAndLogEx(WARNING, "command execution time out");
|
||||
return -1;
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
|
||||
switch (rawsignal) {
|
||||
|
@ -93,13 +93,13 @@ static int CmdCOTAGRead(const char *Cmd) {
|
|||
|
||||
if (!GetFromDevice(BIG_BUF, DemodBuffer, COTAG_BITS, 0, NULL, 1000, false)) {
|
||||
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
||||
return -1;
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
DemodBufferLen = COTAG_BITS;
|
||||
return CmdCOTAGDemod("");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static command_t CommandTable[] = {
|
||||
|
@ -112,7 +112,7 @@ static command_t CommandTable[] = {
|
|||
static int CmdHelp(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
int CmdLFCOTAG(const char *Cmd) {
|
||||
|
@ -125,5 +125,5 @@ int demodCOTAG(void) {
|
|||
}
|
||||
|
||||
int readCOTAGUid(void) {
|
||||
return CmdCOTAGRead("") > 0;
|
||||
return (CmdCOTAGRead("") == PM3_SUCCESS);
|
||||
}
|
||||
|
|
|
@ -45,10 +45,9 @@ static int CmdVikingDemod(const char *Cmd) {
|
|||
return PM3_ESOFT;
|
||||
}
|
||||
size_t size = DemodBufferLen;
|
||||
|
||||
int ans = detectViking(DemodBuffer, &size);
|
||||
if (ans < 0) {
|
||||
PrintAndLogEx(DEBUG, "DEBUG: Error - Viking Demod %d %s", ans, (ans == -5) ? "[chksum error]" : "");
|
||||
PrintAndLogEx(DEBUG, "DEBUG: Error - Viking Demod %d %s", ans, (ans == -5) ? _RED_("[chksum error]") : "");
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
//got a good demod
|
||||
|
@ -56,8 +55,8 @@ static int CmdVikingDemod(const char *Cmd) {
|
|||
uint32_t raw2 = bytebits_to_byte(DemodBuffer + ans + 32, 32);
|
||||
uint32_t cardid = bytebits_to_byte(DemodBuffer + ans + 24, 32);
|
||||
uint8_t checksum = bytebits_to_byte(DemodBuffer + ans + 32 + 24, 8);
|
||||
PrintAndLogEx(SUCCESS, "Viking Tag Found: Card ID %08X, Checksum: %02X", cardid, checksum);
|
||||
PrintAndLogEx(SUCCESS, "Raw: %08X%08X", raw1, raw2);
|
||||
PrintAndLogEx(SUCCESS, "Viking Tag Found: Card ID " _YELLOW_("%08X")" checksum "_YELLOW_("%02X"), cardid, checksum);
|
||||
PrintAndLogEx(SUCCESS, "Raw hex: %08X%08X", raw1, raw2);
|
||||
setDemodBuff(DemodBuffer, 64, ans);
|
||||
setClockGrid(g_DemodClock, g_DemodStartIdx + (ans * g_DemodClock));
|
||||
return PM3_SUCCESS;
|
||||
|
@ -86,7 +85,7 @@ static int CmdVikingClone(const char *Cmd) {
|
|||
|
||||
rawID = getVikingBits(id);
|
||||
|
||||
PrintAndLogEx(INFO, "Preparing to clone Viking tag - ID: %08X, Raw: %08X%08X", id, (uint32_t)(rawID >> 32), (uint32_t)(rawID & 0xFFFFFFFF));
|
||||
PrintAndLogEx(INFO, "Preparing to clone Viking tag - ID " _YELLOW_("%08X")" raw " _YELLOW_("%08X%08X"), id, (uint32_t)(rawID >> 32), (uint32_t)(rawID & 0xFFFFFFFF));
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandMIX(CMD_VIKING_CLONE_TAG, rawID >> 32, rawID & 0xFFFFFFFF, Q5, NULL, 0);
|
||||
|
@ -109,7 +108,7 @@ static int CmdVikingSim(const char *Cmd) {
|
|||
|
||||
rawID = getVikingBits(id);
|
||||
|
||||
PrintAndLogEx(SUCCESS, "Simulating Viking - ID: %08X, Raw: %08X%08X", id, (uint32_t)(rawID >> 32), (uint32_t)(rawID & 0xFFFFFFFF));
|
||||
PrintAndLogEx(SUCCESS, "Simulating Viking - ID " _YELLOW_("%08X")" raw "_YELLOW_("%08X%08X"), id, (uint32_t)(rawID >> 32), (uint32_t)(rawID & 0xFFFFFFFF));
|
||||
|
||||
uint8_t bs[64];
|
||||
num_to_bytebits(rawID, sizeof(bs), bs);
|
||||
|
@ -164,22 +163,23 @@ uint64_t getVikingBits(uint32_t id) {
|
|||
}
|
||||
// by marshmellow
|
||||
// find viking preamble 0xF200 in already demoded data
|
||||
int detectViking(uint8_t *dest, size_t *size) {
|
||||
int detectViking(uint8_t *src, size_t *size) {
|
||||
//make sure buffer has data
|
||||
if (*size < 64 * 2) return -2;
|
||||
if (*size < 64) return -2;
|
||||
size_t startIdx = 0;
|
||||
uint8_t preamble[] = {1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
if (!preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx))
|
||||
if (!preambleSearch(src, preamble, sizeof(preamble), size, &startIdx))
|
||||
return -4; //preamble not found
|
||||
|
||||
uint32_t checkCalc = bytebits_to_byte(dest + startIdx, 8) ^
|
||||
bytebits_to_byte(dest + startIdx + 8, 8) ^
|
||||
bytebits_to_byte(dest + startIdx + 16, 8) ^
|
||||
bytebits_to_byte(dest + startIdx + 24, 8) ^
|
||||
bytebits_to_byte(dest + startIdx + 32, 8) ^
|
||||
bytebits_to_byte(dest + startIdx + 40, 8) ^
|
||||
bytebits_to_byte(dest + startIdx + 48, 8) ^
|
||||
bytebits_to_byte(dest + startIdx + 56, 8);
|
||||
uint32_t checkCalc = bytebits_to_byte(src + startIdx, 8) ^
|
||||
bytebits_to_byte(src + startIdx + 8, 8) ^
|
||||
bytebits_to_byte(src + startIdx + 16, 8) ^
|
||||
bytebits_to_byte(src + startIdx + 24, 8) ^
|
||||
bytebits_to_byte(src + startIdx + 32, 8) ^
|
||||
bytebits_to_byte(src + startIdx + 40, 8) ^
|
||||
bytebits_to_byte(src + startIdx + 48, 8) ^
|
||||
bytebits_to_byte(src + startIdx + 56, 8);
|
||||
|
||||
if (checkCalc != 0xA8) return -5;
|
||||
if (*size != 64) return -6;
|
||||
//return start position
|
||||
|
|
|
@ -315,10 +315,10 @@ static int getClosestClock(int testclk) {
|
|||
uint16_t clocks[] = {8, 16, 32, 40, 50, 64, 100, 128, 256, 384};
|
||||
uint8_t limit[] = {1, 2, 4, 4, 5, 8, 8, 8, 8, 8};
|
||||
|
||||
for (uint8_t i = 0; i < 10; i++)
|
||||
for (uint8_t i = 0; i < 10; i++) {
|
||||
if (testclk >= clocks[i] - limit[i] && testclk <= clocks[i] + limit[i])
|
||||
return clocks[i];
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -480,17 +480,19 @@ bool DetectCleanAskWave(uint8_t *dest, size_t size, uint8_t high, uint8_t low) {
|
|||
// by marshmellow
|
||||
// to help detect clocks on heavily clipped samples
|
||||
// based on count of low to low
|
||||
int DetectStrongAskClock(uint8_t *dest, size_t size, int high, int low, int *clock) {
|
||||
int DetectStrongAskClock(uint8_t *src, size_t size, int high, int low, int *clock) {
|
||||
size_t i = 100;
|
||||
size_t minClk = 512;
|
||||
uint16_t shortestWaveIdx = 0;
|
||||
|
||||
// get to first full low to prime loop and skip incomplete first pulse
|
||||
getNextHigh(dest, size, high, &i);
|
||||
getNextLow(dest, size, low, &i);
|
||||
getNextHigh(src, size, high, &i);
|
||||
getNextLow(src, size, low, &i);
|
||||
|
||||
if (i == size)
|
||||
return -1;
|
||||
if (size < 512)
|
||||
return -2;
|
||||
|
||||
// clock, numoftimes, first idx
|
||||
uint16_t tmpclk[10][3] = {
|
||||
|
@ -507,12 +509,12 @@ int DetectStrongAskClock(uint8_t *dest, size_t size, int high, int low, int *clo
|
|||
};
|
||||
|
||||
// loop through all samples (well, we don't want to go out-of-bounds)
|
||||
while (i < size - 512) {
|
||||
while (i < (size - 512)) {
|
||||
// measure from low to low
|
||||
size_t startwave = i;
|
||||
|
||||
getNextHigh(dest, size, high, &i);
|
||||
getNextLow(dest, size, low, &i);
|
||||
getNextHigh(src, size, high, &i);
|
||||
getNextLow(src, size, low, &i);
|
||||
|
||||
//get minimum measured distance
|
||||
if (i - startwave < minClk && i < size) {
|
||||
|
@ -1401,17 +1403,18 @@ int BiphaseRawDecode(uint8_t *bits, size_t *size, int *offset, int invert) {
|
|||
//take 10 and 01 and manchester decode
|
||||
//run through 2 times and take least errCnt
|
||||
// "," indicates 00 or 11 wrong bit
|
||||
int manrawdecode(uint8_t *bits, size_t *size, uint8_t invert, uint8_t *alignPos) {
|
||||
uint16_t manrawdecode(uint8_t *bits, size_t *size, uint8_t invert, uint8_t *alignPos) {
|
||||
|
||||
// sanity check
|
||||
if (*size < 16) return -1;
|
||||
if (*size < 16) return 0xFFFF;
|
||||
|
||||
int errCnt = 0, bestErr = 1000;
|
||||
uint16_t bitnum = 0, maxBits = 512, bestRun = 0;
|
||||
size_t i, k;
|
||||
|
||||
//find correct start position [alignment]
|
||||
for (k = 0; k < 2; ++k) {
|
||||
for (k = 0; k < 2; k++) {
|
||||
|
||||
for (i = k; i < *size - 1; i += 2) {
|
||||
|
||||
if (bits[i] == bits[i + 1])
|
||||
|
@ -1431,7 +1434,7 @@ int manrawdecode(uint8_t *bits, size_t *size, uint8_t invert, uint8_t *alignPos)
|
|||
|
||||
*alignPos = bestRun;
|
||||
//decode
|
||||
for (i = bestRun; i < *size - 1; i += 2) {
|
||||
for (i = bestRun; i < *size; i += 2) {
|
||||
if (bits[i] == 1 && (bits[i + 1] == 0)) {
|
||||
bits[bitnum++] = invert;
|
||||
} else if ((bits[i] == 0) && bits[i + 1] == 1) {
|
||||
|
@ -1448,7 +1451,7 @@ int manrawdecode(uint8_t *bits, size_t *size, uint8_t invert, uint8_t *alignPos)
|
|||
//by marshmellow
|
||||
//demodulates strong heavily clipped samples
|
||||
//RETURN: num of errors. if 0, is ok.
|
||||
static int cleanAskRawDemod(uint8_t *bits, size_t *size, int clk, int invert, int high, int low, int *startIdx) {
|
||||
static uint16_t cleanAskRawDemod(uint8_t *bits, size_t *size, int clk, int invert, int high, int low, int *startIdx) {
|
||||
*startIdx = 0;
|
||||
size_t bitCnt = 0, smplCnt = 1, errCnt = 0, pos = 0;
|
||||
uint8_t cl_4 = clk / 4;
|
||||
|
@ -1463,7 +1466,8 @@ static int cleanAskRawDemod(uint8_t *bits, size_t *size, int clk, int invert, in
|
|||
smplCnt++;
|
||||
} else if (bits[i] <= low && !waveHigh) {
|
||||
smplCnt++;
|
||||
} else { //transition
|
||||
} else {
|
||||
//transition
|
||||
if ((bits[i] >= high && !waveHigh) || (bits[i] <= low && waveHigh)) {
|
||||
|
||||
// 8 :: 8-2-1 = 5 8+2+1 = 11
|
||||
|
@ -1472,7 +1476,8 @@ static int cleanAskRawDemod(uint8_t *bits, size_t *size, int clk, int invert, in
|
|||
// 64 :: 64-16-1 = 47 64+16+1 = 81
|
||||
if (smplCnt > clk - cl_4 - 1) { //full clock
|
||||
|
||||
if (smplCnt > clk + cl_4 + 1) { //too many samples
|
||||
if (smplCnt > clk + cl_4 + 1) {
|
||||
//too many samples
|
||||
errCnt++;
|
||||
if (g_debugMode == 2) prnt("DEBUG ASK: cleanAskRawDemod ASK Modulation Error FULL at: %u [%u > %u]", i, smplCnt, clk + cl_4 + 1);
|
||||
bits[bitCnt++] = 7;
|
||||
|
@ -1515,6 +1520,7 @@ static int cleanAskRawDemod(uint8_t *bits, size_t *size, int clk, int invert, in
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
*size = bitCnt;
|
||||
|
||||
if (*startIdx < 0)
|
||||
|
@ -1823,6 +1829,7 @@ static size_t aggregate_bits(uint8_t *dest, size_t size, uint8_t clk, uint8_t in
|
|||
}
|
||||
memset(dest + numBits, dest[i - 1] ^ invert, n);
|
||||
numBits += n;
|
||||
if (g_debugMode == 2) prnt("DEBUG (aggregate_bits) extra bits in the end");
|
||||
}
|
||||
return numBits;
|
||||
}
|
||||
|
@ -1833,7 +1840,9 @@ size_t fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uint8
|
|||
if (signalprop.isnoise) return 0;
|
||||
// FSK demodulator
|
||||
size = fsk_wave_demod(dest, size, fchigh, fclow, start_idx);
|
||||
if (g_debugMode == 2) prnt("DEBUG (fskdemod) got %zu bits", size);
|
||||
size = aggregate_bits(dest, size, rfLen, invert, fchigh, fclow, start_idx);
|
||||
if (g_debugMode == 2) prnt("DEBUG (fskdemod) got %zu bits", size);
|
||||
return size;
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ size_t fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uin
|
|||
void getHiLo(int *high, int *low, uint8_t fuzzHi, uint8_t fuzzLo);
|
||||
uint32_t manchesterEncode2Bytes(uint16_t datain);
|
||||
int ManchesterEncode(uint8_t *bits, size_t size);
|
||||
int manrawdecode(uint8_t *bits, size_t *size, uint8_t invert, uint8_t *alignPos);
|
||||
uint16_t manrawdecode(uint8_t *bits, size_t *size, uint8_t invert, uint8_t *alignPos);
|
||||
int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int *startIdx);
|
||||
bool parityTest(uint32_t bits, uint8_t bitLen, uint8_t pType);
|
||||
bool preambleSearch(uint8_t *bits, uint8_t *preamble, size_t pLen, size_t *size, size_t *startIdx);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue