Merge remote-tracking branch 'upstream/master' into felica_support_request_service

# Conflicts:
#	armsrc/felica.c
#	client/cmdhffelica.c
This commit is contained in:
Thomas Sutter 2019-10-20 18:40:16 +02:00
commit ce4c651853
68 changed files with 40575 additions and 301 deletions

View file

@ -1,8 +1,8 @@
# RRG / Iceman repo - Proxmark3
This repo is based on iceman fork for Proxmark3. It supports other Proxmark3 platforms as well.
This repo is based on iceman fork for Proxmark3.
It is dedicated to bringing the most out of the new features for Proxmark3 RDV4.0 new hardware and design.
It supports RDV4.0 and other Proxmark3 platforms as well.
| Releases | Linux & OSX CI | Windows CI | Coverity |
@ -56,6 +56,8 @@ This repo compiles nicely on
- WSL, WSL2 (Windows subsystem linux) on Windows 10
- Docker container
The [public roadmap](https://github.com/RfidResearchGroup/proxmark3/wiki/Public-Roadmap) is an excellent start to read if you are interesting in contributing.
> 👉 **Remember!** If you intend to contribute to the code, please read the [coding style notes](HACKING.md) first.
We usually merge your contributions fast since we do like the idea of getting a functionality in the Proxmark3 and weed out the bugs afterwards.
@ -93,7 +95,8 @@ The new universal GUI will work. [Proxmark3 Universal GUI](https://github.com/bu
Please see the [Proxmark Forum](http://www.proxmark.org/forum/index.php) and see if your issue is listed in the first instance Google is your friend :) Questions will be answered via the forum by Iceman and the team.
It's needed to have a good USB cable to connect Proxmark3 to USB. If you have stability problems (Proxmark3 resets, firmware hangs, especially firmware hangs just after start, etc.) - check your cable with a USB tester (or try to change it). It needs to have a resistance smaller or equal to 0.3 Ohm.
Read the [Troubleshooting](/doc/md/Installation_Instructions/Troubleshooting.md) guide to weed out most known problems.
## The end

View file

@ -217,12 +217,12 @@ void RAMFUNC SniffAndStore(uint8_t param) {
if (DBGLEVEL > 1)
Dbprintf("[!] Authentication attempts = %u", auth_attempts);
size_t size = 4 * auth_attempts;
uint8_t *data = BigBuf_malloc(size);
uint8_t *buf = BigBuf_malloc(size);
if (!exists_in_spiffs((char *)HF_BOG_LOGFILE)) {
rdv40_spiffs_write((char *)HF_BOG_LOGFILE, (uint8_t *)data, size, RDV40_SPIFFS_SAFETY_SAFE);
rdv40_spiffs_write((char *)HF_BOG_LOGFILE, buf, size, RDV40_SPIFFS_SAFETY_SAFE);
} else {
rdv40_spiffs_append((char *)HF_BOG_LOGFILE, (uint8_t *)data, size, RDV40_SPIFFS_SAFETY_SAFE);
rdv40_spiffs_append((char *)HF_BOG_LOGFILE, buf, size, RDV40_SPIFFS_SAFETY_SAFE);
}
}

View file

@ -857,7 +857,7 @@ int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) {
DbprintfEx(FLAG_NEWLINE, "Halt error");
};
crypto1_destroy(pcs);
crypto1_deinit(pcs);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
@ -894,12 +894,12 @@ int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, ui
SpinDelayUs(AUTHENTICATION_TIMEOUT);
continue;
}
crypto1_destroy(pcs);
crypto1_deinit(pcs);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
*key = ui64Key;
return i;
}
crypto1_destroy(pcs);
crypto1_deinit(pcs);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
return -1;

View file

@ -195,12 +195,12 @@ static int saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, ui
SpinDelayUs(AUTHENTICATION_TIMEOUT);
continue;
}
crypto1_destroy(pcs);
crypto1_deinit(pcs);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
*key = ui64Key;
return i;
}
crypto1_destroy(pcs);
crypto1_deinit(pcs);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
return -1;

View file

