mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-05-12 11:18:11 -07:00
Merge branch 'RfidResearchGroup:master' into master
This commit is contained in:
@@ -3,6 +3,20 @@ All notable changes to this project will be documented in this file.
|
||||
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
||||
|
||||
## [unreleased][unreleased]
|
||||
|
||||
## [Seven.4.16717][2023-06-25]
|
||||
- Change `hf 14a info` - now identifes QL88 tags (@iceman1001)
|
||||
- Added support for compiling on iOS (@The-SamminAter)
|
||||
- Fixed viewing MFC dump - border char is now white (@iceman1001)
|
||||
- Changed `data diff` - to print filenames in header if it fits (@iceman1001)
|
||||
- Changed viewing MFC dump files - it now colors ACL + GPB bytes (@iceman1001)
|
||||
- Added `hf mf supercard --furui` - now supports key recovery from Furui detection card. Thanks foxushka! (@iceman1001)
|
||||
- Added `hf topaz dump --ns` - now supports nosave param (@iceman1001)
|
||||
- Changed `hf topaz rdbl` - unified output (@iceman1001)
|
||||
- Fixed `hf topaz wrbl` - now supports tear off and write_nonerase command (@iceman1001)
|
||||
- Fixed `hf mf` commands (@iceman1001)
|
||||
- Fixed `hf mfp` commands (@iceman1001)
|
||||
- Added more default keys (@iceman1001) Thanks anon!
|
||||
- Fixed `pm3-flash-all` shell script now correctly identify the if running on outdated bootloader (@iceman1001)
|
||||
- Fixed `hf 15693/iclass sniff` trace timings (@nvx)
|
||||
- Fix LegicCash segment handling in `hf_legic.lua` script (@jmichelp)
|
||||
|
||||
+13
-1
@@ -75,7 +75,15 @@ else
|
||||
endif
|
||||
|
||||
ifeq ($(platform),Darwin)
|
||||
USE_BREW ?= 1
|
||||
ifeq ($(shell uname -p),arm64)
|
||||
# The platform is iOS
|
||||
USE_BREW ?= 0
|
||||
# iOS refuses to compile unless this is set
|
||||
export IPHONEOS_DEPLOYMENT_TARGET=11.0
|
||||
else
|
||||
# M* macOS devices return arm
|
||||
USE_BREW ?= 1
|
||||
endif
|
||||
USE_MACPORTS ?= 0
|
||||
AR= /usr/bin/ar rcs
|
||||
RANLIB= /usr/bin/ranlib
|
||||
@@ -132,6 +140,10 @@ ifeq ($(shell expr $(CC_VERSION) \>= 10), 1)
|
||||
endif
|
||||
endif
|
||||
ifeq ($(platform),Darwin)
|
||||
ifeq ($(shell uname -p),arm64)
|
||||
# iOS will refuse to compile without the minimum target of iOS 11.0
|
||||
DEFCFLAGS += -mios-version-min=11.0
|
||||
endif
|
||||
# their readline has strict-prototype issues
|
||||
DEFCFLAGS += -Wno-strict-prototypes
|
||||
# some warnings about braced initializers on structs we want to ignore
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Iceman Fork - Proxmark3 a RFID / NFC project.
|
||||
# Iceman Fork - Proxmark3
|
||||
|
||||
The Proxmark3 is the swiss-army tool of RFID, allowing for interactions with the vast majority of RFID tags on a global scale. Originally built by Jonathan Westhues, the device is now the goto tool for RFID Analysis for the enthusiast. Iceman repository is considered to be the pinnacle of features and functionality, enabling a huge range of extremely useful and convenient commands and LUA scripts to automate chip identification, penetration testing, and programming
|
||||
|
||||
|
||||
+26
-6
@@ -3094,13 +3094,33 @@ void ReaderIso14443a(PacketCommandNG *c) {
|
||||
}
|
||||
}
|
||||
|
||||
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred
|
||||
FpgaDisableTracing();
|
||||
reply_mix(CMD_ACK, 0, 0, 0, NULL, 0);
|
||||
if ((param & ISO14A_TOPAZMODE)) {
|
||||
|
||||
if (cmd[0] == TOPAZ_WRITE_E8 || cmd[0] == TOPAZ_WRITE_NE8) {
|
||||
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred
|
||||
FpgaDisableTracing();
|
||||
reply_mix(CMD_ACK, 0, 0, 0, NULL, 0);
|
||||
} else {
|
||||
arg0 = ReaderReceive(buf, par);
|
||||
FpgaDisableTracing();
|
||||
reply_old(CMD_ACK, arg0, 0, 0, buf, sizeof(buf));
|
||||
}
|
||||
} else {
|
||||
arg0 = ReaderReceive(buf, par);
|
||||
FpgaDisableTracing();
|
||||
reply_old(CMD_ACK, arg0, 0, 0, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
} else {
|
||||
arg0 = ReaderReceive(buf, par);
|
||||
FpgaDisableTracing();
|
||||
reply_old(CMD_ACK, arg0, 0, 0, buf, sizeof(buf));
|
||||
|
||||
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred
|
||||
FpgaDisableTracing();
|
||||
reply_mix(CMD_ACK, 0, 0, 0, NULL, 0);
|
||||
} else {
|
||||
arg0 = ReaderReceive(buf, par);
|
||||
FpgaDisableTracing();
|
||||
reply_old(CMD_ACK, arg0, 0, 0, buf, sizeof(buf));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+14
-14
@@ -1835,20 +1835,20 @@ void SniffIso15693(uint8_t jam_search_len, uint8_t *jam_search_string, bool icla
|
||||
switch_off();
|
||||
|
||||
DbpString("");
|
||||
DbpString(_CYAN_("Sniff statistics"));
|
||||
DbpString("=================================");
|
||||
Dbprintf(" DecodeTag State........%d", dtag.state);
|
||||
Dbprintf(" DecodeTag byteCnt......%d", dtag.len);
|
||||
Dbprintf(" DecodeTag posCount.....%d", dtag.posCount);
|
||||
Dbprintf(" DecodeTagFSK State.....%d", dtagfsk.state);
|
||||
Dbprintf(" DecodeTagFSK byteCnt...%d", dtagfsk.len);
|
||||
Dbprintf(" DecodeTagFSK count.....%d", dtagfsk.count);
|
||||
Dbprintf(" DecodeReader State.....%d", dreader.state);
|
||||
Dbprintf(" DecodeReader byteCnt...%d", dreader.byteCount);
|
||||
Dbprintf(" DecodeReader posCount..%d", dreader.posCount);
|
||||
Dbprintf(" Trace length..........." _YELLOW_("%d"), BigBuf_get_traceLen());
|
||||
DbpString("");
|
||||
|
||||
if (g_dbglevel > DBG_ERROR) {
|
||||
DbpString(_CYAN_("Sniff statistics"));
|
||||
DbpString("=================================");
|
||||
Dbprintf("DecodeTag State........ %d", dtag.state);
|
||||
Dbprintf("DecodeTag byteCnt...... %d", dtag.len);
|
||||
Dbprintf("DecodeTag posCount..... %d", dtag.posCount);
|
||||
Dbprintf("DecodeTagFSK State..... %d", dtagfsk.state);
|
||||
Dbprintf("DecodeTagFSK byteCnt... %d", dtagfsk.len);
|
||||
Dbprintf("DecodeTagFSK count..... %d", dtagfsk.count);
|
||||
Dbprintf("DecodeReader State..... %d", dreader.state);
|
||||
Dbprintf("DecodeReader byteCnt... %d", dreader.byteCount);
|
||||
Dbprintf("DecodeReader posCount.. %d", dreader.posCount);
|
||||
}
|
||||
Dbprintf("Trace length........... " _YELLOW_("%d"), BigBuf_get_traceLen());
|
||||
}
|
||||
|
||||
// Initialize Proxmark3 as ISO15693 reader
|
||||
|
||||
+115
-63
@@ -484,8 +484,8 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) {
|
||||
if (res == PM3_ETEAROFF) {
|
||||
retval = PM3_ETEAROFF;
|
||||
goto OUT;
|
||||
} else if (res) {
|
||||
if (g_dbglevel >= DBG_ERROR) Dbprintf("Write block error");
|
||||
} else if (res != PM3_SUCCESS) {
|
||||
if (g_dbglevel >= DBG_INFO) Dbprintf("Write block error");
|
||||
retval = PM3_ESOFT;
|
||||
goto OUT;
|
||||
}
|
||||
@@ -554,7 +554,7 @@ void MifareWriteBlockGDM(uint8_t blockno, uint8_t keytype, uint8_t *key, uint8_t
|
||||
if (res == PM3_ETEAROFF) {
|
||||
retval = PM3_ETEAROFF;
|
||||
goto OUT;
|
||||
} else if (res) {
|
||||
} else if (res != PM3_SUCCESS) {
|
||||
retval = PM3_ESOFT;
|
||||
goto OUT;
|
||||
}
|
||||
@@ -688,8 +688,8 @@ void MifareValue(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) {
|
||||
break;
|
||||
};
|
||||
|
||||
if (mifare_classic_value(pcs, cuid, blockNo, blockdata, action)) {
|
||||
if (g_dbglevel >= DBG_ERROR) Dbprintf("Write block error");
|
||||
if (mifare_classic_value(pcs, cuid, blockNo, blockdata, action) != PM3_SUCCESS) {
|
||||
if (g_dbglevel >= DBG_INFO) Dbprintf("Write block error");
|
||||
break;
|
||||
};
|
||||
|
||||
@@ -777,8 +777,8 @@ static void MifareUWriteBlockEx(uint8_t arg0, uint8_t arg1, uint8_t *datain, boo
|
||||
}
|
||||
}
|
||||
|
||||
if (mifare_ultra_writeblock(blockNo, blockdata)) {
|
||||
if (g_dbglevel >= DBG_ERROR) Dbprintf("Write block error");
|
||||
if (mifare_ultra_writeblock(blockNo, blockdata) != PM3_SUCCESS) {
|
||||
if (g_dbglevel >= DBG_INFO) Dbprintf("Write block error");
|
||||
OnError(0);
|
||||
return;
|
||||
};
|
||||
@@ -851,8 +851,8 @@ void MifareUWriteBlockCompat(uint8_t arg0, uint8_t arg1, uint8_t *datain) {
|
||||
}
|
||||
}
|
||||
|
||||
if (mifare_ultra_writeblock_compat(blockNo, blockdata)) {
|
||||
if (g_dbglevel >= DBG_ERROR) Dbprintf("Write block error");
|
||||
if (mifare_ultra_writeblock_compat(blockNo, blockdata) != PM3_SUCCESS) {
|
||||
if (g_dbglevel >= DBG_INFO) Dbprintf("Write block error");
|
||||
OnError(0);
|
||||
return;
|
||||
};
|
||||
@@ -896,8 +896,8 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain) {
|
||||
blockdata[1] = pwd[6];
|
||||
blockdata[2] = pwd[5];
|
||||
blockdata[3] = pwd[4];
|
||||
if (mifare_ultra_writeblock(44, blockdata)) {
|
||||
if (g_dbglevel >= DBG_ERROR) Dbprintf("Write block error");
|
||||
if (mifare_ultra_writeblock(44, blockdata) != PM3_SUCCESS) {
|
||||
if (g_dbglevel >= DBG_INFO) Dbprintf("Write block error");
|
||||
OnError(44);
|
||||
return;
|
||||
};
|
||||
@@ -906,8 +906,8 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain) {
|
||||
blockdata[1] = pwd[2];
|
||||
blockdata[2] = pwd[1];
|
||||
blockdata[3] = pwd[0];
|
||||
if (mifare_ultra_writeblock(45, blockdata)) {
|
||||
if (g_dbglevel >= DBG_ERROR) Dbprintf("Write block error");
|
||||
if (mifare_ultra_writeblock(45, blockdata) != PM3_SUCCESS) {
|
||||
if (g_dbglevel >= DBG_INFO) Dbprintf("Write block error");
|
||||
OnError(45);
|
||||
return;
|
||||
};
|
||||
@@ -916,8 +916,8 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain) {
|
||||
blockdata[1] = pwd[14];
|
||||
blockdata[2] = pwd[13];
|
||||
blockdata[3] = pwd[12];
|
||||
if (mifare_ultra_writeblock(46, blockdata)) {
|
||||
if (g_dbglevel >= DBG_ERROR) Dbprintf("Write block error");
|
||||
if (mifare_ultra_writeblock(46, blockdata) != PM3_SUCCESS) {
|
||||
if (g_dbglevel >= DBG_INFO) Dbprintf("Write block error");
|
||||
OnError(46);
|
||||
return;
|
||||
};
|
||||
@@ -926,8 +926,8 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain) {
|
||||
blockdata[1] = pwd[10];
|
||||
blockdata[2] = pwd[9];
|
||||
blockdata[3] = pwd[8];
|
||||
if (mifare_ultra_writeblock(47, blockdata)) {
|
||||
if (g_dbglevel >= DBG_ERROR) Dbprintf("Write block error");
|
||||
if (mifare_ultra_writeblock(47, blockdata) != PM3_SUCCESS) {
|
||||
if (g_dbglevel >= DBG_INFO) Dbprintf("Write block error");
|
||||
OnError(47);
|
||||
return;
|
||||
};
|
||||
@@ -1522,7 +1522,6 @@ void MifareStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo,
|
||||
target_ks[0] = nt2 ^ target_nt[0];
|
||||
|
||||
// second collection
|
||||
|
||||
if (mifare_classic_halt(pcs, cuid)) {
|
||||
continue;
|
||||
}
|
||||
@@ -2303,64 +2302,98 @@ int MifareECardLoadExt(uint8_t sectorcnt, uint8_t keytype) {
|
||||
|
||||
int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype) {
|
||||
|
||||
uint32_t cuid = 0;
|
||||
struct Crypto1State mpcs = {0, 0};
|
||||
struct Crypto1State *pcs;
|
||||
pcs = &mpcs;
|
||||
|
||||
// variables
|
||||
uint8_t dataoutbuf[16] = {0x00};
|
||||
uint8_t dataoutbuf2[16] = {0x00};
|
||||
uint8_t uid[10] = {0x00};
|
||||
|
||||
LED_A_ON();
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
|
||||
clear_trace();
|
||||
set_tracing(true);
|
||||
|
||||
// variables
|
||||
bool have_uid = false;
|
||||
uint8_t cascade_levels = 0;
|
||||
uint32_t cuid = 0;
|
||||
uint8_t uid[10] = {0x00};
|
||||
struct Crypto1State mpcs = {0, 0};
|
||||
struct Crypto1State *pcs;
|
||||
pcs = &mpcs;
|
||||
|
||||
int retval = PM3_SUCCESS;
|
||||
|
||||
if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {
|
||||
retval = PM3_ESOFT;
|
||||
if (g_dbglevel > DBG_ERROR) Dbprintf("Can't select card");
|
||||
goto out;
|
||||
}
|
||||
for (uint8_t s = 0; s < sectorcnt; s++) {
|
||||
uint64_t ui64Key = emlGetKey(s, keytype);
|
||||
|
||||
for (uint8_t sectorNo = 0; sectorNo < sectorcnt; sectorNo++) {
|
||||
uint64_t ui64Key = emlGetKey(sectorNo, keytype);
|
||||
if (sectorNo == 0) {
|
||||
if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keytype, ui64Key, AUTH_FIRST)) {
|
||||
retval = PM3_EPARTIAL;
|
||||
if (g_dbglevel > DBG_ERROR) Dbprintf("Sector[%2d]. Auth error", sectorNo);
|
||||
// MFC 1K EV1 sector 16,17 don't use key A.
|
||||
if ((sectorcnt == 18) && (keytype == 0) && s > 15) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// use fast select
|
||||
if (have_uid == false) { // need a full select cycle to get the uid first
|
||||
iso14a_card_select_t card_info;
|
||||
if (iso14443a_select_card(uid, &card_info, &cuid, true, 0, true) == 0) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keytype, ui64Key, AUTH_NESTED)) {
|
||||
retval = PM3_EPARTIAL;
|
||||
if (g_dbglevel > DBG_ERROR) Dbprintf("Sector[%2d]. Auth nested error", sectorNo);
|
||||
|
||||
switch (card_info.uidlen) {
|
||||
case 4 :
|
||||
cascade_levels = 1;
|
||||
break;
|
||||
case 7 :
|
||||
cascade_levels = 2;
|
||||
break;
|
||||
case 10:
|
||||
cascade_levels = 3;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
have_uid = true;
|
||||
} else { // no need for anticollision. We can directly select the card
|
||||
if (iso14443a_fast_select_card(uid, cascade_levels) == 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t blockNo = 0; blockNo < NumBlocksPerSector(sectorNo); blockNo++) {
|
||||
if (mifare_classic_readblock(pcs, cuid, FirstBlockOfSector(sectorNo) + blockNo, dataoutbuf)) {
|
||||
retval = PM3_EPARTIAL;
|
||||
|
||||
if (g_dbglevel > DBG_ERROR) Dbprintf("Error reading sector %2d block %2d", sectorNo, blockNo);
|
||||
continue;
|
||||
// Auth
|
||||
if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(s), keytype, ui64Key, AUTH_FIRST)) {
|
||||
retval = PM3_EPARTIAL;
|
||||
if (g_dbglevel > DBG_ERROR) {
|
||||
Dbprintf("Sector %2d - Auth error", s);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (memcmp(dataoutbuf, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16) == 0) {
|
||||
continue;
|
||||
}
|
||||
#define MAX_RETRIES 2
|
||||
|
||||
if (blockNo < NumBlocksPerSector(sectorNo) - 1) {
|
||||
emlSetMem(dataoutbuf, FirstBlockOfSector(sectorNo) + blockNo, 1);
|
||||
} else { // sector trailer, keep the keys, set only the AC
|
||||
emlGetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1);
|
||||
memcpy(dataoutbuf2 + 6, dataoutbuf + 6, 4);
|
||||
emlSetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1);
|
||||
uint8_t data[16] = {0x00};
|
||||
for (uint8_t b = 0; b < NumBlocksPerSector(s); b++) {
|
||||
|
||||
memset(data, 0x00, sizeof(data));
|
||||
|
||||
for (uint8_t r = 0; r < MAX_RETRIES; r++) {
|
||||
|
||||
if (mifare_classic_readblock(pcs, cuid, FirstBlockOfSector(s) + b, data)) {
|
||||
retval |= PM3_EPARTIAL;
|
||||
if (g_dbglevel > DBG_ERROR) {
|
||||
Dbprintf("Error reading sector %2d block %2d", s, b);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// No need to copy empty
|
||||
if (memcmp(data, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (b < NumBlocksPerSector(s) - 1) {
|
||||
emlSetMem(data, FirstBlockOfSector(s) + b, 1);
|
||||
} else {
|
||||
// sector trailer, keep the keys, set only the AC
|
||||
uint8_t st[16] = {0x00};
|
||||
emlGetMem(st, FirstBlockOfSector(s) + b, 1);
|
||||
memcpy(st + 6, data + 6, 4);
|
||||
emlSetMem(st, FirstBlockOfSector(s) + b, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2368,9 +2401,6 @@ int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype) {
|
||||
int res = mifare_classic_halt(pcs, cuid);
|
||||
(void)res;
|
||||
|
||||
if (g_dbglevel >= DBG_INFO) DbpString("Emulator fill sectors finished");
|
||||
|
||||
out:
|
||||
crypto1_deinit(pcs);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LEDsoff();
|
||||
@@ -2601,6 +2631,7 @@ void MifareCIdent(bool is_mfc) {
|
||||
uint8_t gen4gmd[4] = {MIFARE_MAGIC_GDM_AUTH_KEY, 0x00, 0x6C, 0x92};
|
||||
uint8_t gen4GetConf[8] = {GEN_4GTU_CMD, 0x00, 0x00, 0x00, 0x00, GEN_4GTU_GETCNF, 0, 0};
|
||||
uint8_t superGen1[9] = {0x0A, 0x00, 0x00, 0xA6, 0xB0, 0x00, 0x10, 0x14, 0x1D};
|
||||
|
||||
uint8_t *par = BigBuf_malloc(MAX_PARITY_SIZE);
|
||||
uint8_t *buf = BigBuf_malloc(PM3_CMD_DATA_SIZE);
|
||||
uint8_t *uid = BigBuf_malloc(10);
|
||||
@@ -2757,7 +2788,24 @@ void MifareCIdent(bool is_mfc) {
|
||||
isGen = MAGIC_GEN_4GDM;
|
||||
}
|
||||
}
|
||||
|
||||
if (isGen != MAGIC_GEN_4GDM) {
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
SpinDelay(40);
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true);
|
||||
if (res == 2) {
|
||||
struct Crypto1State mpcs = {0, 0};
|
||||
struct Crypto1State *pcs;
|
||||
pcs = &mpcs;
|
||||
if (mifare_classic_authex(pcs, cuid, 68, MF_KEY_B, 0x707B11FC1481, AUTH_FIRST, NULL, NULL) == 0) {
|
||||
isGen = MAGIC_QL88;
|
||||
}
|
||||
crypto1_deinit(pcs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2836,6 +2884,10 @@ OUT:
|
||||
crypto1_deinit(pcs);
|
||||
}
|
||||
|
||||
// FUDAN card w static encrypted nonces
|
||||
// 2B F9 1C 1B D5 08 48 48 03 A4 B1 B1 75 FF 2D 90
|
||||
// ^^ ^^
|
||||
|
||||
void OnSuccessMagic(void) {
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LEDsoff();
|
||||
@@ -3218,7 +3270,7 @@ void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain) {
|
||||
return;
|
||||
};
|
||||
|
||||
if (mifare_desfire_des_auth1(cuid, dataout)) {
|
||||
if (mifare_desfire_des_auth1(cuid, dataout) != PM3_SUCCESS) {
|
||||
if (g_dbglevel >= DBG_ERROR) Dbprintf("Authentication part1: Fail.");
|
||||
OnError(4);
|
||||
return;
|
||||
@@ -3238,7 +3290,7 @@ void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain) {
|
||||
|
||||
isOK = mifare_desfire_des_auth2(cuid, key, dataout);
|
||||
|
||||
if (isOK) {
|
||||
if (isOK != PM3_SUCCESS) {
|
||||
if (g_dbglevel >= DBG_EXTENDED) Dbprintf("Authentication part2: Failed");
|
||||
OnError(4);
|
||||
return;
|
||||
|
||||
+23
-2
@@ -46,6 +46,15 @@
|
||||
#include "dbprint.h"
|
||||
#include "ticks.h"
|
||||
|
||||
static bool IsKeyBReadable(uint8_t blockNo) {
|
||||
uint8_t sector_trailer[16];
|
||||
emlGetMem(sector_trailer, SectorTrailer(blockNo), 1);
|
||||
uint8_t AC = ((sector_trailer[7] >> 5) & 0x04)
|
||||
| ((sector_trailer[8] >> 2) & 0x02)
|
||||
| ((sector_trailer[8] >> 7) & 0x01);
|
||||
return (AC == 0x00 || AC == 0x01 || AC == 0x02);
|
||||
}
|
||||
|
||||
static bool IsTrailerAccessAllowed(uint8_t blockNo, uint8_t keytype, uint8_t action) {
|
||||
uint8_t sector_trailer[16];
|
||||
emlGetMem(sector_trailer, blockNo, 1);
|
||||
@@ -872,8 +881,8 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
|
||||
break;
|
||||
}
|
||||
*/
|
||||
|
||||
if (MifareBlockToSector(receivedCmd_dec[1]) != cardAUTHSC) {
|
||||
blockNo = receivedCmd_dec[1];
|
||||
if (MifareBlockToSector(blockNo) != cardAUTHSC) {
|
||||
EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA));
|
||||
FpgaDisableTracing();
|
||||
|
||||
@@ -881,6 +890,18 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
|
||||
Dbprintf("[MFEMUL_WORK] Reader tried to operate (0x%02x) on block (0x%02x) not authenticated for (0x%02x), nacking", receivedCmd_dec[0], receivedCmd_dec[1], cardAUTHSC);
|
||||
break;
|
||||
}
|
||||
|
||||
// Compliance of MIFARE Classic EV1 1K Datasheet footnote of Table 8
|
||||
// If access bits show that key B is Readable, any subsequent memory access will be refused.
|
||||
|
||||
if (cardAUTHKEY == AUTHKEYB && IsKeyBReadable(blockNo)) {
|
||||
EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA));
|
||||
FpgaDisableTracing();
|
||||
|
||||
if (g_dbglevel >= DBG_ERROR)
|
||||
Dbprintf("[MFEMUL_WORK] Access denied: Reader tried to access memory on authentication with key B while key B is readable in sector (0x%02x)", cardAUTHSC);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// case MFEMUL_WORK => CMD READ block
|
||||
|
||||
+36
-33
@@ -433,8 +433,8 @@ int mifare_classic_writeblock_ex(struct Crypto1State *pcs, uint32_t uid, uint8_t
|
||||
}
|
||||
|
||||
if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
|
||||
if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
|
||||
return 1;
|
||||
if (g_dbglevel >= DBG_INFO) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
|
||||
return PM3_EFAILED;
|
||||
}
|
||||
|
||||
uint8_t d_block[18], d_block_enc[18];
|
||||
@@ -465,11 +465,11 @@ int mifare_classic_writeblock_ex(struct Crypto1State *pcs, uint32_t uid, uint8_t
|
||||
res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 3)) << 3;
|
||||
|
||||
if ((len != 1) || (res != 0x0A)) {
|
||||
if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd send data2 Error: %02x", res);
|
||||
return 2;
|
||||
if (g_dbglevel >= DBG_INFO) Dbprintf("Cmd send data2 Error: %02x", res);
|
||||
return PM3_EFAILED;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
int mifare_classic_write_cfg_block_gdm(struct Crypto1State *pcs, uint32_t uid, uint8_t *blockData) {
|
||||
@@ -480,7 +480,7 @@ int mifare_classic_write_cfg_block_gdm(struct Crypto1State *pcs, uint32_t uid, u
|
||||
|
||||
uint16_t len = mifare_sendcmd_short(pcs, 1, MIFARE_MAGIC_GDM_WRITE_CFG, 0, receivedAnswer, receivedAnswerPar, NULL);
|
||||
if ((len != 1) || (receivedAnswer[0] != 0x0A)) {
|
||||
return 1;
|
||||
return PM3_EFAILED;
|
||||
}
|
||||
|
||||
uint8_t d_block[18], d_block_enc[18];
|
||||
@@ -511,14 +511,12 @@ int mifare_classic_write_cfg_block_gdm(struct Crypto1State *pcs, uint32_t uid, u
|
||||
res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 3)) << 3;
|
||||
|
||||
if ((len != 1) || (res != 0x0A)) {
|
||||
return 2;
|
||||
return PM3_EFAILED;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int mifare_classic_value(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData, uint8_t action) {
|
||||
// variables
|
||||
uint16_t len = 0;
|
||||
@@ -540,8 +538,8 @@ int mifare_classic_value(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo
|
||||
len = mifare_sendcmd_short(pcs, 1, command, blockNo, receivedAnswer, receivedAnswerPar, NULL);
|
||||
|
||||
if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
|
||||
if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
|
||||
return 1;
|
||||
if (g_dbglevel >= DBG_INFO) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
|
||||
return PM3_EFAILED;
|
||||
}
|
||||
|
||||
memcpy(d_block, blockData, 4);
|
||||
@@ -566,12 +564,12 @@ int mifare_classic_value(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo
|
||||
res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 3)) << 3;
|
||||
|
||||
if ((len != 1) || (res != 0x0A)) {
|
||||
if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd send data2 Error: %02x", res);
|
||||
return 2;
|
||||
if (g_dbglevel >= DBG_INFO) Dbprintf("Cmd send data2 Error: %02x", res);
|
||||
return PM3_EFAILED;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
int mifare_ultra_writeblock_compat(uint8_t blockNo, uint8_t *blockData) {
|
||||
@@ -585,9 +583,10 @@ int mifare_ultra_writeblock_compat(uint8_t blockNo, uint8_t *blockData) {
|
||||
len = mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL);
|
||||
|
||||
if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK
|
||||
if (g_dbglevel >= DBG_ERROR)
|
||||
if (g_dbglevel >= DBG_INFO) {
|
||||
Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0], len);
|
||||
return 1;
|
||||
}
|
||||
return PM3_EFAILED;
|
||||
}
|
||||
|
||||
memcpy(d_block, blockData, 16);
|
||||
@@ -599,11 +598,12 @@ int mifare_ultra_writeblock_compat(uint8_t blockNo, uint8_t *blockData) {
|
||||
len = ReaderReceive(receivedAnswer, receivedAnswerPar);
|
||||
|
||||
if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK
|
||||
if (g_dbglevel >= DBG_ERROR)
|
||||
if (g_dbglevel >= DBG_INFO) {
|
||||
Dbprintf("Cmd Send Data Error: %02x %d", receivedAnswer[0], len);
|
||||
return 2;
|
||||
}
|
||||
return PM3_EFAILED;
|
||||
}
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData) {
|
||||
@@ -618,11 +618,12 @@ int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData) {
|
||||
len = mifare_sendcmd(MIFARE_ULC_WRITE, block, sizeof(block), receivedAnswer, receivedAnswerPar, NULL);
|
||||
|
||||
if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK
|
||||
if (g_dbglevel >= DBG_ERROR)
|
||||
if (g_dbglevel >= DBG_INFO) {
|
||||
Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0], len);
|
||||
return 1;
|
||||
}
|
||||
return PM3_EFAILED;
|
||||
}
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
int mifare_classic_halt_ex(struct Crypto1State *pcs) {
|
||||
uint8_t receivedAnswer[4] = {0x00, 0x00, 0x00, 0x00};
|
||||
@@ -729,8 +730,8 @@ int emlSetValBl(uint32_t blReg, uint8_t blBlock, int blockNum) {
|
||||
|
||||
uint64_t emlGetKey(int sectorNum, int keyType) {
|
||||
uint8_t key[6] = {0x00};
|
||||
uint8_t *emCARD = BigBuf_get_EM_addr();
|
||||
memcpy(key, emCARD + 16 * (FirstBlockOfSector(sectorNum) + NumBlocksPerSector(sectorNum) - 1) + keyType * 10, 6);
|
||||
uint8_t *em = BigBuf_get_EM_addr();
|
||||
memcpy(key, em + 16 * (FirstBlockOfSector(sectorNum) + NumBlocksPerSector(sectorNum) - 1) + keyType * 10, 6);
|
||||
return bytes_to_num(key, 6);
|
||||
}
|
||||
|
||||
@@ -804,9 +805,10 @@ int mifare_desfire_des_auth1(uint32_t uid, uint8_t *blockData) {
|
||||
|
||||
len = mifare_sendcmd_special(NULL, 1, 0x02, data, receivedAnswer, receivedAnswerPar, NULL);
|
||||
if (len == 1) {
|
||||
if (g_dbglevel >= DBG_ERROR)
|
||||
if (g_dbglevel >= DBG_INFO) {
|
||||
Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
|
||||
return 1;
|
||||
}
|
||||
return PM3_EFAILED;
|
||||
}
|
||||
|
||||
if (len == 12) {
|
||||
@@ -817,9 +819,9 @@ int mifare_desfire_des_auth1(uint32_t uid, uint8_t *blockData) {
|
||||
receivedAnswer[10], receivedAnswer[11]);
|
||||
}
|
||||
memcpy(blockData, receivedAnswer, 12);
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
return 1;
|
||||
return PM3_EFAILED;
|
||||
}
|
||||
|
||||
int mifare_desfire_des_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData) {
|
||||
@@ -834,9 +836,10 @@ int mifare_desfire_des_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData) {
|
||||
len = mifare_sendcmd_special2(NULL, 1, 0x03, data, receivedAnswer, receivedAnswerPar, NULL);
|
||||
|
||||
if ((receivedAnswer[0] == 0x03) && (receivedAnswer[1] == 0xae)) {
|
||||
if (g_dbglevel >= DBG_ERROR)
|
||||
if (g_dbglevel >= DBG_ERROR) {
|
||||
Dbprintf("Auth Error: %02x %02x", receivedAnswer[0], receivedAnswer[1]);
|
||||
return 1;
|
||||
}
|
||||
return PM3_EFAILED;
|
||||
}
|
||||
|
||||
if (len == 12) {
|
||||
@@ -847,7 +850,7 @@ int mifare_desfire_des_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData) {
|
||||
receivedAnswer[10], receivedAnswer[11]);
|
||||
}
|
||||
memcpy(blockData, receivedAnswer, 12);
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
return 1;
|
||||
return PM3_EFAILED;
|
||||
}
|
||||
|
||||
+17
-1
@@ -380,7 +380,23 @@ message(STATUS "CMAKE_SYSTEM_PROCESSOR := ${CMAKE_SYSTEM_PROCESSOR}")
|
||||
if (APPLE)
|
||||
message(STATUS "Apple device detected.")
|
||||
set(ADDITIONAL_SRC ${PM3_ROOT}/client/src/util_darwin.h ${PM3_ROOT}/client/src/util_darwin.m ${ADDITIONAL_SRC})
|
||||
set(ADDITIONAL_LNK "-framework Foundation" "-framework AppKit")
|
||||
|
||||
find_library(UIKIT_LIBRARY UIKit)
|
||||
if (NOT UIKIT_LIBRARY)
|
||||
message(STATUS "UIKit.framework NOT found!")
|
||||
else()
|
||||
message(STATUS "UIKit.framework found! ${UIKIT_LIBRARY}")
|
||||
set(ADDITIONAL_LNK "-framework Foundation" "-framework UIKit")
|
||||
endif()
|
||||
|
||||
find_library(APPKIT_LIBRARY AppKit)
|
||||
if (NOT APPKIT_LIBRARY)
|
||||
message(STATUS "AppKit.framework NOT found!")
|
||||
else()
|
||||
message(STATUS "AppKit.framework found! ${APPKIT_LIBRARY}")
|
||||
set(ADDITIONAL_LNK "-framework Foundation" "-framework AppKit")
|
||||
endif()
|
||||
|
||||
endif (APPLE)
|
||||
|
||||
if ((NOT SKIPQT EQUAL 1) AND (Qt5_FOUND))
|
||||
|
||||
+7
-1
@@ -434,7 +434,13 @@ LDFLAGS += $(MYLDFLAGS)
|
||||
|
||||
PM3LDFLAGS = $(LDFLAGS)
|
||||
ifeq ($(platform),Darwin)
|
||||
PM3LDFLAGS += -framework Foundation -framework AppKit
|
||||
ifeq ($(shell uname -p),arm64)
|
||||
# The platform is iOS
|
||||
PM3LDFLAGS += -framework Foundation -framework UIKit
|
||||
else
|
||||
# M* macOS devices return arm
|
||||
PM3LDFLAGS += -framework Foundation -framework AppKit
|
||||
endif
|
||||
endif
|
||||
|
||||
###################
|
||||
|
||||
@@ -22,6 +22,9 @@ endif
|
||||
ifneq ($(findstring aarch64, $(cpu_arch)), )
|
||||
IS_SIMD_ARCH=arm64
|
||||
endif
|
||||
ifneq ($(findstring iP, $(cpu_arch)), )
|
||||
IS_SIMD_ARCH=arm64
|
||||
endif
|
||||
|
||||
ifneq ($(IS_SIMD_ARCH), )
|
||||
MULTIARCHSRCS = hardnested_bf_core.c hardnested_bitarray_core.c
|
||||
|
||||
@@ -31,6 +31,11 @@ D01AFEEB890A
|
||||
# 17 B
|
||||
4B791BEA7BCC
|
||||
#
|
||||
# QL88 keys
|
||||
# 17 A/B
|
||||
2612C6DE84CA
|
||||
707B11FC1481
|
||||
#
|
||||
#
|
||||
B0B1B2B3B4B5
|
||||
C0C1C2C3C4C5
|
||||
@@ -145,6 +150,9 @@ F1D83F964314
|
||||
222222222222
|
||||
27DD91F1FCF1
|
||||
#
|
||||
# Hotel system
|
||||
505209016A1F
|
||||
#
|
||||
# Directory and eventlog KeyB
|
||||
2BA9621E0A36
|
||||
#
|
||||
|
||||
@@ -37,7 +37,7 @@ A5B4C3D2
|
||||
E9920427
|
||||
# paxton bullit?
|
||||
575F4F4B
|
||||
#
|
||||
# Hotel system
|
||||
50520901
|
||||
# iCopy-X
|
||||
20206666
|
||||
@@ -52,6 +52,8 @@ C0F5009A
|
||||
# prefered pwds of members in the community
|
||||
FEEDBEEF
|
||||
DEADC0DE
|
||||
# derived from BCARD key B
|
||||
A9EF2AFC
|
||||
# Default pwd, simple:
|
||||
00000000
|
||||
11111111
|
||||
|
||||
@@ -380,7 +380,23 @@ message(STATUS "CMAKE_SYSTEM_PROCESSOR := ${CMAKE_SYSTEM_PROCESSOR}")
|
||||
if (APPLE)
|
||||
message(STATUS "Apple device detected.")
|
||||
set(ADDITIONAL_SRC ${PM3_ROOT}/client/src/util_darwin.h ${PM3_ROOT}/client/src/util_darwin.m ${ADDITIONAL_SRC})
|
||||
set(ADDITIONAL_LNK "-framework Foundation" "-framework AppKit")
|
||||
|
||||
find_library(UIKIT_LIBRARY UIKit)
|
||||
if (NOT UIKIT_LIBRARY)
|
||||
message(STATUS "UIKit.framework NOT found!")
|
||||
else()
|
||||
message(STATUS "UIKit.framework found! ${UIKIT_LIBRARY}")
|
||||
set(ADDITIONAL_LNK "-framework Foundation" "-framework UIKit")
|
||||
endif()
|
||||
|
||||
find_library(APPKIT_LIBRARY AppKit)
|
||||
if (NOT APPKIT_LIBRARY)
|
||||
message(STATUS "AppKit.framework NOT found!")
|
||||
else()
|
||||
message(STATUS "AppKit.framework found! ${APPKIT_LIBRARY}")
|
||||
set(ADDITIONAL_LNK "-framework Foundation" "-framework AppKit")
|
||||
endif()
|
||||
|
||||
endif (APPLE)
|
||||
|
||||
if ((NOT SKIPQT EQUAL 1) AND (Qt5_FOUND))
|
||||
|
||||
@@ -2520,11 +2520,11 @@ function modifyMode()
|
||||
---
|
||||
-- edit data-portion of single segment
|
||||
["ed"] = function(x)
|
||||
if (type(x)=="string" and string.len(x)>0) then sel=tonumber(x,10)
|
||||
else sel=selectSegment(inTAG) end
|
||||
if (type(x) == "string" and string.len(x)>0) then sel=tonumber(x,10)
|
||||
else sel = selectSegment(inTAG) end
|
||||
if (istable(inTAG.SEG[sel])) then
|
||||
local uid = inTAG.MCD..inTAG.MSN0..inTAG.MSN1..inTAG.MSN2
|
||||
inTAG.SEG[sel].data=editSegmentData(inTAG.SEG[sel].data, uid)
|
||||
local uid = inTAG.MCD..inTAG.MSN0..inTAG.MSN1..inTAG.MSN2
|
||||
inTAG.SEG[sel].data = editSegmentData(inTAG.SEG[sel].data, uid)
|
||||
end
|
||||
end,
|
||||
---
|
||||
|
||||
@@ -113,7 +113,7 @@ local function getDefault(block0)
|
||||
|
||||
block0 = block0:upper()
|
||||
|
||||
local T55X7_DEFAULT_CONFIG_BLOCK = '000880E8' --// compat mode, RF/32, manchester, STT, 7 data blocks
|
||||
local T55X7_DEFAULT_CONFIG_BLOCK = '000880E8' --// compat mode, RF/32, manchester, STT, 7 data blocks
|
||||
local T55X7_RAW_CONFIG_BLOCK = '000880E0' --// compat mode, RF/32, manchester, 7 data blocks
|
||||
local T55X7_EM_UNIQUE_CONFIG_BLOCK = '00148040' --// emulate em4x02/unique - compat mode, manchester, RF/64, 2 data blocks
|
||||
-- FDXB requires data inversion and BiPhase 57 is simply BipHase 50 inverted, so we can either do it using the modulation scheme or the inversion flag
|
||||
|
||||
@@ -62,21 +62,19 @@ def build_arg_parser():
|
||||
|
||||
|
||||
def build_help_regex():
|
||||
"""The regex uses to parse the full text output of help data from the pm3 client."""
|
||||
# Reads the divider followed by the command itself
|
||||
re_command = r'-{87}\n(?P<command>.+)\n'
|
||||
# Reads if the command is available offline
|
||||
re_offline = r'available offline: (?P<offline>yes|no)\n+'
|
||||
# Reads the description lines
|
||||
re_description = r'(?P<description>(?:.+\n)+)\n+'
|
||||
re_description = r'(?P<description>\n[\s\S]*?(?=usage:))'
|
||||
# Reads the usage string
|
||||
re_usage = r'(?:usage:\n(?P<usage>(?:.+\n)+)\n+)?'
|
||||
# Reads the options and there individual descriptions
|
||||
re_options = r'(?:options:\n(?P<options>(?:.+\n)+)\n+)?'
|
||||
# Reads the notes and examples
|
||||
re_notes = r'(?:examples\/notes:\n(?P<notes>(?:.+\n)+)\n+)?'
|
||||
re_notes = r'(?:examples\/notes:\n(?P<notes>[\s\S]*?(?=(===|---|\n\n))))'
|
||||
# Combine them into a single regex object
|
||||
re_full = re.compile(re_command+re_offline+re_description+re_usage+re_options+re_notes, re.MULTILINE);
|
||||
re_full = re.compile(re_command+re_offline+re_description+re_usage+re_options+re_notes, re.MULTILINE)
|
||||
return re_full
|
||||
|
||||
|
||||
|
||||
@@ -2255,13 +2255,21 @@
|
||||
"Description": "Student ID cards",
|
||||
"Type": "identity"
|
||||
},
|
||||
{
|
||||
"AID": "D2760000254D010200",
|
||||
"Vendor": "Zentraler Kreditausschuss (ZKA)",
|
||||
"Country": "Germany",
|
||||
"Name": "Girocard Jugendschutz",
|
||||
"Description": "Age verification",
|
||||
"Type": "identity"
|
||||
},
|
||||
{
|
||||
"AID": "A000000809434343444B467631",
|
||||
"Vendor": "Car Connectivity Consortium (CCC)",
|
||||
"Country": "",
|
||||
"Name": "Digital Car Key Framework",
|
||||
"Description": "Used during key provisioning and configuration",
|
||||
"Type": "access"
|
||||
"Type": ""
|
||||
},
|
||||
{
|
||||
"AID": "A000000809434343444B417631",
|
||||
@@ -2295,13 +2303,69 @@
|
||||
"Description": "AID prefix used by MIFARE 2GO-based cards",
|
||||
"Type": ""
|
||||
},
|
||||
{
|
||||
"AID": "A00000039656434103F1216000000000",
|
||||
"Vendor": "LV Monorail",
|
||||
"Country": "United States",
|
||||
"Name": "Las Vegas Monorail",
|
||||
"Description": "",
|
||||
"Type": "transport"
|
||||
},
|
||||
{
|
||||
"AID": "A00000039656434103F8852200000000",
|
||||
"Vendor": "Ubian",
|
||||
"Country": "Slovakia",
|
||||
"Name": "Ubian digital transit card",
|
||||
"Description": "DESFire-based virtual transit card",
|
||||
"Type": "transport"
|
||||
},
|
||||
{
|
||||
"AID": "DE5C0D1F1CADA5",
|
||||
"Vendor": "CRTM",
|
||||
"Country": "Spain",
|
||||
"Name": "Madrid transit card",
|
||||
"Description": "DESFire-based transit card",
|
||||
"Type": "transport"
|
||||
},
|
||||
{
|
||||
"AID": "A00000F21100",
|
||||
"Vendor": "PTV",
|
||||
"Country": "Australia",
|
||||
"Name": "Myki transit card",
|
||||
"Description": "DESFire-based transit card",
|
||||
"Type": "transport"
|
||||
},
|
||||
{
|
||||
"AID": "637001ff4c41",
|
||||
"Vendor": "Cubic",
|
||||
"Country": "United States",
|
||||
"Name": "LA Tap",
|
||||
"Description": "DESFire-based transit card (ASCII cp\\x01\\xffLA)",
|
||||
"Type": "transport"
|
||||
},
|
||||
{
|
||||
"AID": "637001ff574d415441",
|
||||
"Vendor": "Cubic",
|
||||
"Country": "United States",
|
||||
"Name": "Smart Trip",
|
||||
"Description": "DESFire-based transit card (ASCII cp\\x01\\xffWMATA)",
|
||||
"Type": "transport"
|
||||
},
|
||||
{
|
||||
"AID": "637001ff434c4950504552",
|
||||
"Vendor": "Cubic",
|
||||
"Country": "United States",
|
||||
"Name": "Clipper",
|
||||
"Description": "DESFire-based transit card (ASCII cp\\x01\\xffCLIPPER)",
|
||||
"Type": "transport"
|
||||
},
|
||||
{
|
||||
"AID": "A0000002164954534F2D31",
|
||||
"Vendor": "ITSO",
|
||||
"Country": "United Kingdom",
|
||||
"Name": "ITSO CMD2",
|
||||
"Description": "AID used by ITSO for smartcard/phone-based transit cards",
|
||||
"Type": "transit"
|
||||
"Type": "transport"
|
||||
},
|
||||
{
|
||||
"AID": "A000000632010105",
|
||||
@@ -2309,22 +2373,38 @@
|
||||
"Country": "China",
|
||||
"Name": "China T-Union",
|
||||
"Description": "Universal transit card used by many big public transit operators",
|
||||
"Type": "transit"
|
||||
},
|
||||
{
|
||||
"AID": "D2760000254D010200",
|
||||
"Vendor": "Zentraler Kreditausschuss (ZKA)",
|
||||
"Country": "Germany",
|
||||
"Name": "Girocard Jugendschutz",
|
||||
"Description": "Age verification",
|
||||
"Type": ""
|
||||
"Type": "transport"
|
||||
},
|
||||
{
|
||||
"AID": "A00000000491",
|
||||
"Vendor": "MasterCard International",
|
||||
"Country": "",
|
||||
"Name": "Mastercard Private Label Transit",
|
||||
"Description": "AID prefix used by transit cards that use private label mastercards (E.g. Ventra and HOP)",
|
||||
"Type": "transit"
|
||||
"Description": "AID prefix used by transit cards that use private label mastercard",
|
||||
"Type": "transport"
|
||||
},
|
||||
{
|
||||
"AID": "A0000000049100",
|
||||
"Vendor": "MasterCard International",
|
||||
"Country": "United States",
|
||||
"Name": "HOP Fastpass",
|
||||
"Description": "",
|
||||
"Type": "transport"
|
||||
},
|
||||
{
|
||||
"AID": "A0000000049101",
|
||||
"Vendor": "MasterCard International",
|
||||
"Country": "United States",
|
||||
"Name": "Ventra",
|
||||
"Description": "",
|
||||
"Type": "transport"
|
||||
},
|
||||
{
|
||||
"AID": "A000000858044F53452E4348",
|
||||
"Vendor": "Apple",
|
||||
"Country": "",
|
||||
"Name": "AirDrop connection negotiation",
|
||||
"Description": "Used by NFC-based AirDrop negotiation added in IOS17",
|
||||
"Type": ""
|
||||
}
|
||||
]
|
||||
|
||||
@@ -4073,6 +4073,20 @@
|
||||
"service_provider": "HID Corporation",
|
||||
"system_integrator": "HID Corporation"
|
||||
},
|
||||
{
|
||||
"application": "City transport, prepaid ticket, cardholder, servicespass",
|
||||
"company": "Ridango AS",
|
||||
"mad": "0x3C56",
|
||||
"service_provider": "Pilet.ee ekaart",
|
||||
"system_integrator": "Pilet.ee ekaart"
|
||||
},
|
||||
{
|
||||
"application": "City transport, prepaid ticket, cardholder, servicespass",
|
||||
"company": "Ridango AS",
|
||||
"mad": "0x3D56",
|
||||
"service_provider": "Pilet.ee ekaart",
|
||||
"system_integrator": "Pilet.ee ekaart"
|
||||
},
|
||||
{
|
||||
"application": "City transport bus, ferry, administration",
|
||||
"company": "VFJ Technology Pty Ltd",
|
||||
|
||||
+13
-4
@@ -2939,7 +2939,7 @@ static int CmdDiff(const char *Cmd) {
|
||||
// "data diff -a fileA --cb\n"
|
||||
"data diff --fa fileA -b fileB\n"
|
||||
"data diff --fa fileA --fb fileB\n"
|
||||
"data diff --ea --cb\n"
|
||||
// "data diff --ea --cb\n"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
@@ -3083,10 +3083,19 @@ static int CmdDiff(const char *Cmd) {
|
||||
PrintAndLogEx(INFO, "inB null");
|
||||
|
||||
int hdr_sln = (width * 4) + 2;
|
||||
char hdr0[300] = {0};
|
||||
|
||||
char hdr0[200] = " # | " _CYAN_("a");
|
||||
memset(hdr0 + strlen(hdr0), ' ', hdr_sln - 2);
|
||||
strcat(hdr0 + strlen(hdr0), "| " _CYAN_("b"));
|
||||
int max_fn_space = (width * 5);
|
||||
|
||||
if (fnlenA && fnlenB && (max_fn_space > fnlenA) && (max_fn_space > fnlenB)) {
|
||||
snprintf(hdr0, sizeof(hdr0) - 1, " # | " _CYAN_("%.*s"), max_fn_space, filenameA);
|
||||
memset(hdr0 + strlen(hdr0), ' ', hdr_sln - strlen(filenameA) - 1);
|
||||
snprintf(hdr0 + strlen(hdr0), sizeof(hdr0) - 1 - strlen(hdr0), "| " _CYAN_("%.*s"), max_fn_space, filenameB);
|
||||
} else {
|
||||
strcat(hdr0, " # | " _CYAN_("a"));
|
||||
memset(hdr0 + strlen(hdr0), ' ', hdr_sln - 2);
|
||||
strcat(hdr0 + strlen(hdr0), "| " _CYAN_("b"));
|
||||
}
|
||||
|
||||
char hdr1[200] = "----+";
|
||||
memset(hdr1 + strlen(hdr1), '-', hdr_sln);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user