This commit is contained in:
iceman1001 2019-03-09 11:30:48 +01:00
commit 37423ed2ad
18 changed files with 1562 additions and 1562 deletions

View file

@ -28,20 +28,20 @@ from the client to view the stored quadlets.
#define MAX_PWDS_PER_SESSION 64
uint8_t FindOffsetInFlash() {
uint8_t mem[4] = { 0x00, 0x00, 0x00, 0x00 };
uint8_t eom[4] = { 0xFF, 0xFF, 0xFF, 0xFF };
uint8_t memcnt = 0;
uint8_t mem[4] = { 0x00, 0x00, 0x00, 0x00 };
uint8_t eom[4] = { 0xFF, 0xFF, 0xFF, 0xFF };
uint8_t memcnt = 0;
while (memcnt < 0xFF)
{
Flash_ReadData(memcnt, mem, 4);
if (memcmp(mem, eom, 4) == 0) {
return memcnt;
}
memcnt += 4;
}
while (memcnt < 0xFF)
{
Flash_ReadData(memcnt, mem, 4);
if (memcmp(mem, eom, 4) == 0) {
return memcnt;
}
memcnt += 4;
}
return 0; // wrap-around
return 0; // wrap-around
}
void EraseMemory() {
@ -55,247 +55,247 @@ void EraseMemory() {
if (MF_DBGLEVEL > 1) Dbprintf("[!] Erased flash!");
FlashStop();
SpinDelay(100);
SpinDelay(100);
}
// This is actually copied from SniffIso14443a
void RAMFUNC SniffAndStore(uint8_t param) {
iso14443a_setup(FPGA_HF_ISO14443A_SNIFFER);
iso14443a_setup(FPGA_HF_ISO14443A_SNIFFER);
// Allocate memory from BigBuf for some buffers
// free all previous allocations first
BigBuf_free(); BigBuf_Clear_ext(false);
clear_trace();
set_tracing(true);
// Allocate memory from BigBuf for some buffers
// free all previous allocations first
BigBuf_free(); BigBuf_Clear_ext(false);
clear_trace();
set_tracing(true);
// Array to store the authpwds
uint8_t *capturedPwds = BigBuf_malloc(4 * MAX_PWDS_PER_SESSION);
// Array to store the authpwds
uint8_t *capturedPwds = BigBuf_malloc(4 * MAX_PWDS_PER_SESSION);
// The command (reader -> tag) that we're receiving.
uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
uint8_t *receivedCmdPar = BigBuf_malloc(MAX_PARITY_SIZE);
// The command (reader -> tag) that we're receiving.
uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
uint8_t *receivedCmdPar = BigBuf_malloc(MAX_PARITY_SIZE);
// The response (tag -> reader) that we're receiving.
uint8_t *receivedResp = BigBuf_malloc(MAX_FRAME_SIZE);
uint8_t *receivedRespPar = BigBuf_malloc(MAX_PARITY_SIZE);
// The response (tag -> reader) that we're receiving.
uint8_t *receivedResp = BigBuf_malloc(MAX_FRAME_SIZE);
uint8_t *receivedRespPar = BigBuf_malloc(MAX_PARITY_SIZE);
// The DMA buffer, used to stream samples from the FPGA
uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
uint8_t *data = dmaBuf;
// The DMA buffer, used to stream samples from the FPGA
uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
uint8_t *data = dmaBuf;
uint8_t previous_data = 0;
int dataLen = 0;
bool TagIsActive = false;
bool ReaderIsActive = false;
uint8_t previous_data = 0;
int dataLen = 0;
bool TagIsActive = false;
bool ReaderIsActive = false;
// Set up the demodulator for tag -> reader responses.
DemodInit(receivedResp, receivedRespPar);
// Set up the demodulator for tag -> reader responses.
DemodInit(receivedResp, receivedRespPar);
// Set up the demodulator for the reader -> tag commands
UartInit(receivedCmd, receivedCmdPar);
// Set up the demodulator for the reader -> tag commands
UartInit(receivedCmd, receivedCmdPar);
// Setup and start DMA.
if ( !FpgaSetupSscDma((uint8_t*) dmaBuf, DMA_BUFFER_SIZE) ){
if (MF_DBGLEVEL > 1) Dbprintf("FpgaSetupSscDma failed. Exiting");
return;
}
// Setup and start DMA.
if ( !FpgaSetupSscDma((uint8_t*) dmaBuf, DMA_BUFFER_SIZE) ){
if (MF_DBGLEVEL > 1) Dbprintf("FpgaSetupSscDma failed. Exiting");
return;
}
tUart* uart = GetUart();
tDemod* demod = GetDemod();
tUart* uart = GetUart();
tDemod* demod = GetDemod();
// We won't start recording the frames that we acquire until we trigger;
// a good trigger condition to get started is probably when we see a
// response from the tag.
// triggered == false -- to wait first for card
bool triggered = !(param & 0x03);
// We won't start recording the frames that we acquire until we trigger;
// a good trigger condition to get started is probably when we see a
// response from the tag.
// triggered == false -- to wait first for card
bool triggered = !(param & 0x03);
uint32_t rsamples = 0;
uint32_t rsamples = 0;
// Current captured passwords counter
uint8_t auth_attempts = 0;
// Current captured passwords counter
uint8_t auth_attempts = 0;
SpinDelay(50);
SpinDelay(50);
// loop and listen
while (!BUTTON_PRESS()) {
// loop and listen
while (!BUTTON_PRESS()) {
WDT_HIT();
LED_A_ON();
int register readBufDataP = data - dmaBuf;
int register dmaBufDataP = DMA_BUFFER_SIZE - AT91C_BASE_PDC_SSC->PDC_RCR;
if (readBufDataP <= dmaBufDataP)
dataLen = dmaBufDataP - readBufDataP;
else
dataLen = DMA_BUFFER_SIZE - readBufDataP + dmaBufDataP;
int register readBufDataP = data - dmaBuf;
int register dmaBufDataP = DMA_BUFFER_SIZE - AT91C_BASE_PDC_SSC->PDC_RCR;
if (readBufDataP <= dmaBufDataP)
dataLen = dmaBufDataP - readBufDataP;
else
dataLen = DMA_BUFFER_SIZE - readBufDataP + dmaBufDataP;
// test for length of buffer
if (dataLen > DMA_BUFFER_SIZE) { // TODO: Check if this works properly
Dbprintf("[!] blew circular buffer! | datalen %u", dataLen);
break;
}
if (dataLen < 1) continue;
// test for length of buffer
if (dataLen > DMA_BUFFER_SIZE) { // TODO: Check if this works properly
Dbprintf("[!] blew circular buffer! | datalen %u", dataLen);
break;
}
if (dataLen < 1) continue;
// primary buffer was stopped( <-- we lost data!
if (!AT91C_BASE_PDC_SSC->PDC_RCR) {
AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) dmaBuf;
AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE;
//Dbprintf("[-] RxEmpty ERROR | data length %d", dataLen); // temporary
}
// secondary buffer sets as primary, secondary buffer was stopped
if (!AT91C_BASE_PDC_SSC->PDC_RNCR) {
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf;
AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
}
// primary buffer was stopped( <-- we lost data!
if (!AT91C_BASE_PDC_SSC->PDC_RCR) {
AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) dmaBuf;
AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE;
//Dbprintf("[-] RxEmpty ERROR | data length %d", dataLen); // temporary
}
// secondary buffer sets as primary, secondary buffer was stopped
if (!AT91C_BASE_PDC_SSC->PDC_RNCR) {
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf;
AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
}
LED_A_OFF();
LED_A_OFF();
// Need two samples to feed Miller and Manchester-Decoder
if (rsamples & 0x01) {
// Need two samples to feed Miller and Manchester-Decoder
if (rsamples & 0x01) {
if (!TagIsActive) { // no need to try decoding reader data if the tag is sending
uint8_t readerdata = (previous_data & 0xF0) | (*data >> 4);
if (MillerDecoding(readerdata, (rsamples-1)*4)) {
LED_C_ON();
if (!TagIsActive) { // no need to try decoding reader data if the tag is sending
uint8_t readerdata = (previous_data & 0xF0) | (*data >> 4);
if (MillerDecoding(readerdata, (rsamples-1)*4)) {
LED_C_ON();
// check - if there is a short 7bit request from reader
if ((!triggered) && (param & 0x02) && (uart->len == 1) && (uart->bitCount == 7)) triggered = true;
// check - if there is a short 7bit request from reader
if ((!triggered) && (param & 0x02) && (uart->len == 1) && (uart->bitCount == 7)) triggered = true;
if (triggered) {
if ((receivedCmd) && ((receivedCmd[0] == MIFARE_ULEV1_AUTH) || (receivedCmd[0] == MIFARE_ULC_AUTH_1))) {
if (MF_DBGLEVEL > 1) Dbprintf("PWD-AUTH KEY: 0x%02x%02x%02x%02x", receivedCmd[1], receivedCmd[2], receivedCmd[3], receivedCmd[4]);
if (triggered) {
if ((receivedCmd) && ((receivedCmd[0] == MIFARE_ULEV1_AUTH) || (receivedCmd[0] == MIFARE_ULC_AUTH_1))) {
if (MF_DBGLEVEL > 1) Dbprintf("PWD-AUTH KEY: 0x%02x%02x%02x%02x", receivedCmd[1], receivedCmd[2], receivedCmd[3], receivedCmd[4]);
// temporarily save the captured pwd in our array
memcpy(&capturedPwds[4 * auth_attempts], receivedCmd+1, 4);
auth_attempts++;
}
// temporarily save the captured pwd in our array
memcpy(&capturedPwds[4 * auth_attempts], receivedCmd+1, 4);
auth_attempts++;
}
if (!LogTrace(receivedCmd,
uart->len,
uart->startTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER,
uart->endTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER,
uart->parity,
true)) break;
}
/* ready to receive another command. */
UartReset();
/* reset the demod code, which might have been */
/* false-triggered by the commands from the reader. */
DemodReset();
LED_B_OFF();
}
ReaderIsActive = (uart->state != STATE_UNSYNCD);
}
if (!LogTrace(receivedCmd,
uart->len,
uart->startTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER,
uart->endTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER,
uart->parity,
true)) break;
}
/* ready to receive another command. */
UartReset();
/* reset the demod code, which might have been */
/* false-triggered by the commands from the reader. */
DemodReset();
LED_B_OFF();
}
ReaderIsActive = (uart->state != STATE_UNSYNCD);
}
// no need to try decoding tag data if the reader is sending - and we cannot afford the time
if (!ReaderIsActive) {
uint8_t tagdata = (previous_data << 4) | (*data & 0x0F);
if (ManchesterDecoding(tagdata, 0, (rsamples-1)*4)) {
LED_B_ON();
// no need to try decoding tag data if the reader is sending - and we cannot afford the time
if (!ReaderIsActive) {
uint8_t tagdata = (previous_data << 4) | (*data & 0x0F);
if (ManchesterDecoding(tagdata, 0, (rsamples-1)*4)) {
LED_B_ON();
if (!LogTrace(receivedResp,
demod->len,
demod->startTime*16 - DELAY_TAG_AIR2ARM_AS_SNIFFER,
demod->endTime*16 - DELAY_TAG_AIR2ARM_AS_SNIFFER,
demod->parity,
false)) break;
if (!LogTrace(receivedResp,
demod->len,
demod->startTime*16 - DELAY_TAG_AIR2ARM_AS_SNIFFER,
demod->endTime*16 - DELAY_TAG_AIR2ARM_AS_SNIFFER,
demod->parity,
false)) break;
if ((!triggered) && (param & 0x01)) triggered = true;
if ((!triggered) && (param & 0x01)) triggered = true;
// ready to receive another response.
DemodReset();
// reset the Miller decoder including its (now outdated) input buffer
UartReset();
//UartInit(receivedCmd, receivedCmdPar);
LED_C_OFF();
}
TagIsActive = (demod->state != DEMOD_UNSYNCD);
}
}
// ready to receive another response.
DemodReset();
// reset the Miller decoder including its (now outdated) input buffer
UartReset();
//UartInit(receivedCmd, receivedCmdPar);
LED_C_OFF();
}
TagIsActive = (demod->state != DEMOD_UNSYNCD);
}
}
previous_data = *data;
rsamples++;
data++;
if (data == dmaBuf + DMA_BUFFER_SIZE) {
data = dmaBuf;
}
} // end main loop
previous_data = *data;
rsamples++;
data++;
if (data == dmaBuf + DMA_BUFFER_SIZE) {
data = dmaBuf;
}
} // end main loop
FpgaDisableSscDma();
set_tracing(false);
FpgaDisableSscDma();
set_tracing(false);
Dbprintf("Stopped sniffing");
Dbprintf("Stopped sniffing");
SpinDelay(200);
SpinDelay(200);
// Write stuff to flash
if (auth_attempts > 0) {
if (MF_DBGLEVEL > 1) Dbprintf("[!] Authentication attempts = %u", auth_attempts);
// Write stuff to flash
if (auth_attempts > 0) {
if (MF_DBGLEVEL > 1) Dbprintf("[!] Authentication attempts = %u", auth_attempts);
// Setting the SPI Baudrate to 48MHz to avoid the bit-flip issue (https://github.com/RfidResearchGroup/proxmark3/issues/34)
FlashmemSetSpiBaudrate(48000000);
// Setting the SPI Baudrate to 48MHz to avoid the bit-flip issue (https://github.com/RfidResearchGroup/proxmark3/issues/34)
FlashmemSetSpiBaudrate(48000000);
// Find the offset in flash mem to continue writing the auth attempts
uint8_t memoffset = FindOffsetInFlash();
if (MF_DBGLEVEL > 1) Dbprintf("[!] Memory offset = %u", memoffset);
// Find the offset in flash mem to continue writing the auth attempts
uint8_t memoffset = FindOffsetInFlash();
if (MF_DBGLEVEL > 1) Dbprintf("[!] Memory offset = %u", memoffset);
if ((memoffset + 4 * auth_attempts) > 0xFF)
{
// We opt to keep the new data only
memoffset = 0;
if (MF_DBGLEVEL > 1) Dbprintf("[!] Size of total data > 256 bytes. Discarding the old data.");
}
if ((memoffset + 4 * auth_attempts) > 0xFF)
{
// We opt to keep the new data only
memoffset = 0;
if (MF_DBGLEVEL > 1) Dbprintf("[!] Size of total data > 256 bytes. Discarding the old data.");
}
// Get previous data from flash mem
uint8_t *previousdata = BigBuf_malloc(memoffset);
if (memoffset > 0)
{
uint16_t readlen = Flash_ReadData(0, previousdata, memoffset);
if (MF_DBGLEVEL > 1) Dbprintf("[!] Read %u bytes from flash mem", readlen);
}
// Get previous data from flash mem
uint8_t *previousdata = BigBuf_malloc(memoffset);
if (memoffset > 0)
{
uint16_t readlen = Flash_ReadData(0, previousdata, memoffset);
if (MF_DBGLEVEL > 1) Dbprintf("[!] Read %u bytes from flash mem", readlen);
}
// create new bigbuf to hold all data
size_t total_size = memoffset + 4 * auth_attempts;
uint8_t *total_data = BigBuf_malloc(total_size);
// create new bigbuf to hold all data
size_t total_size = memoffset + 4 * auth_attempts;
uint8_t *total_data = BigBuf_malloc(total_size);
// Add the previousdata array into total_data array
memcpy(total_data, previousdata, memoffset);
// Add the previousdata array into total_data array
memcpy(total_data, previousdata, memoffset);
// Copy bytes of capturedPwds immediately following bytes of previousdata
memcpy(total_data + memoffset, capturedPwds, 4 * auth_attempts);
// Copy bytes of capturedPwds immediately following bytes of previousdata
memcpy(total_data + memoffset, capturedPwds, 4 * auth_attempts);
// Erase first page of flash mem
EraseMemory();
// Erase first page of flash mem
EraseMemory();
// Write total data to flash mem
uint16_t writelen = Flash_WriteData(0, total_data, memoffset + 4 * auth_attempts);
if (MF_DBGLEVEL > 1) Dbprintf("[!] Wrote %u bytes into flash mem", writelen);
// Write total data to flash mem
uint16_t writelen = Flash_WriteData(0, total_data, memoffset + 4 * auth_attempts);
if (MF_DBGLEVEL > 1) Dbprintf("[!] Wrote %u bytes into flash mem", writelen);
// If pwd saved successfully, blink led A three times
if (writelen > 0) {
SpinErr(0, 200, 5); // blink led A
}
if (writelen > 0) {
SpinErr(0, 200, 5); // blink led A
}
SpinDelay(100);
SpinDelay(100);
// Reset the SPI Baudrate to the default value (24MHz)
FlashmemSetSpiBaudrate(24000000);
}
// Reset the SPI Baudrate to the default value (24MHz)
FlashmemSetSpiBaudrate(24000000);
}
}
void RunMod() {
StandAloneMode();
StandAloneMode();
Dbprintf(">> Bogiton 14a Sniff UL/UL-EV1/NTAG a.k.a BogitoRun Started <<");
Dbprintf("Starting to sniff");
Dbprintf(">> Bogiton 14a Sniff UL/UL-EV1/NTAG a.k.a BogitoRun Started <<");
Dbprintf("Starting to sniff");
// param:
// bit 0 - trigger from first card answer
// bit 1 - trigger from first reader 7-bit request
SniffAndStore(0);
LEDsoff();
SpinDelay(300);
Dbprintf("- [ End ] -> You can take shell back ...");
Dbprintf("- [ ! ] -> use 'script run read_pwd_mem' to print passwords");
// param:
// bit 0 - trigger from first card answer
// bit 1 - trigger from first reader 7-bit request
SniffAndStore(0);
LEDsoff();
SpinDelay(300);
Dbprintf("- [ End ] -> You can take shell back ...");
Dbprintf("- [ ! ] -> use 'script run read_pwd_mem' to print passwords");
}

