proxmark3/armsrc/Standalone/hf_legic.c

173 lines
4.7 KiB
C

//-----------------------------------------------------------------------------
// (c) Stefanie Hofmann, 2020
// (c) Uli Heilmeier, 2020
//
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// main code for Legic Prime read/sim
//-----------------------------------------------------------------------------
#include "standalone.h"
#include "proxmark3_arm.h"
#include "BigBuf.h"
#include "appmain.h"
#include "fpgaloader.h"
#include "util.h"
#include "dbprint.h"
#include "ticks.h"
#include "legicrf.h"
#include "legicrfsim.h"
#include "legic.h" // legic_card_select_t struct
#include "spiffs.h" // flashmem
/*
* To list all dump files from flash:
*
* 1. mem spiffs tree
*
*
* To retrieve dump files from flash:
*
* 1. mem spiffs dump o hf-legic-XXYYZZWW-dump.bin f hf-legic-XXYYZZWW-dump.bin
* Copies log file from flash to your client.
*
*
* This module emits debug strings during normal operation -- so try it out in
* the lab connected to PM3 client before taking it into the field.
*
* To delete a dump file from flash:
*
* 1. mem spiffs remove hf-legic-XXYYZZWW-dump.bin
*
*/
void DownloadLogInstructions() {
Dbprintf("");
Dbprintf("[=] List all dumps from flash:");
Dbprintf("[=] " _YELLOW_("-") " mem spiffs tree");
Dbprintf("");
Dbprintf("[=] To save a dump file from flash to client:");
Dbprintf("[=] " _YELLOW_("-") " mem spiffs dump o hf-legic-UID-dump.bin f hf-legic-UID-dump.bin");
}
void save_dump_to_file(legic_card_select_t *p_card) {
#ifdef WITH_FLASH
// legic functions puts it memory in Emulator reserved memory.
uint8_t *mem = BigBuf_get_EM_addr();
char *preferredName = (char *)BigBuf_malloc(30);
if (preferredName == NULL) {
goto OUT;
}
sprintf(preferredName, "hf-legic-%02X%02X%02X%02X-dump", p_card->uid[0], p_card->uid[1], p_card->uid[2], p_card->uid[3]);
uint16_t preferredNameLen = strlen(preferredName);
char *filename = (char *)BigBuf_malloc(preferredNameLen + 4 + 1 + 10);
if (filename == NULL) {
goto OUT;
}
sprintf(filename, "%.*s%s", preferredNameLen, preferredName, ".bin");
uint16_t num = 1;
while (exists_in_spiffs(filename)) {
sprintf(filename, "%.*s-%d%s", preferredNameLen, preferredName, num, ".bin");
num++;
}
rdv40_spiffs_write(filename, mem, p_card->cardsize, RDV40_SPIFFS_SAFETY_SAFE);
Dbprintf("[=] saved card dump to flashmem::" _YELLOW_("%s"), filename);
OUT:
BigBuf_free_keep_EM();
#endif
}
void ModInfo(void) {
DbpString(" HF Legic Prime standalone");
}
// Searching for Legic card until found and read.
// Simulating recorded Legic Prime card.
// C = Searching
// A, B, C = Reading
// A, D = Simulating
void RunMod() {
StandAloneMode();
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
Dbprintf("[=] >> HF Legic Prime Read/Simulate Started <<");
DbpString("[=] press and HOLD button to exit standalone mode");
for (;;) {
WDT_HIT();
//exit from hf_legic, send usbcommand
if (data_available()) break;
//Was our button held down or pressed?
int button_pressed = BUTTON_HELD(280);
if (button_pressed == BUTTON_HOLD) {
break;
}
LEDsoff();
LED_C_ON();
DbpString("[=] looking for tags");
int read_success = PM3_ESOFT;
//search for legic card until reading successfull or button pressed
do {
LED_C_ON();
SpinDelay(500);
// We don't care if we read a MIM256, MIM512 or MIM1024
// we just read 1024 bytes
read_success = LegicRfReaderEx(0, 1024, 0x55);
} while (read_success == PM3_ESOFT && !BUTTON_PRESS());
LEDsoff();
//simulate if read successfully
if (read_success != PM3_ESOFT) {
legic_card_select_t *p_card;
p_card = getLegicCardInfo();
if (p_card->cardsize == 0)
continue;
save_dump_to_file(p_card);
LED_D_ON();
uint8_t ct;
switch (p_card->tagtype) {
case 0x0D:
ct = 0;
break;
case 0x1D:
ct = 1;
break;
case 0x3D:
ct = 2;
break;
default:
continue;
}
// The read data is migrated to a MIM1024 card
LegicRfSimulate(ct);
}
}
LEDsoff();
#ifdef WITH_FLASH
DownloadLogInstructions();
#endif
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
}