]>
Commit | Line | Data |
---|---|---|
1 | local cmds = require('commands') | |
2 | local getopt = require('getopt') | |
3 | local lib14a = require('read14a') | |
4 | local utils = require('utils') | |
5 | local pre = require('precalc') | |
6 | ||
7 | local lsh = bit32.lshift | |
8 | local rsh = bit32.rshift | |
9 | local bor = bit32.bor | |
10 | local band = bit32.band | |
11 | ||
12 | example =[[ | |
13 | script run tnp3dump | |
14 | script run tnp3dump -h | |
15 | script run tnp3dump -t aa00 | |
16 | ||
17 | ]] | |
18 | author = "Iceman" | |
19 | usage = "script run tnp3clone -t <toytype>" | |
20 | desc =[[ | |
21 | This script will try making a barebone clone of a tnp3 tag on to a magic generation1 card. | |
22 | ||
23 | Arguments: | |
24 | -h : this help | |
25 | -k <key> : toytype id, 4 hex symbols. | |
26 | ]] | |
27 | ||
28 | ||
29 | -- This is only meant to be used when errors occur | |
30 | function oops(err) | |
31 | print("ERROR: ",err) | |
32 | end | |
33 | -- Usage help | |
34 | function help() | |
35 | print(desc) | |
36 | print("Example usage") | |
37 | print(example) | |
38 | end | |
39 | ||
40 | local function waitCmd() | |
41 | local response = core.WaitForResponseTimeout(cmds.CMD_ACK,2000) | |
42 | if response then | |
43 | local count,cmd,arg0 = bin.unpack('LL',response) | |
44 | if(arg0==1) then | |
45 | local count,arg1,arg2,data = bin.unpack('LLH511',response,count) | |
46 | return data:sub(1,32) | |
47 | else | |
48 | return nil, "Couldn't read block." | |
49 | end | |
50 | end | |
51 | return nil, "No response from device" | |
52 | end | |
53 | ||
54 | local function readblock( keyA ) | |
55 | -- Read block 0 | |
56 | cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = 0,arg2 = 0,arg3 = 0, data = keyA} | |
57 | err = core.SendCommand(cmd:getBytes()) | |
58 | if err then return oops(err) end | |
59 | local block0, err = waitCmd() | |
60 | if err then return oops(err) end | |
61 | return block0 | |
62 | end | |
63 | ||
64 | local function main(args) | |
65 | ||
66 | local numBlocks = 64 | |
67 | local cset = 'hf mf csetbl' | |
68 | local empty = '00000000000000000000000000000000' | |
69 | local AccAndKeyB = '7F078869000000000000' | |
70 | -- Defaults to Gusto | |
71 | local toytype = 'C201' | |
72 | ||
73 | -- Arguments for the script | |
74 | for o, a in getopt.getopt(args, 'ht:') do | |
75 | if o == "h" then return help() end | |
76 | if o == "t" then toytype = a end | |
77 | end | |
78 | ||
79 | if #toytype ~= 4 then return oops('Wrong size in toytype. (4hex symbols)') end | |
80 | ||
81 | -- find tag | |
82 | result, err = lib14a.read1443a(false) | |
83 | if not result then return oops(err) end | |
84 | ||
85 | -- Show tag info | |
86 | print((' Found tag %s'):format(result.name)) | |
87 | ||
88 | -- load keys | |
89 | local akeys = pre.GetAll(result.uid) | |
90 | local keyA = akeys:sub(1, 12 ) | |
91 | ||
92 | local b0 = readblock(keyA) | |
93 | local b1 = toytype..'000000000000000000000000' | |
94 | ||
95 | local calc = utils.Crc16(b0..b1) | |
96 | local calcEndian = bor(rsh(calc,8), lsh(band(calc, 0xff), 8)) | |
97 | ||
98 | local cmd = ('hf mf csetbl 1 %s%04x'):format( b1, calcEndian) | |
99 | core.console( cmd) | |
100 | ||
101 | local pos, key | |
102 | for blockNo = 2, numBlocks-1, 1 do | |
103 | pos = (math.floor( blockNo / 4 ) * 12)+1 | |
104 | key = akeys:sub(pos, pos + 11 ) | |
105 | if blockNo%4 ~= 3 then | |
106 | cmd = ('%s %d %s'):format(cset,blockNo,empty) | |
107 | else | |
108 | cmd = ('%s %d %s%s'):format(cset,blockNo,key,AccAndKeyB) | |
109 | end | |
110 | core.console(cmd) | |
111 | end | |
112 | end | |
113 | main(args) |