@ -65,7 +65,7 @@ void RunMod() {
continue;
// Button was held for a second, begin recording
if (button_pressed > 0 && cardRead == 0) {
if (cardRead == 0) {
LEDsoff();
LED(selected + 1, 0);
LED(LED_D, 0);

View file

@ -96,7 +96,7 @@ void RunMod() {
if (data_available()) break;
// Was our button held down or pressed?
int button_pressed = BUTTON_HELD(280);
button_pressed = BUTTON_HELD(280);
if (button_pressed != BUTTON_HOLD) break;
Dbprintf("[=] trying Facility = %08x ID %08x", high, i);

View file

@ -1591,7 +1591,7 @@ static void PacketReceived(PacketCommandNG *packet) {
uint16_t offset = MIN(BIGBUF_SIZE - PM3_CMD_DATA_SIZE - 3, payload->offset);
uint8_t *mem = BigBuf_get_addr();
memcpy(mem + offset, &payload->data, PM3_CMD_DATA_SIZE - 3);
memcpy(mem + offset, &payload->data, PM3_CMD_DATA_SIZE - 3 - offset);
reply_ng(CMD_LF_UPLOAD_SIM_SAMPLES, PM3_SUCCESS, NULL, 0);
break;
}
@ -1711,8 +1711,10 @@ static void PacketReceived(PacketCommandNG *packet) {
strncpy((char *)src, token, sizeof(src) - 1);
token = strtok(NULL, ",");
strncpy((char *)dest, token, sizeof(dest) - 1);
if (DBGLEVEL > 1) Dbprintf("> Filename received as source for spiffs RENAME : %s", src);
if (DBGLEVEL > 1) Dbprintf("> Filename received as destination for spiffs RENAME : %s", dest);
if (DBGLEVEL > 1) {
Dbprintf("> Filename received as source for spiffs RENAME : %s", src);
Dbprintf("> Filename received as destination for spiffs RENAME : %s", dest);
}
rdv40_spiffs_rename((char *) src, (char *)dest, RDV40_SPIFFS_SAFETY_SAFE);
LED_B_OFF();
break;
@ -1727,8 +1729,10 @@ static void PacketReceived(PacketCommandNG *packet) {
strncpy((char *)src, token, sizeof(src) - 1);
token = strtok(NULL, ",");
strncpy((char *)dest, token, sizeof(dest) - 1);
if (DBGLEVEL > 1) Dbprintf("> Filename received as source for spiffs COPY : %s", src);
if (DBGLEVEL > 1) Dbprintf("> Filename received as destination for spiffs COPY : %s", dest);
if (DBGLEVEL > 1) {
Dbprintf("> Filename received as source for spiffs COPY : %s", src);
Dbprintf("> Filename received as destination for spiffs COPY : %s", dest);
}
rdv40_spiffs_copy((char *) src, (char *)dest, RDV40_SPIFFS_SAFETY_SAFE);
LED_B_OFF();
break;
@ -1899,9 +1903,13 @@ static void PacketReceived(PacketCommandNG *packet) {
break;
}
case CMD_TIA: {
while ((AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINRDY) == 0); // Wait for MAINF value to become available...
uint16_t mainf = AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINF;
Dbprintf(" Slow clock old measured value:.........%d Hz", (16 * MAINCK) / mainf);
TimingIntervalAcquisition();
while ((AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINRDY) == 0); // Wait for MAINF value to become available...
mainf = AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINF;
Dbprintf(""); // first message gets lost
Dbprintf(" Slow clock new measured value:.........%d Hz", (16 * MAINCK) / mainf);

View file

@ -524,7 +524,7 @@ void felica_sendraw(PacketCommandNG *c) {
arg0 = felica_select_card(&card);
reply_mix(CMD_ACK, arg0, sizeof(card.uid), 0, &card, sizeof(felica_card_select_t));
if (arg0 > 0) {
Dbprintf("Error: Failed selecting card!");
if (DBGLEVEL >= DBG_DEBUG) Dbprintf("Error: Failed selecting card! ");
felica_reset_frame_mode();
return;
}
@ -613,7 +613,7 @@ void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) {
//crc NOT checked
if (FelicaFrame.state == STATE_FULL) {
endframe = GetCountSspClk();
//*dest = FelicaFrame.crc_ok; //kind of wasteful
// *dest = FelicaFrame.crc_ok; //kind of wasteful
dest++;
for (int i = 0; i < FelicaFrame.len; i++) {
*dest = FelicaFrame.framebytes[i];
@ -754,12 +754,16 @@ void felica_sim_lite(uint64_t uid) {
DbpString("Felica Lite-S sim end");
}
#define RES_SVC_LEN 11 + 3
void felica_dump() {
uint8_t ndef[8];
uint8_t poll[10] = { 0xb2, 0x4d, 0x06, FELICA_POLL_REQ, 0xff, 0xff, 0x00, 0x00, 0x09, 0x21}; // B24D0600FFFF00000921
iso18092_setup(FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD);
TransmitFor18092_AsReader(poll, 10, NULL, 1, 0);
// iceman, no exit path in this loop
while (!BUTTON_PRESS() && !data_available()) {
WDT_HIT();
TransmitFor18092_AsReader(poll, 10, NULL, 1, 0);
@ -769,12 +773,12 @@ void felica_dump() {
felica_send_request_service(request_service);
}
}
}
void felica_send_request_service(uint8_t *request_service) {
uint8_t len = sizeof(request_service) / sizeof((request_service)[0]);
Dbprintf("Send Service Request - len: d%", len);
TransmitFor18092_AsReader(request_service, len, NULL, 1, 0);
Dbprintf("Send Service Request - len: d%", RES_SVC_LEN);
TransmitFor18092_AsReader(request_service, RES_SVC_LEN, NULL, 1, 0);
if (WaitForFelicaReply(512) && FelicaFrame.framebytes[3] == FELICA_REQSRV_ACK) {
Dbprintf("Got Service Response!");
}
@ -791,7 +795,7 @@ uint8_t *felica_create_request_service_frame(uint8_t nodeNumber, uint8_t *idm) {
nodeNumber = 1;
}
// Sync 2-Byte, Length 1-Byte, CMD 1-Byte, IDm 8-Byte, nodeNumber 1 <= n <= 32 1-Byte, Node Code List <Little Endian>
uint8_t *request_service = BigBuf_malloc(sizeof(uint8_t) * 11);
uint8_t *request_service = BigBuf_malloc(sizeof(uint8_t) * RES_SVC_LEN);
//{ 0xb2, 0x4d, 0x06, FELICA_REQSRV_REQ, 0xff, 0xff, 0x00, 0x00, 0x09, 0x21};
request_service[0] = 0xb2; //Sync
request_service[1] = 0x4d; //Sync
@ -803,10 +807,10 @@ uint8_t *felica_create_request_service_frame(uint8_t nodeNumber, uint8_t *idm) {
request_service[7] = idm[3];
request_service[8] = idm[4];
request_service[9] = idm[5];
request_service[9] = idm[6];
request_service[9] = idm[7];
request_service[10] = nodeNumber; // Node we like to ask for services
request_service[11] = 0x00; // Node Code List // TODO FIND OUT WHAT NEEDS TO BE IN HERE
request_service[10] = idm[6];
request_service[11] = idm[7];
request_service[12] = nodeNumber; // Node we like to ask for services
request_service[13] = 0x00; // Node Code List // TODO FIND OUT WHAT NEEDS TO BE IN HERE
return request_service;
}

View file

@ -201,8 +201,8 @@ int json_printf_array(struct json_out *, va_list *ap);
* Return number of elements successfully scanned & converted.
* Negative number means scan error.
*/
int json_scanf(const char *str, int str_len, const char *fmt, ...);
int json_vscanf(const char *str, int str_len, const char *fmt, va_list ap);
int json_scanf(const char *str, int len, const char *fmt, ...);
int json_vscanf(const char *str, int len, const char *fmt, va_list ap);
/* json_scanf's %M handler */
typedef void (*json_scanner_t)(const char *str, int len, void *user_data);
@ -234,7 +234,7 @@ int json_escape(struct json_out *out, const char *str, size_t str_len);
* Read the whole file in memory.
* Return malloc-ed file content, or NULL on error. The caller must free().
*/
char *json_fread(const char *file_name);
char *json_fread(const char *path);
/*
* Update given JSON string `s,len` by changing the value at given `json_path`.

View file

@ -1235,8 +1235,8 @@ void CmdAWIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol)
uint8_t *dest = BigBuf_get_addr();
//big enough to catch 2 sequences of largest format
size_t size = 12800; //50 * 128 * 2;
//big enough to catch 2 sequences of largest format but don't exeed whats available in bigbuff.
size_t size = MIN(12800, BigBuf_max_traceLen()); //50 * 128 * 2;
int dummyIdx = 0;
@ -1544,13 +1544,12 @@ void T55xxWriteBit(uint8_t bit, uint8_t downlink_idx) {
// max_len - how many bytes can the bit_array hold (ensure no buffer overflow)
// returns "Next" bit offset / bits stored (for next store)
uint8_t T55xx_SetBits(uint8_t *bs, uint8_t start_offset, uint32_t data, uint8_t num_bits, uint8_t max_len) {
int8_t offset;
int8_t next_offset = start_offset;
// Check if data will fit.
if ((start_offset + num_bits) <= (max_len * 8)) {
// Loop through the data and store
for (offset = (num_bits - 1); offset >= 0; offset--) {
for (int8_t offset = (num_bits - 1); offset >= 0; offset--) {
if ((data >> offset) & 1)
bs[BITSTREAM_BYTE(next_offset)] |= (1 << BITSTREAM_BIT(next_offset)); // Set 1

View file

@ -103,7 +103,7 @@ void MifareReadBlock(uint8_t blockNo, uint8_t keyType, uint8_t *datain) {
break;
}
crypto1_destroy(pcs);
crypto1_deinit(pcs);
if (DBGLEVEL >= 2) DbpString("READ BLOCK FINISHED");
@ -264,7 +264,7 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t *datain) {
if (DBGLEVEL >= 2) DbpString("READ SECTOR FINISHED");
crypto1_destroy(pcs);
crypto1_deinit(pcs);
LED_B_ON();
reply_old(CMD_ACK, isOK, 0, 0, dataoutbuf, 16 * NumBlocksPerSector(sectorNo));
@ -430,7 +430,7 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) {
break;
}
crypto1_destroy(pcs);
crypto1_deinit(pcs);
if (DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");
@ -847,7 +847,7 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags,
}
LED_C_OFF();
crypto1_destroy(pcs);
crypto1_deinit(pcs);
LED_B_ON();
reply_old(CMD_ACK, isOK, cuid, num_nonces, buf, sizeof(buf));
LED_B_OFF();
@ -1061,7 +1061,7 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8
LED_C_OFF();
crypto1_destroy(pcs);
crypto1_deinit(pcs);
struct p {
int16_t isOK;
@ -1510,7 +1510,7 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
OUT:
LEDsoff();
crypto1_destroy(pcs);
crypto1_deinit(pcs);
// All keys found, send to client, or last keychunk from client
if (foundkeys == allkeys || lastchunk) {
@ -1660,7 +1660,7 @@ void MifareChkKeys(uint8_t *datain) {
LEDsoff();
set_tracing(false);
crypto1_destroy(pcs);
crypto1_deinit(pcs);
}
//-----------------------------------------------------------------------------
@ -1780,7 +1780,7 @@ int MifareECardLoad(uint8_t numSectors, uint8_t keyType) {
if (DBGLEVEL >= DBG_INFO) DbpString("Emulator fill sectors finished");
out:
crypto1_destroy(pcs);
crypto1_deinit(pcs);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
set_tracing(false);
@ -2110,7 +2110,7 @@ void MifareSetMod(uint8_t *datain) {
break;
}
crypto1_destroy(pcs);
crypto1_deinit(pcs);
LED_B_ON();
reply_ng(CMD_HF_MIFARE_SETMOD, isOK, NULL, 0);

View file

@ -571,7 +571,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
EmSendPrecompiledCmd(&responses[ATQA]);
// init crypto block
crypto1_destroy(pcs);
crypto1_deinit(pcs);
cardAUTHKEY = AUTHKEYNONE;
nonce = prng_successor(selTimer, 32);
// prepare NT for nested authentication
@ -743,10 +743,10 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] KEY %c: %012" PRIx64, (cardAUTHKEY == 0) ? 'A' : 'B', emlGetKey(cardAUTHSC, cardAUTHKEY));
// first authentication
crypto1_destroy(pcs);
crypto1_deinit(pcs);
// Load key into crypto
crypto1_create(pcs, emlGetKey(cardAUTHSC, cardAUTHKEY));
crypto1_init(pcs, emlGetKey(cardAUTHSC, cardAUTHKEY));
if (!encrypted_data) {
// Receive Cmd in clear txt

View file

@ -149,10 +149,10 @@ int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockN
// ----------------------------- crypto1 create
if (isNested)
crypto1_destroy(pcs);
crypto1_deinit(pcs);
// Init cipher with key
crypto1_create(pcs, ui64Key);
crypto1_init(pcs, ui64Key);
if (isNested == AUTH_NESTED) {
// decrypt nt with help of new key
@ -276,7 +276,7 @@ int mifare_ultra_auth(uint8_t *keybytes) {
uint8_t respPar[3] = {0, 0, 0};
// REQUEST AUTHENTICATION
len = mifare_sendcmd_short(NULL, 1, MIFARE_ULC_AUTH_1, 0x00, resp, respPar, NULL);
len = mifare_sendcmd_short(NULL, CRYPT_NONE, MIFARE_ULC_AUTH_1, 0x00, resp, respPar, NULL);
if (len != 11) {
if (DBGLEVEL >= DBG_ERROR) Dbprintf("Cmd Error: %02x", resp[0]);
return 0;
@ -351,7 +351,7 @@ int mifare_ultra_readblockEx(uint8_t blockNo, uint8_t *blockData) {
uint8_t receivedAnswer[MAX_FRAME_SIZE] = {0x00};
uint8_t receivedAnswerPar[MAX_PARITY_SIZE] = {0x00};
len = mifare_sendcmd_short(NULL, 1, ISO14443A_CMD_READBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL);
len = mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_READBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL);
if (len == 1) {
if (DBGLEVEL >= DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
return 1;
@ -444,7 +444,7 @@ int mifare_ultra_writeblock_compat(uint8_t blockNo, uint8_t *blockData) {
uint8_t receivedAnswer[MAX_FRAME_SIZE];
uint8_t receivedAnswerPar[MAX_PARITY_SIZE];
len = mifare_sendcmd_short(NULL, true, ISO14443A_CMD_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL);
len = mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL);
if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
if (DBGLEVEL >= DBG_ERROR)

View file

@ -536,21 +536,28 @@ int rdv40_spiffs_read_as_filetype(char *filename, uint8_t *dst, uint32_t size, R
////////////////////////////////////////////////////////////////////////////////
///////// MISC HIGH LEVEL FUNCTIONS ////////////////////////////////////////////
#define SPIFFS_BANNER DbpString(_BLUE_("Flash Memory FileSystem tree (SPIFFS)"));
void rdv40_spiffs_safe_print_fsinfo() {
rdv40_spiffs_fsinfo fsinfo;
rdv40_spiffs_getfsinfo(&fsinfo, RDV40_SPIFFS_SAFETY_SAFE);
DbpString(_BLUE_("Flash Memory FileSystem Info (SPIFFS)"));
Dbprintf("-------------------------------------");
Dbprintf("* Filesystem Logical Block Size.........%d bytes", fsinfo.blockSize);
Dbprintf("* Filesystem Logical Page Size..........%d bytes", fsinfo.pageSize);
Dbprintf("--");
Dbprintf("* Filesystem Max Open Files.............%d file descriptors", fsinfo.maxOpenFiles);
Dbprintf("* Filesystem Max Path Length............%d chars", fsinfo.maxPathLength);
Dbprintf("--");
Dbprintf("Filesystem\tSize\tUsed\tAvailable\tUse%\tMounted on");
Dbprintf("spiffs\t%dB\t%dB\t%dB\t\t%d%\t/", fsinfo.totalBytes, fsinfo.usedBytes, fsinfo.freeBytes,
fsinfo.usedPercent);
Dbprintf(" Logical Block Size........." _YELLOW_("%d")"bytes", fsinfo.blockSize);
Dbprintf(" Logical Page Size.........." _YELLOW_("%d")"bytes", fsinfo.pageSize);
Dbprintf("");
Dbprintf(" Max Open Files............." _YELLOW_("%d")"file descriptors", fsinfo.maxOpenFiles);
Dbprintf(" Max Path Length............" _YELLOW_("%d")"chars", fsinfo.maxPathLength);
DbpString("");
Dbprintf(" filesystem size used available use% mounted");
Dbprintf(" spiffs %6d B %6d B %6d B"_YELLOW_("%2d%")" /"
, fsinfo.totalBytes
, fsinfo.usedBytes
, fsinfo.freeBytes
, fsinfo.usedPercent
);
}
// this function is safe and WILL rollback since it is only a PRINTING function,
@ -562,14 +569,16 @@ void rdv40_spiffs_safe_print_fsinfo() {
// dont want, as prefix are way easier and lighter in every aspect.
void rdv40_spiffs_safe_print_tree(uint8_t banner) {
int changed = rdv40_spiffs_lazy_mount();
spiffs_DIR d;
struct spiffs_dirent e;
struct spiffs_dirent *pe = &e;
if (banner) {
DbpString(_BLUE_("Flash Memory FileSystem tree (SPIFFS)"));
Dbprintf("-------------------------------------");
}
int changed = rdv40_spiffs_lazy_mount();
spiffs_DIR d;
struct spiffs_dirent e;
struct spiffs_dirent *pe = &e;
SPIFFS_opendir(&fs, "/", &d);
Dbprintf(" \t \t/");
while ((pe = SPIFFS_readdir(&d, pe))) {
@ -592,29 +601,40 @@ void rdv40_spiffs_safe_print_tree(uint8_t banner) {
rdv40_spiffs_lazy_mount_rollback(changed);
}
// Selftest function
void test_spiffs() {
Dbprintf("---------------------------");
Dbprintf("----------------------------------------------");
Dbprintf("Testing SPIFFS operations");
Dbprintf("---------------------------");
Dbprintf("(all test are made using lazy safetylevel)");
Dbprintf("* Mounting filesystem (lazy).......");
Dbprintf("----------------------------------------------");
Dbprintf("-- all test are made using lazy safetylevel");
Dbprintf(" Mounting filesystem (lazy).......");
int changed = rdv40_spiffs_lazy_mount();
Dbprintf("* Printing tree..............");
Dbprintf(" Printing tree..............");
rdv40_spiffs_safe_print_tree(false);
Dbprintf("* Writing 'I love Proxmark' in a testspiffs.txt");
Dbprintf(" Writing 'I love Proxmark3 RDV4' in a testspiffs.txt");
// Since We lazy_mounted manually before hand, the wrte safety level will
// just imply noops
rdv40_spiffs_write((char *)"testspiffs.txt", (uint8_t *)"I love Proxmark", 15, RDV40_SPIFFS_SAFETY_SAFE);
Dbprintf("* Printing tree again.......");
rdv40_spiffs_write((char *)"testspiffs.txt", (uint8_t *)"I love Proxmark3 RDV4", 21, RDV40_SPIFFS_SAFETY_SAFE);
Dbprintf(" Printing tree again.......");
rdv40_spiffs_safe_print_tree(false);
Dbprintf("* Making a symlink to testspiffs.txt");
Dbprintf(" Making a symlink to testspiffs.txt");
rdv40_spiffs_make_symlink((char *)"testspiffs.txt", (char *)"linktotestspiffs.txt", RDV40_SPIFFS_SAFETY_SAFE);
Dbprintf("* Printing tree again.......");
Dbprintf(" Printing tree again.......");
rdv40_spiffs_safe_print_tree(false);
// TODO READBACK, rename,print tree read back, remove, print tree;
Dbprintf("* Rollbacking The mount status IF things have changed");
Dbprintf(" Rollbacking The mount status IF things have changed");
rdv40_spiffs_lazy_mount_rollback(changed);
Dbprintf("All done");
Dbprintf(_GREEN_("All done"));
return;
}

View file

@ -63,7 +63,7 @@ static void CodeThinfilmAsTag(const uint8_t *cmd, uint16_t len) {
for (uint16_t i = 0; i < len; i++) {
uint8_t b = cmd[i];
for (uint8_t j = 0; j < 8; j++) {
ToSend[++ToSendMax] = b & 0x80 ? SEC_D : SEC_E;
ToSend[++ToSendMax] = (b & 0x80) ? SEC_D : SEC_E;
b <<= 1;
}
}

View file

@ -109,9 +109,11 @@ ifneq ($(SKIPQT),1)
endif
ifneq ($(QTLDLIBS),)
QTGUISRCS = proxgui.cpp proxguiqt.cpp proxguiqt.moc.cpp
QTGUIOBJS = $(OBJDIR)/proxgui.o $(OBJDIR)/proxguiqt.o $(OBJDIR)/proxguiqt.moc.o
PM3CFLAGS += -DHAVE_GUI
else
QTGUISRCS = guidummy.cpp
QTGUIOBJS = $(OBJDIR)/guidummy.o
endif
@ -257,7 +259,6 @@ ifeq ($(MULTIARCHSRCS), )
CMDSRCS += hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c
endif
QTGUISRCS = proxgui.cpp proxguiqt.cpp proxguiqt.moc.cpp guidummy.cpp
COREOBJS = $(CORESRCS:%.c=$(OBJDIR)/%.o)
CMDOBJS = $(CMDSRCS:%.c=$(OBJDIR)/%.o)

View file

@ -1872,7 +1872,7 @@ int CmdPlot(const char *Cmd) {
return PM3_SUCCESS;
}
static int CmdSave(const char *Cmd) {
int CmdSave(const char *Cmd) {
int len = 0;
char filename[FILE_PATH_SIZE] = {0x00};

View file

@ -53,6 +53,7 @@ int CmdHpf(const char *Cmd);
int CmdLtrim(const char *Cmd); // used by cmd lf em4x, lf t55xx
int CmdNorm(const char *Cmd); // used by cmd lf data (!)
int CmdPlot(const char *Cmd); // used by cmd lf cotag
int CmdSave(const char *Cmd); // used by cmd auto
int CmdTuneSamples(const char *Cmd); // used by cmd lf hw
int ASKbiphaseDemod(const char *Cmd, bool verbose); // used by cmd lf em4x, lf fdx, lf guard, lf jablotron, lf nedap, lf t55xx
int ASKDemod(const char *Cmd, bool verbose, bool emSearch, uint8_t askType); // used by cmd lf em4x, lf t55xx, lf viking

View file

@ -70,6 +70,8 @@ static int usage_hf_tune() {
return PM3_SUCCESS;
}
#define PROMPT_CLEARLINE PrintAndLogEx(INPLACE, " ")
int CmdHFSearch(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
@ -77,6 +79,7 @@ int CmdHFSearch(const char *Cmd) {
PrintAndLogEx(INFO, "Checking for known tags...\n");
PROMPT_CLEARLINE;
PrintAndLogEx(INPLACE, "Searching for ThinFilm tag...");
if (IfPm3NfcBarcode()) {
if (infoThinFilm(false) == PM3_SUCCESS) {
@ -85,6 +88,7 @@ int CmdHFSearch(const char *Cmd) {
}
}
PROMPT_CLEARLINE;
PrintAndLogEx(INPLACE, "Searching for ISO14443-A tag...");
if (IfPm3Iso14443a()) {
if (infoHF14A(false, false) > 0) {
@ -93,6 +97,7 @@ int CmdHFSearch(const char *Cmd) {
}
}
PROMPT_CLEARLINE;
PrintAndLogEx(INPLACE, "Searching for ISO15693 tag...");
if (IfPm3Iso15693()) {
if (readHF15Uid(false) == 1) {
@ -104,6 +109,7 @@ int CmdHFSearch(const char *Cmd) {
DropField();
}
PROMPT_CLEARLINE;
PrintAndLogEx(INPLACE, "Searching for LEGIC tag...");
if (IfPm3Legicrf()) {
if (readLegicUid(false) == PM3_SUCCESS) {
@ -112,6 +118,7 @@ int CmdHFSearch(const char *Cmd) {
}
}
PROMPT_CLEARLINE;
PrintAndLogEx(INPLACE, "Searching for Topaz tag...");
if (IfPm3Iso14443a()) {
if (readTopazUid() == PM3_SUCCESS) {
@ -120,7 +127,17 @@ int CmdHFSearch(const char *Cmd) {
}
}
PROMPT_CLEARLINE;
PrintAndLogEx(INPLACE, "Searching for FeliCa tag...");
if (IfPm3Felica()) {
if (readFelicaUid(false) == PM3_SUCCESS) {
PrintAndLogEx(NORMAL, "\nValid " _GREEN_("ISO18092 / FeliCa tag") " found\n");
return PM3_SUCCESS;
}
}
// 14b and iclass is the longest test (put last)
PROMPT_CLEARLINE;
PrintAndLogEx(INPLACE, "Searching for ISO14443-B tag...");
if (IfPm3Iso14443a()) {
if (readHF14B(false) == 1) {
@ -129,6 +146,7 @@ int CmdHFSearch(const char *Cmd) {
}
}
PROMPT_CLEARLINE;
PrintAndLogEx(INPLACE, "Searching for iClass / PicoPass tag...");
if (IfPm3Iclass()) {
if (readIclass(false, false) == 1) {
@ -137,17 +155,6 @@ int CmdHFSearch(const char *Cmd) {
}
}
// PrintAndLogEx(INPLACE, "Searching for FeliCa tag...");
//if (IfPm3Felica()) {
// ans = CmdHFFelicaReader("s");
// if (ans) {
// PrintAndLogEx(NORMAL, "\nValid " _GREEN_("ISO18092 / FeliCa tag") " found\n");
// return ans;
// }
//}
PrintAndLogEx(INPLACE, "No known/supported 13.56 MHz tags found");
PrintAndLogEx(NORMAL, "");
return PM3_ESOFT;

View file

@ -36,7 +36,7 @@ static int usage_hf_felica_sim(void) {
PrintAndLogEx(NORMAL, " v : (Optional) Verbose");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " hf felica sim t 1 ");
return 0;
return PM3_SUCCESS;
}
*/
@ -48,7 +48,7 @@ static int usage_hf_felica_sniff(void) {
PrintAndLogEx(NORMAL, " t triggers to skip (decimal)");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " hf felica sniff s 1000");
return 0;
return PM3_SUCCESS;
}
static int usage_hf_felica_simlite(void) {
PrintAndLogEx(NORMAL, "\n Emulating ISO/18092 FeliCa Lite tag \n");
@ -58,7 +58,7 @@ static int usage_hf_felica_simlite(void) {
PrintAndLogEx(NORMAL, " uid : UID in hexsymbol");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " hf felica litesim 11223344556677");
return 0;
return PM3_SUCCESS;
}
static int usage_hf_felica_dumplite(void) {
PrintAndLogEx(NORMAL, "\n Dump ISO/18092 FeliCa Lite tag \n");
@ -68,7 +68,7 @@ static int usage_hf_felica_dumplite(void) {
PrintAndLogEx(NORMAL, " h : This help");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " hf felica litedump");
return 0;
return PM3_SUCCESS;
}
static int usage_hf_felica_raw(void) {
PrintAndLogEx(NORMAL, "Usage: hf felica raw [-h] [-r] [-c] [-p] [-a] <0A 0B 0C ... hex>");
@ -78,7 +78,7 @@ static int usage_hf_felica_raw(void) {
PrintAndLogEx(NORMAL, " -p leave the signal field ON after receive");
PrintAndLogEx(NORMAL, " -a active signal field ON without select");
PrintAndLogEx(NORMAL, " -s active signal field ON with select");
return 0;
return PM3_SUCCESS;
}
static int usage_hf_felica_request_service(void) {
@ -89,30 +89,30 @@ static int usage_hf_felica_request_service(void) {
PrintAndLogEx(NORMAL, " -h this help");
PrintAndLogEx(NORMAL, " -c calculate and append CRC");
PrintAndLogEx(NORMAL, "Example: rqservice 01100910c11bc407 01 FFFF 2837");
return 0;
return PM3_SUCCESS;
}
static int usage_hf_felica_dump(void) {
PrintAndLogEx(NORMAL, "Usage: hf felica dump [-h] <outputfile>");
PrintAndLogEx(NORMAL, " -h this help");
return 0;
return PM3_SUCCESS;
}
static int CmdHFFelicaList(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
//PrintAndLogEx(NORMAL, "Deprecated command, use 'hf list felica' instead");
CmdTraceList("felica");
return 0;
return PM3_SUCCESS;
}
static int CmdHFFelicaReader(const char *Cmd) {
bool verbose = !(Cmd[0] == 's' || Cmd[0] == 'S');
readFelicaUid(verbose);
return 0;
bool verbose = !(tolower(Cmd[0]) == 's');
return readFelicaUid(verbose);
}
static int CmdHFFelicaDump(const char *Cmd) {
if (strlen(Cmd) < 1) return usage_hf_felica_dump();
return dump(*Cmd);
clearCommandBuffer();
char ctmp = tolower(param_getchar(Cmd, 0));
if (ctmp == 'h') return usage_hf_felica_dumplite();
@ -268,7 +268,7 @@ static int CmdHFFelicaSim(const char *Cmd) {
while (!kbd_enter_pressed()) {
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) continue;
}
return 0;
return PM3_SUCCESS;
}
*/
@ -304,7 +304,7 @@ static int CmdHFFelicaSniff(const char *Cmd) {
clearCommandBuffer();
SendCommandMIX(CMD_HF_FELICA_SNIFF, samples2skip, triggers2skip, 0, NULL, 0);
return 0;
return PM3_SUCCESS;
}
// uid hex
@ -316,7 +316,7 @@ static int CmdHFFelicaSimLite(const char *Cmd) {
clearCommandBuffer();
SendCommandMIX(CMD_HF_FELICALITE_SIMULATE, uid, 0, 0, NULL, 0);
return 0;
return PM3_SUCCESS;
}
static void printSep() {
@ -489,35 +489,35 @@ static int CmdHFFelicaDumpLite(const char *Cmd) {
if (kbd_enter_pressed()) {
PrintAndLogEx(WARNING, "\n[!] aborted via keyboard!\n");
DropField();
return 1;
return PM3_EOPABORTED;
}
if (timeout > 100) {
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
DropField();
return 1;
return PM3_ETIMEOUT;
}
}
if (resp.oldarg[0] == 0) {
PrintAndLogEx(WARNING, "\nButton pressed. Aborted.");
return 1;
return PM3_EOPABORTED;
}
uint32_t tracelen = resp.oldarg[1];
if (tracelen == 0) {
PrintAndLogEx(WARNING, "\nNo trace data! Maybe not a FeliCa Lite card?");
return 1;
return PM3_ESOFT;
}
uint8_t *trace = calloc(tracelen, sizeof(uint8_t));
if (trace == NULL) {
PrintAndLogEx(WARNING, "Cannot allocate memory for trace");
return 1;
return PM3_EMALLOC;
}
if (!GetFromDevice(BIG_BUF, trace, tracelen, 0, NULL, 0, NULL, 2500, false)) {
PrintAndLogEx(WARNING, "command execution time out");
free(trace);
return 0;
return PM3_ETIMEOUT;
}
PrintAndLogEx(SUCCESS, "Recorded Activity (trace len = %"PRIu64" bytes)", tracelen);
@ -532,7 +532,7 @@ static int CmdHFFelicaDumpLite(const char *Cmd) {
printSep();
free(trace);
return 0;
return PM3_SUCCESS;
}
static void waitCmdFelica(uint8_t iSelect) {
@ -624,7 +624,7 @@ static int CmdHFFelicaCmdRaw(const char *Cmd) {
continue;
}
PrintAndLogEx(WARNING, "Invalid char on input");
return 0;
return PM3_EINVARG;
}
if (crc && datalen > 0 && datalen < sizeof(data) - 2) {
@ -664,7 +664,7 @@ static int CmdHFFelicaCmdRaw(const char *Cmd) {
waitCmdFelica(0);
}
}
return 0;
return PM3_SUCCESS;
}
int readFelicaUid(bool verbose) {
@ -675,7 +675,7 @@ int readFelicaUid(bool verbose) {
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) {
if (verbose) PrintAndLogEx(WARNING, "FeliCa card select failed");
//SendCommandMIX(CMD_HF_FELICA_COMMAND, 0, 0, 0, NULL, 0);
return 0;
return PM3_ESOFT;
}
felica_card_select_t card;
@ -686,19 +686,20 @@ int readFelicaUid(bool verbose) {
case 1: {
if (verbose)
PrintAndLogEx(WARNING, "card timeout");
break;
return PM3_ETIMEOUT;
}
case 2: {
if (verbose)
PrintAndLogEx(WARNING, "card answered wrong");
break;
return PM3_ESOFT;
}
case 3: {
if (verbose)
PrintAndLogEx(WARNING, "CRC check failed");
break;
return PM3_ESOFT;
}
case 0: {
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(SUCCESS, "FeliCa tag info");
PrintAndLogEx(NORMAL, "IDm %s", sprint_hex(card.IDm, sizeof(card.IDm)));
@ -713,24 +714,24 @@ int readFelicaUid(bool verbose) {
break;
}
}
return status;
return PM3_SUCCESS;
}
int dump() {
int dump(const char *Cmd) {
clearCommandBuffer();
char ctmp = tolower(param_getchar(Cmd, 0));
if (ctmp == 'h') return usage_hf_felica_dumplite();
// TODO FINISH THIS METHOD
PrintAndLogEx(SUCCESS, "NOT IMPLEMENTED YET!");
return 0;
return PM3_SUCCESS;
}
int request_service() {
return 0;
return PM3_SUCCESS;
}
static command_t CommandTable[] = {
{"----------- General -----------", CmdHelp, IfPm3Iso14443a, ""},
{"help", CmdHelp, AlwaysAvailable, "This help"},
@ -769,7 +770,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 CmdHFFelica(const char *Cmd) {

View file

@ -2330,7 +2330,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) {
uint8_t found_offset = 0;
uint32_t key_offset = 0;
// main keychunk loop
for (uint32_t key_offset = 0; key_offset < keycount; key_offset += chunksize) {
for (key_offset = 0; key_offset < keycount; key_offset += chunksize) {
uint64_t t2 = msclock();
uint8_t timeout = 0;
@ -2806,16 +2806,18 @@ int readIclass(bool loop, bool verbose) {
FLAG_ICLASS_READER_ONE_TRY;
// loop in client not device - else on windows have a communication error
PacketResponseNG resp;
while (!kbd_enter_pressed()) {
clearCommandBuffer();
SendCommandMIX(CMD_HF_ICLASS_READER, flags, 0, 0, NULL, 0);
PacketResponseNG resp;
if (WaitForResponseTimeout(CMD_ACK, &resp, 4500)) {
uint8_t readStatus = resp.oldarg[0] & 0xff;
uint8_t *data = resp.data.asBytes;
if (verbose) PrintAndLogEx(INFO, "Readstatus:%02x", readStatus);
// if (verbose) PrintAndLogEx(INFO, "Readstatus:%02x", readStatus);
// no tag found or button pressed
if ((readStatus == 0 && !loop) || readStatus == 0xFF) {
@ -2837,18 +2839,29 @@ int readIclass(bool loop, bool verbose) {
printIclassDumpInfo(data);
}
// if CSN ends with FF12E0, it's inside HID CSN range.
bool isHidRange = (memcmp((uint8_t *)(data + 5), "\xFF\x12\xE0", 3) == 0);
if (readStatus & FLAG_ICLASS_READER_AIA) {
bool legacy = (memcmp((uint8_t *)(data + 8 * 5), "\xff\xff\xff\xff\xff\xff\xff\xff", 8) == 0);
bool se_enabled = (memcmp((uint8_t *)(data + 8 * 5), "\xff\xff\xff\x00\x06\xff\xff\xff", 8) == 0);
PrintAndLogEx(NORMAL, " App IA: %s", sprint_hex(data + 8 * 5, 8));
if (isHidRange) {
if (legacy)
PrintAndLogEx(SUCCESS, " : Possible iClass (legacy credential tag)");
else if (se_enabled)
PrintAndLogEx(SUCCESS, " : Possible iClass (SE credential tag)");
else
PrintAndLogEx(WARNING, " : Possible iClass (NOT legacy tag)");
PrintAndLogEx(SUCCESS, " : Possible iClass - legacy credential tag");
if (se_enabled)
PrintAndLogEx(SUCCESS, " : Possible iClass - SE credential tag");
}
if (isHidRange) {
PrintAndLogEx(SUCCESS, " : Tag is "_YELLOW_("iClass")", CSN is in HID range");
} else {
PrintAndLogEx(SUCCESS, " : Tag is "_YELLOW_("PicoPass")", CSN is not in HID range");
}
}
if (tagFound && !loop) {

View file

@ -2920,7 +2920,7 @@ void readerAttack(nonces_t data, bool setEmulatorMem, bool verbose) {
if (k_sector == NULL)
emptySectorTable();
success = mfkey32_moebius(data, &key);
success = mfkey32_moebius(&data, &key);
if (success) {
uint8_t sector = data.sector;
uint8_t keytype = data.keytype;

View file

@ -1052,6 +1052,11 @@ static void estimate_sum_a8(void) {
static int read_nonce_file(char *filename) {
if (filename == NULL) {
PrintAndLogEx(WARNING, "Filename is NULL");
return 1;
}
FILE *fnonces = NULL;
char progress_text[80] = "";
uint8_t read_buf[9];
@ -1061,6 +1066,7 @@ static int read_nonce_file(char *filename) {
PrintAndLogEx(WARNING, "Could not open file %s", filename);
return 1;
}
snprintf(progress_text, 80, "Reading nonces from file %s...", filename);
hardnested_print_progress(0, progress_text, (float)(1LL << 47), 0);
size_t bytes_read = fread(read_buf, 1, 6, fnonces);
@ -1766,7 +1772,7 @@ static void add_matching_states(statelist_t *candidates, uint8_t part_sum_a0, ui
}
static statelist_t *add_more_candidates(void) {
statelist_t *new_candidates = candidates;
statelist_t *new_candidates;
if (candidates == NULL) {
candidates = (statelist_t *)malloc(sizeof(statelist_t));
new_candidates = candidates;

View file

@ -63,12 +63,12 @@ static int usage_lf_cmdread(void) {
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h This help");
PrintAndLogEx(NORMAL, " d <delay> delay OFF period, (0 for bitbang mode) (decimal)");
PrintAndLogEx(NORMAL, " z <zero> time period ZERO, (decimal)");
PrintAndLogEx(NORMAL, " o <one> time period ONE, (decimal)");
PrintAndLogEx(NORMAL, " z <zero> ZERO time period (decimal)");
PrintAndLogEx(NORMAL, " o <one> ONE time period (decimal)");
PrintAndLogEx(NORMAL, " c <cmd> Command bytes (in ones and zeros)");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, " ************* All periods in microseconds (ms)");
PrintAndLogEx(NORMAL, " ************* Use lf config to configure options.");
PrintAndLogEx(NORMAL, " ************* " _YELLOW_("All periods in microseconds (us)"));
PrintAndLogEx(NORMAL, " ************* Use " _YELLOW_("'lf config'") "to configure options.");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " lf cmdread d 80 z 100 o 200 c 11000");
return PM3_SUCCESS;
@ -77,7 +77,7 @@ static int usage_lf_read(void) {
PrintAndLogEx(NORMAL, "Usage: lf read [h] [s] [d numofsamples]");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h This help");
PrintAndLogEx(NORMAL, " s silent run no printout");
PrintAndLogEx(NORMAL, " s silent run, no printout");
PrintAndLogEx(NORMAL, " d #samples # samples to collect (optional)");
PrintAndLogEx(NORMAL, "Use 'lf config' to set parameters.");
PrintAndLogEx(NORMAL, "");

View file

@ -523,7 +523,7 @@ static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "this help"},
{"demod", CmdAWIDDemod, AlwaysAvailable, "demodulate an AWID FSK tag from the GraphBuffer"},
{"read", CmdAWIDRead, IfPm3Lf, "attempt to read and extract tag data"},
{"clone", CmdAWIDClone, IfPm3Lf, "clone AWID to T55x7"},
{"clone", CmdAWIDClone, IfPm3Lf, "clone AWID tag to T55x7 (or to q5/T5555)"},
{"sim", CmdAWIDSim, IfPm3Lf, "simulate AWID tag"},
{"brute", CmdAWIDBrute, IfPm3Lf, "Bruteforce card number against reader"},
{"watch", CmdAWIDWatch, IfPm3Lf, "continuously watch for cards. Reader mode"},

View file

@ -135,7 +135,7 @@ static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"demod", CmdGallagherDemod, AlwaysAvailable, "Demodulate an GALLAGHER tag from the GraphBuffer"},
{"read", CmdGallagherRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"},
{"clone", CmdGallagherClone, IfPm3Lf, "clone GALLAGHER tag"},
{"clone", CmdGallagherClone, IfPm3Lf, "clone GALLAGHER tag to T55x7"},
{"sim", CmdGallagherSim, IfPm3Lf, "simulate GALLAGHER tag"},
{NULL, NULL, NULL, NULL}
};

View file

@ -238,7 +238,7 @@ static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "this help"},
{"demod", CmdGuardDemod, AlwaysAvailable, "demodulate a G Prox II tag from the GraphBuffer"},
{"read", CmdGuardRead, IfPm3Lf, "attempt to read and extract tag data from the antenna"},
{"clone", CmdGuardClone, IfPm3Lf, "clone Guardall tag"},
{"clone", CmdGuardClone, IfPm3Lf, "clone Guardall tag to T55x7"},
{"sim", CmdGuardSim, IfPm3Lf, "simulate Guardall tag"},
{NULL, NULL, NULL, NULL}
};

View file

@ -452,7 +452,7 @@ static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "this help"},
{"demod", CmdHIDDemod, AlwaysAvailable, "demodulate HID Prox tag from the GraphBuffer"},
{"read", CmdHIDRead, IfPm3Lf, "attempt to read and extract tag data"},
{"clone", CmdHIDClone, IfPm3Lf, "clone HID to T55x7"},
{"clone", CmdHIDClone, IfPm3Lf, "clone HID tag to T55x7"},
{"sim", CmdHIDSim, IfPm3Lf, "simulate HID tag"},
{"brute", CmdHIDBrute, IfPm3Lf, "bruteforce card number against reader"},
{"watch", CmdHIDWatch, IfPm3Lf, "continuously watch for cards. Reader mode"},

View file

@ -534,7 +534,7 @@ static command_t CommandTable[] = {
{"demod", CmdIndalaDemod, AlwaysAvailable, "demodulate an indala tag (PSK1) from GraphBuffer"},
{"altdemod", CmdIndalaDemodAlt, AlwaysAvailable, "alternative method to Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"},
{"read", CmdIndalaRead, IfPm3Lf, "read an Indala Prox tag from the antenna"},
{"clone", CmdIndalaClone, IfPm3Lf, "clone Indala to T55x7"},
{"clone", CmdIndalaClone, IfPm3Lf, "clone Indala tag to T55x7"},
{"sim", CmdIndalaSim, IfPm3Lf, "simulate Indala tag"},
{NULL, NULL, NULL, NULL}
};

View file

@ -282,7 +282,7 @@ static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "this help"},
{"demod", CmdIOProxDemod, AlwaysAvailable, "demodulate an IOProx tag from the GraphBuffer"},
{"read", CmdIOProxRead, IfPm3Lf, "attempt to read and extract tag data"},
{"clone", CmdIOProxClone, IfPm3Lf, "clone IOProx to T55x7"},
{"clone", CmdIOProxClone, IfPm3Lf, "clone IOProx tag to T55x7 (or to q5/T5555)"},
{"sim", CmdIOProxSim, IfPm3Lf, "simulate IOProx tag"},
{"watch", CmdIOProxWatch, IfPm3Lf, "continuously watch for cards. Reader mode"},
{NULL, NULL, NULL, NULL}

View file

@ -217,7 +217,7 @@ static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"demod", CmdJablotronDemod, AlwaysAvailable, "Demodulate an Jablotron tag from the GraphBuffer"},
{"read", CmdJablotronRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"},
{"clone", CmdJablotronClone, IfPm3Lf, "clone jablotron tag"},
{"clone", CmdJablotronClone, IfPm3Lf, "clone jablotron tag to T55x7 (or to q5/T5555)"},
{"sim", CmdJablotronSim, IfPm3Lf, "simulate jablotron tag"},
{NULL, NULL, NULL, NULL}
};

View file

@ -209,7 +209,7 @@ static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"demod", CmdKeriDemod, AlwaysAvailable, "Demodulate an KERI tag from the GraphBuffer"},
{"read", CmdKeriRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"},
{"clone", CmdKeriClone, IfPm3Lf, "clone KERI to T55x7"},
{"clone", CmdKeriClone, IfPm3Lf, "clone KERI tag to T55x7 (or to q5/T5555)"},
{"sim", CmdKeriSim, IfPm3Lf, "simulate KERI tag"},
{NULL, NULL, NULL, NULL}
};

View file

@ -192,7 +192,7 @@ static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"demod", CmdMotorolaDemod, AlwaysAvailable, "Demodulate an MOTOROLA tag from the GraphBuffer"},
{"read", CmdMotorolaRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"},
{"clone", CmdMotorolaClone, IfPm3Lf, "clone MOTOROLA to T55x7"},
{"clone", CmdMotorolaClone, IfPm3Lf, "clone MOTOROLA tag to T55x7"},
{"sim", CmdMotorolaSim, IfPm3Lf, "simulate MOTOROLA tag"},
{NULL, NULL, NULL, NULL}
};

View file

@ -152,7 +152,7 @@ static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"demod", CmdNexWatchDemod, AlwaysAvailable, "Demodulate a NexWatch tag (nexkey, quadrakey) from the GraphBuffer"},
{"read", CmdNexWatchRead, IfPm3Lf, "Attempt to Read and Extract tag data from the antenna"},
{"clone", CmdNexWatchClone, IfPm3Lf, "clone NexWatch tag"},
{"clone", CmdNexWatchClone, IfPm3Lf, "clone NexWatch tag to T55x7"},
{"sim", CmdNexWatchSim, IfPm3Lf, "simulate NexWatch tag"},
{NULL, NULL, NULL, NULL}
};

View file

@ -219,7 +219,7 @@ static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"demod", CmdNoralsyDemod, AlwaysAvailable, "Demodulate an Noralsy tag from the GraphBuffer"},
{"read", CmdNoralsyRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"},
{"clone", CmdNoralsyClone, IfPm3Lf, "clone Noralsy to T55x7"},
{"clone", CmdNoralsyClone, IfPm3Lf, "clone Noralsy tag to T55x7 (or to q5/T5555)"},
{"sim", CmdNoralsySim, IfPm3Lf, "simulate Noralsy tag"},
{NULL, NULL, NULL, NULL}
};

View file

@ -135,7 +135,7 @@ static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"demod", CmdPacDemod, AlwaysAvailable, "Demodulate an PAC tag from the GraphBuffer"},
{"read", CmdPacRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"},
{"clone", CmdPacClone, IfPm3Lf, "clone PAC tag"},
{"clone", CmdPacClone, IfPm3Lf, "clone PAC tag to T55x7"},
{"sim", CmdPacSim, IfPm3Lf, "simulate PAC tag"},
{NULL, NULL, NULL, NULL}
};

View file

@ -224,7 +224,7 @@ static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"demod", CmdParadoxDemod, AlwaysAvailable, "Demodulate a Paradox FSK tag from the GraphBuffer"},
{"read", CmdParadoxRead, IfPm3Lf, "Attempt to read and Extract tag data from the antenna"},
{"clone", CmdParadoxClone, IfPm3Lf, "clone paradox tag"},
{"clone", CmdParadoxClone, IfPm3Lf, "clone paradox tag to T55x7"},
{"sim", CmdParadoxSim, IfPm3Lf, "simulate paradox tag"},
{NULL, NULL, NULL, NULL}
};

View file

@ -176,7 +176,7 @@ static int CmdPrescoSim(const char *Cmd) {
static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"read", CmdPrescoRead, IfPm3Lf, "Attempt to read and Extract tag data"},
{"clone", CmdPrescoClone, IfPm3Lf, "clone presco tag"},
{"clone", CmdPrescoClone, IfPm3Lf, "clone presco tag to T55x7 (or to q5/T5555)"},
{"sim", CmdPrescoSim, IfPm3Lf, "simulate presco tag"},
{NULL, NULL, NULL, NULL}
};

View file

@ -300,7 +300,7 @@ static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "this help"},
{"demod", CmdPyramidDemod, AlwaysAvailable, "demodulate a Pyramid FSK tag from the GraphBuffer"},
{"read", CmdPyramidRead, IfPm3Lf, "attempt to read and extract tag data"},
{"clone", CmdPyramidClone, IfPm3Lf, "clone pyramid tag"},
{"clone", CmdPyramidClone, IfPm3Lf, "clone pyramid tag to T55x7 (or to q5/T5555)"},
{"sim", CmdPyramidSim, IfPm3Lf, "simulate pyramid tag"},
{NULL, NULL, NULL, NULL}
};

View file

@ -180,7 +180,7 @@ static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"demod", CmdSecurakeyDemod, AlwaysAvailable, "Demodulate an Securakey tag from the GraphBuffer"},
{"read", CmdSecurakeyRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"},
{"clone", CmdSecurakeyClone, IfPm3Lf, "clone Securakey tag"},
{"clone", CmdSecurakeyClone, IfPm3Lf, "clone Securakey tag to T55x7"},
{"sim", CmdSecurakeySim, IfPm3Lf, "simulate Securakey tag"},
{NULL, NULL, NULL, NULL}
};

View file

@ -371,8 +371,42 @@ static int usage_t55xx_dangerraw() {
return PM3_SUCCESS;
}
static int usage_t55xx_clonehelp() {
PrintAndLogEx(NORMAL, "For cloning specific techs on T55xx tags, see commands available in corresponding LF sub-menus, e.g.:");
PrintAndLogEx(NORMAL, _GREEN_("lf awid clone"));
// todo: rename to clone
PrintAndLogEx(NORMAL, _GREEN_("lf em 410x_write"));
// todo: implement restore
// PrintAndLogEx(NORMAL, _GREEN_("lf em 4x05_write"));
// PrintAndLogEx(NORMAL, _GREEN_("lf em 4x50_write"));
PrintAndLogEx(NORMAL, _GREEN_("lf fdx clone"));
PrintAndLogEx(NORMAL, _GREEN_("lf gallagher clone"));
PrintAndLogEx(NORMAL, _GREEN_("lf gproxii clone"));
PrintAndLogEx(NORMAL, _GREEN_("lf hid clone"));
PrintAndLogEx(NORMAL, _GREEN_("lf indala clone"));
PrintAndLogEx(NORMAL, _GREEN_("lf io clone"));
PrintAndLogEx(NORMAL, _GREEN_("lf jablotron clone"));
PrintAndLogEx(NORMAL, _GREEN_("lf keri clone"));
PrintAndLogEx(NORMAL, _GREEN_("lf nedap clone"));
PrintAndLogEx(NORMAL, _GREEN_("lf noralsy clone"));
PrintAndLogEx(NORMAL, _GREEN_("lf motorola clone"));
PrintAndLogEx(NORMAL, _GREEN_("lf pac clone"));
PrintAndLogEx(NORMAL, _GREEN_("lf paradox clone"));
PrintAndLogEx(NORMAL, _GREEN_("lf presco clone"));
PrintAndLogEx(NORMAL, _GREEN_("lf pyramid clone"));
PrintAndLogEx(NORMAL, _GREEN_("lf securakey clone"));
PrintAndLogEx(NORMAL, _GREEN_("lf viking clone"));
PrintAndLogEx(NORMAL, _GREEN_("lf visa2000 clone"));
return PM3_SUCCESS;
}
static int CmdHelp(const char *Cmd);
static int CmdT55xxCloneHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
return usage_t55xx_clonehelp();
}
void T55x7_SaveBlockData(uint8_t idx, uint32_t data) {
if (idx < T55x7_BLOCK_COUNT) {
cardmem[idx].valid = true;
@ -1049,7 +1083,7 @@ static int CmdT55xxDetect(const char *Cmd) {
if (try_all_dl_modes) {
for (uint8_t m = downlink_mode; m < 4; m++) {
if (AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, try_with_pwd & usepwd, password, m) == false)
if (AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, try_with_pwd && usepwd, password, m) == false)
continue;
// pre fill to save passing in.
@ -1077,7 +1111,7 @@ static int CmdT55xxDetect(const char *Cmd) {
}
}
if (!found & usepwd)
if (!found && usepwd)
try_with_pwd = !try_with_pwd; // toggle so we loop back if not found and try with pwd
if (found)
@ -3652,6 +3686,7 @@ static command_t CommandTable[] = {
{"bruteforce", CmdT55xxBruteForce, IfPm3Lf, "<start password> <end password> Simple bruteforce attack to find password"},
{"config", CmdT55xxSetConfig, AlwaysAvailable, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"},
{"chk", CmdT55xxChkPwds, IfPm3Lf, "Check passwords from dictionary/flash"},
{"clonehelp", CmdT55xxCloneHelp, IfPm3Lf, "Shows the available clone commands"},
{"dangerraw", CmdT55xxDangerousRaw, IfPm3Lf, "Sends raw bitstream. Dangerous, do not use!! b <bitstream> t <timing>"},
{"detect", CmdT55xxDetect, AlwaysAvailable, "[1] Try detecting the tag modulation from reading the configuration block."},
{"deviceconfig", CmdT55xxSetDeviceConfig, IfPm3Lf, "Set/Get T55XX device configuration (startgap, writegap, write0, write1, readgap"},

View file

@ -148,7 +148,7 @@ char *GetQ5ModulationStr(uint32_t id);
char *GetModulationStr(uint32_t id, bool xmode);
char *GetModelStrFromCID(uint32_t cid);
char *GetSelectedModulationStr(uint8_t id);
char *GetDownlinkModeStr(uint8_t dlmode);
char *GetDownlinkModeStr(uint8_t downlink_mode);
void printT5xxHeader(uint8_t page);
void printT55xxBlock(uint8_t blockNum, bool page1);
int printConfiguration(t55xx_conf_block_t b);

View file

@ -160,8 +160,8 @@ static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"demod", CmdVikingDemod, AlwaysAvailable, "Demodulate a Viking tag from the GraphBuffer"},
{"read", CmdVikingRead, IfPm3Lf, "Attempt to read and Extract tag data from the antenna"},
{"clone", CmdVikingClone, IfPm3Lf, "<8 digit ID number> clone viking tag"},
{"sim", CmdVikingSim, IfPm3Lf, "<8 digit ID number> simulate viking tag"},
{"clone", CmdVikingClone, IfPm3Lf, "clone Viking tag to T55x7 (or to q5/T5555)"},
{"sim", CmdVikingSim, IfPm3Lf, "simulate Viking tag"},
{NULL, NULL, NULL, NULL}
};

View file

@ -228,7 +228,7 @@ static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"demod", CmdVisa2kDemod, AlwaysAvailable, "demodulate an VISA2000 tag from the GraphBuffer"},
{"read", CmdVisa2kRead, IfPm3Lf, "attempt to read and extract tag data from the antenna"},
{"clone", CmdVisa2kClone, IfPm3Lf, "clone Visa2000 to t55x7"},
{"clone", CmdVisa2kClone, IfPm3Lf, "clone Visa2000 tag to T55x7 (or to q5/T5555)"},
{"sim", CmdVisa2kSim, IfPm3Lf, "simulate Visa2000 tag"},
{NULL, NULL, NULL, NULL}
};

View file

@ -18,6 +18,7 @@
#include <string.h>
#include <ctype.h>
#include <time.h> // MingW
#include <stdlib.h> // calloc
#include "comms.h"
#include "cmdhf.h"
@ -38,20 +39,6 @@
static int CmdHelp(const char *Cmd);
static int CmdRem(const char *Cmd) {
char buf[22] = {0};
struct tm *ct, tm_buf;
time_t now = time(NULL);
#if defined(_WIN32)
ct = gmtime_s(&tm_buf, &now) == 0 ? &tm_buf : NULL;
#else
ct = gmtime_r(&now, &tm_buf);
#endif
strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%SZ", ct); // ISO8601
PrintAndLogEx(NORMAL, "%s remark: %s", buf, Cmd);
return PM3_SUCCESS;
}
static int usage_msleep(void) {
PrintAndLogEx(NORMAL, "Sleep for given amount of milliseconds");
PrintAndLogEx(NORMAL, "");
@ -65,6 +52,63 @@ static int usage_msleep(void) {
return PM3_SUCCESS;
}
static int usage_auto(void) {
PrintAndLogEx(NORMAL, "Run LF SEARCH / HF SEARCH / DATA PLOT / DATA SAVE ");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: auto <ms>");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h This help");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " auto");
return PM3_SUCCESS;
}
static void AppendDate(char *s, size_t slen, char *fmt) {
struct tm *ct, tm_buf;
time_t now = time(NULL);
#if defined(_WIN32)
ct = gmtime_s(&tm_buf, &now) == 0 ? &tm_buf : NULL;
#else
ct = gmtime_r(&now, &tm_buf);
#endif
if (fmt == NULL)
strftime(s, slen, "%Y-%m-%dT%H:%M:%SZ", ct); // ISO8601
else
strftime(s, slen, fmt, ct);
}
static int CmdAuto(const char *Cmd) {
char ctmp = tolower(param_getchar(Cmd, 0));
if (ctmp == 'h') return usage_auto();
int ret = CmdLFfind("");
if (ret == PM3_SUCCESS)
return ret;
ret = CmdHFSearch("");
if (ret == PM3_SUCCESS)
return ret;
PrintAndLogEx(INFO, "Failed both LF / HF SEARCH,");
PrintAndLogEx(INFO, "Trying 'lf read' and save a trace for you...");
CmdPlot("");
lf_read(true, 40000);
char *fname = calloc(100, sizeof(uint8_t));
AppendDate(fname, 100, "lf_unknown_%Y-%m-%d_%H:%M.pm3");
CmdSave(fname);
free(fname);
return PM3_SUCCESS;
}
int CmdRem(const char *Cmd) {
char buf[22] = {0};
AppendDate(buf, sizeof(buf), NULL);
PrintAndLogEx(NORMAL, "%s remark: %s", buf, Cmd);
return PM3_SUCCESS;
}
static int CmdMsleep(const char *Cmd) {
uint32_t ms = 0;
char ctmp = tolower(param_getchar(Cmd, 0));
@ -90,6 +134,7 @@ static int CmdRev(const char *Cmd) {
static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help. Use '<command> help' for details of a particular command."},
{"auto", CmdAuto, IfPm3Present, "Automated detection process for unknown tags"},
{"analyse", CmdAnalyse, AlwaysAvailable, "{ Analyse utils... }"},
{"data", CmdData, AlwaysAvailable, "{ Plot window / data buffer manipulation... }"},
{"emv", CmdEMV, AlwaysAvailable, "{ EMV ISO-14443 / ISO-7816... }"},

View file

@ -15,6 +15,7 @@
#include "cmdparser.h" // command_t
int CommandReceived(char *Cmd);
int CmdRem(const char *Cmd);
command_t *getTopLevelCommandTable(void);
#endif

View file

@ -154,9 +154,11 @@ void CmdsHelp(const command_t Commands[]) {
if (Commands[0].Name == NULL) return;
int i = 0;
while (Commands[i].Name) {
if (Commands[i].IsAvailable())
// PrintAndLogEx(NORMAL, _GREEN_("%-16s")" %s", Commands[i].Name, Commands[i].Help);
printf(_GREEN_("%-16s")" %s\n", Commands[i].Name, Commands[i].Help);
if (Commands[i].IsAvailable()) {
g_printAndLog = PRINTANDLOG_PRINT;
PrintAndLogEx(NORMAL, _GREEN_("%-16s")" %s", Commands[i].Name, Commands[i].Help);
g_printAndLog = PRINTANDLOG_PRINT | PRINTANDLOG_LOG;
}
++i;
}
}

View file

@ -548,7 +548,6 @@ static int CmdSmartUpgrade(const char *Cmd) {
//Validations
if (errors || cmdp == 0) return usage_sm_upgrade();
char sha512filename[FILE_PATH_SIZE] = {'\0'};
char *bin_extension = filename;
char *dot_position = NULL;
@ -556,11 +555,7 @@ static int CmdSmartUpgrade(const char *Cmd) {
bin_extension = dot_position + 1;
}
if (!strcmp(bin_extension, "BIN")
#ifdef _WIN32
|| !strcmp(bin_extension, "bin")
#endif
) {
if (!strcmp(bin_extension, "BIN") || !strcmp(bin_extension, "bin")) {
memcpy(sha512filename, filename, strlen(filename) - strlen("bin"));
strcat(sha512filename, "sha512.txt");
} else {

View file

@ -150,11 +150,11 @@ int CmdWiegandDecode(const char *Cmd) {
bool errors = false;
char cmdp = 0;
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
uint32_t strlen = param_getlength(Cmd, cmdp);
strlen++; // null termin
if (strlen > 2) {
char *s = calloc(strlen, sizeof(uint8_t));
param_getstr(Cmd, cmdp, s, strlen);
uint32_t slen = param_getlength(Cmd, cmdp);
slen++; // null termin
if (slen > 2) {
char *s = calloc(slen, sizeof(uint8_t));
param_getstr(Cmd, cmdp, s, slen);
hexstring_to_u96(&top, &mid, &bot, s);
free(s);
gothex = true;

View file

@ -1089,7 +1089,7 @@ int RecoveryCertificates(struct tlvdb *tlvRoot, json_t *root) {
char *icc_pk_c = emv_pk_dump_pk(icc_pk);
JsonSaveStr(root, "$.ApplicationData.ICCPublicKeyDec", icc_pk_c);
JsonSaveBufAsHex(root, "$.ApplicationData.ICCPublicKeyModulus", icc_pk->modulus, icc_pk->mlen);
free(issuer_pk_c);
free(icc_pk_c);
return 0;
}

View file

@ -372,8 +372,8 @@ bool ParamLoadFromJson(struct tlvdb *tlv) {
return false;
}
tlv_tag_t tag = 0;
for (int i = 0; i < buflen; i++) {
tag = (tag << 8) | buf[i];
for (int j = 0; j < buflen; j++) {
tag = (tag << 8) | buf[j];
}
if (!HexToBuffer("TLV Error value:", tlvValue, buf, sizeof(buf) - 1, &buflen)) {

View file

@ -75,9 +75,9 @@ static CborError dumpelm(CborValue *it, bool *got_next, int nestingLevel) {
}
case CborSimpleType: {
uint8_t type;
cbor_value_get_simple_type(it, &type);
printf("simple(%u)", type);
uint8_t t;
cbor_value_get_simple_type(it, &t);
printf("simple(%u)", t);
break;
}
@ -206,7 +206,7 @@ int TinyCborPrintFIDOPackage(uint8_t cmdCode, bool isResponse, uint8_t *data, si
if (err) {
fprintf(stderr,
"CBOR parsing failure at offset %" PRId32 " : %s\n",
"CBOR parsing failure at offset %" PRIu32 " : %s\n",
(uint32_t)(cb.ptr - data),
cbor_error_string(err)
);

View file

@ -164,7 +164,7 @@ crack_states_thread(void *x) {
statelist_t *bucket = buckets[current_bucket];
if (bucket) {
#if defined (DEBUG_BRUTE_FORCE)
printf("Thread %u starts working on bucket %u\n", thread_id, current_bucket);
PrintAndLogEx(INFO, "Thread %u starts working on bucket %u\n", thread_id, current_bucket);
#endif
const uint64_t key = crack_states_bitsliced(thread_arg->cuid, thread_arg->best_first_bytes, bucket, &keys_found, &num_keys_tested, nonces_to_bruteforce, bf_test_nonce_2nd_byte, thread_arg->nonces);
if (key != -1) {
@ -250,16 +250,16 @@ void prepare_bf_test_nonces(noncelist_t *nonces, uint8_t best_first_byte) {
uint32_t bf_test_nonce_temp[4];
uint8_t bf_test_nonce_par_temp[4];
uint8_t bf_test_nonce_2nd_byte_temp[4];
for (uint8_t i = 0; i < 4 && i < nonces_to_bruteforce; i++) {
bf_test_nonce_temp[i] = bf_test_nonce[best_4[i]];
for (uint8_t j = 0; j < 4 && j < nonces_to_bruteforce; j++) {
bf_test_nonce_temp[j] = bf_test_nonce[best_4[j]];
bf_test_nonce_par_temp[i] = bf_test_nonce_par[best_4[i]];
bf_test_nonce_2nd_byte_temp[i] = bf_test_nonce_2nd_byte[best_4[i]];
bf_test_nonce_par_temp[j] = bf_test_nonce_par[best_4[j]];
bf_test_nonce_2nd_byte_temp[j] = bf_test_nonce_2nd_byte[best_4[j]];
}
for (uint8_t i = 0; i < 4 && i < nonces_to_bruteforce; i++) {
bf_test_nonce[i] = bf_test_nonce_temp[i];
bf_test_nonce_par[i] = bf_test_nonce_par_temp[i];
bf_test_nonce_2nd_byte[i] = bf_test_nonce_2nd_byte_temp[i];
for (uint8_t j = 0; j < 4 && j < nonces_to_bruteforce; j++) {
bf_test_nonce[j] = bf_test_nonce_temp[j];
bf_test_nonce_par[j] = bf_test_nonce_par_temp[j];
bf_test_nonce_2nd_byte[j] = bf_test_nonce_2nd_byte_temp[j];
}
}

View file

@ -0,0 +1,96 @@
local getopt = require('getopt')
copyright = 'Copyright (c) 2019 IceSQL AB. All rights reserved.'
author = 'Christian Herrmann'
version = 'v1.0.0'
desc = [[
This script initialize a Proxmark3 RDV4.0 with
- uploading dictionary files to flashmem
- configuring the LF T55X7 device settings
]]
example = [[
script run init_rdv4
]]
usage = [[
script run init_rdv4 -h
Arguments:
-h : this help
]]
local DEBUG = true
---
-- A debug printout-function
local function dbg(args)
if not DEBUG then return end
if type(args) == 'table' then
local i = 1
while args[i] do
dbg(args[i])
i = i+1
end
else
print('###', args)
end
end
---
-- This is only meant to be used when errors occur
local function oops(err)
print('ERROR:', err)
core.clearCommandBuffer()
return nil, err
end
---
-- Usage help
local function help()
print(copyright)
print(author)
print(version)
print(desc)
print('Example usage')
print(example)
print(usage)
end
---
-- The main entry point
function main(args)
local dash = string.rep('--', 20)
print( dash )
print( dash )
print()
-- Read the parameters
for o, a in getopt.getopt(args, 'h') do
if o == 'h' then return help() end
end
print('Prepping your Proxmark3 RDV4')
-- Upload dictionaries
print('Uploading dictionaries to RDV4 flashmemory')
print(dash)
core.console('mem load f mfc_default_keys m')
core.console('mem load f t55xx_default_pwds t')
core.console('mem load f iclass_default_keys i')
print(dash)
-- T55x7 Device configuration
print('Configure T55XX device side to match RDV4')
print(dash)
core.console('lf t55xx deviceconfig r 0 a 29 b 17 c 15 d 47 e 15 p')
core.console('lf t55xx deviceconfig r 1 a 29 b 17 c 18 d 50 e 15 p')
core.console('lf t55xx deviceconfig r 2 a 29 b 17 c 18 d 40 e 15 p')
core.console('lf t55xx deviceconfig r 3 a 29 b 17 c 15 d 31 e 15 f 47 g 63 p')
print('')
print('')
core.console('hw status')
print(dash)
print('all done!')
end
main(args)

View file

@ -181,7 +181,7 @@ int MADCheck(uint8_t *sector0, uint8_t *sector10, bool verbose, bool *haveMAD2)
if (!res)
res = res2;
if (verbose & !res2)
if (verbose && !res2)
PrintAndLogEx(NORMAL, "CRC8-MAD2 OK.");
}

View file

@ -89,25 +89,25 @@ uint32_t nonce2key(uint32_t uid, uint32_t nt, uint32_t nr, uint32_t ar, uint64_t
}
// recover key from 2 different reader responses on same tag challenge
bool mfkey32(nonces_t data, uint64_t *outputkey) {
bool mfkey32(nonces_t *data, uint64_t *outputkey) {
struct Crypto1State *s, *t;
uint64_t outkey = 0;
uint64_t key = 0; // recovered key
bool isSuccess = false;
uint8_t counter = 0;
uint32_t p640 = prng_successor(data.nonce, 64);
uint32_t p640 = prng_successor(data->nonce, 64);
s = lfsr_recovery32(data.ar ^ p640, 0);
s = lfsr_recovery32(data->ar ^ p640, 0);
for (t = s; t->odd | t->even; ++t) {
lfsr_rollback_word(t, 0, 0);
lfsr_rollback_word(t, data.nr, 1);
lfsr_rollback_word(t, data.cuid ^ data.nonce, 0);
lfsr_rollback_word(t, data->nr, 1);
lfsr_rollback_word(t, data->cuid ^ data->nonce, 0);
crypto1_get_lfsr(t, &key);
crypto1_word(t, data.cuid ^ data.nonce, 0);
crypto1_word(t, data.nr2, 1);
if (data.ar2 == (crypto1_word(t, 0, 0) ^ p640)) {
crypto1_word(t, data->cuid ^ data->nonce, 0);
crypto1_word(t, data->nr2, 1);
if (data->ar2 == (crypto1_word(t, 0, 0) ^ p640)) {
outkey = key;
counter++;
if (counter == 20) break;
@ -121,26 +121,26 @@ bool mfkey32(nonces_t data, uint64_t *outputkey) {
// recover key from 2 reader responses on 2 different tag challenges
// skip "several found keys". Only return true if ONE key is found
bool mfkey32_moebius(nonces_t data, uint64_t *outputkey) {
bool mfkey32_moebius(nonces_t *data, uint64_t *outputkey) {
struct Crypto1State *s, *t;
uint64_t outkey = 0;
uint64_t key = 0; // recovered key
bool isSuccess = false;
int counter = 0;
uint32_t p640 = prng_successor(data.nonce, 64);
uint32_t p641 = prng_successor(data.nonce2, 64);
uint32_t p640 = prng_successor(data->nonce, 64);
uint32_t p641 = prng_successor(data->nonce2, 64);
s = lfsr_recovery32(data.ar ^ p640, 0);
s = lfsr_recovery32(data->ar ^ p640, 0);
for (t = s; t->odd | t->even; ++t) {
lfsr_rollback_word(t, 0, 0);
lfsr_rollback_word(t, data.nr, 1);
lfsr_rollback_word(t, data.cuid ^ data.nonce, 0);
lfsr_rollback_word(t, data->nr, 1);
lfsr_rollback_word(t, data->cuid ^ data->nonce, 0);
crypto1_get_lfsr(t, &key);
crypto1_word(t, data.cuid ^ data.nonce2, 0);
crypto1_word(t, data.nr2, 1);
if (data.ar2 == (crypto1_word(t, 0, 0) ^ p641)) {
crypto1_word(t, data->cuid ^ data->nonce2, 0);
crypto1_word(t, data->nr2, 1);
if (data->ar2 == (crypto1_word(t, 0, 0) ^ p641)) {
outkey = key;
++counter;
if (counter == 20) break;
@ -153,20 +153,20 @@ bool mfkey32_moebius(nonces_t data, uint64_t *outputkey) {
}
// recover key from reader response and tag response of one authentication sequence
int mfkey64(nonces_t data, uint64_t *outputkey) {
int mfkey64(nonces_t *data, uint64_t *outputkey) {
uint64_t key = 0; // recovered key
uint32_t ks2; // keystream used to encrypt reader response
uint32_t ks3; // keystream used to encrypt tag response
struct Crypto1State *revstate;
// Extract the keystream from the messages
ks2 = data.ar ^ prng_successor(data.nonce, 64);
ks3 = data.at ^ prng_successor(data.nonce, 96);
ks2 = data->ar ^ prng_successor(data->nonce, 64);
ks3 = data->at ^ prng_successor(data->nonce, 96);
revstate = lfsr_recovery64(ks2, ks3);
lfsr_rollback_word(revstate, 0, 0);
lfsr_rollback_word(revstate, 0, 0);
lfsr_rollback_word(revstate, data.nr, 1);
lfsr_rollback_word(revstate, data.cuid ^ data.nonce, 0);
lfsr_rollback_word(revstate, data->nr, 1);
lfsr_rollback_word(revstate, data->cuid ^ data->nonce, 0);
crypto1_get_lfsr(revstate, &key);
crypto1_destroy(revstate);
*outputkey = key;

View file

@ -17,9 +17,9 @@
#include "mifare.h"
uint32_t nonce2key(uint32_t uid, uint32_t nt, uint32_t nr, uint32_t ar, uint64_t par_info, uint64_t ks_info, uint64_t **keys);
bool mfkey32(nonces_t data, uint64_t *outputkey);
bool mfkey32_moebius(nonces_t data, uint64_t *outputkey);
int mfkey64(nonces_t data, uint64_t *outputkey);
bool mfkey32(nonces_t *data, uint64_t *outputkey);
bool mfkey32_moebius(nonces_t *data, uint64_t *outputkey);
int mfkey64(nonces_t *data, uint64_t *outputkey);
int compare_uint64(const void *a, const void *b);
uint32_t intersection(uint64_t *listA, uint64_t *listB);

View file

@ -29,6 +29,8 @@
static void showBanner(void) {
g_printAndLog = PRINTANDLOG_PRINT;
PrintAndLogEx(NORMAL, "\n");
#if defined(__linux__) || (__APPLE__) || (_WIN32)
PrintAndLogEx(NORMAL, _BLUE_("██████╗ ███╗ ███╗ ████╗ ") " ...iceman fork");
@ -50,6 +52,8 @@ static void showBanner(void) {
// printf("\nMonero: 43mNJLpgBVaTvyZmX9ajcohpvVkaRy1kbZPm8tqAb7itZgfuYecgkRF36rXrKFUkwEGeZedPsASRxgv4HPBHvJwyJdyvQuP");
PrintAndLogEx(NORMAL, "\n");
fflush(stdout);
g_printAndLog = PRINTANDLOG_PRINT | PRINTANDLOG_LOG;
}
int check_comm(void) {
@ -466,6 +470,35 @@ finish2:
return ret;
}
// Check if windows AnsiColor Support is enabled in the registery
// [HKEY_CURRENT_USER\Console]
// "VirtualTerminalLevel"=dword:00000001
static bool DetectWindowsAnsiSupport(void) {
bool ret = false;
#if defined(_WIN32)
HKEY hKey = NULL;
if (RegOpenKeyA(HKEY_CURRENT_USER, "Console", &hKey) == ERROR_SUCCESS) {
DWORD dwType = REG_SZ;
BYTE KeyValue[sizeof(dwType)];
DWORD len = sizeof(KeyValue);
if (RegQueryValueEx(hKey, "VirtualTerminalLevel", NULL, &dwType, KeyValue, &len) != ERROR_FILE_NOT_FOUND) {
uint8_t i;
uint32_t Data = 0;
for (i = 0; i < 4; i++)
Data += KeyValue[i] << (8 * i);
if (Data == 1) { // Reg key is set to 1, Ansi Color Enabled
ret = true;
}
}
RegCloseKey(hKey);
}
#endif
return ret;
}
int main(int argc, char *argv[]) {
srand(time(0));
@ -683,34 +716,7 @@ int main(int argc, char *argv[]) {
return 1;
}
session.supports_colors = false;
#if defined(_WIN32)
// Check if windows AnsiColor Support is enabled in the registery
// [HKEY_CURRENT_USER\Console]
// "VirtualTerminalLevel"=dword:00000001
HKEY hKey = NULL;
if (RegOpenKeyA(HKEY_CURRENT_USER, "Console", &hKey) == ERROR_SUCCESS) {
DWORD dwType = REG_SZ;
BYTE KeyValue[sizeof(dwType)];
DWORD len = sizeof(KeyValue);
if (RegQueryValueEx(hKey, "VirtualTerminalLevel", NULL, &dwType, KeyValue, &len) != ERROR_FILE_NOT_FOUND) {
uint8_t i;
uint32_t Data = 0;
for (i = 0; i < 4; i++)
Data += KeyValue[i] << (8 * i);
if (Data == 1) { // Reg key is set to 1, Ansi Color Enabled
session.supports_colors = true;
}
}
RegCloseKey(hKey);
}
#endif
session.supports_colors = DetectWindowsAnsiSupport();
session.stdinOnTTY = isatty(STDIN_FILENO);
session.stdoutOnTTY = isatty(STDOUT_FILENO);

View file

@ -32,6 +32,7 @@
#include "crc16.h"
#include "protocols.h"
#include "fileutils.h" // searchfile
#include "cmdlf.h" // lf_config
static int returnToLuaWithError(lua_State *L, const char *fmt, ...) {
char buffer[200];
@ -1056,6 +1057,22 @@ static int l_ndefparse(lua_State *L) {
return 1;
}
static int l_remark(lua_State *L) {
//Check number of arguments
int n = lua_gettop(L);
if (n != 1) {
return returnToLuaWithError(L, "Only one string allowed");
}
size_t size;
// data
const char *s = luaL_checklstring(L, 1, &size);
int res = CmdRem(s);
lua_pushinteger(L, res);
return 1;
}
static int l_searchfile(lua_State *L) {
//Check number of arguments
int n = lua_gettop(L);
@ -1141,6 +1158,7 @@ int set_pm3_libraries(lua_State *L) {
{"ndefparse", l_ndefparse},
{"fast_push_mode", l_fast_push_mode},
{"search_file", l_searchfile},
{"rem", l_remark},
{NULL, NULL}
};

View file

@ -672,16 +672,16 @@ void HIDDisplayUnpackedCard(wiegand_card_t *card, const cardformat_t format) {
char s[80] = {0};
if (format.Fields.hasFacilityCode)
snprintf(s, sizeof(s), "FC: %d", card->FacilityCode);
snprintf(s, sizeof(s), "FC: %u", card->FacilityCode);
if (format.Fields.hasCardNumber)
snprintf(s + strlen(s), sizeof(s) - strlen(s), " CN: %" PRIu64, card->CardNumber);
if (format.Fields.hasIssueLevel)
snprintf(s + strlen(s), sizeof(s) - strlen(s), " Issue %d", card->IssueLevel);
snprintf(s + strlen(s), sizeof(s) - strlen(s), " Issue %u", card->IssueLevel);
if (format.Fields.hasOEMCode)
snprintf(s + strlen(s), sizeof(s) - strlen(s), " OEM: %d", card->OEM);
snprintf(s + strlen(s), sizeof(s) - strlen(s), " OEM: %u", card->OEM);
if (format.Fields.hasParity)
snprintf(s + strlen(s), sizeof(s) - strlen(s), " parity: %s", card->ParityValid ? "valid" : "invalid");

View file

@ -43,6 +43,6 @@ void HIDListFormats();
int HIDFindCardFormat(const char *format);
cardformat_t HIDGetCardFormat(int idx);
bool HIDPack(int FormatIndex, wiegand_card_t *card, wiegand_message_t *packed);
bool HIDTryUnpack(wiegand_message_t *packed, bool ignoreParity);
bool HIDTryUnpack(wiegand_message_t *packed, bool ignore_parity);
#endif

View file

@ -124,6 +124,9 @@ recover(uint32_t *o_head, uint32_t *o_tail, uint32_t oks,
return sl;
}
#if !defined(__arm__) || defined(__linux__) || defined(_WIN32) || defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free()
/** lfsr_recovery
* recover the state of the lfsr given 32 bits of the keystream
* additionally you can use the in parameter to specify the value
@ -286,6 +289,7 @@ continue2:
}
return statelist;
}
#endif
/** lfsr_rollback_bit
* Rollback the shift register in order to get previous states
@ -465,7 +469,7 @@ static struct Crypto1State *check_pfx_parity(uint32_t prefix, uint32_t rresp, ui
return sl + good;
}
#if !defined(__arm__) || defined(__linux__) || defined(_WIN32) || defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free()
/** lfsr_common_prefix
* Implentation of the common prefix attack.
* Requires the 28 bit constant prefix used as reader nonce (pfx)
@ -504,3 +508,4 @@ out:
free(even);
return statelist;
}
#endif

View file

@ -25,23 +25,25 @@
#include <stdbool.h>
struct Crypto1State {uint32_t odd, even;};
#if defined(__arm__) && !defined(__linux__) && !defined(_WIN32) && !defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free()
void crypto1_create(struct Crypto1State *s, uint64_t key);
#else
void crypto1_init(struct Crypto1State *s, uint64_t key);
void crypto1_deinit(struct Crypto1State *);
#if !defined(__arm__) || defined(__linux__) || defined(_WIN32) || defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free()
struct Crypto1State *crypto1_create(uint64_t key);
#endif
void crypto1_destroy(struct Crypto1State *);
#endif
void crypto1_get_lfsr(struct Crypto1State *, uint64_t *);
uint8_t crypto1_bit(struct Crypto1State *, uint8_t, int);
uint8_t crypto1_byte(struct Crypto1State *, uint8_t, int);
uint32_t crypto1_word(struct Crypto1State *, uint32_t, int);
uint32_t prng_successor(uint32_t x, uint32_t n);
#if !defined(__arm__) || defined(__linux__) || defined(_WIN32) || defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free()
struct Crypto1State *lfsr_recovery32(uint32_t ks2, uint32_t in);
struct Crypto1State *lfsr_recovery64(uint32_t ks2, uint32_t ks3);
uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd);
struct Crypto1State *
lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8], uint32_t no_par);
#endif
uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd);
uint8_t lfsr_rollback_bit(struct Crypto1State *s, uint32_t in, int fb);

View file

@ -25,38 +25,37 @@
#define SWAPENDIAN(x)\
(x = (x >> 8 & 0xff00ff) | (x & 0xff00ff) << 8, x = x >> 16 | x << 16)
#if defined(__arm__) && !defined(__linux__) && !defined(_WIN32) && !defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free()
void crypto1_create(struct Crypto1State *s, uint64_t key) {
void crypto1_init(struct Crypto1State *state, uint64_t key) {
state->odd = 0;
state->even = 0;
int i;
for (i = 47; s && i > 0; i -= 2) {
s->odd = s->odd << 1 | BIT(key, (i - 1) ^ 7);
s->even = s->even << 1 | BIT(key, i ^ 7);
for (i = 47; state && i > 0; i -= 2) {
state->odd = state->odd << 1 | BIT(key, (i - 1) ^ 7);
state->even = state->even << 1 | BIT(key, i ^ 7);
}
return;
}
void crypto1_destroy(struct Crypto1State *state) {
void crypto1_deinit(struct Crypto1State *state) {
state->odd = 0;
state->even = 0;
}
#else
#if !defined(__arm__) || defined(__linux__) || defined(_WIN32) || defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free()
struct Crypto1State *crypto1_create(uint64_t key) {
struct Crypto1State *s = malloc(sizeof(*s));
if (!s) return NULL;
s->odd = s->even = 0;
int i;
for (i = 47; i > 0; i -= 2) {
s->odd = s->odd << 1 | BIT(key, (i - 1) ^ 7);
s->even = s->even << 1 | BIT(key, i ^ 7);
}
return s;
struct Crypto1State *state = malloc(sizeof(*state));
if (!state) return NULL;
crypto1_init(state, key);
return state;
}
void crypto1_destroy(struct Crypto1State *state) {
free(state);
}
#endif
void crypto1_get_lfsr(struct Crypto1State *state, uint64_t *lfsr) {
int i;
for (*lfsr = 0, i = 23; i >= 0; --i) {

View file

@ -16,7 +16,8 @@ Always use the latest repository commits from *master* branch. There are always
* [Troubles with SIM card reader](#troubles-with-sim-card-reader)
* [Troubles with t5577 commands or MFC/iClass/T55x7 dictionaries](#troubles-with-t5577-commands-or-mfciclasst55x7-dictionaries)
* [File not found](#file-not-found)
* [pixmap / pixbuf warnings](#pixmap--pixbuf-warnings)
* [Pixmap / pixbuf warnings](#pixmap--pixbuf-warnings)
* [Usb cable](#usb-cable)
## `pm3` or `pm3-flash*` doesn't see my Proxmark
@ -154,6 +155,12 @@ pm3 --> sc upgrade f ../tools/simmodule/sim011.bin
etc.
## pixmap / pixbuf warnings
## Pixmap / pixbuf warnings
If you get warnings related to pixmap or pixbuf such as *Pixbuf theme: Cannot load pixmap file* or *Invalid borders specified for theme pixmap*, it's a problem of your Theme, try another one and the problem should vanish. See e.g. [#354](https://github.com/RfidResearchGroup/proxmark3/issues/354) (Yaru theme on Ubuntu) and [#386](https://github.com/RfidResearchGroup/proxmark3/issues/386) (Kali-X theme on Kali).
## Usb cable
It's needed to have a good USB cable to connect Proxmark3 to USB. If you have stability problems (Proxmark3 resets, firmware hangs, especially firmware hangs just after start, etc.)
- check your cable with a USB tester (or try to change it). It needs to have a resistance smaller or equal to 0.3 Ohm.

View file

@ -34,7 +34,7 @@ typedef struct {
uint8_t signature[32];
uint8_t counter_tearing[3][4]; // 3 bytes counter, 1 byte tearing flag
uint8_t data[1024];
} mfu_dump_t;
} PACKED mfu_dump_t;
//-----------------------------------------------------------------------------
// ISO 14443A
@ -69,7 +69,7 @@ typedef struct {
uint16_t modulation_n;
uint32_t ProxToAirDuration;
uint8_t par; // enough for precalculated parity of 8 Byte responses
} tag_response_info_t;
} PACKED tag_response_info_t;
//-----------------------------------------------------------------------------
// ISO 14443B
//-----------------------------------------------------------------------------
@ -79,7 +79,7 @@ typedef struct {
uint8_t atqb[7];
uint8_t chipid;
uint8_t cid;
} __attribute__((__packed__)) iso14b_card_select_t;
} PACKED iso14b_card_select_t;
typedef enum ISO14B_COMMAND {
ISO14B_CONNECT = (1 << 0),
@ -121,7 +121,7 @@ typedef struct {
FIRST,
SECOND,
} state;
} nonces_t;
} PACKED nonces_t;
//-----------------------------------------------------------------------------
// ISO 7618 Smart Card

View file

@ -27,4 +27,5 @@ HID-weak-fob-11647.pm3: HID 32bit Prox Card#: 11647. very weak tag/read but jus
visa2000.pm3: VISA2000 ASK/MAN RF/64, Card: 480518
securakey-64169.pm3 Securakey Tag BitLen: 26, Card ID: 64169, FC: 0x35
motorola_0437_00072.pm3 - Motorola Grey clamshell card, old. (RAW: A0000000E308C0C1)
motorola_0437_00072.pm3: Motorola Grey clamshell card, old. (RAW: A0000000E308C0C1)
verichip_1022000000084146.pm3: VeriChip, epoxy encased glasschip (ID: 1022-00000000084146)

File diff suppressed because it is too large Load diff