]> cvs.zerfleddert.de Git - proxmark3-svn/blob - client/cmdhf14a.c
Andreas fix for LEGIC MIM1024
[proxmark3-svn] / client / cmdhf14a.c
1 #include <stdio.h>
2 #include <string.h>
3 #include "iso14443crc.h"
4 #include "data.h"
5 #include "proxusb.h"
6 #include "ui.h"
7 #include "cmdparser.h"
8 #include "cmdhf14a.h"
9
10 static int CmdHelp(const char *Cmd);
11
12 int CmdHF14AList(const char *Cmd)
13 {
14 uint8_t got[1920];
15 GetFromBigBuf(got, sizeof(got));
16
17 PrintAndLog("recorded activity:");
18 PrintAndLog(" ETU :rssi: who bytes");
19 PrintAndLog("---------+----+----+-----------");
20
21 int i = 0;
22 int prev = -1;
23
24 for (;;) {
25 if(i >= 1900) {
26 break;
27 }
28
29 bool isResponse;
30 int timestamp = *((uint32_t *)(got+i));
31 if (timestamp & 0x80000000) {
32 timestamp &= 0x7fffffff;
33 isResponse = 1;
34 } else {
35 isResponse = 0;
36 }
37
38 int metric = 0;
39 int parityBits = *((uint32_t *)(got+i+4));
40 // 4 bytes of additional information...
41 // maximum of 32 additional parity bit information
42 //
43 // TODO:
44 // at each quarter bit period we can send power level (16 levels)
45 // or each half bit period in 256 levels.
46
47
48 int len = got[i+8];
49
50 if (len > 100) {
51 break;
52 }
53 if (i + len >= 1900) {
54 break;
55 }
56
57 uint8_t *frame = (got+i+9);
58
59 // Break and stick with current result if buffer was not completely full
60 if (frame[0] == 0x44 && frame[1] == 0x44 && frame[3] == 0x44) { break; }
61
62 char line[1000] = "";
63 int j;
64 for (j = 0; j < len; j++) {
65 int oddparity = 0x01;
66 int k;
67
68 for (k=0;k<8;k++) {
69 oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);
70 }
71
72 //if((parityBits >> (len - j - 1)) & 0x01) {
73 if (isResponse && (oddparity != ((parityBits >> (len - j - 1)) & 0x01))) {
74 sprintf(line+(j*4), "%02x! ", frame[j]);
75 }
76 else {
77 sprintf(line+(j*4), "%02x ", frame[j]);
78 }
79 }
80
81 char *crc;
82 crc = "";
83 if (len > 2) {
84 uint8_t b1, b2;
85 for (j = 0; j < (len - 1); j++) {
86 // gives problems... search for the reason..
87 /*if(frame[j] == 0xAA) {
88 switch(frame[j+1]) {
89 case 0x01:
90 crc = "[1] Two drops close after each other";
91 break;
92 case 0x02:
93 crc = "[2] Potential SOC with a drop in second half of bitperiod";
94 break;
95 case 0x03:
96 crc = "[3] Segment Z after segment X is not possible";
97 break;
98 case 0x04:
99 crc = "[4] Parity bit of a fully received byte was wrong";
100 break;
101 default:
102 crc = "[?] Unknown error";
103 break;
104 }
105 break;
106 }*/
107 }
108
109 if (strlen(crc)==0) {
110 ComputeCrc14443(CRC_14443_A, frame, len-2, &b1, &b2);
111 if (b1 != frame[len-2] || b2 != frame[len-1]) {
112 crc = (isResponse & (len < 6)) ? "" : " !crc";
113 } else {
114 crc = "";
115 }
116 }
117 } else {
118 crc = ""; // SHORT
119 }
120
121 char metricString[100];
122 if (isResponse) {
123 sprintf(metricString, "%3d", metric);
124 } else {
125 strcpy(metricString, " ");
126 }
127
128 PrintAndLog(" +%7d: %s: %s %s %s",
129 (prev < 0 ? 0 : (timestamp - prev)),
130 metricString,
131 (isResponse ? "TAG" : " "), line, crc);
132
133 prev = timestamp;
134 i += (len + 9);
135 }
136 return 0;
137 }
138
139 int CmdHF14AMifare(const char *Cmd)
140 {
141 UsbCommand c = {CMD_READER_MIFARE, {strtol(Cmd, NULL, 0), 0, 0}};
142 SendCommand(&c);
143 return 0;
144 }
145
146 int CmdHF14AReader(const char *Cmd)
147 {
148 UsbCommand c = {CMD_READER_ISO_14443a, {strtol(Cmd, NULL, 0), 0, 0}};
149 SendCommand(&c);
150 return 0;
151 }
152
153 // ## simulate iso14443a tag
154 // ## greg - added ability to specify tag UID
155 int CmdHF14ASim(const char *Cmd)
156 {
157
158 unsigned int hi = 0, lo = 0;
159 int n = 0, i = 0;
160 while (sscanf(&Cmd[i++], "%1x", &n ) == 1) {
161 hi= (hi << 4) | (lo >> 28);
162 lo= (lo << 4) | (n & 0xf);
163 }
164
165 // c.arg should be set to *Cmd or convert *Cmd to the correct format for a uid
166 UsbCommand c = {CMD_SIMULATE_TAG_ISO_14443a, {hi, lo, 0}};
167 PrintAndLog("Emulating 14443A TAG with UID %x%16x", hi, lo);
168 SendCommand(&c);
169 return 0;
170 }
171
172 int CmdHF14ASnoop(const char *Cmd)
173 {
174 UsbCommand c = {CMD_SNOOP_ISO_14443a};
175 SendCommand(&c);
176 return 0;
177 }
178
179 static command_t CommandTable[] =
180 {
181 {"help", CmdHelp, 1, "This help"},
182 {"list", CmdHF14AList, 0, "List ISO 14443a history"},
183 {"mifare", CmdHF14AMifare, 0, "Read out sector 0 parity error messages"},
184 {"reader", CmdHF14AReader, 0, "Act like an ISO14443 Type A reader"},
185 {"sim", CmdHF14ASim, 0, "<UID> -- Fake ISO 14443a tag"},
186 {"snoop", CmdHF14ASnoop, 0, "Eavesdrop ISO 14443 Type A"},
187 {NULL, NULL, 0, NULL}
188 };
189
190 int CmdHF14A(const char *Cmd)
191 {
192 CmdsParse(CommandTable, Cmd);
193 return 0;
194 }
195
196 int CmdHelp(const char *Cmd)
197 {
198 CmdsHelp(CommandTable);
199 return 0;
200 }
Impressum, Datenschutz