-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
hf_legic.c
183 lines (153 loc) · 5.26 KB
/
hf_legic.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
//-----------------------------------------------------------------------------
// Copyright (C) Stefanie Hofmann and Uli Heilmeier, 2020
// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// See LICENSE.txt 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 -s hf-legic-XXYYZZWW-dump.bin -d 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 -f hf-legic-XXYYZZWW-dump.bin
*
*/
#ifdef WITH_FLASH
static void DownloadLogInstructions(void) {
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 -s hf-legic-UID-dump.bin -d hf-legic-UID-dump.bin");
}
#endif
static 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(void) {
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 successful 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() == false));
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, false);
}
}
LEDsoff();
#ifdef WITH_FLASH
DownloadLogInstructions();
#endif
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
}