View file

@ -171,8 +171,8 @@ void WriteTagToFlash(uint8_t index, size_t size)
while (bytes_remaining > 0)
{
Flash_CheckBusy(BUSY_TIMEOUT);
Flash_WriteEnable();
Flash_CheckBusy(BUSY_TIMEOUT);
Flash_WriteEnable();
uint32_t bytes_in_packet = MIN(FLASH_MEM_BLOCK_SIZE, bytes_remaining);
@ -210,7 +210,7 @@ void WriteTagToFlash(uint8_t index, size_t size)
void RunMod()
{
StandAloneMode();
StandAloneMode();
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
currline = 20;
@ -323,12 +323,12 @@ ACCBITS : 796788[00]+VALUE
{
for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++)
{
foundKey[t][sectorNo][0] = 0xFF;
foundKey[t][sectorNo][1] = 0xFF;
foundKey[t][sectorNo][2] = 0xFF;
foundKey[t][sectorNo][3] = 0xFF;
foundKey[t][sectorNo][4] = 0xFF;
foundKey[t][sectorNo][5] = 0xFF;
foundKey[t][sectorNo][0] = 0xFF;
foundKey[t][sectorNo][1] = 0xFF;
foundKey[t][sectorNo][2] = 0xFF;
foundKey[t][sectorNo][3] = 0xFF;
foundKey[t][sectorNo][4] = 0xFF;
foundKey[t][sectorNo][5] = 0xFF;
}
}

View file

@ -215,244 +215,244 @@ static int saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, ui
void RunMod() {
StandAloneMode();
Dbprintf(">> Matty mifare chk/dump/sim a.k.a MattyRun Started <<");
StandAloneMode();
Dbprintf(">> Matty mifare chk/dump/sim a.k.a MattyRun Started <<");
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
/*
It will check if the keys from the attacked tag are a subset from
the hardcoded set of keys inside of the ARM. If this is the case
then it will load the keys into the emulator memory and also the
content of the victim tag, to finally simulate it.
/*
It will check if the keys from the attacked tag are a subset from
the hardcoded set of keys inside of the ARM. If this is the case
then it will load the keys into the emulator memory and also the
content of the victim tag, to finally simulate it.
Alternatively, it can be dumped into a blank card.
Alternatively, it can be dumped into a blank card.
This source code has been tested only in Mifare 1k.
This source code has been tested only in Mifare 1k.
If you're using the proxmark connected to a device that has an OS, and you're not using the proxmark3 client to see the debug
messages, you MUST uncomment usb_disable().
*/
If you're using the proxmark connected to a device that has an OS, and you're not using the proxmark3 client to see the debug
messages, you MUST uncomment usb_disable().
*/
// Comment this line below if you want to see debug messages.
// Comment this line below if you want to see debug messages.
// usb_disable();
/*
Pseudo-configuration block.
Pseudo-configuration block.
*/
bool printKeys = false; // Prints keys
bool transferToEml = true; // Transfer keys to emulator memory
bool ecfill = true; // Fill emulator memory with cards content.
bool simulation = true; // Simulates an exact copy of the target tag
bool fillFromEmulator = false; // Dump emulator memory.
bool printKeys = false; // Prints keys
bool transferToEml = true; // Transfer keys to emulator memory
bool ecfill = true; // Fill emulator memory with cards content.
bool simulation = true; // Simulates an exact copy of the target tag
bool fillFromEmulator = false; // Dump emulator memory.
uint16_t mifare_size = 1024; // Mifare 1k (only 1k supported for now)
uint8_t sectorSize = 64; // 1k's sector size is 64 bytes.
uint8_t blockNo = 3; // Security block is number 3 for each sector.
uint8_t sectorsCnt = (mifare_size/sectorSize);
uint8_t keyType = 2; // Keytype buffer
uint64_t key64; // Defines current key
uint8_t *keyBlock = NULL; // Where the keys will be held in memory.
uint8_t stKeyBlock = 20; // Set the quantity of keys in the block.
uint8_t filled = 0; // Used to check if the memory was filled with success.
bool keyFound = false;
uint16_t mifare_size = 1024; // Mifare 1k (only 1k supported for now)
uint8_t sectorSize = 64; // 1k's sector size is 64 bytes.
uint8_t blockNo = 3; // Security block is number 3 for each sector.
uint8_t sectorsCnt = (mifare_size/sectorSize);
uint8_t keyType = 2; // Keytype buffer
uint64_t key64; // Defines current key
uint8_t *keyBlock = NULL; // Where the keys will be held in memory.
uint8_t stKeyBlock = 20; // Set the quantity of keys in the block.
uint8_t filled = 0; // Used to check if the memory was filled with success.
bool keyFound = false;
/*
Set of keys to be used.
*/
uint64_t mfKeys[] = {
0xffffffffffff, // Default key
0x000000000000, // Blank key
0xa0a1a2a3a4a5, // NFCForum MAD key
0xb0b1b2b3b4b5,
0xaabbccddeeff,
0x4d3a99c351dd,
0x1a982c7e459a,
0xd3f7d3f7d3f7,
0x714c5c886e97,
0x587ee5f9350f,
0xa0478cc39091,
0x533cb6c723f6,
0x8fd0a4f256e9,
};
/*
Set of keys to be used.
*/
uint64_t mfKeys[] = {
0xffffffffffff, // Default key
0x000000000000, // Blank key
0xa0a1a2a3a4a5, // NFCForum MAD key
0xb0b1b2b3b4b5,
0xaabbccddeeff,
0x4d3a99c351dd,
0x1a982c7e459a,
0xd3f7d3f7d3f7,
0x714c5c886e97,
0x587ee5f9350f,
0xa0478cc39091,
0x533cb6c723f6,
0x8fd0a4f256e9,
};
/*
This part allocates the byte representation of the
keys in keyBlock's memory space .
*/
keyBlock = BigBuf_malloc(stKeyBlock * 6);
int mfKeysCnt = sizeof(mfKeys) / sizeof(uint64_t);
/*
This part allocates the byte representation of the
keys in keyBlock's memory space .
*/
keyBlock = BigBuf_malloc(stKeyBlock * 6);
int mfKeysCnt = sizeof(mfKeys) / sizeof(uint64_t);
for (int mfKeyCounter = 0; mfKeyCounter < mfKeysCnt; mfKeyCounter++) {
num_to_bytes(mfKeys[mfKeyCounter], 6, (uint8_t*)(keyBlock + mfKeyCounter * 6));
}
for (int mfKeyCounter = 0; mfKeyCounter < mfKeysCnt; mfKeyCounter++) {
num_to_bytes(mfKeys[mfKeyCounter], 6, (uint8_t*)(keyBlock + mfKeyCounter * 6));
}
/*
Pretty print of the keys to be checked.
*/
if (printKeys) {
Dbprintf("[+] Printing mf keys");
for (uint8_t keycnt = 0; keycnt < mfKeysCnt; keycnt++)
Dbprintf("[-] chk mf key[%2d] %02x%02x%02x%02x%02x%02x", keycnt,
(keyBlock + 6*keycnt)[0],(keyBlock + 6*keycnt)[1], (keyBlock + 6*keycnt)[2],
(keyBlock + 6*keycnt)[3], (keyBlock + 6*keycnt)[4], (keyBlock + 6*keycnt)[5], 6);
DbpString("--------------------------------------------------------");
}
/*
Pretty print of the keys to be checked.
*/
if (printKeys) {
Dbprintf("[+] Printing mf keys");
for (uint8_t keycnt = 0; keycnt < mfKeysCnt; keycnt++)
Dbprintf("[-] chk mf key[%2d] %02x%02x%02x%02x%02x%02x", keycnt,
(keyBlock + 6*keycnt)[0], (keyBlock + 6*keycnt)[1], (keyBlock + 6*keycnt)[2],
(keyBlock + 6*keycnt)[3], (keyBlock + 6*keycnt)[4], (keyBlock + 6*keycnt)[5], 6);
DbpString("--------------------------------------------------------");
}
/*
Initialization of validKeys and foundKeys storages.
- validKey will store whether the sector has a valid A/B key.
- foundKey will store the found A/B key for each sector.
*/
bool validKey[2][40];
uint8_t foundKey[2][40][6];
for (uint16_t t = 0; t < 2; t++) {
for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) {
validKey[t][sectorNo] = false;
for (uint16_t i = 0; i < 6; i++) {
foundKey[t][sectorNo][i] = 0xff;
}
}
}
/*
Initialization of validKeys and foundKeys storages.
- validKey will store whether the sector has a valid A/B key.
- foundKey will store the found A/B key for each sector.
*/
bool validKey[2][40];
uint8_t foundKey[2][40][6];
for (uint16_t t = 0; t < 2; t++) {
for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) {
validKey[t][sectorNo] = false;
for (uint16_t i = 0; i < 6; i++) {
foundKey[t][sectorNo][i] = 0xff;
}
}
}
/*
Iterates through each sector checking if there is a correct key.
*/
int key = -1;
int block = 0;
bool err = 0;
bool allKeysFound = true;
uint32_t size = mfKeysCnt;
/*
Iterates through each sector checking if there is a correct key.
*/
int key = -1;
int block = 0;
bool err = 0;
bool allKeysFound = true;
uint32_t size = mfKeysCnt;
for (int type = !keyType; type < 2 && !err; keyType == 2 ? (type++) : (type = 2)) {
block = blockNo;
for (int sec = 0; sec < sectorsCnt && !err; ++sec) {
Dbprintf("\tCurrent sector:%3d, block:%3d, key type: %c, key count: %i ", sec, block, type ? 'B':'A', mfKeysCnt);
key = saMifareChkKeys(block, type, true, size, &keyBlock[0], &key64);
if (key == -1) {
LED(LED_RED, 50); //red
Dbprintf("\t✕ Key not found for this sector!");
allKeysFound = false;
// break;
} else if (key == -2) {
err = 1; // Can't select card.
break;
} else {
num_to_bytes(key64, 6, foundKey[type][sec]);
validKey[type][sec] = true;
keyFound = true;
Dbprintf("\t✓ Found valid key: [%02x%02x%02x%02x%02x%02x]\n",
(keyBlock + 6*key)[0], (keyBlock + 6*key)[1], (keyBlock + 6*key)[2],
(keyBlock + 6*key)[3], (keyBlock + 6*key)[4], (keyBlock + 6*key)[5]
);
}
for (int type = !keyType; type < 2 && !err; keyType == 2 ? (type++) : (type = 2)) {
block = blockNo;
for (int sec = 0; sec < sectorsCnt && !err; ++sec) {
Dbprintf("\tCurrent sector:%3d, block:%3d, key type: %c, key count: %i ", sec, block, type ? 'B':'A', mfKeysCnt);
key = saMifareChkKeys(block, type, true, size, &keyBlock[0], &key64);
if (key == -1) {
LED(LED_RED, 50); //red
Dbprintf("\t✕ Key not found for this sector!");
allKeysFound = false;
// break;
} else if (key == -2) {
err = 1; // Can't select card.
break;
} else {
num_to_bytes(key64, 6, foundKey[type][sec]);
validKey[type][sec] = true;
keyFound = true;
Dbprintf("\t✓ Found valid key: [%02x%02x%02x%02x%02x%02x]\n",
(keyBlock + 6*key)[0], (keyBlock + 6*key)[1], (keyBlock + 6*key)[2],
(keyBlock + 6*key)[3], (keyBlock + 6*key)[4], (keyBlock + 6*key)[5]
);
}
block < 127 ? (block += 4) : (block += 16);
}
}
block < 127 ? (block += 4) : (block += 16);
}
}
/*
TODO:
- Get UID from tag and set accordingly in emulator memory and call mifare1ksim with right flags (iceman)
*/
if (!allKeysFound && keyFound) {
Dbprintf("\t✕ There's currently no nested attack in MattyRun, sorry!");
LED_C_ON(); //red
LED_A_ON(); //yellow
// no room to run nested attack on device (iceman)
// Do nested attack, set allKeysFound = true;
// allKeysFound = true;
} else {
Dbprintf("\t✕ There's nothing I can do without at least a one valid key, sorry!");
LED_C_ON(); //red
}
/*
TODO:
- Get UID from tag and set accordingly in emulator memory and call mifare1ksim with right flags (iceman)
*/
if (!allKeysFound && keyFound) {
Dbprintf("\t✕ There's currently no nested attack in MattyRun, sorry!");
LED_C_ON(); //red
LED_A_ON(); //yellow
// no room to run nested attack on device (iceman)
// Do nested attack, set allKeysFound = true;
// allKeysFound = true;
} else {
Dbprintf("\t✕ There's nothing I can do without at least a one valid key, sorry!");
LED_C_ON(); //red
}
/*
If enabled, transfers found keys to memory and loads target content in emulator memory. Then it simulates to be the tag it has basically cloned.
*/
if ((transferToEml) && (allKeysFound)) {
/*
If enabled, transfers found keys to memory and loads target content in emulator memory. Then it simulates to be the tag it has basically cloned.
*/
if ((transferToEml) && (allKeysFound)) {
emlClearMem();
emlClearMem();
uint8_t mblock[16];
for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) {
if (validKey[0][sectorNo] || validKey[1][sectorNo]) {
emlGetMem(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1); // data, block num, blocks count (max 4)
for (uint16_t t = 0; t < 2; t++) {
if (validKey[t][sectorNo]) {
memcpy(mblock + t*10, foundKey[t][sectorNo], 6);
}
}
emlSetMem(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1);
}
}
Dbprintf("\t✓ Found keys have been transferred to the emulator memory.");
if (ecfill) {
uint8_t mblock[16];
for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) {
if (validKey[0][sectorNo] || validKey[1][sectorNo]) {
emlGetMem(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1); // data, block num, blocks count (max 4)
for (uint16_t t = 0; t < 2; t++) {
if (validKey[t][sectorNo]) {
memcpy(mblock + t*10, foundKey[t][sectorNo], 6);
}
}
emlSetMem(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1);
}
}
Dbprintf("\t✓ Found keys have been transferred to the emulator memory.");
if (ecfill) {
Dbprintf("\tFilling in with key A.");
MifareECardLoad(sectorsCnt, 0, 0, &filled);
if (filled != 1) {
Dbprintf("\t✕ Failed filling with A.");
}
Dbprintf("\tFilling in with key A.");
MifareECardLoad(sectorsCnt, 0, 0, &filled);
if (filled != 1) {
Dbprintf("\t✕ Failed filling with A.");
}
Dbprintf("\tFilling in with key B.");
MifareECardLoad(sectorsCnt, 1, 0, &filled);
if (filled != 1) {
Dbprintf("\t✕ Failed filling with B.");
}
Dbprintf("\tFilling in with key B.");
MifareECardLoad(sectorsCnt, 1, 0, &filled);
if (filled != 1) {
Dbprintf("\t✕ Failed filling with B.");
}
if ((filled == 1) && simulation) {
Dbprintf("\t✓ Filled, simulation started.");
if ((filled == 1) && simulation) {
Dbprintf("\t✓ Filled, simulation started.");
// This will tell the fpga to emulate using previous keys and current target tag content.
Dbprintf("\t Press button to abort simulation at anytime.");
// This will tell the fpga to emulate using previous keys and current target tag content.
Dbprintf("\t Press button to abort simulation at anytime.");
LED_B_ON(); // green
// assuming arg0==0, use hardcoded uid 0xdeadbeaf
Mifare1ksim( FLAG_4B_UID_IN_DATA | FLAG_UID_IN_EMUL, 0, 0, uid);
LED_B_OFF();
LED_B_ON(); // green
// assuming arg0==0, use hardcoded uid 0xdeadbeaf
Mifare1ksim( FLAG_4B_UID_IN_DATA | FLAG_UID_IN_EMUL, 0, 0, uid);
LED_B_OFF();
/*
Needs further testing.
*/
if (fillFromEmulator) {
uint8_t retry = 5, cnt;
Dbprintf("\t Trying to dump into blank card.");
int flags = 0;
LED_A_ON(); //yellow
for (int blockNum = 0; blockNum < 16 * 4; blockNum += 1) {
cnt = 0;
emlGetMem(mblock, blockNum, 1);
// switch on field and send magic sequence
if (blockNum == 0) flags = 0x08 + 0x02;
/*
Needs further testing.
*/
if (fillFromEmulator) {
uint8_t retry = 5, cnt;
Dbprintf("\t Trying to dump into blank card.");
int flags = 0;
LED_A_ON(); //yellow
for (int blockNum = 0; blockNum < 16 * 4; blockNum += 1) {
cnt = 0;
emlGetMem(mblock, blockNum, 1);
// switch on field and send magic sequence
if (blockNum == 0) flags = 0x08 + 0x02;
// just write
if (blockNum == 1) flags = 0;
// just write
if (blockNum == 1) flags = 0;
// Done. Magic Halt and switch off field.
if (blockNum == 16 * 4 - 1) flags = 0x04 + 0x10;
// Done. Magic Halt and switch off field.
if (blockNum == 16 * 4 - 1) flags = 0x04 + 0x10;
while (!saMifareCSetBlock(0, flags & 0xFE, blockNum, mblock) && cnt <= retry) {
cnt++;
Dbprintf("\t! Could not write block. Retrying.");
}
if (cnt == retry) {
Dbprintf("\t✕ Retries failed. Aborting.");
break;
}
}
while (!saMifareCSetBlock(0, flags & 0xFE, blockNum, mblock) && cnt <= retry) {
cnt++;
Dbprintf("\t! Could not write block. Retrying.");
}
if (cnt == retry) {
Dbprintf("\t✕ Retries failed. Aborting.");
break;
}
}
if (!err) {
LED_B_ON();
} else {
LED_C_ON();
}
if (!err) {
LED_B_ON();
} else {
LED_C_ON();
}
}
} else if (filled != 1) {
Dbprintf("\t✕ Memory could not be filled due to errors.");
LED_C_ON();
}
}
}
}
} else if (filled != 1) {
Dbprintf("\t✕ Memory could not be filled due to errors.");
LED_C_ON();
}
}
}
}

