mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 05:13:46 -07:00
added some helper functions
This commit is contained in:
parent
7320f0dd16
commit
bb5d61dca7
11 changed files with 111 additions and 28 deletions
|
@ -76,11 +76,11 @@ void Dbprintf(const char *fmt, ...) {
|
||||||
// prints HEX & ASCII
|
// prints HEX & ASCII
|
||||||
void Dbhexdump(int len, const uint8_t *d, bool bAsci) {
|
void Dbhexdump(int len, const uint8_t *d, bool bAsci) {
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
char ascii[9];
|
char ascii[17];
|
||||||
|
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
|
|
||||||
int l = (len > 8) ? 8 : len;
|
int l = (len > 16) ? 16 : len;
|
||||||
|
|
||||||
memcpy(ascii, d, l);
|
memcpy(ascii, d, l);
|
||||||
ascii[l] = 0;
|
ascii[l] = 0;
|
||||||
|
@ -97,36 +97,44 @@ void Dbhexdump(int len, const uint8_t *d, bool bAsci) {
|
||||||
else
|
else
|
||||||
Dbprintf("%*D", l, d, " ");
|
Dbprintf("%*D", l, d, " ");
|
||||||
|
|
||||||
len -= 8;
|
len -= 16;
|
||||||
d += 8;
|
d += 16;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_result(const char *name, const uint8_t *buf, size_t len) {
|
void print_result(const char *name, const uint8_t *d, size_t n) {
|
||||||
|
|
||||||
const uint8_t *p = buf;
|
const uint8_t *p = d;
|
||||||
uint16_t tmp = len & 0xFFF0;
|
uint16_t tmp = n & 0xFFF0;
|
||||||
|
|
||||||
for (; p - buf < tmp; p += 16) {
|
for (; p - d < tmp; p += 16) {
|
||||||
Dbprintf("[%s: %02d/%02d] %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
|
Dbprintf("[%s: %02d/%02d] %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
|
||||||
name,
|
name,
|
||||||
p - buf,
|
p - d,
|
||||||
len,
|
n,
|
||||||
p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]
|
p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (len % 16 != 0) {
|
|
||||||
|
if (n % 16 != 0) {
|
||||||
char s[46] = {0};
|
char s[46] = {0};
|
||||||
char *sp = s;
|
char *sp = s;
|
||||||
for (; p - buf < len; p++) {
|
for (; p - d < n; p++) {
|
||||||
sprintf(sp, "%02x ", p[0]);
|
sprintf(sp, "%02x ", p[0]);
|
||||||
sp += 3;
|
sp += 3;
|
||||||
}
|
}
|
||||||
Dbprintf("[%s: %02d/%02d] %s", name, p - buf, len, s);
|
Dbprintf("[%s: %02d/%02d] %s", name, p - d, n, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Prints message and hexdump
|
||||||
|
void print_dbg(char *msg, uint8_t *d, uint16_t n) {
|
||||||
|
if (g_dbglevel == DBG_DEBUG) {
|
||||||
|
print_result(msg, d, n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* useful when debugging new protocol implementations like FeliCa
|
/* useful when debugging new protocol implementations like FeliCa
|
||||||
void PrintToSendBuffer(void) {
|
void PrintToSendBuffer(void) {
|
||||||
DbpString("Printing ToSendBuffer:");
|
DbpString("Printing ToSendBuffer:");
|
||||||
|
|
|
@ -28,6 +28,7 @@ void Dbprintf(const char *fmt, ...);
|
||||||
void DbprintfEx(uint32_t flags, const char *fmt, ...);
|
void DbprintfEx(uint32_t flags, const char *fmt, ...);
|
||||||
void Dbhexdump(int len, const uint8_t *d, bool bAsci);
|
void Dbhexdump(int len, const uint8_t *d, bool bAsci);
|
||||||
void print_result(const char *name, const uint8_t *buf, size_t len);
|
void print_result(const char *name, const uint8_t *buf, size_t len);
|
||||||
|
void print_dbg(char *msg, uint8_t *d, uint16_t n);
|
||||||
//void PrintToSendBuffer(void);
|
//void PrintToSendBuffer(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -39,11 +39,6 @@
|
||||||
|
|
||||||
#define I2C_ERROR "I2C_WaitAck Error"
|
#define I2C_ERROR "I2C_WaitAck Error"
|
||||||
|
|
||||||
// 8051 speaks with smart card.
|
|
||||||
// 1000*50*3.07 = 153.5ms
|
|
||||||
// 1 byte transfer == 1ms with max frame being 256 bytes
|
|
||||||
#define SIM_WAIT_DELAY 88000 // about 270ms delay // 109773 -- about 337.7ms delay
|
|
||||||
|
|
||||||
// Direct use the loop to delay. 6 instructions loop, Masterclock 48MHz,
|
// Direct use the loop to delay. 6 instructions loop, Masterclock 48MHz,
|
||||||
// delay=1 is about 200kbps
|
// delay=1 is about 200kbps
|
||||||
// timer.
|
// timer.
|
||||||
|
@ -58,9 +53,6 @@ static void __attribute__((optimize("O0"))) I2CSpinDelayClk(uint16_t delay) {
|
||||||
#define I2C_DELAY_2CLK I2CSpinDelayClk(2)
|
#define I2C_DELAY_2CLK I2CSpinDelayClk(2)
|
||||||
#define I2C_DELAY_XCLK(x) I2CSpinDelayClk((x))
|
#define I2C_DELAY_XCLK(x) I2CSpinDelayClk((x))
|
||||||
|
|
||||||
// The SIM module v4 supports up to 384 bytes for the length.
|
|
||||||
#define ISO7816_MAX_FRAME 270
|
|
||||||
|
|
||||||
// try i2c bus recovery at 100kHz = 5us high, 5us low
|
// try i2c bus recovery at 100kHz = 5us high, 5us low
|
||||||
void I2C_recovery(void) {
|
void I2C_recovery(void) {
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,15 @@
|
||||||
#define I2C_DEVICE_CMD_GETVERSION 0x06
|
#define I2C_DEVICE_CMD_GETVERSION 0x06
|
||||||
#define I2C_DEVICE_CMD_SEND_T0 0x07
|
#define I2C_DEVICE_CMD_SEND_T0 0x07
|
||||||
|
|
||||||
|
// The SIM module v4 supports up to 384 bytes for the length.
|
||||||
|
#define ISO7816_MAX_FRAME 270
|
||||||
|
|
||||||
|
// 8051 speaks with smart card.
|
||||||
|
// 1000*50*3.07 = 153.5ms
|
||||||
|
// 1 byte transfer == 1ms with max frame being 256 bytes
|
||||||
|
#define SIM_WAIT_DELAY 88000 // about 270ms delay // 109773 -- about 337.7ms delay
|
||||||
|
|
||||||
|
|
||||||
void I2C_recovery(void);
|
void I2C_recovery(void);
|
||||||
void I2C_init(bool has_ticks);
|
void I2C_init(bool has_ticks);
|
||||||
void I2C_Reset(void);
|
void I2C_Reset(void);
|
||||||
|
|
|
@ -328,7 +328,7 @@ static int smart_responseEx(uint8_t *out, int maxoutlen, bool verbose) {
|
||||||
needGetData = true;
|
needGetData = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needGetData == true) {
|
if (needGetData) {
|
||||||
// Don't discard data we already received except the SW code.
|
// Don't discard data we already received except the SW code.
|
||||||
// If we only received 1 byte, this is the echo of INS, we discard it.
|
// If we only received 1 byte, this is the echo of INS, we discard it.
|
||||||
totallen -= 2;
|
totallen -= 2;
|
||||||
|
@ -1222,8 +1222,9 @@ int ExchangeAPDUSC(bool verbose, uint8_t *datain, int datainlen, bool activateCa
|
||||||
}
|
}
|
||||||
|
|
||||||
bool smart_select(bool verbose, smart_card_atr_t *atr) {
|
bool smart_select(bool verbose, smart_card_atr_t *atr) {
|
||||||
if (atr)
|
if (atr) {
|
||||||
memset(atr, 0, sizeof(smart_card_atr_t));
|
memset(atr, 0, sizeof(smart_card_atr_t));
|
||||||
|
}
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandNG(CMD_SMART_ATR, NULL, 0);
|
SendCommandNG(CMD_SMART_ATR, NULL, 0);
|
||||||
|
@ -1241,8 +1242,9 @@ bool smart_select(bool verbose, smart_card_atr_t *atr) {
|
||||||
smart_card_atr_t card;
|
smart_card_atr_t card;
|
||||||
memcpy(&card, (smart_card_atr_t *)resp.data.asBytes, sizeof(smart_card_atr_t));
|
memcpy(&card, (smart_card_atr_t *)resp.data.asBytes, sizeof(smart_card_atr_t));
|
||||||
|
|
||||||
if (atr)
|
if (atr) {
|
||||||
memcpy(atr, &card, sizeof(smart_card_atr_t));
|
memcpy(atr, &card, sizeof(smart_card_atr_t));
|
||||||
|
}
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
PrintAndLogEx(INFO, "ISO7816-3 ATR : %s", sprint_hex(card.atr, card.atr_len));
|
PrintAndLogEx(INFO, "ISO7816-3 ATR : %s", sprint_hex(card.atr, card.atr_len));
|
||||||
|
|
|
@ -944,11 +944,11 @@ int hextobinarray_n(char *target, char *source, int sourcelen) {
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert hex to human readable binary string
|
// convert hexstring to human readable binary string
|
||||||
int hextobinstring(char *target, char *source) {
|
int hextobinstring(char *target, char *source) {
|
||||||
return hextobinstring_n(target, source, strlen(source));
|
return hextobinstring_n(target, source, strlen(source));
|
||||||
}
|
}
|
||||||
|
// convert hexstring to human readable binary string
|
||||||
int hextobinstring_n(char *target, char *source, int sourcelen) {
|
int hextobinstring_n(char *target, char *source, int sourcelen) {
|
||||||
int length = hextobinarray_n(target, source, sourcelen);
|
int length = hextobinarray_n(target, source, sourcelen);
|
||||||
if (length == 0) {
|
if (length == 0) {
|
||||||
|
@ -958,6 +958,23 @@ int hextobinstring_n(char *target, char *source, int sourcelen) {
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// convert bytes to binary string
|
||||||
|
int byte_2_binstr(char *target, const uint8_t *source, size_t sourcelen) {
|
||||||
|
//uint8_t *p = *source;
|
||||||
|
for (int i = 0 ; i < sourcelen; ++i) {
|
||||||
|
uint8_t b = *(source++);
|
||||||
|
*(target++) = ((b >> 7) & 0x1) + '0';
|
||||||
|
*(target++) = ((b >> 6) & 0x1) + '0';
|
||||||
|
*(target++) = ((b >> 5) & 0x1) + '0';
|
||||||
|
*(target++) = ((b >> 4) & 0x1) + '0';
|
||||||
|
*(target++) = ((b >> 3) & 0x1) + '0';
|
||||||
|
*(target++) = ((b >> 2) & 0x1) + '0';
|
||||||
|
*(target++) = ((b >> 1) & 0x1) + '0';
|
||||||
|
*(target++) = (b & 0x1) + '0';
|
||||||
|
}
|
||||||
|
*target = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
// convert binary array of 0x00/0x01 values to hex
|
// convert binary array of 0x00/0x01 values to hex
|
||||||
// return number of bits converted
|
// return number of bits converted
|
||||||
int binarraytohex(char *target, const size_t targetlen, const char *source, size_t srclen) {
|
int binarraytohex(char *target, const size_t targetlen, const char *source, size_t srclen) {
|
||||||
|
@ -1007,8 +1024,9 @@ int binarraytohex(char *target, const size_t targetlen, const char *source, size
|
||||||
|
|
||||||
// convert binary array to human readable binary
|
// convert binary array to human readable binary
|
||||||
void binarraytobinstring(char *target, char *source, int length) {
|
void binarraytobinstring(char *target, char *source, int length) {
|
||||||
for (int i = 0 ; i < length; ++i)
|
for (int i = 0 ; i < length; ++i) {
|
||||||
*(target++) = *(source++) + '0';
|
*(target++) = *(source++) + '0';
|
||||||
|
}
|
||||||
*target = '\0';
|
*target = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -122,6 +122,8 @@ int binarraytohex(char *target, const size_t targetlen, const char *source, size
|
||||||
void binarraytobinstring(char *target, char *source, int length);
|
void binarraytobinstring(char *target, char *source, int length);
|
||||||
int binstring2binarray(uint8_t *target, char *source, int length);
|
int binstring2binarray(uint8_t *target, char *source, int length);
|
||||||
|
|
||||||
|
int byte_2_binstr(char *target, const uint8_t *source, size_t sourcelen);
|
||||||
|
|
||||||
uint8_t GetParity(const uint8_t *bits, uint8_t type, int length);
|
uint8_t GetParity(const uint8_t *bits, uint8_t type, int length);
|
||||||
void wiegand_add_parity(uint8_t *target, uint8_t *source, uint8_t length);
|
void wiegand_add_parity(uint8_t *target, uint8_t *source, uint8_t length);
|
||||||
void wiegand_add_parity_swapped(uint8_t *target, uint8_t *source, uint8_t length);
|
void wiegand_add_parity_swapped(uint8_t *target, uint8_t *source, uint8_t length);
|
||||||
|
|
|
@ -60,13 +60,14 @@ bool IsCardHelperPresent(bool verbose) {
|
||||||
bool IsHIDSamPresent(bool verbose) {
|
bool IsHIDSamPresent(bool verbose) {
|
||||||
|
|
||||||
if (IfPm3Smartcard() == false) {
|
if (IfPm3Smartcard() == false) {
|
||||||
|
PrintAndLogEx(WARNING, "Proxmark3 does not have SMARTCARD support enabled, exiting");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// detect SAM
|
// detect SAM
|
||||||
smart_card_atr_t card;
|
smart_card_atr_t card;
|
||||||
smart_select(verbose, &card);
|
smart_select(verbose, &card);
|
||||||
if (!card.atr_len) {
|
if (card.atr_len == 0) {
|
||||||
PrintAndLogEx(ERR, "Can't get ATR from a smart card");
|
PrintAndLogEx(ERR, "Can't get ATR from a smart card");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -485,3 +485,45 @@ void reverse_array_copy(const uint8_t *src, int src_len, uint8_t *dest) {
|
||||||
dest[i] = src[(src_len - 1) - i];
|
dest[i] = src[(src_len - 1) - i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int hexchar_to_dec(char ch) {
|
||||||
|
if (ch >= '0' && ch <= '9') {
|
||||||
|
return ch - '0';
|
||||||
|
}
|
||||||
|
if (ch >= 'a' && ch <= 'f') {
|
||||||
|
return ch - 'a' + 10;
|
||||||
|
}
|
||||||
|
if (ch >= 'A' && ch <= 'F') {
|
||||||
|
return ch - 'A' + 10;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// no spaces allowed for input hex string
|
||||||
|
bool hexstr_to_byte_array(const char *hexstr, uint8_t *d, size_t *n) {
|
||||||
|
|
||||||
|
size_t hexstr_len = strlen(hexstr);
|
||||||
|
if (hexstr_len & 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*n = (hexstr_len >> 1);
|
||||||
|
|
||||||
|
for (int i = 0; i < *n; i++) {
|
||||||
|
|
||||||
|
char c1 = *hexstr++;
|
||||||
|
char c2 = *hexstr++;
|
||||||
|
|
||||||
|
if (c1 == '\0' || c2 == '\0') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int b = (hexchar_to_dec(c1) << 4) | hexchar_to_dec(c2);
|
||||||
|
if (b < 0) {
|
||||||
|
// Error: invalid hex character
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
d[i] = (uint8_t) b;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -109,4 +109,5 @@ uint16_t get_sw(const uint8_t *d, uint16_t n);
|
||||||
void reverse_array(uint8_t *d, size_t n);
|
void reverse_array(uint8_t *d, size_t n);
|
||||||
void reverse_array_copy(const uint8_t *src, int src_len, uint8_t *dest);
|
void reverse_array_copy(const uint8_t *src, int src_len, uint8_t *dest);
|
||||||
|
|
||||||
|
bool hexstr_to_byte_array(const char *hexstr, uint8_t *d, size_t *n);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -585,6 +585,7 @@ typedef struct {
|
||||||
#define CMD_HF_ICLASS_RESTORE 0x039B
|
#define CMD_HF_ICLASS_RESTORE 0x039B
|
||||||
#define CMD_HF_ICLASS_CREDIT_EPURSE 0x039C
|
#define CMD_HF_ICLASS_CREDIT_EPURSE 0x039C
|
||||||
|
|
||||||
|
|
||||||
// For ISO1092 / FeliCa
|
// For ISO1092 / FeliCa
|
||||||
#define CMD_HF_FELICA_SIMULATE 0x03A0
|
#define CMD_HF_FELICA_SIMULATE 0x03A0
|
||||||
#define CMD_HF_FELICA_SNIFF 0x03A1
|
#define CMD_HF_FELICA_SNIFF 0x03A1
|
||||||
|
@ -669,6 +670,7 @@ typedef struct {
|
||||||
#define CMD_HF_MFU_COUNTER_TEAROFF 0x0741
|
#define CMD_HF_MFU_COUNTER_TEAROFF 0x0741
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define CMD_HF_SNIFF 0x0800
|
#define CMD_HF_SNIFF 0x0800
|
||||||
#define CMD_HF_PLOT 0x0801
|
#define CMD_HF_PLOT 0x0801
|
||||||
|
|
||||||
|
@ -698,6 +700,11 @@ typedef struct {
|
||||||
#define CMD_HF_MIFARE_G4_GDM_CONFIG 0x0872
|
#define CMD_HF_MIFARE_G4_GDM_CONFIG 0x0872
|
||||||
#define CMD_HF_MIFARE_G4_GDM_WRCFG 0x0873
|
#define CMD_HF_MIFARE_G4_GDM_WRCFG 0x0873
|
||||||
|
|
||||||
|
// HID SAM
|
||||||
|
#define CMD_HF_SAM_PICOPASS 0x0900
|
||||||
|
#define CMD_HF_SAM_SEOS 0x0901
|
||||||
|
#define CMD_HF_SAM_MFC 0x0902
|
||||||
|
|
||||||
#define CMD_UNKNOWN 0xFFFF
|
#define CMD_UNKNOWN 0xFFFF
|
||||||
|
|
||||||
//Mifare simulation flags
|
//Mifare simulation flags
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue