keyfabe 0.5.3 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -2
- package/dist/commands/repair.d.ts +1 -0
- package/dist/commands/repair.js +160 -0
- package/dist/commands/repair.js.map +1 -0
- package/dist/commands/verify.d.ts +1 -0
- package/dist/commands/verify.js +64 -0
- package/dist/commands/verify.js.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/block0.d.ts +19 -0
- package/dist/lib/block0.js +55 -0
- package/dist/lib/block0.js.map +1 -0
- package/dist/lib/card-ops.d.ts +2 -0
- package/dist/lib/card-ops.js +58 -10
- package/dist/lib/card-ops.js.map +1 -1
- package/dist/lib/constants.d.ts +31 -8
- package/dist/lib/constants.js +54 -8
- package/dist/lib/constants.js.map +1 -1
- package/dist/lib/parsers.d.ts +3 -0
- package/dist/lib/parsers.js +15 -1
- package/dist/lib/parsers.js.map +1 -1
- package/dist/lib/pm3.d.ts +2 -1
- package/dist/lib/pm3.js +1 -1
- package/dist/lib/pm3.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -60,6 +60,9 @@ keyfabe read
|
|
|
60
60
|
# write a previously-saved identity to a blank tag
|
|
61
61
|
keyfabe write [name]
|
|
62
62
|
|
|
63
|
+
# verify a tag against a saved identity
|
|
64
|
+
keyfabe verify [name]
|
|
65
|
+
|
|
63
66
|
# list saved identities
|
|
64
67
|
keyfabe list
|
|
65
68
|
|
|
@@ -77,6 +80,9 @@ keyfabe export > fobs.json
|
|
|
77
80
|
|
|
78
81
|
# import identities from a JSON file
|
|
79
82
|
keyfabe import fobs.json
|
|
83
|
+
|
|
84
|
+
# repair a bricked magic card (bad BCC/anticollision)
|
|
85
|
+
keyfabe repair
|
|
80
86
|
```
|
|
81
87
|
|
|
82
88
|
Commands that take `[name]` arguments are fully optional — when omitted, you'll get an interactive tag picker.
|
|
@@ -103,6 +109,10 @@ Reads and identifies whatever tag is on the antenna. Searches LF first, then fal
|
|
|
103
109
|
|
|
104
110
|
Writes a previously-saved identity to a blank tag. Without a name, presents an interactive picker.
|
|
105
111
|
|
|
112
|
+
### `keyfabe verify [name]`
|
|
113
|
+
|
|
114
|
+
Reads whatever tag is on the antenna and compares its ID against a saved identity. Reports match, partial match (ID matches but type differs), or mismatch. Without a name, presents an interactive picker.
|
|
115
|
+
|
|
106
116
|
### `keyfabe list`
|
|
107
117
|
|
|
108
118
|
Lists all saved tag identities from `~/.keyfabe/fobs.json`.
|
|
@@ -127,13 +137,19 @@ Exports all saved tag identities as JSON to stdout. Pipe to a file for backup: `
|
|
|
127
137
|
|
|
128
138
|
Imports tag identities from a JSON file. New names are added, existing names are updated.
|
|
129
139
|
|
|
140
|
+
### `keyfabe repair`
|
|
141
|
+
|
|
142
|
+
Repairs a bricked magic card that has a corrupted block 0 (bad BCC, broken anticollision). Automates the recovery process: bypasses the broken anticollision, reads the current block 0, computes and writes the correct BCC, then verifies after power-cycle. See [Magic Card Reference](docs/magic-cards.md) for details.
|
|
143
|
+
|
|
130
144
|
## Supported Card Types
|
|
131
145
|
|
|
146
|
+
For detailed information on magic card types, block 0 format, and recovery procedures, see the [Magic Card Reference](docs/magic-cards.md).
|
|
147
|
+
|
|
132
148
|
| Type | Frequency | Read | Clone | Notes |
|
|
133
149
|
|------|-----------|------|-------|-------|
|
|
134
|
-
| EM410x | LF (125 kHz) | yes | yes | Most common LF
|
|
150
|
+
| EM410x | LF (125 kHz) | yes | yes | Most common LF tag |
|
|
135
151
|
| HID Prox | LF (125 kHz) | yes | yes | Uses `lf hid clone` |
|
|
136
|
-
| MIFARE Classic 1K/4K | HF (13.56 MHz) | yes | yes |
|
|
152
|
+
| MIFARE Classic 1K/4K | HF (13.56 MHz) | yes | yes | Supports Gen1A and Gen2/CUID magic cards |
|
|
137
153
|
| MIFARE Ultralight | HF (13.56 MHz) | yes | no | Read-only support |
|
|
138
154
|
| MIFARE DESFire | HF (13.56 MHz) | yes | no | Read-only support |
|
|
139
155
|
| ISO 14443-A | HF (13.56 MHz) | yes | no | Generic HF detection |
|
|
@@ -162,16 +178,19 @@ src/
|
|
|
162
178
|
read.ts # read tag
|
|
163
179
|
clone.ts # guided clone flow
|
|
164
180
|
write.ts # write saved identity
|
|
181
|
+
verify.ts # verify tag against saved identity
|
|
165
182
|
list.ts # list saved identities
|
|
166
183
|
show.ts # show saved identity details
|
|
167
184
|
rename.ts # rename saved identity
|
|
168
185
|
delete.ts # delete saved identity
|
|
169
186
|
export.ts # export identities as JSON
|
|
170
187
|
import.ts # import identities from JSON
|
|
188
|
+
repair.ts # repair bricked magic cards
|
|
171
189
|
lib/
|
|
172
190
|
pm3.ts # spawns pm3 process, sends commands
|
|
173
191
|
firmware.ts # build/flash subprocess helpers
|
|
174
192
|
parsers.ts # parse pm3 output (card type, ID, voltages)
|
|
193
|
+
block0.ts # MIFARE Classic block 0 utilities (BCC, builder)
|
|
175
194
|
store.ts # read/write ~/.keyfabe/fobs.json
|
|
176
195
|
constants.ts # shared card type and pm3 command constants
|
|
177
196
|
card-ops.ts # search, write-and-verify logic shared by commands
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function repair(): Promise<boolean>;
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import * as p from "@clack/prompts";
|
|
2
|
+
import { buildBlock0, computeBcc, parseBlock0, validateBcc } from "../lib/block0.js";
|
|
3
|
+
import { CardType, Pm3Cmd, Pm3Command } from "../lib/constants.js";
|
|
4
|
+
import { printDoctorHint } from "../lib/display.js";
|
|
5
|
+
import { parseBlock0Data, parseHfSearch } from "../lib/parsers.js";
|
|
6
|
+
import { Pm3Error, pm3Exec, requireDevice } from "../lib/pm3.js";
|
|
7
|
+
import { waitForEnter } from "../lib/prompts.js";
|
|
8
|
+
/** Build a chained command that ignores BCC, writes block 0, then resets config. */
|
|
9
|
+
function bccRepairCommand(block0Data) {
|
|
10
|
+
const configBypass = Pm3Cmd.HF_14A_CONFIG.arg("--atqa", "force")
|
|
11
|
+
.arg("--bcc", "ignore")
|
|
12
|
+
.arg("--cl2", "skip")
|
|
13
|
+
.arg("--rats", "skip");
|
|
14
|
+
const write = Pm3Cmd.HF_MF_WRBL.arg("--blk", "0").arg("-k", "FFFFFFFFFFFF").arg("-d", block0Data).arg("--force");
|
|
15
|
+
const configReset = Pm3Cmd.HF_14A_CONFIG.arg("--std");
|
|
16
|
+
return Pm3Command.chain(configBypass, write, configReset);
|
|
17
|
+
}
|
|
18
|
+
/** Read block 0 with BCC bypass enabled. */
|
|
19
|
+
function bccBypassReadCommand() {
|
|
20
|
+
const configBypass = Pm3Cmd.HF_14A_CONFIG.arg("--atqa", "force")
|
|
21
|
+
.arg("--bcc", "ignore")
|
|
22
|
+
.arg("--cl2", "skip")
|
|
23
|
+
.arg("--rats", "skip");
|
|
24
|
+
const read = Pm3Cmd.HF_MF_RDBL.arg("--blk", "0").arg("-k", "FFFFFFFFFFFF");
|
|
25
|
+
const configReset = Pm3Cmd.HF_14A_CONFIG.arg("--std");
|
|
26
|
+
return Pm3Command.chain(configBypass, read, configReset);
|
|
27
|
+
}
|
|
28
|
+
export async function repair() {
|
|
29
|
+
p.intro("Repair Magic Card");
|
|
30
|
+
if (!(await requireDevice()))
|
|
31
|
+
return false;
|
|
32
|
+
p.log.info("This command repairs MIFARE Classic magic cards with corrupted block 0.");
|
|
33
|
+
p.log.info('Common symptom: "Card doesn\'t support standard iso14443-3 anticollision"');
|
|
34
|
+
await waitForEnter("Place the broken card on the antenna.");
|
|
35
|
+
// Step 1: Try normal hf search first
|
|
36
|
+
const normalSpinner = p.spinner();
|
|
37
|
+
normalSpinner.start("Checking card state...");
|
|
38
|
+
try {
|
|
39
|
+
const { stdout } = await pm3Exec(Pm3Cmd.HF_SEARCH);
|
|
40
|
+
const card = parseHfSearch(stdout);
|
|
41
|
+
if (card) {
|
|
42
|
+
normalSpinner.stop("Card is readable — anticollision is working.");
|
|
43
|
+
p.log.success(`UID: ${card.id} (${card.type})`);
|
|
44
|
+
p.log.info("This card doesn't appear to need repair. If you're having write issues, try `keyfabe write` instead.");
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
normalSpinner.stop("Card not readable via normal search.");
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
if (err instanceof Pm3Error && err.message.includes("not found")) {
|
|
51
|
+
normalSpinner.stop(err.message);
|
|
52
|
+
printDoctorHint();
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
normalSpinner.stop("Normal search failed — proceeding with repair.");
|
|
56
|
+
}
|
|
57
|
+
// Step 2: Read block 0 with BCC bypass
|
|
58
|
+
const readSpinner = p.spinner();
|
|
59
|
+
readSpinner.start("Reading block 0 with anticollision bypass...");
|
|
60
|
+
let parsed;
|
|
61
|
+
try {
|
|
62
|
+
const { stdout } = await pm3Exec(bccBypassReadCommand());
|
|
63
|
+
const block0Hex = parseBlock0Data(stdout);
|
|
64
|
+
if (!block0Hex) {
|
|
65
|
+
readSpinner.stop("Could not read block 0.");
|
|
66
|
+
p.log.error("Failed to read block 0 even with BCC bypass. The card may not be a MIFARE Classic or the key may have been changed.");
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
parsed = parseBlock0(block0Hex);
|
|
70
|
+
if (!parsed) {
|
|
71
|
+
readSpinner.stop("Block 0 data too short to parse.");
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
const bccValid = validateBcc(parsed.uid, parsed.bcc);
|
|
75
|
+
if (bccValid) {
|
|
76
|
+
readSpinner.stop("Block 0 BCC is already correct.");
|
|
77
|
+
p.log.info(`UID: ${parsed.uid}, BCC: 0x${parsed.bcc.toString(16).padStart(2, "0").toUpperCase()} (valid)`);
|
|
78
|
+
p.log.warn("The BCC is correct but the card still isn't readable. The issue may be with ATQA or SAK values.");
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
const expectedBcc = computeBcc(parsed.uid);
|
|
82
|
+
readSpinner.stop("Found corrupted BCC.");
|
|
83
|
+
p.log.warn(`UID: ${parsed.uid}, BCC: 0x${parsed.bcc.toString(16).padStart(2, "0").toUpperCase()} (expected 0x${expectedBcc.toString(16).padStart(2, "0").toUpperCase()})`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
if (err instanceof Pm3Error) {
|
|
88
|
+
readSpinner.stop(err.message);
|
|
89
|
+
if (err.message.includes("not found")) {
|
|
90
|
+
printDoctorHint();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
readSpinner.stop("Failed to read block 0.");
|
|
95
|
+
}
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
// Step 3: Determine correct card type from SAK
|
|
99
|
+
let cardType;
|
|
100
|
+
if (parsed.sak === 0x18) {
|
|
101
|
+
cardType = CardType.MIFARE_CLASSIC_4K;
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
cardType = CardType.MIFARE_CLASSIC_1K;
|
|
105
|
+
}
|
|
106
|
+
// Step 4: Build corrected block 0 and write
|
|
107
|
+
const correctedBlock0 = buildBlock0(parsed.uid, cardType);
|
|
108
|
+
p.log.info(`Repairing: ${parsed.uid} as ${cardType}`);
|
|
109
|
+
p.log.info(`Corrected block 0: ${correctedBlock0}`);
|
|
110
|
+
const writeSpinner = p.spinner();
|
|
111
|
+
writeSpinner.start("Writing corrected block 0...");
|
|
112
|
+
try {
|
|
113
|
+
const { stdout: writeOut } = await pm3Exec(bccRepairCommand(correctedBlock0));
|
|
114
|
+
if (!/write\s*\(\s*ok\s*\)/i.test(writeOut)) {
|
|
115
|
+
writeSpinner.stop("Write command did not confirm success.");
|
|
116
|
+
p.log.error("Failed to write corrected block 0. The key may have been changed from default.");
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
writeSpinner.stop("Corrected block 0 written.");
|
|
120
|
+
}
|
|
121
|
+
catch (err) {
|
|
122
|
+
if (err instanceof Pm3Error) {
|
|
123
|
+
writeSpinner.stop(err.message);
|
|
124
|
+
if (err.message.includes("not found")) {
|
|
125
|
+
printDoctorHint();
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
writeSpinner.stop("Failed to write corrected block 0.");
|
|
130
|
+
}
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
// Step 5: Power cycle and verify
|
|
134
|
+
await waitForEnter("Remove the card from the antenna, then place it back.");
|
|
135
|
+
const verifySpinner = p.spinner();
|
|
136
|
+
verifySpinner.start("Verifying repair...");
|
|
137
|
+
try {
|
|
138
|
+
const { stdout } = await pm3Exec(Pm3Cmd.HF_SEARCH);
|
|
139
|
+
const card = parseHfSearch(stdout);
|
|
140
|
+
if (card) {
|
|
141
|
+
verifySpinner.stop("Card repaired successfully!");
|
|
142
|
+
p.log.success(`UID: ${card.id} (${card.type})`);
|
|
143
|
+
p.outro("Repair complete!");
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
verifySpinner.stop("Card still not readable after repair.");
|
|
147
|
+
p.log.error("The repair may not have taken effect. Try removing and replacing the card again.");
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
catch (err) {
|
|
151
|
+
if (err instanceof Pm3Error) {
|
|
152
|
+
verifySpinner.stop(err.message);
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
verifySpinner.stop("Verification failed.");
|
|
156
|
+
}
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=repair.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repair.js","sourceRoot":"","sources":["../../src/commands/repair.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function verify(name?: string): Promise<boolean>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import * as p from "@clack/prompts";
|
|
2
|
+
import { searchCard } from "../lib/card-ops.js";
|
|
3
|
+
import { printDoctorHint, printFobNotFound, printNoSavedTags } from "../lib/display.js";
|
|
4
|
+
import { Pm3Error, requireDevice } from "../lib/pm3.js";
|
|
5
|
+
import { selectFob, waitForEnter } from "../lib/prompts.js";
|
|
6
|
+
import { getFob, loadFobs } from "../lib/store.js";
|
|
7
|
+
export async function verify(name) {
|
|
8
|
+
p.intro("Verify Tag");
|
|
9
|
+
if (!name) {
|
|
10
|
+
const fobs = await loadFobs();
|
|
11
|
+
if (fobs.length === 0) {
|
|
12
|
+
printNoSavedTags();
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
name = await selectFob(fobs, "Which saved tag to verify against?");
|
|
16
|
+
}
|
|
17
|
+
const fob = await getFob(name);
|
|
18
|
+
if (!fob) {
|
|
19
|
+
printFobNotFound(name);
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
if (!(await requireDevice()))
|
|
23
|
+
return false;
|
|
24
|
+
p.log.info(`Verifying against "${fob.name}" (${fob.type} ${fob.id})`);
|
|
25
|
+
await waitForEnter("Place the tag to check on the antenna.");
|
|
26
|
+
const spinner = p.spinner();
|
|
27
|
+
spinner.start("Reading tag...");
|
|
28
|
+
try {
|
|
29
|
+
const card = await searchCard();
|
|
30
|
+
if (!card) {
|
|
31
|
+
spinner.stop("No tag detected.");
|
|
32
|
+
p.log.error("Could not read a tag. Make sure it's on the antenna.");
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
spinner.stop(`Read: ${card.type} ${card.id}`);
|
|
36
|
+
const idMatch = card.id === fob.id;
|
|
37
|
+
const typeMatch = card.type === fob.type;
|
|
38
|
+
if (idMatch && typeMatch) {
|
|
39
|
+
p.log.success(`Match! ID ${card.id} matches "${fob.name}".`);
|
|
40
|
+
p.outro("Verification passed.");
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
if (idMatch) {
|
|
44
|
+
p.log.warn(`ID matches (${card.id}) but type differs: read ${card.type}, expected ${fob.type}.`);
|
|
45
|
+
p.outro("Partial match — ID is correct.");
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
p.log.error(`Mismatch: read ${card.id}, expected ${fob.id}.`);
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
if (err instanceof Pm3Error) {
|
|
53
|
+
spinner.stop(err.message);
|
|
54
|
+
if (err.message.includes("not found")) {
|
|
55
|
+
printDoctorHint();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
spinner.stop("Failed to read tag.");
|
|
60
|
+
}
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=verify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/commands/verify.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -10,8 +10,10 @@ import { importFile } from "./commands/import.js";
|
|
|
10
10
|
import { list } from "./commands/list.js";
|
|
11
11
|
import { read } from "./commands/read.js";
|
|
12
12
|
import { rename } from "./commands/rename.js";
|
|
13
|
+
import { repair } from "./commands/repair.js";
|
|
13
14
|
import { setup } from "./commands/setup.js";
|
|
14
15
|
import { show } from "./commands/show.js";
|
|
16
|
+
import { verify } from "./commands/verify.js";
|
|
15
17
|
import { write } from "./commands/write.js";
|
|
16
18
|
const require = createRequire(import.meta.url);
|
|
17
19
|
const { version } = require("../package.json");
|
|
@@ -35,6 +37,7 @@ program.action(withExitCode(async () => {
|
|
|
35
37
|
{ value: "clone", label: "Clone a tag", hint: "read + write + verify" },
|
|
36
38
|
{ value: "read", label: "Read a tag", hint: "identify and save" },
|
|
37
39
|
{ value: "write", label: "Write a saved identity", hint: "write to blank tag" },
|
|
40
|
+
{ value: "verify", label: "Verify a tag", hint: "compare to saved identity" },
|
|
38
41
|
{ value: "list", label: "List saved tags" },
|
|
39
42
|
{ value: "doctor", label: "Health check", hint: "diagnose device" },
|
|
40
43
|
{ value: "setup", label: "Firmware setup", hint: "flash Iceman firmware" },
|
|
@@ -51,6 +54,8 @@ program.action(withExitCode(async () => {
|
|
|
51
54
|
return read();
|
|
52
55
|
case "write":
|
|
53
56
|
return write();
|
|
57
|
+
case "verify":
|
|
58
|
+
return verify();
|
|
54
59
|
case "list":
|
|
55
60
|
return list();
|
|
56
61
|
case "doctor":
|
|
@@ -103,5 +108,14 @@ program
|
|
|
103
108
|
.argument("<file>", "path to JSON file")
|
|
104
109
|
.action(withExitCode(importFile));
|
|
105
110
|
program.command("setup").description("Flash Iceman firmware to a stock Proxmark3 Easy").action(withExitCode(setup));
|
|
111
|
+
program
|
|
112
|
+
.command("verify")
|
|
113
|
+
.description("Read a tag and compare it against a saved identity")
|
|
114
|
+
.argument("[name]", "name of the saved tag identity")
|
|
115
|
+
.action(withExitCode(verify));
|
|
116
|
+
program
|
|
117
|
+
.command("repair")
|
|
118
|
+
.description("Repair a bricked magic card with corrupted block 0 (bad BCC)")
|
|
119
|
+
.action(withExitCode(repair));
|
|
106
120
|
program.parse();
|
|
107
121
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** Compute BCC (XOR of all UID bytes). */
|
|
2
|
+
export declare function computeBcc(uid: string): number;
|
|
3
|
+
/** Validate that a BCC byte matches the UID. */
|
|
4
|
+
export declare function validateBcc(uid: string, bcc: number): boolean;
|
|
5
|
+
/**
|
|
6
|
+
* Build a 16-byte block 0 for a 4-byte UID MIFARE Classic card.
|
|
7
|
+
* Returns 32 hex characters (16 bytes).
|
|
8
|
+
*/
|
|
9
|
+
export declare function buildBlock0(uid: string, cardType: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* Parse block 0 hex data and extract UID, BCC, SAK, ATQA.
|
|
12
|
+
* Returns null if data is too short.
|
|
13
|
+
*/
|
|
14
|
+
export declare function parseBlock0(hex: string): {
|
|
15
|
+
uid: string;
|
|
16
|
+
bcc: number;
|
|
17
|
+
sak: number;
|
|
18
|
+
atqa: [number, number];
|
|
19
|
+
} | null;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { CardType } from "./constants.js";
|
|
2
|
+
/** SAK byte values for MIFARE Classic card types. */
|
|
3
|
+
const SAK = {
|
|
4
|
+
[CardType.MIFARE_CLASSIC_1K]: 0x08,
|
|
5
|
+
[CardType.MIFARE_CLASSIC_4K]: 0x18,
|
|
6
|
+
};
|
|
7
|
+
/** ATQA bytes as stored in block 0 (reversed from on-wire order). */
|
|
8
|
+
const ATQA = {
|
|
9
|
+
[CardType.MIFARE_CLASSIC_1K]: [0x04, 0x00],
|
|
10
|
+
[CardType.MIFARE_CLASSIC_4K]: [0x02, 0x00],
|
|
11
|
+
};
|
|
12
|
+
/** Compute BCC (XOR of all UID bytes). */
|
|
13
|
+
export function computeBcc(uid) {
|
|
14
|
+
const bytes = uid.match(/.{2}/g);
|
|
15
|
+
if (!bytes || bytes.length !== 4) {
|
|
16
|
+
throw new Error(`BCC requires a 4-byte (8 hex char) UID, got: ${uid}`);
|
|
17
|
+
}
|
|
18
|
+
return bytes.reduce((xor, b) => xor ^ Number.parseInt(b, 16), 0);
|
|
19
|
+
}
|
|
20
|
+
/** Validate that a BCC byte matches the UID. */
|
|
21
|
+
export function validateBcc(uid, bcc) {
|
|
22
|
+
return computeBcc(uid) === bcc;
|
|
23
|
+
}
|
|
24
|
+
function toHex(byte) {
|
|
25
|
+
return byte.toString(16).padStart(2, "0").toUpperCase();
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Build a 16-byte block 0 for a 4-byte UID MIFARE Classic card.
|
|
29
|
+
* Returns 32 hex characters (16 bytes).
|
|
30
|
+
*/
|
|
31
|
+
export function buildBlock0(uid, cardType) {
|
|
32
|
+
const sak = SAK[cardType];
|
|
33
|
+
const atqa = ATQA[cardType];
|
|
34
|
+
if (sak === undefined || !atqa) {
|
|
35
|
+
throw new Error(`Unsupported card type for block 0: ${cardType}`);
|
|
36
|
+
}
|
|
37
|
+
const bcc = computeBcc(uid);
|
|
38
|
+
const uidUpper = uid.toUpperCase();
|
|
39
|
+
return `${uidUpper}${toHex(bcc)}${toHex(sak)}${toHex(atqa[0])}${toHex(atqa[1])}${"00".repeat(8)}`;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Parse block 0 hex data and extract UID, BCC, SAK, ATQA.
|
|
43
|
+
* Returns null if data is too short.
|
|
44
|
+
*/
|
|
45
|
+
export function parseBlock0(hex) {
|
|
46
|
+
const clean = hex.replace(/\s+/g, "").toUpperCase();
|
|
47
|
+
if (clean.length < 16)
|
|
48
|
+
return null; // need at least 8 bytes (UID+BCC+SAK+ATQA)
|
|
49
|
+
const uid = clean.slice(0, 8);
|
|
50
|
+
const bcc = Number.parseInt(clean.slice(8, 10), 16);
|
|
51
|
+
const sak = Number.parseInt(clean.slice(10, 12), 16);
|
|
52
|
+
const atqa = [Number.parseInt(clean.slice(12, 14), 16), Number.parseInt(clean.slice(14, 16), 16)];
|
|
53
|
+
return { uid, bcc, sak, atqa };
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=block0.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"block0.js","sourceRoot":"","sources":["../../src/lib/block0.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/card-ops.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import { type CardInfo } from "./parsers.js";
|
|
2
2
|
export declare function searchCard(): Promise<CardInfo | null>;
|
|
3
|
+
/** Detect magic card type by running hf search and parsing capabilities. */
|
|
4
|
+
export declare function detectMagicType(): Promise<string>;
|
|
3
5
|
export declare function writeAndVerify(card: CardInfo): Promise<boolean>;
|
package/dist/lib/card-ops.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import * as p from "@clack/prompts";
|
|
2
|
-
import {
|
|
2
|
+
import { buildBlock0 } from "./block0.js";
|
|
3
|
+
import { CardType, cardFrequency, MagicCardType, Pm3Cmd, WriteTarget } from "./constants.js";
|
|
3
4
|
import { printDoctorHint } from "./display.js";
|
|
4
|
-
import { parseCloneResult, parseHfSearch, parseLfSearch, parseT55xxDetect } from "./parsers.js";
|
|
5
|
+
import { parseCloneResult, parseHfSearch, parseLfSearch, parseMagicType, parseT55xxDetect, } from "./parsers.js";
|
|
5
6
|
import { Pm3Error, pm3Exec } from "./pm3.js";
|
|
6
7
|
export async function searchCard() {
|
|
7
8
|
const { stdout: lfOut } = await pm3Exec(Pm3Cmd.LF_SEARCH);
|
|
@@ -11,19 +12,41 @@ export async function searchCard() {
|
|
|
11
12
|
const { stdout: hfOut } = await pm3Exec(Pm3Cmd.HF_SEARCH);
|
|
12
13
|
return parseHfSearch(hfOut);
|
|
13
14
|
}
|
|
14
|
-
|
|
15
|
+
/** Detect magic card type by running hf search and parsing capabilities. */
|
|
16
|
+
export async function detectMagicType() {
|
|
17
|
+
const { stdout } = await pm3Exec(Pm3Cmd.HF_SEARCH);
|
|
18
|
+
return parseMagicType(stdout);
|
|
19
|
+
}
|
|
20
|
+
function gen1aCloneCommand(card) {
|
|
21
|
+
return Pm3Cmd.HF_MF_CSETUID.arg("-u", card.id);
|
|
22
|
+
}
|
|
23
|
+
function gen2CloneCommand(card) {
|
|
24
|
+
const block0 = buildBlock0(card.id, card.type);
|
|
25
|
+
return Pm3Cmd.HF_MF_WRBL.arg("--blk", "0").arg("-k", "FFFFFFFFFFFF").arg("-d", block0).arg("--force");
|
|
26
|
+
}
|
|
27
|
+
function cloneCommand(card, magicType) {
|
|
15
28
|
switch (card.type) {
|
|
16
29
|
case CardType.EM410x:
|
|
17
|
-
return
|
|
30
|
+
return Pm3Cmd.LF_EM_410X_CLONE.arg("--id", card.id);
|
|
18
31
|
case CardType.HID_PROX:
|
|
19
|
-
return
|
|
32
|
+
return Pm3Cmd.LF_HID_CLONE.arg("-r", card.id);
|
|
20
33
|
case CardType.MIFARE_CLASSIC_1K:
|
|
21
34
|
case CardType.MIFARE_CLASSIC_4K:
|
|
22
|
-
|
|
35
|
+
if (magicType === MagicCardType.GEN2_CUID) {
|
|
36
|
+
return gen2CloneCommand(card);
|
|
37
|
+
}
|
|
38
|
+
return gen1aCloneCommand(card);
|
|
23
39
|
default:
|
|
24
40
|
throw new Error(`Unsupported card type: ${card.type}`);
|
|
25
41
|
}
|
|
26
42
|
}
|
|
43
|
+
/** Match clone result patterns for Gen2 wrbl output (e.g. "Write ( ok )"). */
|
|
44
|
+
function isWriteSuccess(stdout, magicType) {
|
|
45
|
+
if (magicType === MagicCardType.GEN2_CUID) {
|
|
46
|
+
return /write\s*\(\s*ok\s*\)/i.test(stdout);
|
|
47
|
+
}
|
|
48
|
+
return parseCloneResult(stdout).success;
|
|
49
|
+
}
|
|
27
50
|
function verifyCommand(card) {
|
|
28
51
|
switch (card.type) {
|
|
29
52
|
case CardType.EM410x:
|
|
@@ -71,17 +94,42 @@ export async function writeAndVerify(card) {
|
|
|
71
94
|
return false;
|
|
72
95
|
}
|
|
73
96
|
}
|
|
97
|
+
// Detect magic card type (HF only)
|
|
98
|
+
let magicType;
|
|
99
|
+
if (freq === "HF") {
|
|
100
|
+
const magicSpinner = p.spinner();
|
|
101
|
+
magicSpinner.start("Detecting magic card type...");
|
|
102
|
+
try {
|
|
103
|
+
magicType = await detectMagicType();
|
|
104
|
+
if (magicType === MagicCardType.UNKNOWN) {
|
|
105
|
+
stopWithError(magicSpinner, `Target is not a recognized magic card. Use a ${WriteTarget.HF}.`);
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
magicSpinner.stop(`Magic card detected (${magicType})`);
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
if (err instanceof Pm3Error) {
|
|
112
|
+
stopWithError(magicSpinner, err.message);
|
|
113
|
+
if (err.message.includes("not found")) {
|
|
114
|
+
printDoctorHint();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
stopWithError(magicSpinner, "Failed to detect magic card type.");
|
|
119
|
+
}
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
74
123
|
// Clone
|
|
75
124
|
const cloneSpinner = p.spinner();
|
|
76
125
|
cloneSpinner.start("Writing card data...");
|
|
77
126
|
try {
|
|
78
|
-
const cmd = cloneCommand(card);
|
|
127
|
+
const cmd = cloneCommand(card, magicType);
|
|
79
128
|
const { stdout } = await pm3Exec(cmd);
|
|
80
|
-
|
|
81
|
-
if (!result.success) {
|
|
129
|
+
if (!isWriteSuccess(stdout, magicType)) {
|
|
82
130
|
stopWithError(cloneSpinner, "Write command did not confirm success.");
|
|
83
131
|
if (freq === "HF") {
|
|
84
|
-
p.log.warn(`Make sure the target is a ${WriteTarget.HF}
|
|
132
|
+
p.log.warn(`Make sure the target is a ${WriteTarget.HF}.`);
|
|
85
133
|
}
|
|
86
134
|
return false;
|
|
87
135
|
}
|
package/dist/lib/card-ops.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"card-ops.js","sourceRoot":"","sources":["../../src/lib/card-ops.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"card-ops.js","sourceRoot":"","sources":["../../src/lib/card-ops.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/constants.d.ts
CHANGED
|
@@ -11,14 +11,37 @@ export type CardTypeName = (typeof CardType)[keyof typeof CardType];
|
|
|
11
11
|
export declare function cardFrequency(type: string): "LF" | "HF";
|
|
12
12
|
export declare const WriteTarget: {
|
|
13
13
|
readonly LF: "blank T55x7 tag";
|
|
14
|
-
readonly HF: "Gen1A
|
|
14
|
+
readonly HF: "magic card (Gen1A or Gen2/CUID)";
|
|
15
15
|
};
|
|
16
|
+
export declare const MagicCardType: {
|
|
17
|
+
readonly GEN1A: "Gen1A";
|
|
18
|
+
readonly GEN2_CUID: "Gen2/CUID";
|
|
19
|
+
readonly UNKNOWN: "unknown";
|
|
20
|
+
};
|
|
21
|
+
export type MagicCardTypeName = (typeof MagicCardType)[keyof typeof MagicCardType];
|
|
22
|
+
export declare class Pm3Command {
|
|
23
|
+
readonly parts: readonly string[];
|
|
24
|
+
constructor(...parts: string[]);
|
|
25
|
+
/** Extend this command path with a subcommand. */
|
|
26
|
+
sub(name: string): Pm3Command;
|
|
27
|
+
/** Append a flag (and optional value) as runtime arguments. */
|
|
28
|
+
arg(flag: string, value?: string): Pm3Command;
|
|
29
|
+
/** Chain multiple commands into a single pm3 session (separated by `;`). */
|
|
30
|
+
static chain(...commands: Pm3Command[]): Pm3Command;
|
|
31
|
+
toString(): string;
|
|
32
|
+
}
|
|
16
33
|
export declare const Pm3Cmd: {
|
|
17
|
-
readonly LF_SEARCH:
|
|
18
|
-
readonly HF_SEARCH:
|
|
19
|
-
readonly LF_T55XX_DETECT:
|
|
20
|
-
readonly LF_EM_410X_READER:
|
|
21
|
-
readonly
|
|
22
|
-
readonly
|
|
23
|
-
readonly
|
|
34
|
+
readonly LF_SEARCH: Pm3Command;
|
|
35
|
+
readonly HF_SEARCH: Pm3Command;
|
|
36
|
+
readonly LF_T55XX_DETECT: Pm3Command;
|
|
37
|
+
readonly LF_EM_410X_READER: Pm3Command;
|
|
38
|
+
readonly LF_EM_410X_CLONE: Pm3Command;
|
|
39
|
+
readonly LF_HID_READER: Pm3Command;
|
|
40
|
+
readonly LF_HID_CLONE: Pm3Command;
|
|
41
|
+
readonly HF_MF_CSETUID: Pm3Command;
|
|
42
|
+
readonly HF_MF_WRBL: Pm3Command;
|
|
43
|
+
readonly HF_MF_RDBL: Pm3Command;
|
|
44
|
+
readonly HF_14A_CONFIG: Pm3Command;
|
|
45
|
+
readonly HW_STATUS: Pm3Command;
|
|
46
|
+
readonly HW_TUNE: Pm3Command;
|
|
24
47
|
};
|
package/dist/lib/constants.js
CHANGED
|
@@ -18,15 +18,61 @@ export function cardFrequency(type) {
|
|
|
18
18
|
}
|
|
19
19
|
export const WriteTarget = {
|
|
20
20
|
LF: "blank T55x7 tag",
|
|
21
|
-
HF: "Gen1A
|
|
21
|
+
HF: "magic card (Gen1A or Gen2/CUID)",
|
|
22
22
|
};
|
|
23
|
+
export const MagicCardType = {
|
|
24
|
+
GEN1A: "Gen1A",
|
|
25
|
+
GEN2_CUID: "Gen2/CUID",
|
|
26
|
+
UNKNOWN: "unknown",
|
|
27
|
+
};
|
|
28
|
+
export class Pm3Command {
|
|
29
|
+
parts;
|
|
30
|
+
constructor(...parts) {
|
|
31
|
+
this.parts = parts;
|
|
32
|
+
}
|
|
33
|
+
/** Extend this command path with a subcommand. */
|
|
34
|
+
sub(name) {
|
|
35
|
+
return new Pm3Command(...this.parts, name);
|
|
36
|
+
}
|
|
37
|
+
/** Append a flag (and optional value) as runtime arguments. */
|
|
38
|
+
arg(flag, value) {
|
|
39
|
+
return value !== undefined ? new Pm3Command(...this.parts, flag, value) : new Pm3Command(...this.parts, flag);
|
|
40
|
+
}
|
|
41
|
+
/** Chain multiple commands into a single pm3 session (separated by `;`). */
|
|
42
|
+
static chain(...commands) {
|
|
43
|
+
const parts = [];
|
|
44
|
+
for (let i = 0; i < commands.length; i++) {
|
|
45
|
+
if (i > 0)
|
|
46
|
+
parts.push(";");
|
|
47
|
+
parts.push(...commands[i].parts);
|
|
48
|
+
}
|
|
49
|
+
return new Pm3Command(...parts);
|
|
50
|
+
}
|
|
51
|
+
toString() {
|
|
52
|
+
return this.parts.join(" ");
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// Shared command path segments — each string appears exactly once
|
|
56
|
+
const lf = new Pm3Command("lf");
|
|
57
|
+
const hf = new Pm3Command("hf");
|
|
58
|
+
const hw = new Pm3Command("hw");
|
|
59
|
+
const em410x = lf.sub("em").sub("410x");
|
|
60
|
+
const hid = lf.sub("hid");
|
|
61
|
+
const mf = hf.sub("mf");
|
|
62
|
+
const hf14a = hf.sub("14a");
|
|
23
63
|
export const Pm3Cmd = {
|
|
24
|
-
LF_SEARCH: "
|
|
25
|
-
HF_SEARCH: "
|
|
26
|
-
LF_T55XX_DETECT: "
|
|
27
|
-
LF_EM_410X_READER: "
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
64
|
+
LF_SEARCH: lf.sub("search"),
|
|
65
|
+
HF_SEARCH: hf.sub("search"),
|
|
66
|
+
LF_T55XX_DETECT: lf.sub("t55xx").sub("detect"),
|
|
67
|
+
LF_EM_410X_READER: em410x.sub("reader"),
|
|
68
|
+
LF_EM_410X_CLONE: em410x.sub("clone"),
|
|
69
|
+
LF_HID_READER: hid.sub("reader"),
|
|
70
|
+
LF_HID_CLONE: hid.sub("clone"),
|
|
71
|
+
HF_MF_CSETUID: mf.sub("csetuid"),
|
|
72
|
+
HF_MF_WRBL: mf.sub("wrbl"),
|
|
73
|
+
HF_MF_RDBL: mf.sub("rdbl"),
|
|
74
|
+
HF_14A_CONFIG: hf14a.sub("config"),
|
|
75
|
+
HW_STATUS: hw.sub("status"),
|
|
76
|
+
HW_TUNE: hw.sub("tune"),
|
|
31
77
|
};
|
|
32
78
|
//# sourceMappingURL=constants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/lib/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,QAAQ,GAAG;IACpB,MAAM,EAAE,QAAQ;IAChB,QAAQ,EAAE,UAAU;IACpB,iBAAiB,EAAE,mBAAmB;IACtC,iBAAiB,EAAE,mBAAmB;IACtC,iBAAiB,EAAE,mBAAmB;IACtC,cAAc,EAAE,gBAAgB;IAChC,UAAU,EAAE,aAAa;CACnB,CAAC;AAIX,MAAM,UAAU,aAAa,CAAC,IAAY;IACtC,QAAQ,IAAI,EAAE,CAAC;QACX,KAAK,QAAQ,CAAC,MAAM,CAAC;QACrB,KAAK,QAAQ,CAAC,QAAQ;YAClB,OAAO,IAAI,CAAC;QAChB;YACI,OAAO,IAAI,CAAC;IACpB,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAG;IACvB,EAAE,EAAE,iBAAiB;IACrB,EAAE,EAAE,
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/lib/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,QAAQ,GAAG;IACpB,MAAM,EAAE,QAAQ;IAChB,QAAQ,EAAE,UAAU;IACpB,iBAAiB,EAAE,mBAAmB;IACtC,iBAAiB,EAAE,mBAAmB;IACtC,iBAAiB,EAAE,mBAAmB;IACtC,cAAc,EAAE,gBAAgB;IAChC,UAAU,EAAE,aAAa;CACnB,CAAC;AAIX,MAAM,UAAU,aAAa,CAAC,IAAY;IACtC,QAAQ,IAAI,EAAE,CAAC;QACX,KAAK,QAAQ,CAAC,MAAM,CAAC;QACrB,KAAK,QAAQ,CAAC,QAAQ;YAClB,OAAO,IAAI,CAAC;QAChB;YACI,OAAO,IAAI,CAAC;IACpB,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAG;IACvB,EAAE,EAAE,iBAAiB;IACrB,EAAE,EAAE,iCAAiC;CAC/B,CAAC;AAEX,MAAM,CAAC,MAAM,aAAa,GAAG;IACzB,KAAK,EAAE,OAAO;IACd,SAAS,EAAE,WAAW;IACtB,OAAO,EAAE,SAAS;CACZ,CAAC;AAIX,MAAM,OAAO,UAAU;IACV,KAAK,CAAoB;IAElC,YAAY,GAAG,KAAe;QAC1B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACvB,CAAC;IAED,kDAAkD;IAClD,GAAG,CAAC,IAAY;QACZ,OAAO,IAAI,UAAU,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC/C,CAAC;IAED,+DAA+D;IAC/D,GAAG,CAAC,IAAY,EAAE,KAAc;QAC5B,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAClH,CAAC;IAED,4EAA4E;IAC5E,MAAM,CAAC,KAAK,CAAC,GAAG,QAAsB;QAClC,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACvC,IAAI,CAAC,GAAG,CAAC;gBAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC3B,KAAK,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACrC,CAAC;QACD,OAAO,IAAI,UAAU,CAAC,GAAG,KAAK,CAAC,CAAC;IACpC,CAAC;IAED,QAAQ;QACJ,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC;CACJ;AAED,kEAAkE;AAClE,MAAM,EAAE,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;AAChC,MAAM,EAAE,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;AAChC,MAAM,EAAE,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;AAEhC,MAAM,MAAM,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACxC,MAAM,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAC1B,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAExB,MAAM,KAAK,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAE5B,MAAM,CAAC,MAAM,MAAM,GAAG;IAClB,SAAS,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC;IAC3B,SAAS,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC;IAC3B,eAAe,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC;IAC9C,iBAAiB,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IACvC,gBAAgB,EAAE,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC;IACrC,aAAa,EAAE,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC;IAChC,YAAY,EAAE,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC;IAC9B,aAAa,EAAE,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC;IAChC,UAAU,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC;IAC1B,UAAU,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC;IAC1B,aAAa,EAAE,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClC,SAAS,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC;IAC3B,OAAO,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC;CACjB,CAAC"}
|
package/dist/lib/parsers.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type MagicCardTypeName } from "./constants.js";
|
|
1
2
|
export interface HwStatus {
|
|
2
3
|
connected: boolean;
|
|
3
4
|
firmwareVersion: string;
|
|
@@ -24,4 +25,6 @@ export declare function parseHwTune(output: string): HwTune;
|
|
|
24
25
|
export declare function parseLfSearch(output: string): CardInfo | null;
|
|
25
26
|
export declare function parseT55xxDetect(output: string): T55xxInfo | null;
|
|
26
27
|
export declare function parseHfSearch(output: string): CardInfo | null;
|
|
28
|
+
export declare function parseMagicType(output: string): MagicCardTypeName;
|
|
29
|
+
export declare function parseBlock0Data(output: string): string | null;
|
|
27
30
|
export declare function parseCloneResult(output: string): CloneResult;
|
package/dist/lib/parsers.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CardType } from "./constants.js";
|
|
1
|
+
import { CardType, MagicCardType } from "./constants.js";
|
|
2
2
|
export function parseHwStatus(output) {
|
|
3
3
|
const isStockFirmware = output.includes("unknown command");
|
|
4
4
|
const connected = !isStockFirmware && !output.includes("cannot communicate") && !output.includes("ERROR");
|
|
@@ -74,6 +74,20 @@ export function parseHfSearch(output) {
|
|
|
74
74
|
}
|
|
75
75
|
return { type, id: uid };
|
|
76
76
|
}
|
|
77
|
+
export function parseMagicType(output) {
|
|
78
|
+
if (/Gen\s*1\s*a|magic\s*backdoor/i.test(output))
|
|
79
|
+
return MagicCardType.GEN1A;
|
|
80
|
+
if (/Gen\s*2|CUID/i.test(output))
|
|
81
|
+
return MagicCardType.GEN2_CUID;
|
|
82
|
+
return MagicCardType.UNKNOWN;
|
|
83
|
+
}
|
|
84
|
+
export function parseBlock0Data(output) {
|
|
85
|
+
// Matches rdbl output: "0 | 81 54 98 C5 88 08 04 00 ..."
|
|
86
|
+
const match = output.match(/\|\s*([0-9A-Fa-f]{2}(?:\s+[0-9A-Fa-f]{2}){15})\s*\|/);
|
|
87
|
+
if (!match)
|
|
88
|
+
return null;
|
|
89
|
+
return match[1].replace(/\s+/g, "").toUpperCase();
|
|
90
|
+
}
|
|
77
91
|
export function parseCloneResult(output) {
|
|
78
92
|
const hasError = /error/i.test(output) && !/errorrate/i.test(output);
|
|
79
93
|
const hasDone = /done/i.test(output) || /written/i.test(output) || /cloned/i.test(output) || /verified/i.test(output);
|
package/dist/lib/parsers.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parsers.js","sourceRoot":"","sources":["../../src/lib/parsers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"parsers.js","sourceRoot":"","sources":["../../src/lib/parsers.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/pm3.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Pm3Command } from "./constants.js";
|
|
1
2
|
export declare class Pm3Error extends Error {
|
|
2
3
|
stdout: string;
|
|
3
4
|
stderr: string;
|
|
@@ -7,6 +8,6 @@ export interface Pm3Result {
|
|
|
7
8
|
stdout: string;
|
|
8
9
|
stderr: string;
|
|
9
10
|
}
|
|
10
|
-
export declare function pm3Exec(command:
|
|
11
|
+
export declare function pm3Exec(command: Pm3Command, timeout?: number): Promise<Pm3Result>;
|
|
11
12
|
export declare function requireDevice(): Promise<boolean>;
|
|
12
13
|
export declare function detectPort(): Promise<string | null>;
|
package/dist/lib/pm3.js
CHANGED
|
@@ -14,7 +14,7 @@ export class Pm3Error extends Error {
|
|
|
14
14
|
}
|
|
15
15
|
export async function pm3Exec(command, timeout = DEFAULT_TIMEOUT) {
|
|
16
16
|
return new Promise((resolve, reject) => {
|
|
17
|
-
const _proc = execFile("pm3", ["-c", command], { timeout }, (error, stdout, stderr) => {
|
|
17
|
+
const _proc = execFile("pm3", ["-c", command.toString()], { timeout }, (error, stdout, stderr) => {
|
|
18
18
|
const out = stdout?.toString() ?? "";
|
|
19
19
|
const err = stderr?.toString() ?? "";
|
|
20
20
|
if (error) {
|
package/dist/lib/pm3.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pm3.js","sourceRoot":"","sources":["../../src/lib/pm3.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"pm3.js","sourceRoot":"","sources":["../../src/lib/pm3.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AAGpC,MAAM,eAAe,GAAG,MAAM,CAAC;AAE/B,MAAM,OAAO,QAAS,SAAQ,KAAK;IAC/B,MAAM,CAAS;IACf,MAAM,CAAS;IACf,YAAY,OAAe,EAAE,MAAc,EAAE,MAAc;QACvD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACzB,CAAC;CACJ;AAOD,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,OAAmB,EAAE,OAAO,GAAG,eAAe;IACxE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACnC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YAC7F,MAAM,GAAG,GAAG,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;YACrC,MAAM,GAAG,GAAG,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;YACrC,IAAI,KAAK,EAAE,CAAC;gBACR,kEAAkE;gBAClE,iEAAiE;gBACjE,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBACrD,MAAM,CACF,IAAI,QAAQ,CACR,yEAAyE,EACzE,GAAG,EACH,GAAG,CACN,CACJ,CAAC;oBACF,OAAO;gBACX,CAAC;gBACD,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;oBACf,MAAM,CAAC,IAAI,QAAQ,CAAC,+BAA+B,OAAO,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;oBAC3E,OAAO;gBACX,CAAC;gBACD,8CAA8C;gBAC9C,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;gBACtC,OAAO;YACX,CAAC;YACD,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa;IAC/B,MAAM,IAAI,GAAG,MAAM,UAAU,EAAE,CAAC;IAChC,IAAI,CAAC,IAAI,EAAE,CAAC;QACR,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;QAC5D,OAAO,KAAK,CAAC;IACjB,CAAC;IACD,OAAO,IAAI,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU;IAC5B,IAAI,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;QACtC,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC;QAChE,OAAO,KAAK,CAAC,CAAC,CAAC,QAAQ,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,IAAI,CAAC;IAChB,CAAC;AACL,CAAC"}
|