View file

@ -14,8 +14,8 @@
//#include <stdbool.h> // for bool
#include "standalone.h" // standalone definitions
#include "apps.h" // debugstatements, lfops?
#include "usb_cmd.h" // mifare1ksim flags
#include "apps.h" // debugstatements, lfops?
#include "usb_cmd.h" // mifare1ksim flags
#include "mifareutil.h"
#define OPTS 2

View file

@ -11,252 +11,252 @@
#include "hf_young.h"
typedef struct {
uint8_t uid[10];
uint8_t uidlen;
uint8_t atqa[2];
uint8_t sak;
uint8_t uid[10];
uint8_t uidlen;
uint8_t atqa[2];
uint8_t sak;
} __attribute__((__packed__)) card_clone_t;
void RunMod() {
StandAloneMode();
Dbprintf(">> Craig Young Mifare sniff UID/clone uid 2 magic/sim a.k.a YoungRun Started <<");
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
StandAloneMode();
Dbprintf(">> Craig Young Mifare sniff UID/clone uid 2 magic/sim a.k.a YoungRun Started <<");
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
int selected = 0, playing = 0, iGotoRecord = 0, iGotoClone = 0;
int cardRead[OPTS] = {0};
int selected = 0, playing = 0, iGotoRecord = 0, iGotoClone = 0;
int cardRead[OPTS] = {0};
card_clone_t uids[OPTS];
iso14a_card_select_t card[OPTS];
uint8_t params = (MAGIC_SINGLE | MAGIC_DATAIN);
card_clone_t uids[OPTS];
iso14a_card_select_t card[OPTS];
uint8_t params = (MAGIC_SINGLE | MAGIC_DATAIN);
LED(selected + 1, 0);
LED(selected + 1, 0);
for (;;) {
WDT_HIT();
// exit from Standalone Mode, send a usbcommand.
if (usb_poll_validate_length()) return;
for (;;) {
WDT_HIT();
// exit from Standalone Mode, send a usbcommand.
if (usb_poll_validate_length()) return;
SpinDelay(300);
SpinDelay(300);
if (iGotoRecord == 1 || cardRead[selected] == 0) {
iGotoRecord = 0;
LEDsoff();
LED(selected + 1, 0);
LED(LED_RED2, 0);
if (iGotoRecord == 1 || cardRead[selected] == 0) {
iGotoRecord = 0;
LEDsoff();
LED(selected + 1, 0);
LED(LED_RED2, 0);
// record
Dbprintf("Enabling iso14443a reader mode for [Bank: %d]...", selected);
/* need this delay to prevent catching some weird data */
SpinDelay(500);
iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
// record
Dbprintf("Enabling iso14443a reader mode for [Bank: %d]...", selected);
/* need this delay to prevent catching some weird data */
SpinDelay(500);
iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
for (;;) {
// exit from Standalone Mode, send a usbcommand.
if (usb_poll_validate_length()) return;
for (;;) {
// exit from Standalone Mode, send a usbcommand.
if (usb_poll_validate_length()) return;
if (BUTTON_PRESS()) {
if (cardRead[selected]) {
Dbprintf("Button press detected -- replaying card in bank[%d]", selected);
break;
} else if (cardRead[(selected+1) % OPTS]) {
Dbprintf("Button press detected but no card in bank[%d] so playing from bank[%d]", selected, (selected+1)%OPTS);
selected = (selected+1) % OPTS;
break; // playing = 1;
} else {
Dbprintf("Button press detected but no stored tag to play. (Ignoring button)");
SpinDelay(300);
}
}
if (BUTTON_PRESS()) {
if (cardRead[selected]) {
Dbprintf("Button press detected -- replaying card in bank[%d]", selected);
break;
} else if (cardRead[(selected+1) % OPTS]) {
Dbprintf("Button press detected but no card in bank[%d] so playing from bank[%d]", selected, (selected+1)%OPTS);
selected = (selected+1) % OPTS;
break; // playing = 1;
} else {
Dbprintf("Button press detected but no stored tag to play. (Ignoring button)");
SpinDelay(300);
}
}
if (!iso14443a_select_card(NULL, &card[selected], NULL, true, 0, true)) {
continue;
} else {
Dbprintf("Read UID:");
Dbhexdump(card[selected].uidlen, card[selected].uid, 0);
if (!iso14443a_select_card(NULL, &card[selected], NULL, true, 0, true)) {
continue;
} else {
Dbprintf("Read UID:");
Dbhexdump(card[selected].uidlen, card[selected].uid, 0);
if (memcmp(uids[(selected+1)%OPTS].uid, card[selected].uid, card[selected].uidlen ) == 0 ) {
Dbprintf("Card selected has same UID as what is stored in the other bank. Skipping.");
} else {
uids[selected].sak = card[selected].sak;
uids[selected].uidlen = card[selected].uidlen;
memcpy(uids[selected].uid , card[selected].uid, uids[selected].uidlen);
memcpy(uids[selected].atqa, card[selected].atqa, 2);
if (memcmp(uids[(selected+1)%OPTS].uid, card[selected].uid, card[selected].uidlen ) == 0 ) {
Dbprintf("Card selected has same UID as what is stored in the other bank. Skipping.");
} else {
uids[selected].sak = card[selected].sak;
uids[selected].uidlen = card[selected].uidlen;
memcpy(uids[selected].uid , card[selected].uid, uids[selected].uidlen);
memcpy(uids[selected].atqa, card[selected].atqa, 2);
if (uids[selected].uidlen > 4)
Dbprintf("Bank[%d] received a 7-byte UID", selected);
else
Dbprintf("Bank[%d] received a 4-byte UID", selected);
break;
}
}
}
if (uids[selected].uidlen > 4)
Dbprintf("Bank[%d] received a 7-byte UID", selected);
else
Dbprintf("Bank[%d] received a 4-byte UID", selected);
break;
}
}
}
Dbprintf("ATQA = %02X%02X", uids[selected].atqa[0], uids[selected].atqa[1]);
Dbprintf("SAK = %02X", uids[selected].sak);
LEDsoff();
LED(LED_GREEN, 200);
LED(LED_ORANGE, 200);
LED(LED_GREEN, 200);
LED(LED_ORANGE, 200);
Dbprintf("ATQA = %02X%02X", uids[selected].atqa[0], uids[selected].atqa[1]);
Dbprintf("SAK = %02X", uids[selected].sak);
LEDsoff();
LED(LED_GREEN, 200);
LED(LED_ORANGE, 200);
LED(LED_GREEN, 200);
LED(LED_ORANGE, 200);
LEDsoff();
LED(selected + 1, 0);
LEDsoff();
LED(selected + 1, 0);
// Next state is replay:
playing = 1;
// Next state is replay:
playing = 1;
cardRead[selected] = 1;
}
cardRead[selected] = 1;
}
/* MF Classic UID clone */
else if (iGotoClone==1) {
iGotoClone=0;
LEDsoff();
LED(selected + 1, 0);
LED(LED_ORANGE, 250);
/* MF Classic UID clone */
else if (iGotoClone==1) {
iGotoClone=0;
LEDsoff();
LED(selected + 1, 0);
LED(LED_ORANGE, 250);
// magiccards holds 4bytes uid. *usually*
uint32_t tmpuid = bytes_to_num(uids[selected].uid, 4);
// magiccards holds 4bytes uid. *usually*
uint32_t tmpuid = bytes_to_num(uids[selected].uid, 4);
// record
Dbprintf("Preparing to Clone card [Bank: %d]; uid: %08x", selected, tmpuid);
// record
Dbprintf("Preparing to Clone card [Bank: %d]; uid: %08x", selected, tmpuid);
// wait for button to be released
// Delay cloning until card is in place
while (BUTTON_PRESS())
WDT_HIT();
// wait for button to be released
// Delay cloning until card is in place
while (BUTTON_PRESS())
WDT_HIT();
Dbprintf("Starting clone. [Bank: %d]", selected);
// need this delay to prevent catching some weird data
SpinDelay(500);
// Begin clone function here:
/* Example from client/mifarehost.c for commanding a block write for "magic Chinese" cards:
UsbCommand c = {CMD_MIFARE_CSETBLOCK, {params & (0xFE | (uid == NULL ? 0:1)), blockNo, 0}};
memcpy(c.d.asBytes, data, 16);
SendCommand(&c);
Dbprintf("Starting clone. [Bank: %d]", selected);
// need this delay to prevent catching some weird data
SpinDelay(500);
// Begin clone function here:
/* Example from client/mifarehost.c for commanding a block write for "magic Chinese" cards:
UsbCommand c = {CMD_MIFARE_CSETBLOCK, {params & (0xFE | (uid == NULL ? 0:1)), blockNo, 0}};
memcpy(c.d.asBytes, data, 16);
SendCommand(&c);
Block read is similar:
UsbCommand c = {CMD_MIFARE_CGETBLOCK, {params, blockNo, 0}};
We need to imitate that call with blockNo 0 to set a uid.
Block read is similar:
UsbCommand c = {CMD_MIFARE_CGETBLOCK, {params, blockNo, 0}};
We need to imitate that call with blockNo 0 to set a uid.
The get and set commands are handled in this file:
// Work with "magic Chinese" card
case CMD_MIFARE_CSETBLOCK:
MifareCSetBlock(c->arg[0], c->arg[1], c->d.asBytes);
break;
case CMD_MIFARE_CGETBLOCK:
MifareCGetBlock(c->arg[0], c->arg[1], c->d.asBytes);
break;
The get and set commands are handled in this file:
// Work with "magic Chinese" card
case CMD_MIFARE_CSETBLOCK:
MifareCSetBlock(c->arg[0], c->arg[1], c->d.asBytes);
break;
case CMD_MIFARE_CGETBLOCK:
MifareCGetBlock(c->arg[0], c->arg[1], c->d.asBytes);
break;
mfCSetUID provides example logic for UID set workflow:
-Read block0 from card in field with MifareCGetBlock()
-Configure new values without replacing reserved bytes
memcpy(block0, uid, 4); // Copy UID bytes from byte array
// Mifare UID BCC
block0[4] = block0[0]^block0[1]^block0[2]^block0[3]; // BCC on byte 5
Bytes 5-7 are reserved SAK and ATQA for mifare classic
-Use mfCSetBlock(0, block0, oldUID, wantWipe, MAGIC_SINGLE) to write it
*/
uint8_t oldBlock0[16] = {0}, newBlock0[16] = {0}, testBlock0[16] = {0};
// arg0 = Flags, arg1=blockNo
MifareCGetBlock(params, 0, oldBlock0);
if (oldBlock0[0] == 0 && oldBlock0[0] == oldBlock0[1] && oldBlock0[1] == oldBlock0[2] && oldBlock0[2] == oldBlock0[3]) {
Dbprintf("No changeable tag detected. Returning to replay mode for bank[%d]", selected);
playing = 1;
} else {
Dbprintf("UID from target tag: %02X%02X%02X%02X", oldBlock0[0], oldBlock0[1], oldBlock0[2], oldBlock0[3]);
memcpy(newBlock0, oldBlock0, 16);
mfCSetUID provides example logic for UID set workflow:
-Read block0 from card in field with MifareCGetBlock()
-Configure new values without replacing reserved bytes
memcpy(block0, uid, 4); // Copy UID bytes from byte array
// Mifare UID BCC
block0[4] = block0[0]^block0[1]^block0[2]^block0[3]; // BCC on byte 5
Bytes 5-7 are reserved SAK and ATQA for mifare classic
-Use mfCSetBlock(0, block0, oldUID, wantWipe, MAGIC_SINGLE) to write it
*/
uint8_t oldBlock0[16] = {0}, newBlock0[16] = {0}, testBlock0[16] = {0};
// arg0 = Flags, arg1=blockNo
MifareCGetBlock(params, 0, oldBlock0);
if (oldBlock0[0] == 0 && oldBlock0[0] == oldBlock0[1] && oldBlock0[1] == oldBlock0[2] && oldBlock0[2] == oldBlock0[3]) {
Dbprintf("No changeable tag detected. Returning to replay mode for bank[%d]", selected);
playing = 1;
} else {
Dbprintf("UID from target tag: %02X%02X%02X%02X", oldBlock0[0], oldBlock0[1], oldBlock0[2], oldBlock0[3]);
memcpy(newBlock0, oldBlock0, 16);
// Copy uid for bank (2nd is for longer UIDs not supported if classic)
memcpy(newBlock0, uids[selected].uid, 4);
newBlock0[4] = newBlock0[0] ^ newBlock0[1] ^ newBlock0[2] ^ newBlock0[3];
// Copy uid for bank (2nd is for longer UIDs not supported if classic)
memcpy(newBlock0, uids[selected].uid, 4);
newBlock0[4] = newBlock0[0] ^ newBlock0[1] ^ newBlock0[2] ^ newBlock0[3];
// arg0 = workFlags, arg1 = blockNo, datain
MifareCSetBlock(params, 0, newBlock0);
MifareCGetBlock(params, 0, testBlock0);
// arg0 = workFlags, arg1 = blockNo, datain
MifareCSetBlock(params, 0, newBlock0);
MifareCGetBlock(params, 0, testBlock0);
if (memcmp(testBlock0, newBlock0, 16)==0) {
DbpString("Cloned successfull!");
cardRead[selected] = 0; // Only if the card was cloned successfully should we clear it
playing = 0;
iGotoRecord = 1;
selected = (selected + 1) % OPTS;
} else {
Dbprintf("Clone failed. Back to replay mode on bank[%d]", selected);
playing = 1;
}
}
LEDsoff();
LED(selected + 1, 0);
}
if (memcmp(testBlock0, newBlock0, 16)==0) {
DbpString("Cloned successfull!");
cardRead[selected] = 0; // Only if the card was cloned successfully should we clear it
playing = 0;
iGotoRecord = 1;
selected = (selected + 1) % OPTS;
} else {
Dbprintf("Clone failed. Back to replay mode on bank[%d]", selected);
playing = 1;
}
}
LEDsoff();
LED(selected + 1, 0);
}
// Change where to record (or begin playing)
// button_pressed == BUTTON_SINGLE_CLICK && cardRead[selected])
else if (playing==1) {
LEDsoff();
LED(selected + 1, 0);
// Change where to record (or begin playing)
// button_pressed == BUTTON_SINGLE_CLICK && cardRead[selected])
else if (playing==1) {
LEDsoff();
LED(selected + 1, 0);
// Begin transmitting
LED(LED_GREEN, 0);
DbpString("Playing");
for ( ; ; ) {
// exit from Standalone Mode, send a usbcommand.
if (usb_poll_validate_length()) return;
// Begin transmitting
LED(LED_GREEN, 0);
DbpString("Playing");
for ( ; ; ) {
// exit from Standalone Mode, send a usbcommand.
if (usb_poll_validate_length()) return;
int button_action = BUTTON_HELD(1000);
if ( button_action == 0) { // No button action, proceed with sim
int button_action = BUTTON_HELD(1000);
if ( button_action == 0) { // No button action, proceed with sim
uint8_t flags = FLAG_4B_UID_IN_DATA;
uint8_t data[USB_CMD_DATA_SIZE] = {0}; // in case there is a read command received we shouldn't break
uint8_t flags = FLAG_4B_UID_IN_DATA;
uint8_t data[USB_CMD_DATA_SIZE] = {0}; // in case there is a read command received we shouldn't break
memcpy(data, uids[selected].uid, uids[selected].uidlen);
memcpy(data, uids[selected].uid, uids[selected].uidlen);
uint64_t tmpuid = bytes_to_num(uids[selected].uid, uids[selected].uidlen);
uint64_t tmpuid = bytes_to_num(uids[selected].uid, uids[selected].uidlen);
if ( uids[selected].uidlen == 7 ) {
flags = FLAG_7B_UID_IN_DATA;
Dbprintf("Simulating ISO14443a tag with uid: %014" PRIx64 " [Bank: %d]", tmpuid, selected);
} else {
Dbprintf("Simulating ISO14443a tag with uid: %08" PRIx64 " [Bank: %d]", tmpuid, selected);
}
if ( uids[selected].uidlen == 7 ) {
flags = FLAG_7B_UID_IN_DATA;
Dbprintf("Simulating ISO14443a tag with uid: %014" PRIx64 " [Bank: %d]", tmpuid, selected);
} else {
Dbprintf("Simulating ISO14443a tag with uid: %08" PRIx64 " [Bank: %d]", tmpuid, selected);
}
if (uids[selected].sak == 0x08 && uids[selected].atqa[0] == 0x04 && uids[selected].atqa[1] == 0) {
DbpString("Mifare Classic 1k");
SimulateIso14443aTag(1, flags, data);
} else if (uids[selected].sak == 0x18 && uids[selected].atqa[0] == 0x02 && uids[selected].atqa[1] == 0) {
DbpString("Mifare Classic 4k (4b uid)");
SimulateIso14443aTag(8, flags, data);
} else if (uids[selected].sak == 0x08 && uids[selected].atqa[0] == 0x44 && uids[selected].atqa[1] == 0) {
DbpString("Mifare Classic 4k (7b uid)");
SimulateIso14443aTag(8, flags, data);
} else if (uids[selected].sak == 0x00 && uids[selected].atqa[0] == 0x44 && uids[selected].atqa[1] == 0) {
DbpString("Mifare Ultralight");
SimulateIso14443aTag(2, flags, data);
} else if (uids[selected].sak == 0x20 && uids[selected].atqa[0] == 0x04 && uids[selected].atqa[1] == 0x03) {
DbpString("Mifare DESFire");
SimulateIso14443aTag(3, flags, data);
} else {
Dbprintf("Unrecognized tag type -- defaulting to Mifare Classic emulation");
SimulateIso14443aTag(1, flags, data);
}
if (uids[selected].sak == 0x08 && uids[selected].atqa[0] == 0x04 && uids[selected].atqa[1] == 0) {
DbpString("Mifare Classic 1k");
SimulateIso14443aTag(1, flags, data);
} else if (uids[selected].sak == 0x18 && uids[selected].atqa[0] == 0x02 && uids[selected].atqa[1] == 0) {
DbpString("Mifare Classic 4k (4b uid)");
SimulateIso14443aTag(8, flags, data);
} else if (uids[selected].sak == 0x08 && uids[selected].atqa[0] == 0x44 && uids[selected].atqa[1] == 0) {
DbpString("Mifare Classic 4k (7b uid)");
SimulateIso14443aTag(8, flags, data);
} else if (uids[selected].sak == 0x00 && uids[selected].atqa[0] == 0x44 && uids[selected].atqa[1] == 0) {
DbpString("Mifare Ultralight");
SimulateIso14443aTag(2, flags, data);
} else if (uids[selected].sak == 0x20 && uids[selected].atqa[0] == 0x04 && uids[selected].atqa[1] == 0x03) {
DbpString("Mifare DESFire");
SimulateIso14443aTag(3, flags, data);
} else {
Dbprintf("Unrecognized tag type -- defaulting to Mifare Classic emulation");
SimulateIso14443aTag(1, flags, data);
}
} else if (button_action == BUTTON_SINGLE_CLICK) {
selected = (selected + 1) % OPTS;
Dbprintf("Done playing. Switching to record mode on bank %d", selected);
iGotoRecord = 1;
break;
} else if (button_action == BUTTON_HOLD) {
Dbprintf("Playtime over. Begin cloning...");
iGotoClone = 1;
break;
}
}
} else if (button_action == BUTTON_SINGLE_CLICK) {
selected = (selected + 1) % OPTS;
Dbprintf("Done playing. Switching to record mode on bank %d", selected);
iGotoRecord = 1;
break;
} else if (button_action == BUTTON_HOLD) {
Dbprintf("Playtime over. Begin cloning...");
iGotoClone = 1;
break;
}
}
/* We pressed a button so ignore it here with a delay */
SpinDelay(300);
LEDsoff();
LED(selected + 1, 0);
}
}
/* We pressed a button so ignore it here with a delay */
SpinDelay(300);
LEDsoff();
LED(selected + 1, 0);
}
}
}

View file

@ -28,296 +28,296 @@
// samy's sniff and repeat routine for LF
void RunMod() {
StandAloneMode();
Dbprintf(">> LF HID corporate bruteforce a.k.a CorporateBrute Started <<");
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
StandAloneMode();
Dbprintf(">> LF HID corporate bruteforce a.k.a CorporateBrute Started <<");
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
uint32_t high[OPTS], low[OPTS];
int selected = 0;
int playing = 0;
int cardRead = 0;
uint32_t high[OPTS], low[OPTS];
int selected = 0;
int playing = 0;
int cardRead = 0;
// Turn on selected LED
LED(selected + 1, 0);
// Turn on selected LED
LED(selected + 1, 0);
for (;;) {
WDT_HIT();
for (;;) {
WDT_HIT();
// exit from SamyRun, send a usbcommand.
if (usb_poll_validate_length()) break;
// exit from SamyRun, send a usbcommand.
if (usb_poll_validate_length()) break;
// Was our button held down or pressed?
int button_pressed = BUTTON_HELD(1000);
SpinDelay(300);
// Was our button held down or pressed?
int button_pressed = BUTTON_HELD(1000);
SpinDelay(300);
// Button was held for a second, begin recording
if (button_pressed > 0 && cardRead == 0) {
LEDsoff();
LED(selected + 1, 0);
LED(LED_RED2, 0);
// Button was held for a second, begin recording
if (button_pressed > 0 && cardRead == 0) {
LEDsoff();
LED(selected + 1, 0);
LED(LED_RED2, 0);
// record
DbpString("[=] starting recording");
// record
DbpString("[=] starting recording");
// wait for button to be released
while(BUTTON_PRESS())
WDT_HIT();
// wait for button to be released
while(BUTTON_PRESS())
WDT_HIT();
/* need this delay to prevent catching some weird data */
SpinDelay(500);
/* need this delay to prevent catching some weird data */
SpinDelay(500);
CmdHIDdemodFSK(1, &high[selected], &low[selected], 0);
Dbprintf("[=] recorded %x %x %08x", selected, high[selected], low[selected]);
CmdHIDdemodFSK(1, &high[selected], &low[selected], 0);
Dbprintf("[=] recorded %x %x %08x", selected, high[selected], low[selected]);
LEDsoff();
LED(selected + 1, 0);
// Finished recording
// If we were previously playing, set playing off
// so next button push begins playing what we recorded
playing = 0;
cardRead = 1;
}
else if (button_pressed > 0 && cardRead == 1) {
LEDsoff();
LED(selected + 1, 0);
LED(LED_ORANGE, 0);
LEDsoff();
LED(selected + 1, 0);
// Finished recording
// If we were previously playing, set playing off
// so next button push begins playing what we recorded
playing = 0;
cardRead = 1;
}
else if (button_pressed > 0 && cardRead == 1) {
LEDsoff();
LED(selected + 1, 0);
LED(LED_ORANGE, 0);
// record
Dbprintf("[=] cloning %x %x %08x", selected, high[selected], low[selected]);
// record
Dbprintf("[=] cloning %x %x %08x", selected, high[selected], low[selected]);
// wait for button to be released
while(BUTTON_PRESS())
WDT_HIT();
// wait for button to be released
while(BUTTON_PRESS())
WDT_HIT();
/* need this delay to prevent catching some weird data */
SpinDelay(500);
/* need this delay to prevent catching some weird data */
SpinDelay(500);
CopyHIDtoT55x7(0, high[selected], low[selected], 0);
Dbprintf("[=] cloned %x %x %08x", selected, high[selected], low[selected]);
CopyHIDtoT55x7(0, high[selected], low[selected], 0);
Dbprintf("[=] cloned %x %x %08x", selected, high[selected], low[selected]);
LEDsoff();
LED(selected + 1, 0);
// Finished recording
LEDsoff();
LED(selected + 1, 0);
// Finished recording
// If we were previously playing, set playing off
// so next button push begins playing what we recorded
playing = 0;
cardRead = 0;
}
// If we were previously playing, set playing off
// so next button push begins playing what we recorded
playing = 0;
cardRead = 0;
}
// Change where to record (or begin playing)
else if (button_pressed) {
// Next option if we were previously playing
if (playing)
selected = (selected + 1) % OPTS;
// Change where to record (or begin playing)
else if (button_pressed) {
// Next option if we were previously playing
if (playing)
selected = (selected + 1) % OPTS;
playing = !playing;
playing = !playing;
LEDsoff();
LED(selected + 1, 0);
LEDsoff();
LED(selected + 1, 0);
// Begin transmitting
if (playing && selected != 2) {
// Begin transmitting
if (playing && selected != 2) {
LED(LED_GREEN, 0);
DbpString("[=] playing");
LED(LED_GREEN, 0);
DbpString("[=] playing");
// wait for button to be released
while (BUTTON_PRESS())
WDT_HIT();
// wait for button to be released
while (BUTTON_PRESS())
WDT_HIT();
Dbprintf("[=] %x %x %08x", selected, high[selected], low[selected]);
CmdHIDsimTAG(high[selected], low[selected], 0);
DbpString("[=] done playing");
Dbprintf("[=] %x %x %08x", selected, high[selected], low[selected]);
CmdHIDsimTAG(high[selected], low[selected], 0);
DbpString("[=] done playing");
if (BUTTON_HELD(1000) > 0)
goto out;
if (BUTTON_HELD(1000) > 0)
goto out;
/* We pressed a button so ignore it here with a delay */
SpinDelay(300);
/* We pressed a button so ignore it here with a delay */
SpinDelay(300);
// when done, we're done playing, move to next option
selected = (selected + 1) % OPTS;
playing = !playing;
LEDsoff();
LED(selected + 1, 0);
}
else if (playing && selected == 2)
{
// Now it work only with HID Corporate 1000 (35bit), but is easily extensible to others RFID.
// It is necessary only to calculate the correct parity.
// when done, we're done playing, move to next option
selected = (selected + 1) % OPTS;
playing = !playing;
LEDsoff();
LED(selected + 1, 0);
}
else if (playing && selected == 2)
{
// Now it work only with HID Corporate 1000 (35bit), but is easily extensible to others RFID.
// It is necessary only to calculate the correct parity.
// Brute force code
// Check if the badge is an HID Corporate 1000
if( (high[selected] & 0xFFFFFFF8) != 0x28 ) {
DbpString("[-] Card is not a HID Corporate 1000. Skipping bruteforce.");
continue;
}
// Brute force code
// Check if the badge is an HID Corporate 1000
if( (high[selected] & 0xFFFFFFF8) != 0x28 ) {
DbpString("[-] Card is not a HID Corporate 1000. Skipping bruteforce.");
continue;
}
LED(LED_GREEN, 0);
DbpString("[=] entering bruteforce mode");
// wait for button to be released
while (BUTTON_PRESS())
WDT_HIT();
LED(LED_GREEN, 0);
DbpString("[=] entering bruteforce mode");
// wait for button to be released
while (BUTTON_PRESS())
WDT_HIT();
// Calculate Facility Code and Card Number from high and low
uint32_t cardnum = (low[selected] >> 1) & 0xFFFFF;
uint32_t fc = ((high[selected] & 1 ) << 11 ) | (low[selected] >> 21);
uint32_t original_cardnum = cardnum;
// Calculate Facility Code and Card Number from high and low
uint32_t cardnum = (low[selected] >> 1) & 0xFFFFF;
uint32_t fc = ((high[selected] & 1 ) << 11 ) | (low[selected] >> 21);
uint32_t original_cardnum = cardnum;
Dbprintf("[=] Proxbrute - starting decrementing card number");
Dbprintf("[=] Proxbrute - starting decrementing card number");
while (cardnum >= 0) {
while (cardnum >= 0) {
// Needed for exiting from proxbrute when button is pressed
if (BUTTON_PRESS()) {
if (BUTTON_HELD(1000) > 0) {
goto out;
} else {
while (BUTTON_PRESS()) {
WDT_HIT();
}
break;
}
}
// Needed for exiting from proxbrute when button is pressed
if (BUTTON_PRESS()) {
if (BUTTON_HELD(1000) > 0) {
goto out;
} else {
while (BUTTON_PRESS()) {
WDT_HIT();
}
break;
}
}
// Decrement Card Number
cardnum--;
// Decrement Card Number
cardnum--;
// Calculate checksum of HID Corporate 1000 and set card number and facility code in high and low variables
hid_corporate_1000_calculate_checksum_and_set(&high[selected], &low[selected], cardnum, fc);
// Calculate checksum of HID Corporate 1000 and set card number and facility code in high and low variables
hid_corporate_1000_calculate_checksum_and_set(&high[selected], &low[selected], cardnum, fc);
// Print actual code to brute
Dbprintf("[=] TAG ID: %x%08x (%d) - FC: %u - Card: %u", high[selected], low[selected], (low[selected] >> 1) & 0xFFFF, fc, cardnum);
// Print actual code to brute
Dbprintf("[=] TAG ID: %x%08x (%d) - FC: %u - Card: %u", high[selected], low[selected], (low[selected] >> 1) & 0xFFFF, fc, cardnum);
CmdHIDsimTAGEx(high[selected], low[selected], 1, 50000);
}
CmdHIDsimTAGEx(high[selected], low[selected], 1, 50000);
}
cardnum = original_cardnum;
cardnum = original_cardnum;
Dbprintf("[=] Proxbrute - starting incrementing card number");
Dbprintf("[=] Proxbrute - starting incrementing card number");
while (cardnum <= 0xFFFFF) {
while (cardnum <= 0xFFFFF) {
// Needed for exiting from proxbrute when button is pressed
if (BUTTON_PRESS()) {
if (BUTTON_HELD(1000) > 0) {
goto out;
} else {
while (BUTTON_PRESS()) { WDT_HIT(); }
break;
}
}
// Needed for exiting from proxbrute when button is pressed
if (BUTTON_PRESS()) {
if (BUTTON_HELD(1000) > 0) {
goto out;
} else {
while (BUTTON_PRESS()) { WDT_HIT(); }
break;
}
}
// Decrement Card Number
cardnum++;
// Decrement Card Number
cardnum++;
// Calculate checksum of HID Corporate 1000 and set card number and facility code in high and low variables
hid_corporate_1000_calculate_checksum_and_set(&high[selected], &low[selected], cardnum, fc);
// Calculate checksum of HID Corporate 1000 and set card number and facility code in high and low variables
hid_corporate_1000_calculate_checksum_and_set(&high[selected], &low[selected], cardnum, fc);
// Print actual code to brute
Dbprintf("[=] TAG ID: %x%08x (%d) - FC: %u - Card: %u", high[selected], low[selected], (low[selected] >> 1) & 0xFFFF, fc, cardnum);
// Print actual code to brute
Dbprintf("[=] TAG ID: %x%08x (%d) - FC: %u - Card: %u", high[selected], low[selected], (low[selected] >> 1) & 0xFFFF, fc, cardnum);
CmdHIDsimTAGEx(high[selected], low[selected], 1, 50000);
}
CmdHIDsimTAGEx(high[selected], low[selected], 1, 50000);
}
DbpString("[=] done bruteforcing");
if (BUTTON_HELD(1000) > 0)
goto out;
DbpString("[=] done bruteforcing");
if (BUTTON_HELD(1000) > 0)
goto out;
/* We pressed a button so ignore it here with a delay */
SpinDelay(300);
/* We pressed a button so ignore it here with a delay */
SpinDelay(300);
// when done, we're done playing, move to next option
selected = (selected + 1) % OPTS;
playing = !playing;
LEDsoff();
LED(selected + 1, 0);
// when done, we're done playing, move to next option
selected = (selected + 1) % OPTS;
playing = !playing;
LEDsoff();
LED(selected + 1, 0);
} else {
while(BUTTON_PRESS())
WDT_HIT();
}
}
}
} else {
while(BUTTON_PRESS())
WDT_HIT();
}
}
}
out:
DbpString("[=] exiting");
LEDsoff();
DbpString("[=] exiting");
LEDsoff();
}
// Function that calculate next value for the brutforce of HID corporate 1000
void hid_corporate_1000_calculate_checksum_and_set( uint32_t *high, uint32_t *low, uint32_t cardnum, uint32_t fc) {
uint32_t new_high = 0;
uint32_t new_low = 0;
uint32_t new_high = 0;
uint32_t new_low = 0;
// Calculate new high and low base value from card number and facility code, without parity
new_low = (fc << 21) | (cardnum << 1);
new_high = 0x28 | ((fc >> 11) & 1); // 0x28 is 101000
// Calculate new high and low base value from card number and facility code, without parity
new_low = (fc << 21) | (cardnum << 1);
new_high = 0x28 | ((fc >> 11) & 1); // 0x28 is 101000
int n_ones;
uint32_t i;
int n_ones;
uint32_t i;
// Calculating and setting parity bit 34
// Select only bit used for parity bit 34 in low number (10110110110110110110110110110110)
uint32_t parity_bit_34_low = new_low & 0xB6DB6DB6;
n_ones = 0;
// Calculate number of ones in low number
for ( i = 1; i != 0; i <<= 1) {
if( parity_bit_34_low & i )
n_ones++;
}
// Calculate number of ones in high number
if (new_high & 1)
n_ones++;
// Calculating and setting parity bit 34
// Select only bit used for parity bit 34 in low number (10110110110110110110110110110110)
uint32_t parity_bit_34_low = new_low & 0xB6DB6DB6;
n_ones = 0;
// Calculate number of ones in low number
for ( i = 1; i != 0; i <<= 1) {
if( parity_bit_34_low & i )
n_ones++;
}
// Calculate number of ones in high number
if (new_high & 1)
n_ones++;
// Set parity bit (Even parity)
if (n_ones % 2)
new_high = new_high | 0x2;
// Set parity bit (Even parity)
if (n_ones % 2)
new_high = new_high | 0x2;
// Calculating and setting parity bit 1
// Select only bit used for parity bit 1 in low number (01101101101101101101101101101100)
uint32_t parity_bit_1_low = new_low & 0x6DB6DB6C;
n_ones = 0;
// Calculating and setting parity bit 1
// Select only bit used for parity bit 1 in low number (01101101101101101101101101101100)
uint32_t parity_bit_1_low = new_low & 0x6DB6DB6C;
n_ones = 0;
// Calculate number of ones in low number
for ( i=1; i != 0; i <<= 1) {
if( parity_bit_1_low & i )
n_ones++;
}
// Calculate number of ones in high number
if ( new_high & 0x1)
n_ones++;
// Calculate number of ones in low number
for ( i=1; i != 0; i <<= 1) {
if( parity_bit_1_low & i )
n_ones++;
}
// Calculate number of ones in high number
if ( new_high & 0x1)
n_ones++;
if ( new_high & 0x2)
n_ones++;
if ( new_high & 0x2)
n_ones++;
// Set parity bit (Odd parity)
if (!(n_ones % 2))
new_low = new_low | 0x1;
// Set parity bit (Odd parity)
if (!(n_ones % 2))
new_low = new_low | 0x1;
// Calculating and setting parity bit 35
n_ones = 0;
// Calculate number of ones in low number (all bit of low, bitmask unnecessary)
for (i = 1; i != 0; i <<= 1) {
if ( new_low & i )
n_ones++;
}
// Calculate number of ones in high number
if ( new_high & 0x1)
n_ones++;
// Calculating and setting parity bit 35
n_ones = 0;
// Calculate number of ones in low number (all bit of low, bitmask unnecessary)
for (i = 1; i != 0; i <<= 1) {
if ( new_low & i )
n_ones++;
}
// Calculate number of ones in high number
if ( new_high & 0x1)
n_ones++;
if ( new_high & 0x2)
n_ones++;
if ( new_high & 0x2)
n_ones++;
// Set parity bit (Odd parity)
if (!(n_ones % 2))
new_high = new_high | 0x4;
// Set parity bit (Odd parity)
if (!(n_ones % 2))
new_high = new_high | 0x4;
// Setting new calculated values
*low = new_low;
*high = new_high;
// Setting new calculated values
*low = new_low;
*high = new_high;
}
// prepare a waveform pattern in the buffer based on the ID given then

View file

@ -13,157 +13,157 @@
// samy's sniff and repeat routine for LF
void RunMod() {
StandAloneMode();
Dbprintf(">> LF HID proxII bruteforce a.k.a ProxBrute Started (Brad Antoniewicz) <<");
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
StandAloneMode();
Dbprintf(">> LF HID proxII bruteforce a.k.a ProxBrute Started (Brad Antoniewicz) <<");
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
uint32_t high[OPTS], low[OPTS];
int selected = 0;
int playing = 0;
int cardRead = 0;
uint32_t high[OPTS], low[OPTS];
int selected = 0;
int playing = 0;
int cardRead = 0;
// Turn on selected LED
LED(selected + 1, 0);
// Turn on selected LED
LED(selected + 1, 0);
for (;;) {
WDT_HIT();
for (;;) {
WDT_HIT();
// exit from SamyRun, send a usbcommand.
if (usb_poll_validate_length()) break;
// exit from SamyRun, send a usbcommand.
if (usb_poll_validate_length()) break;
// Was our button held down or pressed?
int button_pressed = BUTTON_HELD(1000);
SpinDelay(300);
// Was our button held down or pressed?
int button_pressed = BUTTON_HELD(1000);
SpinDelay(300);
// Button was held for a second, begin recording
if (button_pressed > 0 && cardRead == 0) {
LEDsoff();
LED(selected + 1, 0);
LED(LED_RED2, 0);
// Button was held for a second, begin recording
if (button_pressed > 0 && cardRead == 0) {
LEDsoff();
LED(selected + 1, 0);
LED(LED_RED2, 0);
// record
DbpString("[=] starting recording");
// record
DbpString("[=] starting recording");
// wait for button to be released
while (BUTTON_PRESS())
WDT_HIT();
// wait for button to be released
while (BUTTON_PRESS())
WDT_HIT();
/* need this delay to prevent catching some weird data */
SpinDelay(500);
/* need this delay to prevent catching some weird data */
SpinDelay(500);
CmdHIDdemodFSK(1, &high[selected], &low[selected], 0);
Dbprintf("[=] recorded %x %x %08x", selected, high[selected], low[selected]);
CmdHIDdemodFSK(1, &high[selected], &low[selected], 0);
Dbprintf("[=] recorded %x %x %08x", selected, high[selected], low[selected]);
LEDsoff();
LED(selected + 1, 0);
// Finished recording
// If we were previously playing, set playing off
// so next button push begins playing what we recorded
playing = 0;
cardRead = 1;
}
else if (button_pressed > 0 && cardRead == 1) {
LEDsoff();
LED(selected + 1, 0);
LED(LED_ORANGE, 0);
LEDsoff();
LED(selected + 1, 0);
// Finished recording
// If we were previously playing, set playing off
// so next button push begins playing what we recorded
playing = 0;
cardRead = 1;
}
else if (button_pressed > 0 && cardRead == 1) {
LEDsoff();
LED(selected + 1, 0);
LED(LED_ORANGE, 0);
// record
Dbprintf("[=] cloning %x %x %08x", selected, high[selected], low[selected]);
// record
Dbprintf("[=] cloning %x %x %08x", selected, high[selected], low[selected]);
// wait for button to be released
while (BUTTON_PRESS())
WDT_HIT();
// wait for button to be released
while (BUTTON_PRESS())
WDT_HIT();
/* need this delay to prevent catching some weird data */
SpinDelay(500);
/* need this delay to prevent catching some weird data */
SpinDelay(500);
CopyHIDtoT55x7(0, high[selected], low[selected], 0);
Dbprintf("[=] cloned %x %x %08x", selected, high[selected], low[selected]);
CopyHIDtoT55x7(0, high[selected], low[selected], 0);
Dbprintf("[=] cloned %x %x %08x", selected, high[selected], low[selected]);
LEDsoff();
LED(selected + 1, 0);
// Finished recording
LEDsoff();
LED(selected + 1, 0);
// Finished recording
// If we were previously playing, set playing off
// so next button push begins playing what we recorded
playing = 0;
cardRead = 0;
}
// If we were previously playing, set playing off
// so next button push begins playing what we recorded
playing = 0;
cardRead = 0;
}
// Change where to record (or begin playing)
else if (button_pressed) {
// Next option if we were previously playing
if (playing)
selected = (selected + 1) % OPTS;
playing = !playing;
// Change where to record (or begin playing)
else if (button_pressed) {
// Next option if we were previously playing
if (playing)
selected = (selected + 1) % OPTS;
playing = !playing;
LEDsoff();
LED(selected + 1, 0);
LEDsoff();
LED(selected + 1, 0);
// Begin transmitting
if (playing) {
LED(LED_GREEN, 0);
DbpString("[=] playing");
// wait for button to be released
while (BUTTON_PRESS())
WDT_HIT();
// Begin transmitting
if (playing) {
LED(LED_GREEN, 0);
DbpString("[=] playing");
// wait for button to be released
while (BUTTON_PRESS())
WDT_HIT();
/* START PROXBRUTE */
/* START PROXBRUTE */
/*
ProxBrute - brad a. - foundstone
/*
ProxBrute - brad a. - foundstone
Following code is a trivial brute forcer once you read a valid tag
the idea is you get a valid tag, then just try and brute force to
another priv level. The problem is that it has no idea if the code
worked or not, so its a crap shoot. One option is to time how long
it takes to get a valid ID then start from scratch every time.
*/
if ( selected == 1 ) {
DbpString("[=] entering ProxBrute Mode");
Dbprintf("[=] current Tag: Selected = %x Facility = %08x ID = %08x", selected, high[selected], low[selected]);
LED(LED_ORANGE, 0);
LED(LED_RED, 0);
for (uint16_t i = low[selected]-1; i > 0; i--) {
if (BUTTON_PRESS()) {
DbpString("[-] told to stop");
break;
}
Following code is a trivial brute forcer once you read a valid tag
the idea is you get a valid tag, then just try and brute force to
another priv level. The problem is that it has no idea if the code
worked or not, so its a crap shoot. One option is to time how long
it takes to get a valid ID then start from scratch every time.
*/
if ( selected == 1 ) {
DbpString("[=] entering ProxBrute Mode");
Dbprintf("[=] current Tag: Selected = %x Facility = %08x ID = %08x", selected, high[selected], low[selected]);
LED(LED_ORANGE, 0);
LED(LED_RED, 0);
for (uint16_t i = low[selected]-1; i > 0; i--) {
if (BUTTON_PRESS()) {
DbpString("[-] told to stop");
break;
}
Dbprintf("[=] trying Facility = %08x ID %08x", high[selected], i);
CmdHIDsimTAGEx(high[selected], i, 0, 20000);
SpinDelay(500);
}
Dbprintf("[=] trying Facility = %08x ID %08x", high[selected], i);
CmdHIDsimTAGEx(high[selected], i, 0, 20000);
SpinDelay(500);
}
} else {
DbpString("[=] RED is lit, not entering ProxBrute Mode");
Dbprintf("[=] %x %x %x", selected, high[selected], low[selected]);
CmdHIDsimTAGEx(high[selected], low[selected], 0, 20000);
DbpString("[=] done playing");
}
} else {
DbpString("[=] RED is lit, not entering ProxBrute Mode");
Dbprintf("[=] %x %x %x", selected, high[selected], low[selected]);
CmdHIDsimTAGEx(high[selected], low[selected], 0, 20000);
DbpString("[=] done playing");
}
/* END PROXBRUTE */
/* END PROXBRUTE */
if (BUTTON_HELD(1000) > 0)
goto out;
if (BUTTON_HELD(1000) > 0)
goto out;
/* We pressed a button so ignore it here with a delay */
SpinDelay(300);
/* We pressed a button so ignore it here with a delay */
SpinDelay(300);
// when done, we're done playing, move to next option
selected = (selected + 1) % OPTS;
playing = !playing;
LEDsoff();
LED(selected + 1, 0);
}
else {
while (BUTTON_PRESS())
WDT_HIT();
}
}
}
// when done, we're done playing, move to next option
selected = (selected + 1) % OPTS;
playing = !playing;
LEDsoff();
LED(selected + 1, 0);
}
else {
while (BUTTON_PRESS())
WDT_HIT();
}
}
}
out:
DbpString("[=] exiting");
LEDsoff();
DbpString("[=] exiting");
LEDsoff();
}

View file

@ -12,132 +12,132 @@
// samy's sniff and repeat routine for LF
void RunMod() {
StandAloneMode();
Dbprintf(">> LF HID Read/Clone/Sim a.k.a SamyRun Started <<");
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
StandAloneMode();
Dbprintf(">> LF HID Read/Clone/Sim a.k.a SamyRun Started <<");
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
uint32_t high[OPTS], low[OPTS];
int selected = 0;
int playing = 0;
int cardRead = 0;
bool gotCard;
// Turn on selected LED
LED(selected + 1, 0);
uint32_t high[OPTS], low[OPTS];
int selected = 0;
int playing = 0;
int cardRead = 0;
bool gotCard;
// Turn on selected LED
LED(selected + 1, 0);
for (;;) {
WDT_HIT();
for (;;) {
WDT_HIT();
// exit from SamyRun, send a usbcommand.
if (usb_poll_validate_length()) break;
// exit from SamyRun, send a usbcommand.
if (usb_poll_validate_length()) break;
// Was our button held down or pressed?
int button_pressed = BUTTON_HELD(1000);
// Was our button held down or pressed?
int button_pressed = BUTTON_HELD(1000);
Dbprintf("button %d", button_pressed);
SpinDelay(300);
Dbprintf("button %d", button_pressed);
SpinDelay(300);
// Button was held for a second, begin recording
if (button_pressed > 0 && cardRead == 0) {
LEDsoff();
LED(selected + 1, 0);
LED(LED_RED2, 0);
// Button was held for a second, begin recording
if (button_pressed > 0 && cardRead == 0) {
LEDsoff();
LED(selected + 1, 0);
LED(LED_RED2, 0);
// record
DbpString("[=] starting recording");
// record
DbpString("[=] starting recording");
// wait for button to be released
while (BUTTON_PRESS())
WDT_HIT();
// wait for button to be released
while (BUTTON_PRESS())
WDT_HIT();
/* need this delay to prevent catching some weird data */
SpinDelay(500);
/* need this delay to prevent catching some weird data */
SpinDelay(500);
CmdHIDdemodFSK(1, &high[selected], &low[selected], 0);
Dbprintf("[=] recorded bank %x | %x %08x", selected, high[selected], low[selected]);
CmdHIDdemodFSK(1, &high[selected], &low[selected], 0);
Dbprintf("[=] recorded bank %x | %x %08x", selected, high[selected], low[selected]);
LEDsoff();
LED(selected + 1, 0);
// Finished recording
// If we were previously playing, set playing off
// so next button push begins playing what we recorded
playing = 0;
cardRead = 1;
LEDsoff();
LED(selected + 1, 0);
// Finished recording
// If we were previously playing, set playing off
// so next button push begins playing what we recorded
playing = 0;
cardRead = 1;
gotCard = true;
}
else if (button_pressed > 0 && cardRead == 1) {
LEDsoff();
LED(selected + 1, 0);
LED(LED_ORANGE, 0);
gotCard = true;
}
else if (button_pressed > 0 && cardRead == 1) {
LEDsoff();
LED(selected + 1, 0);
LED(LED_ORANGE, 0);
// record
Dbprintf("[=] cloning %x %x %08x", selected, high[selected], low[selected]);
// record
Dbprintf("[=] cloning %x %x %08x", selected, high[selected], low[selected]);
// wait for button to be released
while (BUTTON_PRESS())
WDT_HIT();
// wait for button to be released
while (BUTTON_PRESS())
WDT_HIT();
/* need this delay to prevent catching some weird data */
SpinDelay(500);
/* need this delay to prevent catching some weird data */
SpinDelay(500);
CopyHIDtoT55x7(0, high[selected], low[selected], 0);
Dbprintf("[=] cloned %x %x %08x", selected, high[selected], low[selected]);
CopyHIDtoT55x7(0, high[selected], low[selected], 0);
Dbprintf("[=] cloned %x %x %08x", selected, high[selected], low[selected]);
LEDsoff();
LED(selected + 1, 0);
// Finished recording
LEDsoff();
LED(selected + 1, 0);
// Finished recording
// If we were previously playing, set playing off
// so next button push begins playing what we recorded
playing = 0;
cardRead = 0;
}
// If we were previously playing, set playing off
// so next button push begins playing what we recorded
playing = 0;
cardRead = 0;
}
// Change where to record (or begin playing)
else if (button_pressed && gotCard) {
// Next option if we were previously playing
if (playing)
selected = (selected + 1) % OPTS;
// Change where to record (or begin playing)
else if (button_pressed && gotCard) {
// Next option if we were previously playing
if (playing)
selected = (selected + 1) % OPTS;
playing = !playing;
playing = !playing;
LEDsoff();
LED(selected + 1, 0);
LEDsoff();
LED(selected + 1, 0);
// Begin transmitting
if (playing) {
// Begin transmitting
if (playing) {
LED(LED_GREEN, 0);
DbpString("[=] playing");
LED(LED_GREEN, 0);
DbpString("[=] playing");
// wait for button to be released
while (BUTTON_PRESS())
WDT_HIT();
// wait for button to be released
while (BUTTON_PRESS())
WDT_HIT();
Dbprintf("[=] %x %x %08x", selected, high[selected], low[selected]);
CmdHIDsimTAG(high[selected], low[selected], false);
DbpString("[=] done playing");
Dbprintf("[=] %x %x %08x", selected, high[selected], low[selected]);
CmdHIDsimTAG(high[selected], low[selected], false);
DbpString("[=] done playing");
if (BUTTON_HELD(1000) > 0)
goto out;
if (BUTTON_HELD(1000) > 0)
goto out;
/* We pressed a button so ignore it here with a delay */
SpinDelay(300);
/* We pressed a button so ignore it here with a delay */
SpinDelay(300);
// when done, we're done playing, move to next option
selected = (selected + 1) % OPTS;
playing = !playing;
LEDsoff();
LED(selected + 1, 0);
}
else {
while (BUTTON_PRESS())
WDT_HIT();
}
}
}
// when done, we're done playing, move to next option
selected = (selected + 1) % OPTS;
playing = !playing;
LEDsoff();
LED(selected + 1, 0);
}
else {
while (BUTTON_PRESS())
WDT_HIT();
}
}
}
out:
DbpString("[=] exiting");
LEDsoff();
DbpString("[=] exiting");
LEDsoff();
}

View file

@ -11,19 +11,19 @@ Each standalone mod needs to have its own compiler flag to be added in `armsrc\m
The RunMod function is your "main" function when running. You need to check for Usb commands, in order to let the pm3 client break the standalone mode. See this basic skeleton of main function RunMod().
````
void RunMod() {
// led show
StandAloneMode();
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
// led show
StandAloneMode();
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
// main loop
for (;;) {
WDT_HIT();
// exit from standalone mode, just send a usbcommand
if (usb_poll_validate_length()) break;
// do your standalone stuff..
}
// main loop
for (;;) {
WDT_HIT();
// exit from standalone mode, just send a usbcommand
if (usb_poll_validate_length()) break;
// do your standalone stuff..
}
````
As it is now, you can only have one standalone mode installed at the time.
@ -47,9 +47,9 @@ Add your source code file like the following sample in the `armsrc\makefile`
```
# WITH_HF_COLIN
ifneq (,$(findstring WITH_HF_COLIN,$(APP_CFLAGS)))
SRC_STANDALONE = hf_colin.c vtsend.c
SRC_STANDALONE = hf_colin.c vtsend.c
else
SRC_STANDALONE =
SRC_STANDALONE =
endif
```
@ -67,36 +67,36 @@ Once all this is done, you and others can now easily compile different standalon
````
#remove one of the following defines and comment out the relevant line
#in the next section to remove that particular feature from compilation.
# NO space,TABs after the "\" sign.
# NO space,TABs after the "\" sign.
APP_CFLAGS = -DWITH_CRC \
-DON_DEVICE \
-DWITH_LF \
-DWITH_HITAG \
-DWITH_ISO15693 \
-DWITH_LEGICRF \
-DWITH_ISO14443b \
-DWITH_ISO14443a \
-DWITH_ICLASS \
-DWITH_FELICA \
-DWITH_FLASH \
-DWITH_SMARTCARD \
-DWITH_HFSNOOP \
-DWITH_HF_COLIN\
-DWITH_FPC \
-fno-strict-aliasing -ffunction-sections -fdata-sections
-DON_DEVICE \
-DWITH_LF \
-DWITH_HITAG \
-DWITH_ISO15693 \
-DWITH_LEGICRF \
-DWITH_ISO14443b \
-DWITH_ISO14443a \
-DWITH_ICLASS \
-DWITH_FELICA \
-DWITH_FLASH \
-DWITH_SMARTCARD \
-DWITH_HFSNOOP \
-DWITH_HF_COLIN\
-DWITH_FPC \
-fno-strict-aliasing -ffunction-sections -fdata-sections
### IMPORTANT - move the commented variable below this line
# -DWITH_LCD \
# -DWITH_EMV \
# -DWITH_FPC \
# -DWITH_LCD \
# -DWITH_EMV \
# -DWITH_FPC \
#
# Standalone Mods
#-------------------------------------------------------
# -DWITH_LF_ICERUN
# -DWITH_LF_SAMYRUN
# -DWITH_LF_PROXBRUTE
# -DWITH_LF_HIDBRUTE
# -DWITH_HF_YOUNG
# -DWITH_HF_MATTYRUN
# -DWITH_HF_COLIN
# -DWITH_LF_ICERUN
# -DWITH_LF_SAMYRUN
# -DWITH_LF_PROXBRUTE
# -DWITH_LF_HIDBRUTE
# -DWITH_HF_YOUNG
# -DWITH_HF_MATTYRUN
# -DWITH_HF_COLIN
````

View file

@ -11,8 +11,8 @@ import matplotlib.pyplot as plt
import sys
if len(sys.argv) != 2:
print "Usage: %s <basename>" % sys.argv[0]
sys.exit(1)
print "Usage: %s <basename>" % sys.argv[0]
sys.exit(1)
BASENAME = sys.argv[1]

View file

@ -1,26 +1,26 @@
#!/bin/bash
function wait4proxmark_Linux {
echo >&2 "Waiting for Proxmark to appear..."
while [ ! -c /dev/ttyACM? -a ! -L /dev/pm3-? ]; do
sleep .1
done
local PM3=`ls -1 /dev/pm3-? /dev/ttyACM? 2>/dev/null | head -1`
echo >&2 -e "Found proxmark on ${PM3}\n"
echo $PM3
echo >&2 "Waiting for Proxmark to appear..."
while [ ! -c /dev/ttyACM? -a ! -L /dev/pm3-? ]; do
sleep .1
done
local PM3=`ls -1 /dev/pm3-? /dev/ttyACM? 2>/dev/null | head -1`
echo >&2 -e "Found proxmark on ${PM3}\n"
echo $PM3
}
function wait4proxmark_macOS {
echo >&2 "Waiting for Proxmark to appear..."
while true; do
PM3=$(ls /dev/pm3-* /dev/cu.usbmodem* 2>/dev/null | head -1)
if [[ $PM3 != "" ]]; then
#echo >&2 -e "Found proxmark on $(ls /dev/pm3-* /dev/cu.usbmodem* 2>/dev/null | head -1)\n"
break
fi
sleep .1
done
echo $PM3
echo >&2 "Waiting for Proxmark to appear..."
while true; do
PM3=$(ls /dev/pm3-* /dev/cu.usbmodem* 2>/dev/null | head -1)
if [[ $PM3 != "" ]]; then
#echo >&2 -e "Found proxmark on $(ls /dev/pm3-* /dev/cu.usbmodem* 2>/dev/null | head -1)\n"
break
fi
sleep .1
done
echo $PM3
}
# start proxmark with first detected interface

View file

@ -44,11 +44,11 @@
#if defined (_WIN32)
#define SERIAL_PORT_H "com3"
#define SERIAL_PORT_H "com3"
#elif defined(__APPLE__)
#define SERIAL_PORT_H "/dev/cu.usbmodem"
#else
#define SERIAL_PORT_H "/dev/ttyACM0"
#define SERIAL_PORT_H "/dev/ttyACM0"
#endif
/* serial_port is declared as a void*, which you should cast to whatever type

View file

@ -62,363 +62,363 @@
typedef struct termios term_info;
typedef struct {
int fd; // Serial port file descriptor
term_info tiOld; // Terminal info before using the port
term_info tiNew; // Terminal info during the transaction
int fd; // Serial port file descriptor
term_info tiOld; // Terminal info before using the port
term_info tiNew; // Terminal info during the transaction
} serial_port_unix;
// Set time-out on 30 miliseconds
struct timeval timeout = {
.tv_sec = 0, // 0 second
.tv_usec = 30000 // 30 000 micro seconds
.tv_sec = 0, // 0 second
.tv_usec = 30000 // 30 000 micro seconds
};
serial_port uart_open(const char* pcPortName) {
serial_port_unix* sp = calloc(sizeof(serial_port_unix), sizeof(uint8_t));
if (sp == 0) return INVALID_SERIAL_PORT;
serial_port_unix* sp = calloc(sizeof(serial_port_unix), sizeof(uint8_t));
if (sp == 0) return INVALID_SERIAL_PORT;
if (memcmp(pcPortName, "tcp:", 4) == 0) {
struct addrinfo *addr, *rp;
char *addrstr = strdup(pcPortName + 4);
if (memcmp(pcPortName, "tcp:", 4) == 0) {
struct addrinfo *addr, *rp;
char *addrstr = strdup(pcPortName + 4);
if (addrstr == NULL) {
printf("Error: strdup\n");
free(sp);
return INVALID_SERIAL_PORT;
}
if (addrstr == NULL) {
printf("Error: strdup\n");
free(sp);
return INVALID_SERIAL_PORT;
}
timeout.tv_usec = 300000; // 300 000 micro seconds
timeout.tv_usec = 300000; // 300 000 micro seconds
char *colon = strrchr(addrstr, ':');
char *portstr;
if (colon) {
portstr = colon + 1;
*colon = '\0';
} else {
portstr = "7901";
}
char *colon = strrchr(addrstr, ':');
char *portstr;
if (colon) {
portstr = colon + 1;
*colon = '\0';
} else {
portstr = "7901";
}
int s = getaddrinfo(addrstr, portstr, NULL, &addr);
if (s != 0) {
printf("Error: getaddrinfo: %s\n", gai_strerror(s));
freeaddrinfo(addr);
free(addrstr);
free(sp);
return INVALID_SERIAL_PORT;
}
int s = getaddrinfo(addrstr, portstr, NULL, &addr);
if (s != 0) {
printf("Error: getaddrinfo: %s\n", gai_strerror(s));
freeaddrinfo(addr);
free(addrstr);
free(sp);
return INVALID_SERIAL_PORT;
}
int sfd;
for (rp = addr; rp != NULL; rp = rp->ai_next) {
sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
int sfd;
for (rp = addr; rp != NULL; rp = rp->ai_next) {
sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
if (sfd == -1)
continue;
if (sfd == -1)
continue;
if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1)
break;
if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1)
break;
close(sfd);
}
close(sfd);
}
if (rp == NULL) { /* No address succeeded */
printf("Error: Could not connect\n");
freeaddrinfo(addr);
free(addrstr);
free(sp);
return INVALID_SERIAL_PORT;
}
if (rp == NULL) { /* No address succeeded */
printf("Error: Could not connect\n");
freeaddrinfo(addr);
free(addrstr);
free(sp);
return INVALID_SERIAL_PORT;
}
freeaddrinfo(addr);
free(addrstr);
freeaddrinfo(addr);
free(addrstr);
sp->fd = sfd;
sp->fd = sfd;
int one = 1;
int res = setsockopt(sp->fd, SOL_TCP, TCP_NODELAY, &one, sizeof(one));
if ( res != 0) {
free(sp);
return INVALID_SERIAL_PORT;
}
return sp;
}
int one = 1;
int res = setsockopt(sp->fd, SOL_TCP, TCP_NODELAY, &one, sizeof(one));
if ( res != 0) {
free(sp);
return INVALID_SERIAL_PORT;
}
return sp;
}
sp->fd = open(pcPortName, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK);
if (sp->fd == -1) {
uart_close(sp);
return INVALID_SERIAL_PORT;
}
sp->fd = open(pcPortName, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK);
if (sp->fd == -1) {
uart_close(sp);
return INVALID_SERIAL_PORT;
}
// Finally figured out a way to claim a serial port interface under unix
// We just try to set a (advisory) lock on the file descriptor
struct flock fl;
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
fl.l_pid = getpid();
// Finally figured out a way to claim a serial port interface under unix
// We just try to set a (advisory) lock on the file descriptor
struct flock fl;
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
fl.l_pid = getpid();
// Does the system allows us to place a lock on this file descriptor
if (fcntl(sp->fd, F_SETLK, &fl) == -1) {
// A conflicting lock is held by another process
free(sp);
return CLAIMED_SERIAL_PORT;
}
// Does the system allows us to place a lock on this file descriptor
if (fcntl(sp->fd, F_SETLK, &fl) == -1) {
// A conflicting lock is held by another process
free(sp);
return CLAIMED_SERIAL_PORT;
}
// Try to retrieve the old (current) terminal info struct
if (tcgetattr(sp->fd,&sp->tiOld) == -1) {
uart_close(sp);
return INVALID_SERIAL_PORT;
}
// Try to retrieve the old (current) terminal info struct
if (tcgetattr(sp->fd,&sp->tiOld) == -1) {
uart_close(sp);
return INVALID_SERIAL_PORT;
}
// Duplicate the (old) terminal info struct
sp->tiNew = sp->tiOld;
// Duplicate the (old) terminal info struct
sp->tiNew = sp->tiOld;
// Configure the serial port
sp->tiNew.c_cflag = CS8 | CLOCAL | CREAD;
sp->tiNew.c_iflag = IGNPAR;
sp->tiNew.c_oflag = 0;
sp->tiNew.c_lflag = 0;
// Configure the serial port
sp->tiNew.c_cflag = CS8 | CLOCAL | CREAD;
sp->tiNew.c_iflag = IGNPAR;
sp->tiNew.c_oflag = 0;
sp->tiNew.c_lflag = 0;
// Block until n bytes are received
sp->tiNew.c_cc[VMIN] = 0;
// Block until a timer expires (n * 100 mSec.)
sp->tiNew.c_cc[VTIME] = 0;
// Block until n bytes are received
sp->tiNew.c_cc[VMIN] = 0;
// Block until a timer expires (n * 100 mSec.)
sp->tiNew.c_cc[VTIME] = 0;
// Try to set the new terminal info struct
if (tcsetattr(sp->fd, TCSANOW, &sp->tiNew) == -1) {
uart_close(sp);
return INVALID_SERIAL_PORT;
}
// Try to set the new terminal info struct
if (tcsetattr(sp->fd, TCSANOW, &sp->tiNew) == -1) {
uart_close(sp);
return INVALID_SERIAL_PORT;
}
// Flush all lingering data that may exist
tcflush(sp->fd, TCIOFLUSH);
#ifdef WITH_FPC
if ( uart_set_speed(sp, 115200) ) {
printf("[=] UART Setting serial baudrate 115200 [FPC enabled]\n");
} else {
uart_set_speed(sp, 9600);
printf("[=] UART Setting serial baudrate 9600 [FPC enabled]\n");
}
if ( uart_set_speed(sp, 115200) ) {
printf("[=] UART Setting serial baudrate 115200 [FPC enabled]\n");
} else {
uart_set_speed(sp, 9600);
printf("[=] UART Setting serial baudrate 9600 [FPC enabled]\n");
}
#else
// set speed, works for UBUNTU 14.04
bool success = uart_set_speed(sp, 460800);
if (success) {
printf("[=] UART Setting serial baudrate 460800\n");
} else {
uart_set_speed(sp, 115200);
printf("[=] UART Setting serial baudrate 115200\n");
}
// set speed, works for UBUNTU 14.04
bool success = uart_set_speed(sp, 460800);
if (success) {
printf("[=] UART Setting serial baudrate 460800\n");
} else {
uart_set_speed(sp, 115200);
printf("[=] UART Setting serial baudrate 115200\n");
}
#endif
return sp;
return sp;
}
void uart_close(const serial_port sp) {
serial_port_unix* spu = (serial_port_unix*)sp;
tcflush(spu->fd, TCIOFLUSH);
tcsetattr(spu->fd, TCSANOW, &(spu->tiOld));
struct flock fl;
fl.l_type = F_UNLCK;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
fl.l_pid = getpid();
serial_port_unix* spu = (serial_port_unix*)sp;
tcflush(spu->fd, TCIOFLUSH);
tcsetattr(spu->fd, TCSANOW, &(spu->tiOld));
struct flock fl;
fl.l_type = F_UNLCK;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
fl.l_pid = getpid();
// Does the system allows us to place a lock on this file descriptor
int err = fcntl(spu->fd, F_SETLK, &fl);
if ( err == -1) {
//perror("fcntl");
}
close(spu->fd);
free(sp);
// Does the system allows us to place a lock on this file descriptor
int err = fcntl(spu->fd, F_SETLK, &fl);
if ( err == -1) {
//perror("fcntl");
}
close(spu->fd);
free(sp);
}
bool uart_receive(const serial_port sp, uint8_t* pbtRx, size_t pszMaxRxLen, size_t* pszRxLen) {
int res;
int byteCount;
fd_set rfds;
struct timeval tv;
int res;
int byteCount;
fd_set rfds;
struct timeval tv;
// Reset the output count
*pszRxLen = 0;
// Reset the output count
*pszRxLen = 0;
do {
// Reset file descriptor
FD_ZERO(&rfds);
FD_SET(((serial_port_unix*)sp)->fd, &rfds);
tv = timeout;
res = select(((serial_port_unix*)sp)->fd + 1, &rfds, NULL, NULL, &tv);
do {
// Reset file descriptor
FD_ZERO(&rfds);
FD_SET(((serial_port_unix*)sp)->fd, &rfds);
tv = timeout;
res = select(((serial_port_unix*)sp)->fd + 1, &rfds, NULL, NULL, &tv);
// Read error
if (res < 0) {
return false;
}
// Read error
if (res < 0) {
return false;
}
// Read time-out
if (res == 0) {
if (*pszRxLen == 0) {
// Error, we received no data
return false;
} else {
// We received some data, but nothing more is available
return true;
}
}
// Read time-out
if (res == 0) {
if (*pszRxLen == 0) {
// Error, we received no data
return false;
} else {
// We received some data, but nothing more is available
return true;
}
}
// Retrieve the count of the incoming bytes
res = ioctl(((serial_port_unix*)sp)->fd, FIONREAD, &byteCount);
if (res < 0) return false;
// Retrieve the count of the incoming bytes
res = ioctl(((serial_port_unix*)sp)->fd, FIONREAD, &byteCount);
if (res < 0) return false;
// Cap the number of bytes, so we don't overrun the buffer
if (pszMaxRxLen - (*pszRxLen) < byteCount) {
byteCount = pszMaxRxLen - (*pszRxLen);
}
// Cap the number of bytes, so we don't overrun the buffer
if (pszMaxRxLen - (*pszRxLen) < byteCount) {
byteCount = pszMaxRxLen - (*pszRxLen);
}
// There is something available, read the data
res = read(((serial_port_unix*)sp)->fd, pbtRx + (*pszRxLen), byteCount);
// There is something available, read the data
res = read(((serial_port_unix*)sp)->fd, pbtRx + (*pszRxLen), byteCount);
// Stop if the OS has some troubles reading the data
if (res <= 0) return false;
// Stop if the OS has some troubles reading the data
if (res <= 0) return false;
*pszRxLen += res;
*pszRxLen += res;
if (*pszRxLen == pszMaxRxLen) {
// We have all the data we wanted.
return true;
}
if (*pszRxLen == pszMaxRxLen) {
// We have all the data we wanted.
return true;
}
} while (byteCount);
} while (byteCount);
return true;
return true;
}
bool uart_send(const serial_port sp, const uint8_t* pbtTx, const size_t len) {
int32_t res;
size_t pos = 0;
fd_set rfds;
struct timeval tv;
int32_t res;
size_t pos = 0;
fd_set rfds;
struct timeval tv;
while (pos < len) {
// Reset file descriptor
FD_ZERO(&rfds);
FD_SET(((serial_port_unix*)sp)->fd, &rfds);
tv = timeout;
res = select(((serial_port_unix*)sp)->fd+1, NULL, &rfds, NULL, &tv);
while (pos < len) {
// Reset file descriptor
FD_ZERO(&rfds);
FD_SET(((serial_port_unix*)sp)->fd, &rfds);
tv = timeout;
res = select(((serial_port_unix*)sp)->fd+1, NULL, &rfds, NULL, &tv);
// Write error
if (res < 0) {
printf("UART:: write error (%d)\n", res);
return false;
}
// Write error
if (res < 0) {
printf("UART:: write error (%d)\n", res);
return false;
}
// Write time-out
if (res == 0) {
printf("UART:: write time-out\n");
return false;
}
// Write time-out
if (res == 0) {
printf("UART:: write time-out\n");
return false;
}
// Send away the bytes
res = write(((serial_port_unix*)sp)->fd, pbtTx + pos, len - pos);
// Send away the bytes
res = write(((serial_port_unix*)sp)->fd, pbtTx + pos, len - pos);
// Stop if the OS has some troubles sending the data
if (res <= 0) return false;
// Stop if the OS has some troubles sending the data
if (res <= 0) return false;
pos += res;
}
return true;
pos += res;
}
return true;
}
bool uart_set_speed(serial_port sp, const uint32_t uiPortSpeed) {
const serial_port_unix* spu = (serial_port_unix*)sp;
speed_t stPortSpeed;
switch (uiPortSpeed) {
case 0: stPortSpeed = B0; break;
case 50: stPortSpeed = B50; break;
case 75: stPortSpeed = B75; break;
case 110: stPortSpeed = B110; break;
case 134: stPortSpeed = B134; break;
case 150: stPortSpeed = B150; break;
case 300: stPortSpeed = B300; break;
case 600: stPortSpeed = B600; break;
case 1200: stPortSpeed = B1200; break;
case 1800: stPortSpeed = B1800; break;
case 2400: stPortSpeed = B2400; break;
case 4800: stPortSpeed = B4800; break;
case 9600: stPortSpeed = B9600; break;
case 19200: stPortSpeed = B19200; break;
case 38400: stPortSpeed = B38400; break;
const serial_port_unix* spu = (serial_port_unix*)sp;
speed_t stPortSpeed;
switch (uiPortSpeed) {
case 0: stPortSpeed = B0; break;
case 50: stPortSpeed = B50; break;
case 75: stPortSpeed = B75; break;
case 110: stPortSpeed = B110; break;
case 134: stPortSpeed = B134; break;
case 150: stPortSpeed = B150; break;
case 300: stPortSpeed = B300; break;
case 600: stPortSpeed = B600; break;
case 1200: stPortSpeed = B1200; break;
case 1800: stPortSpeed = B1800; break;
case 2400: stPortSpeed = B2400; break;
case 4800: stPortSpeed = B4800; break;
case 9600: stPortSpeed = B9600; break;
case 19200: stPortSpeed = B19200; break;
case 38400: stPortSpeed = B38400; break;
# ifdef B57600
case 57600: stPortSpeed = B57600; break;
case 57600: stPortSpeed = B57600; break;
# endif
# ifdef B115200
case 115200: stPortSpeed = B115200; break;
case 115200: stPortSpeed = B115200; break;
# endif
# ifdef B230400
case 230400: stPortSpeed = B230400; break;
case 230400: stPortSpeed = B230400; break;
# endif
# ifdef B460800
case 460800: stPortSpeed = B460800; break;
case 460800: stPortSpeed = B460800; break;
# endif
# ifdef B921600
case 921600: stPortSpeed = B921600; break;
case 921600: stPortSpeed = B921600; break;
# endif
default: return false;
};
default: return false;
};
struct termios ti;
if (tcgetattr(spu->fd,&ti) == -1)
return false;
struct termios ti;
if (tcgetattr(spu->fd,&ti) == -1)
return false;
// Set port speed (Input and Output)
cfsetispeed(&ti, stPortSpeed);
cfsetospeed(&ti, stPortSpeed);
return (tcsetattr(spu->fd, TCSANOW, &ti) != -1);
// Set port speed (Input and Output)
cfsetispeed(&ti, stPortSpeed);
cfsetospeed(&ti, stPortSpeed);
return (tcsetattr(spu->fd, TCSANOW, &ti) != -1);
}
uint32_t uart_get_speed(const serial_port sp) {
struct termios ti;
uint32_t uiPortSpeed;
const serial_port_unix* spu = (serial_port_unix*)sp;
struct termios ti;
uint32_t uiPortSpeed;
const serial_port_unix* spu = (serial_port_unix*)sp;
if (tcgetattr(spu->fd, &ti) == -1)
return 0;
if (tcgetattr(spu->fd, &ti) == -1)
return 0;
// Set port speed (Input)
speed_t stPortSpeed = cfgetispeed(&ti);
switch (stPortSpeed) {
case B0: uiPortSpeed = 0; break;
case B50: uiPortSpeed = 50; break;
case B75: uiPortSpeed = 75; break;
case B110: uiPortSpeed = 110; break;
case B134: uiPortSpeed = 134; break;
case B150: uiPortSpeed = 150; break;
case B300: uiPortSpeed = 300; break;
case B600: uiPortSpeed = 600; break;
case B1200: uiPortSpeed = 1200; break;
case B1800: uiPortSpeed = 1800; break;
case B2400: uiPortSpeed = 2400; break;
case B4800: uiPortSpeed = 4800; break;
case B9600: uiPortSpeed = 9600; break;
case B19200: uiPortSpeed = 19200; break;
case B38400: uiPortSpeed = 38400; break;
// Set port speed (Input)
speed_t stPortSpeed = cfgetispeed(&ti);
switch (stPortSpeed) {
case B0: uiPortSpeed = 0; break;
case B50: uiPortSpeed = 50; break;
case B75: uiPortSpeed = 75; break;
case B110: uiPortSpeed = 110; break;
case B134: uiPortSpeed = 134; break;
case B150: uiPortSpeed = 150; break;
case B300: uiPortSpeed = 300; break;
case B600: uiPortSpeed = 600; break;
case B1200: uiPortSpeed = 1200; break;
case B1800: uiPortSpeed = 1800; break;
case B2400: uiPortSpeed = 2400; break;
case B4800: uiPortSpeed = 4800; break;
case B9600: uiPortSpeed = 9600; break;
case B19200: uiPortSpeed = 19200; break;
case B38400: uiPortSpeed = 38400; break;
# ifdef B57600
case B57600: uiPortSpeed = 57600; break;
case B57600: uiPortSpeed = 57600; break;
# endif
# ifdef B115200
case B115200: uiPortSpeed = 115200; break;
case B115200: uiPortSpeed = 115200; break;
# endif
# ifdef B230400
case B230400: uiPortSpeed = 230400; break;
case B230400: uiPortSpeed = 230400; break;
# endif
# ifdef B460800
case B460800: uiPortSpeed = 460800; break;
case B460800: uiPortSpeed = 460800; break;
# endif
# ifdef B921600
case B921600: uiPortSpeed = 921600; break;
case B921600: uiPortSpeed = 921600; break;
# endif
default: return 0;
};
return uiPortSpeed;
default: return 0;
};
return uiPortSpeed;
}
#endif

View file

@ -49,129 +49,129 @@ typedef struct {
} serial_port_windows;
serial_port uart_open(const char* pcPortName) {
char acPortName[255];
serial_port_windows* sp = calloc(sizeof(serial_port_windows), sizeof(uint8_t));
char acPortName[255];
serial_port_windows* sp = calloc(sizeof(serial_port_windows), sizeof(uint8_t));
if (sp == 0) {
printf("[!] UART failed to allocate memory\n");
return INVALID_SERIAL_PORT;
}
// Copy the input "com?" to "\\.\COM?" format
sprintf(acPortName,"\\\\.\\%s", pcPortName);
_strupr(acPortName);
if (sp == 0) {
printf("[!] UART failed to allocate memory\n");
return INVALID_SERIAL_PORT;
}
// Copy the input "com?" to "\\.\COM?" format
sprintf(acPortName,"\\\\.\\%s", pcPortName);
_strupr(acPortName);
// Try to open the serial port
// r/w, none-share comport, no security, existing, no overlapping, no templates
sp->hPort = CreateFileA(acPortName, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (sp->hPort == INVALID_HANDLE_VALUE) {
uart_close(sp);
return INVALID_SERIAL_PORT;
}
// Try to open the serial port
// r/w, none-share comport, no security, existing, no overlapping, no templates
sp->hPort = CreateFileA(acPortName, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (sp->hPort == INVALID_HANDLE_VALUE) {
uart_close(sp);
return INVALID_SERIAL_PORT;
}
// Prepare the device control
// doesn't matter since PM3 device ignors this CDC command: set_line_coding in usb_cdc.c
memset(&sp->dcb, 0, sizeof(DCB));
sp->dcb.DCBlength = sizeof(DCB);
if (!BuildCommDCBA("baud=115200 parity=N data=8 stop=1", &sp->dcb)) {
uart_close(sp);
printf("[!] UART error cdc setup\n");
return INVALID_SERIAL_PORT;
}
// Prepare the device control
// doesn't matter since PM3 device ignors this CDC command: set_line_coding in usb_cdc.c
memset(&sp->dcb, 0, sizeof(DCB));
sp->dcb.DCBlength = sizeof(DCB);
if (!BuildCommDCBA("baud=115200 parity=N data=8 stop=1", &sp->dcb)) {
uart_close(sp);
printf("[!] UART error cdc setup\n");
return INVALID_SERIAL_PORT;
}
// Update the active serial port
if (!SetCommState(sp->hPort, &sp->dcb)) {
uart_close(sp);
printf("[!] UART error while setting com state\n");
return INVALID_SERIAL_PORT;
}
// all zero's configure: no timeout for read/write used.
// took settings from libnfc/buses/uart.c
// Update the active serial port
if (!SetCommState(sp->hPort, &sp->dcb)) {
uart_close(sp);
printf("[!] UART error while setting com state\n");
return INVALID_SERIAL_PORT;
}
// all zero's configure: no timeout for read/write used.
// took settings from libnfc/buses/uart.c
#ifdef WITH_FPC
sp->ct.ReadIntervalTimeout = 1000;
sp->ct.ReadTotalTimeoutMultiplier = 0;
sp->ct.ReadTotalTimeoutConstant = 1500;
sp->ct.WriteTotalTimeoutMultiplier = 1000;
sp->ct.WriteTotalTimeoutConstant = 0;
sp->ct.ReadIntervalTimeout = 1000;
sp->ct.ReadTotalTimeoutMultiplier = 0;
sp->ct.ReadTotalTimeoutConstant = 1500;
sp->ct.WriteTotalTimeoutMultiplier = 1000;
sp->ct.WriteTotalTimeoutConstant = 0;
#else
sp->ct.ReadIntervalTimeout = 30;
sp->ct.ReadTotalTimeoutMultiplier = 0;
sp->ct.ReadTotalTimeoutConstant = 30;
sp->ct.WriteTotalTimeoutMultiplier = 30;
sp->ct.WriteTotalTimeoutConstant = 0;
sp->ct.ReadIntervalTimeout = 30;
sp->ct.ReadTotalTimeoutMultiplier = 0;
sp->ct.ReadTotalTimeoutConstant = 30;
sp->ct.WriteTotalTimeoutMultiplier = 30;
sp->ct.WriteTotalTimeoutConstant = 0;
#endif
if (!SetCommTimeouts(sp->hPort, &sp->ct)) {
uart_close(sp);
printf("[!] UART error while setting comm time outs\n");
return INVALID_SERIAL_PORT;
}
if (!SetCommTimeouts(sp->hPort, &sp->ct)) {
uart_close(sp);
printf("[!] UART error while setting comm time outs\n");
return INVALID_SERIAL_PORT;
}
PurgeComm(sp->hPort, PURGE_RXABORT | PURGE_RXCLEAR);
PurgeComm(sp->hPort, PURGE_RXABORT | PURGE_RXCLEAR);
#ifdef WITH_FPC
if ( uart_set_speed(sp, 115200) ) {
printf("[=] UART Setting serial baudrate 115200 [FPC enabled]\n");
} else {
uart_set_speed(sp, 9600);
printf("[=] UART Setting serial baudrate 9600 [FPC enabled]\n");
}
if ( uart_set_speed(sp, 115200) ) {
printf("[=] UART Setting serial baudrate 115200 [FPC enabled]\n");
} else {
uart_set_speed(sp, 9600);
printf("[=] UART Setting serial baudrate 9600 [FPC enabled]\n");
}
#else
bool success = uart_set_speed(sp, 460800);
if (success) {
printf("[=] UART Setting serial baudrate 460800\n");
} else {
uart_set_speed(sp, 115200);
printf("[=] UART Setting serial baudrate 115200\n");
}
bool success = uart_set_speed(sp, 460800);
if (success) {
printf("[=] UART Setting serial baudrate 460800\n");
} else {
uart_set_speed(sp, 115200);
printf("[=] UART Setting serial baudrate 115200\n");
}
#endif
return sp;
return sp;
}
void uart_close(const serial_port sp) {
if (((serial_port_windows*)sp)->hPort != INVALID_HANDLE_VALUE )
CloseHandle(((serial_port_windows*)sp)->hPort);
free(sp);
if (((serial_port_windows*)sp)->hPort != INVALID_HANDLE_VALUE )
CloseHandle(((serial_port_windows*)sp)->hPort);
free(sp);
}
bool uart_set_speed(serial_port sp, const uint32_t uiPortSpeed) {
serial_port_windows* spw;
serial_port_windows* spw;
// Set port speed (Input and Output)
switch (uiPortSpeed) {
case 9600:
case 19200:
case 38400:
case 57600:
case 115200:
case 230400:
case 460800:
break;
default:
return false;
};
// Set port speed (Input and Output)
switch (uiPortSpeed) {
case 9600:
case 19200:
case 38400:
case 57600:
case 115200:
case 230400:
case 460800:
break;
default:
return false;
};
spw = (serial_port_windows*)sp;
spw->dcb.BaudRate = uiPortSpeed;
bool result = SetCommState(spw->hPort, &spw->dcb);
PurgeComm(spw->hPort, PURGE_RXABORT | PURGE_RXCLEAR);
return result;
spw = (serial_port_windows*)sp;
spw->dcb.BaudRate = uiPortSpeed;
bool result = SetCommState(spw->hPort, &spw->dcb);
PurgeComm(spw->hPort, PURGE_RXABORT | PURGE_RXCLEAR);
return result;
}
uint32_t uart_get_speed(const serial_port sp) {
const serial_port_windows* spw = (serial_port_windows*)sp;
if (!GetCommState(spw->hPort, (serial_port) & spw->dcb))
return spw->dcb.BaudRate;
const serial_port_windows* spw = (serial_port_windows*)sp;
if (!GetCommState(spw->hPort, (serial_port) & spw->dcb))
return spw->dcb.BaudRate;
return 0;
return 0;
}
bool uart_receive(const serial_port sp, uint8_t* p_rx, size_t pszMaxRxLen, size_t* len) {
return ReadFile(((serial_port_windows*)sp)->hPort, p_rx, pszMaxRxLen, (LPDWORD)len, NULL);
return ReadFile(((serial_port_windows*)sp)->hPort, p_rx, pszMaxRxLen, (LPDWORD)len, NULL);
}
bool uart_send(const serial_port sp, const uint8_t* p_tx, const size_t len) {
DWORD txlen = 0;
return WriteFile(((serial_port_windows*)sp)->hPort, p_tx, len, &txlen, NULL);
DWORD txlen = 0;
return WriteFile(((serial_port_windows*)sp)->hPort, p_tx, len, &txlen, NULL);
}
#endif

View file

@ -1,26 +1,26 @@
#!/bin/bash
function wait4proxmark_Linux {
echo >&2 "Waiting for Proxmark to appear..."
while [ ! -c /dev/ttyACM? -a ! -L /dev/pm3-? ]; do
sleep .1
done
local PM3=`ls -1 /dev/pm3-? /dev/ttyACM? 2>/dev/null | head -1`
echo >&2 -e "Found proxmark on ${PM3}\n"
echo $PM3
echo >&2 "Waiting for Proxmark to appear..."
while [ ! -c /dev/ttyACM? -a ! -L /dev/pm3-? ]; do
sleep .1
done
local PM3=`ls -1 /dev/pm3-? /dev/ttyACM? 2>/dev/null | head -1`
echo >&2 -e "Found proxmark on ${PM3}\n"
echo $PM3
}
function wait4proxmark_macOS {
echo >&2 "Waiting for Proxmark to appear..."
while true; do
PM3=$(ls /dev/pm3-* /dev/cu.usbmodem* 2>/dev/null | head -1)
if [[ $PM3 != "" ]]; then
#echo >&2 -e "Found proxmark on $(ls /dev/pm3-* /dev/cu.usbmodem* 2>/dev/null | head -1)\n"
break
fi
sleep .1
done
echo $PM3
echo >&2 "Waiting for Proxmark to appear..."
while true; do
PM3=$(ls /dev/pm3-* /dev/cu.usbmodem* 2>/dev/null | head -1)
if [[ $PM3 != "" ]]; then
#echo >&2 -e "Found proxmark on $(ls /dev/pm3-* /dev/cu.usbmodem* 2>/dev/null | head -1)\n"
break
fi
sleep .1
done
echo $PM3
}
# Detect OS and flash bootroom & system image

View file

@ -1160,10 +1160,10 @@ local uInt longest_match(s, cur_match)
{
unsigned chain_length = s->max_chain_length;/* max hash chain length */
register Bytef *scan = s->window + s->strstart; /* current string */
register Bytef *match; /* matched string */
register Bytef *match; /* matched string */
register int len; /* length of current match */
#ifdef ZLIB_PM3_TUNED
int best_len = MIN_MATCH-1; // lift the restriction on prev-length
int best_len = MIN_MATCH-1; /* lift the restriction on prev-length */
#else
int best_len = s->prev_length; /* best match length so far */
#endif
@ -1737,73 +1737,73 @@ local block_state deflate_fast(s, flush)
#ifdef ZLIB_PM3_TUNED
local uInt try_harder(s, strstart, lookahead, hash_head)
deflate_state *s;
uInt strstart;
uInt lookahead;
IPos hash_head;
deflate_state *s;
uInt strstart;
uInt lookahead;
IPos hash_head;
{
uInt strstart_save = s->strstart;
s->strstart = strstart;
uInt lookahead_save = s->lookahead;
s->lookahead = lookahead;
uInt ins_h_save = s->ins_h;
uInt combined_gain;
uInt best_combined_gain = 0;
uInt match_length;
uInt prev_length = s->prev_length < MIN_MATCH ? 1 : s->prev_length;
uInt best_prev_length = prev_length;
uInt current_match_start = s->match_start;
uInt current_match_length = s->match_length;
uInt strstart_save = s->strstart;
s->strstart = strstart;
uInt lookahead_save = s->lookahead;
s->lookahead = lookahead;
uInt ins_h_save = s->ins_h;
uInt combined_gain;
uInt best_combined_gain = 0;
uInt match_length;
uInt prev_length = s->prev_length < MIN_MATCH ? 1 : s->prev_length;
uInt best_prev_length = prev_length;
uInt current_match_start = s->match_start;
uInt current_match_length = s->match_length;
do {
do {
if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
match_length = longest_match (s, hash_head);
/* longest_match() sets match_start */
} else {
match_length = MIN_MATCH - 1;
}
match_length = longest_match (s, hash_head);
/* longest_match() sets match_start */
} else {
match_length = MIN_MATCH - 1;
}
#if TOO_FAR <= 32767
if (match_length == MIN_MATCH && s->strstart - s->match_start > TOO_FAR) {
match_length = MIN_MATCH-1;
}
if (match_length == MIN_MATCH && s->strstart - s->match_start > TOO_FAR) {
match_length = MIN_MATCH-1;
}
#endif
if (s->strstart == strstart) { // store match at current position
current_match_length = match_length;
current_match_start = s->match_start;
}
if (s->strstart - strstart + 1 < MIN_MATCH) { // previous match reduced to one or two literals
combined_gain = 0; // need one literal per byte: no gain (assuming 8 bits per literal)
} else {
combined_gain = s->strstart - strstart + 1 - MIN_MATCH; // (possibly truncated) previous_length - 3 literals
}
if (match_length < MIN_MATCH) {
combined_gain += 0; // no gain
} else {
combined_gain += match_length - MIN_MATCH; // match_length bytes are coded as three literals
}
if (combined_gain >= best_combined_gain) { // in case of a tie we prefer the longer prev_length
best_combined_gain = combined_gain;
best_prev_length = s->strstart - strstart + 1;
}
s->strstart++;
s->lookahead--;
UPDATE_HASH(s, s->ins_h, s->window[(s->strstart) + (MIN_MATCH-1)]);
hash_head = s->head[s->ins_h];
} while (s->strstart <= strstart-1 + prev_length // try to truncate the previous match to 1, 3, ... prev_length
&& s->strstart <= s->window_size - MIN_LOOKAHEAD); // watch out for the end of the input
if (s->strstart == strstart) { // store match at current position
current_match_length = match_length;
current_match_start = s->match_start;
}
if (s->strstart - strstart + 1 < MIN_MATCH) { // previous match reduced to one or two literals
combined_gain = 0; // need one literal per byte: no gain (assuming 8 bits per literal)
} else {
combined_gain = s->strstart - strstart + 1 - MIN_MATCH; // (possibly truncated) previous_length - 3 literals
}
if (match_length < MIN_MATCH) {
combined_gain += 0; // no gain
} else {
combined_gain += match_length - MIN_MATCH; // match_length bytes are coded as three literals
}
if (combined_gain >= best_combined_gain) { // in case of a tie we prefer the longer prev_length
best_combined_gain = combined_gain;
best_prev_length = s->strstart - strstart + 1;
}
s->strstart++;
s->lookahead--;
UPDATE_HASH(s, s->ins_h, s->window[(s->strstart) + (MIN_MATCH-1)]);
hash_head = s->head[s->ins_h];
} while (s->strstart <= strstart-1 + prev_length // try to truncate the previous match to 1, 3, ... prev_length
&& s->strstart <= s->window_size - MIN_LOOKAHEAD); // watch out for the end of the input
s->strstart = strstart_save;
s->lookahead = lookahead_save;
s->ins_h = ins_h_save;
s->match_length = current_match_length;
s->match_start = current_match_start;
if (best_prev_length >= MIN_MATCH) {
s->prev_length = best_prev_length;
s->match_length = MIN_MATCH - 1;
} else {
s->prev_length = MIN_MATCH - 1;
}
return best_combined_gain;
s->strstart = strstart_save;
s->lookahead = lookahead_save;
s->ins_h = ins_h_save;
s->match_length = current_match_length;
s->match_start = current_match_start;
if (best_prev_length >= MIN_MATCH) {
s->prev_length = best_prev_length;
s->match_length = MIN_MATCH - 1;
} else {
s->prev_length = MIN_MATCH - 1;
}
return best_combined_gain;
}
#endif
@ -1850,9 +1850,9 @@ local block_state deflate_slow(s, flush)
s->match_length = MIN_MATCH-1;
#ifdef ZLIB_PM3_TUNED
if (s->prev_length < s->max_lazy_match) {
try_harder(s, s->strstart, s->lookahead, hash_head);
}
if (s->prev_length < s->max_lazy_match) {
try_harder(s, s->strstart, s->lookahead, hash_head);
}
#else
if (hash_head != NIL && s->prev_length < s->max_lazy_match &&

View file

@ -857,7 +857,7 @@ int flush;
case 1: /* fixed block */
#ifdef ZLIB_PM3_TUNED
strm->msg = (char *)"fixed block coding not supported";
state->mode = BAD;
state->mode = BAD;
#else
fixedtables(state);
Tracev((stderr, "inflate: fixed codes block%s\n",

View file

@ -989,7 +989,7 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
#endif
} else {
#endif /* !ZLIB_PM3_TUNED */
send_bits(s, (DYN_TREES<<1)+last, 3);
send_bits(s, (DYN_TREES<<1)+last, 3);
send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
max_blindex+1);
compress_block(s, (const ct_data *)s->dyn_ltree,