mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 13:53:55 -07:00
CHG: @marshmellow42 's em4x50 changes
ADD: 'analys chksum' - added a BSD styled 4 and 8 bit shift checksum
This commit is contained in:
parent
f9f5f45000
commit
62dc7d4a6f
2 changed files with 101 additions and 50 deletions
|
@ -75,7 +75,7 @@ static uint8_t calculateLRC( uint8_t* bytes, uint8_t len) {
|
||||||
return LRC;
|
return LRC;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t calcSumCrumbAdd( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
static uint16_t calcSumCrumbAdd( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
||||||
uint8_t sum = 0;
|
uint8_t sum = 0;
|
||||||
for (uint8_t i = 0; i < len; i++) {
|
for (uint8_t i = 0; i < len; i++) {
|
||||||
sum += CRUMB(bytes[i], 0);
|
sum += CRUMB(bytes[i], 0);
|
||||||
|
@ -86,10 +86,10 @@ static uint8_t calcSumCrumbAdd( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
||||||
sum &= mask;
|
sum &= mask;
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
static uint8_t calcSumCrumbAddOnes( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
static uint16_t calcSumCrumbAddOnes( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
||||||
return ~calcSumCrumbAdd(bytes, len, mask);
|
return ~calcSumCrumbAdd(bytes, len, mask);
|
||||||
}
|
}
|
||||||
static uint8_t calcSumNibbleAdd( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
static uint16_t calcSumNibbleAdd( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
||||||
uint8_t sum = 0;
|
uint8_t sum = 0;
|
||||||
for (uint8_t i = 0; i < len; i++) {
|
for (uint8_t i = 0; i < len; i++) {
|
||||||
sum += NIBBLE_LOW(bytes[i]);
|
sum += NIBBLE_LOW(bytes[i]);
|
||||||
|
@ -98,10 +98,10 @@ static uint8_t calcSumNibbleAdd( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
||||||
sum &= mask;
|
sum &= mask;
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
static uint8_t calcSumNibbleAddOnes( uint8_t* bytes, uint8_t len, uint32_t mask){
|
static uint16_t calcSumNibbleAddOnes( uint8_t* bytes, uint8_t len, uint32_t mask){
|
||||||
return ~calcSumNibbleAdd(bytes, len, mask);
|
return ~calcSumNibbleAdd(bytes, len, mask);
|
||||||
}
|
}
|
||||||
static uint8_t calcSumCrumbXor( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
static uint16_t calcSumCrumbXor( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
||||||
uint8_t sum = 0;
|
uint8_t sum = 0;
|
||||||
for (uint8_t i = 0; i < len; i++) {
|
for (uint8_t i = 0; i < len; i++) {
|
||||||
sum ^= CRUMB(bytes[i], 0);
|
sum ^= CRUMB(bytes[i], 0);
|
||||||
|
@ -112,7 +112,7 @@ static uint8_t calcSumCrumbXor( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
||||||
sum &= mask;
|
sum &= mask;
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
static uint8_t calcSumNibbleXor( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
static uint16_t calcSumNibbleXor( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
||||||
uint8_t sum = 0;
|
uint8_t sum = 0;
|
||||||
for (uint8_t i = 0; i < len; i++) {
|
for (uint8_t i = 0; i < len; i++) {
|
||||||
sum ^= NIBBLE_LOW(bytes[i]);
|
sum ^= NIBBLE_LOW(bytes[i]);
|
||||||
|
@ -121,15 +121,14 @@ static uint8_t calcSumNibbleXor( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
||||||
sum &= mask;
|
sum &= mask;
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
static uint8_t calcSumByteXor( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
static uint16_t calcSumByteXor( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
||||||
uint8_t sum = 0;
|
uint8_t sum = 0;
|
||||||
for (uint8_t i = 0; i < len; i++)
|
for (uint8_t i = 0; i < len; i++)
|
||||||
sum ^= bytes[i];
|
sum ^= bytes[i];
|
||||||
sum &= mask;
|
sum &= mask;
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
static uint16_t calcSumByteAdd( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
||||||
static uint8_t calcSumByteAdd( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
|
||||||
uint8_t sum = 0;
|
uint8_t sum = 0;
|
||||||
for (uint8_t i = 0; i < len; i++)
|
for (uint8_t i = 0; i < len; i++)
|
||||||
sum += bytes[i];
|
sum += bytes[i];
|
||||||
|
@ -137,23 +136,21 @@ static uint8_t calcSumByteAdd( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
// Ones complement
|
// Ones complement
|
||||||
static uint8_t calcSumByteAddOnes( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
static uint16_t calcSumByteAddOnes( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
||||||
return ~calcSumByteAdd(bytes, len, mask);
|
return ~calcSumByteAdd(bytes, len, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint16_t calcSumByteSub( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
||||||
|
|
||||||
static uint8_t calcSumByteSub( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
|
||||||
uint8_t sum = 0;
|
uint8_t sum = 0;
|
||||||
for (uint8_t i = 0; i < len; i++)
|
for (uint8_t i = 0; i < len; i++)
|
||||||
sum -= bytes[i];
|
sum -= bytes[i];
|
||||||
sum &= mask;
|
sum &= mask;
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
static uint8_t calcSumByteSubOnes( uint8_t* bytes, uint8_t len, uint32_t mask){
|
static uint16_t calcSumByteSubOnes( uint8_t* bytes, uint8_t len, uint32_t mask){
|
||||||
return ~calcSumByteSub(bytes, len, mask);
|
return ~calcSumByteSub(bytes, len, mask);
|
||||||
}
|
}
|
||||||
static uint8_t calcSumNibbleSub( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
static uint16_t calcSumNibbleSub( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
||||||
uint8_t sum = 0;
|
uint8_t sum = 0;
|
||||||
for (uint8_t i = 0; i < len; i++) {
|
for (uint8_t i = 0; i < len; i++) {
|
||||||
sum -= NIBBLE_LOW(bytes[i]);
|
sum -= NIBBLE_LOW(bytes[i]);
|
||||||
|
@ -162,10 +159,38 @@ static uint8_t calcSumNibbleSub( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
||||||
sum &= mask;
|
sum &= mask;
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
static uint8_t calcSumNibbleSubOnes( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
static uint16_t calcSumNibbleSubOnes( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
||||||
return ~calcSumNibbleSub(bytes, len, mask);
|
return ~calcSumNibbleSub(bytes, len, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BSD shift checksum 8bit version
|
||||||
|
static uint16_t calcBSDchecksum8( uint8_t* bytes, uint8_t len, uint32_t mask){
|
||||||
|
uint16_t sum = 0;
|
||||||
|
for(uint8_t i = 0; i < len; i++){
|
||||||
|
sum = ((sum & 0xFF) >> 1) | ((sum & 0x1) << 7); // rotate accumulator
|
||||||
|
sum += bytes[i]; // add next byte
|
||||||
|
sum &= 0xFF; //
|
||||||
|
}
|
||||||
|
sum &= mask;
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
// BSD shift checksum 4bit version
|
||||||
|
static uint16_t calcBSDchecksum4( uint8_t* bytes, uint8_t len, uint32_t mask){
|
||||||
|
uint16_t sum = 0;
|
||||||
|
for(uint8_t i = 0; i < len; i++){
|
||||||
|
sum = ((sum & 0xF) >> 1) | ((sum & 0x1) << 3); // rotate accumulator
|
||||||
|
sum += NIBBLE_HIGH(bytes[i]); // add high nibble
|
||||||
|
sum &= 0xF; //
|
||||||
|
sum = ((sum & 0xF) >> 1) | ((sum & 0x1) << 3); // rotate accumulator
|
||||||
|
sum += NIBBLE_LOW(bytes[i]); // add low nibble
|
||||||
|
sum &= 0xF; //
|
||||||
|
}
|
||||||
|
sum &= mask;
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// measuring LFSR maximum length
|
// measuring LFSR maximum length
|
||||||
int CmdAnalyseLfsr(const char *Cmd){
|
int CmdAnalyseLfsr(const char *Cmd){
|
||||||
|
|
||||||
|
@ -261,6 +286,7 @@ int CmdAnalyseCHKSUM(const char *Cmd){
|
||||||
uint8_t cmdp = 0;
|
uint8_t cmdp = 0;
|
||||||
uint32_t mask = 0xFFFF;
|
uint32_t mask = 0xFFFF;
|
||||||
bool errors = false;
|
bool errors = false;
|
||||||
|
bool useHeader = false;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
memset(data, 0x0, sizeof(data));
|
memset(data, 0x0, sizeof(data));
|
||||||
|
|
||||||
|
@ -278,6 +304,11 @@ int CmdAnalyseCHKSUM(const char *Cmd){
|
||||||
mask = param_get32ex(Cmd, cmdp+1, 0, 16);
|
mask = param_get32ex(Cmd, cmdp+1, 0, 16);
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
break;
|
break;
|
||||||
|
case 'v':
|
||||||
|
case 'V':
|
||||||
|
useHeader = true;
|
||||||
|
cmdp++;
|
||||||
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
case 'H':
|
case 'H':
|
||||||
return usage_analyse_checksum();
|
return usage_analyse_checksum();
|
||||||
|
@ -291,10 +322,12 @@ int CmdAnalyseCHKSUM(const char *Cmd){
|
||||||
//Validations
|
//Validations
|
||||||
if(errors) return usage_analyse_checksum();
|
if(errors) return usage_analyse_checksum();
|
||||||
|
|
||||||
|
if (useHeader) {
|
||||||
PrintAndLog(" add | sub | add 1's compl | sub 1's compl | xor");
|
PrintAndLog(" add | sub | add 1's compl | sub 1's compl | xor");
|
||||||
PrintAndLog("byte nibble crumb | byte nibble | byte nibble cumb | byte nibble | byte nibble cumb");
|
PrintAndLog("byte nibble crumb | byte nibble | byte nibble cumb | byte nibble | byte nibble cumb | BSD");
|
||||||
PrintAndLog("------------------+-------------+------------------+-----------------+--------------------");
|
PrintAndLog("------------------+-------------+------------------+-----------------+--------------------");
|
||||||
PrintAndLog("0x%02X 0x%02X 0x%02X | 0x%02X 0x%02X | 0x%02X 0x%02X 0x%02X | 0x%02X 0x%02X | 0x%02X 0x%02X 0x%02X",
|
}
|
||||||
|
PrintAndLog("0x%X 0x%X 0x%X | 0x%X 0x%X | 0x%X 0x%X 0x%X | 0x%X 0x%X | 0x%X 0x%X 0x%X | 0x%X 0x%X\n",
|
||||||
calcSumByteAdd(data, len, mask)
|
calcSumByteAdd(data, len, mask)
|
||||||
, calcSumNibbleAdd(data, len, mask)
|
, calcSumNibbleAdd(data, len, mask)
|
||||||
, calcSumCrumbAdd(data, len, mask)
|
, calcSumCrumbAdd(data, len, mask)
|
||||||
|
@ -308,6 +341,8 @@ int CmdAnalyseCHKSUM(const char *Cmd){
|
||||||
, calcSumByteXor(data, len, mask)
|
, calcSumByteXor(data, len, mask)
|
||||||
, calcSumNibbleXor(data, len, mask)
|
, calcSumNibbleXor(data, len, mask)
|
||||||
, calcSumCrumbXor(data, len, mask)
|
, calcSumCrumbXor(data, len, mask)
|
||||||
|
, calcBSDchecksum8(data, len, mask)
|
||||||
|
, calcBSDchecksum4(data, len, mask)
|
||||||
);
|
);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -533,6 +533,9 @@ uint8_t EMpreambleSearch(uint8_t *BitStream, uint8_t *preamble, size_t pLen, siz
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FSK, PSK, ASK/MANCHESTER, ASK/BIPHASE, ASK/DIPHASE
|
||||||
|
// should cover 90% of known used configs
|
||||||
|
// the rest will need to be manually demoded for now...
|
||||||
int demodEM4x05resp(uint8_t bitsNeeded) {
|
int demodEM4x05resp(uint8_t bitsNeeded) {
|
||||||
int ans = 0;
|
int ans = 0;
|
||||||
bool demodFound = false;
|
bool demodFound = false;
|
||||||
|
@ -546,7 +549,6 @@ int demodEM4x05resp(uint8_t bitsNeeded) {
|
||||||
ans = FSKrawDemod("0 0", false);
|
ans = FSKrawDemod("0 0", false);
|
||||||
if (!ans) {
|
if (!ans) {
|
||||||
if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305: FSK Demod failed");
|
if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305: FSK Demod failed");
|
||||||
//return -1;
|
|
||||||
} else {
|
} else {
|
||||||
// set size to 10 to only test first 4 positions for the preamble
|
// set size to 10 to only test first 4 positions for the preamble
|
||||||
size_t size = (10 > DemodBufferLen) ? DemodBufferLen : 10;
|
size_t size = (10 > DemodBufferLen) ? DemodBufferLen : 10;
|
||||||
|
@ -557,7 +559,6 @@ int demodEM4x05resp(uint8_t bitsNeeded) {
|
||||||
uint8_t errChk = !EMpreambleSearch(DemodBuffer, preamble, sizeof(preamble), size, &startIdx);
|
uint8_t errChk = !EMpreambleSearch(DemodBuffer, preamble, sizeof(preamble), size, &startIdx);
|
||||||
if ( errChk == 0) {
|
if ( errChk == 0) {
|
||||||
if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305 preamble not found :: %d", startIdx);
|
if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305 preamble not found :: %d", startIdx);
|
||||||
//return -1;
|
|
||||||
} else {
|
} else {
|
||||||
//can't test size because the preamble doesn't repeat :(
|
//can't test size because the preamble doesn't repeat :(
|
||||||
//meaning chances of false positives are high.
|
//meaning chances of false positives are high.
|
||||||
|
@ -565,11 +566,38 @@ int demodEM4x05resp(uint8_t bitsNeeded) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// PSK clocks should be easy to detect ( but difficult to demod a non-repeating pattern... )
|
||||||
|
if (!demodFound) {
|
||||||
ans = GetPskClock("", FALSE, FALSE);
|
ans = GetPskClock("", FALSE, FALSE);
|
||||||
if (ans>0) {
|
if (ans>0) {
|
||||||
PrintAndLog("PSK response possibly found, run `data rawd p1` to attempt to demod");
|
PrintAndLog("PSK response possibly found, run `data rawd p1` to attempt to demod");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// more common than biphase
|
||||||
|
if (!demodFound) {
|
||||||
|
DemodBufferLen = 0x00;
|
||||||
|
// try manchester - NOTE: ST only applies to T55x7 tags.
|
||||||
|
ans = ASKDemod_ext("0,0,1", false, false, 1, false);
|
||||||
|
if (!ans) {
|
||||||
|
if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305: ASK/Manchester Demod failed");
|
||||||
|
} else {
|
||||||
|
// set size to 10 to only test first 4 positions for the preamble
|
||||||
|
size_t size = (10 > DemodBufferLen) ? DemodBufferLen : 10;
|
||||||
|
size_t startIdx = 0;
|
||||||
|
|
||||||
|
if (g_debugMode) PrintAndLog("ANS: %d | %u | %u", ans, startIdx, size);
|
||||||
|
|
||||||
|
uint8_t errChk = !EMpreambleSearch(DemodBuffer, preamble, sizeof(preamble), size, &startIdx);
|
||||||
|
if ( errChk == 0) {
|
||||||
|
if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305 preamble not found :: %d", startIdx);
|
||||||
|
} else {
|
||||||
|
//can't test size because the preamble doesn't repeat :(
|
||||||
|
//meaning chances of false positives are high.
|
||||||
|
demodFound = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!demodFound) {
|
if (!demodFound) {
|
||||||
DemodBufferLen = 0x00;
|
DemodBufferLen = 0x00;
|
||||||
|
@ -599,11 +627,10 @@ int demodEM4x05resp(uint8_t bitsNeeded) {
|
||||||
|
|
||||||
if (!demodFound) {
|
if (!demodFound) {
|
||||||
DemodBufferLen = 0x00;
|
DemodBufferLen = 0x00;
|
||||||
// try manchester - NOTE: ST only applies to T55x7 tags.
|
//try diphase (differential biphase or inverted)
|
||||||
ans = ASKDemod_ext("0,0,1", false, false, 1, false);
|
ans = ASKbiphaseDemod("0 1 1", FALSE);
|
||||||
if (!ans) {
|
if (!ans) {
|
||||||
if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305: ASK/Manchester Demod failed");
|
if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305: ASK/biphase Demod failed");
|
||||||
//return -1;
|
|
||||||
} else {
|
} else {
|
||||||
// set size to 10 to only test first 4 positions for the preamble
|
// set size to 10 to only test first 4 positions for the preamble
|
||||||
size_t size = (10 > DemodBufferLen) ? DemodBufferLen : 10;
|
size_t size = (10 > DemodBufferLen) ? DemodBufferLen : 10;
|
||||||
|
@ -614,7 +641,6 @@ int demodEM4x05resp(uint8_t bitsNeeded) {
|
||||||
uint8_t errChk = !EMpreambleSearch(DemodBuffer, preamble, sizeof(preamble), size, &startIdx);
|
uint8_t errChk = !EMpreambleSearch(DemodBuffer, preamble, sizeof(preamble), size, &startIdx);
|
||||||
if ( errChk == 0) {
|
if ( errChk == 0) {
|
||||||
if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305 preamble not found :: %d", startIdx);
|
if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305 preamble not found :: %d", startIdx);
|
||||||
//return -1;
|
|
||||||
} else {
|
} else {
|
||||||
//can't test size because the preamble doesn't repeat :(
|
//can't test size because the preamble doesn't repeat :(
|
||||||
//meaning chances of false positives are high.
|
//meaning chances of false positives are high.
|
||||||
|
@ -624,8 +650,10 @@ int demodEM4x05resp(uint8_t bitsNeeded) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (demodFound && bitsNeeded < DemodBufferLen) {
|
if (demodFound && bitsNeeded < DemodBufferLen) {
|
||||||
|
if (bitsNeeded > 0) {
|
||||||
setDemodBuf(DemodBuffer + ans + sizeof(preamble), bitsNeeded, 0);
|
setDemodBuf(DemodBuffer + ans + sizeof(preamble), bitsNeeded, 0);
|
||||||
CmdPrintDemodBuff("x");
|
CmdPrintDemodBuff("x");
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -673,10 +701,9 @@ int CmdReadWord(const char *Cmd) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//need 32 bits for read word
|
//attempt demod:
|
||||||
demodEM4x05resp(32);
|
//need 32 bits from a read word
|
||||||
|
return demodEM4x05resp(32);
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int usage_lf_em_write(void) {
|
int usage_lf_em_write(void) {
|
||||||
|
@ -739,26 +766,15 @@ int CmdWriteWord(const char *Cmd) {
|
||||||
}
|
}
|
||||||
setGraphBuf(got, sizeof(got));
|
setGraphBuf(got, sizeof(got));
|
||||||
|
|
||||||
int ans = 0;
|
|
||||||
//bool ST = true;
|
|
||||||
DemodBufferLen = 0x00;
|
|
||||||
|
|
||||||
//ans = ASKDemod_ext("0 0 1", FALSE, FALSE, 1, &ST);
|
|
||||||
ans = ASKbiphaseDemod("0 0 1", FALSE);
|
|
||||||
if (!ans) {
|
|
||||||
if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305: ASK/Manchester Demod failed");
|
|
||||||
return -3;
|
|
||||||
}
|
|
||||||
|
|
||||||
//todo: check response for 00001010 then write data for write confirmation!
|
//todo: check response for 00001010 then write data for write confirmation!
|
||||||
size_t startIdx = 0, size = DemodBufferLen;
|
|
||||||
|
|
||||||
uint8_t preamble[8] = {0,0,0,0,1,0,1,0};
|
//attempt demod:
|
||||||
if (!preambleSearch(DemodBuffer, preamble, sizeof(preamble), &size, &startIdx)){
|
//need 0 bits demoded (after preamble) to verify write cmd
|
||||||
if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305 preamble not found :: %d", startIdx);
|
int result = demodEM4x05resp(0);
|
||||||
return -4;
|
if (result == 1) {
|
||||||
|
PrintAndLog("Write Verified");
|
||||||
}
|
}
|
||||||
PrintAndLog("Write OK");
|
return result;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue