text
[RRG-proxmark3.git] / client / luascripts / data_mfu_bin2eml.lua
blobeeece3b7ca140d4e788a9b588d45ff40d48df6b9
1 -- The getopt-functionality is loaded from pm3/getopt.lua
2 -- Have a look there for further details
3 getopt = require('getopt')
4 bin = require('bin')
5 local ansicolors = require('ansicolors')
7 copyright = ''
8 author = "Martin Holst Swende \n @Marshmellow \n @iceman"
9 version = 'v1.0.4'
10 desc =[[
11 This script takes a dumpfile from 'hf mfu dump' and converts it to a format that can be used
12 by the emulator
14 example = [[
15 script run data_mfu_bin2eml -i dumpdata-foobar.bin
17 usage = [[
18 script run data_mfu_bin2eml [-i <file>] [-o <file>]
20 arguments = [[
21 -h This help
22 -i <file> Specifies the dump-file (input). If omitted, 'dumpdata.bin' is used
23 -o <filename> Specifies the output file. If omitted, <uid>.eml is used.
27 local DEBUG = false
29 ---
30 -- A debug printout-function
31 local function dbg(args)
32 if not DEBUG then return end
33 if type(args) == 'table' then
34 local i = 1
35 while result[i] do
36 dbg(result[i])
37 i = i+1
38 end
39 else
40 print('###', args)
41 end
42 end
43 ---
44 -- This is only meant to be used when errors occur
45 local function oops(err)
46 print('[!!] ERROR:', err)
47 core.clearCommandBuffer()
48 return nil, err
49 end
50 ---
51 -- Usage help
52 local function help()
53 print(copyright)
54 print(author)
55 print(version)
56 print(desc)
57 print(ansicolors.cyan..'Usage'..ansicolors.reset)
58 print(usage)
59 print(ansicolors.cyan..'Arguments'..ansicolors.reset)
60 print(arguments)
61 print(ansicolors.cyan..'Example usage'..ansicolors.reset)
62 print(example)
63 end
65 local function convert_to_ascii(hexdata)
66 if string.len(hexdata) % 8 ~= 0 then
67 return oops(("Bad data, length should be a multiple of 8 (was %d)"):format(string.len(hexdata)))
68 end
70 local js,i = "[";
71 for i = 1, string.len(hexdata),8 do
72 js = js .."'" ..string.sub(hexdata,i,i+7).."',\n"
73 end
74 js = js .. "]"
75 return js
76 end
78 local function readdump(infile)
79 t = infile:read('*all')
80 len = string.len(t)
81 local len,hex = bin.unpack(('H%d'):format(len),t)
82 return hex
83 end
85 local function convert_to_emulform(hexdata)
86 if string.len(hexdata) % 8 ~= 0 then
87 return oops(('Bad data, length should be a multiple of 8 (was %d)'):format(string.len(hexdata)))
88 end
89 local ascii,i = '';
90 for i = 1, string.len(hexdata), 8 do
91 ascii = ascii..string.sub(hexdata, i, i+7)..'\n'
92 end
93 return string.sub(ascii, 1, -2)
94 end
96 local function main(args)
98 local input = 'dumpdata.bin'
99 local output
101 for o, a in getopt.getopt(args, 'i:o:h') do
102 if o == 'h' then return help() end
103 if o == 'i' then input = a end
104 if o == 'o' then output = a end
106 -- Validate the parameters
108 local infile = io.open(input, 'rb')
109 if infile == nil then
110 return oops('Could not read file ', input)
112 local dumpdata = readdump(infile)
113 -- The hex-data is now in ascii-format,
115 -- But first, check the uid
116 -- lua uses start index and endindex, not count.
117 -- UID is 3three skip bcc0 then 4bytes.
118 -- 1 lua is one-index.
119 -- 1 + 112 (56*2) new dump format has version/signature/counter data here
120 -- 113,114,115,116,117,118 UID first three bytes
121 -- 119,120 bcc0
122 -- 121--- UID last four bytes
123 local uid = string.sub(dumpdata, 113, 113+5)..string.sub(dumpdata, 113+8, 113+8+7)
124 output = output or (uid .. '.eml')
126 -- Format some linebreaks
127 dumpdata = convert_to_emulform(dumpdata)
129 local outfile = io.open(output, 'w')
130 if outfile == nil then
131 return oops('Could not write to file ', output)
134 outfile:write(dumpdata:lower())
135 io.close(outfile)
136 print(('[+] Wrote an emulator-dump to the file %s'):format(output))
139 --[[
140 In the future, we may implement so that scripts are invoked directly
141 into a 'main' function, instead of being executed blindly. For future
142 compatibility, I have done so, but I invoke my main from here.
143 --]]
144 main(args)