1 -- The getopt-functionality is loaded from pm3/getopt.lua
2 -- Have a look there for further details
3 getopt
= require('getopt')
5 local ansicolors
= require('ansicolors')
8 author
= 'Martin Holst Swende'
11 This script takes a dumpfile from 'hf mf dump' and converts it to a format that can be used
15 script run data_mf_bin2eml -i dumpdata-foobar.bin
18 script run data_mf_bin2eml [-i <file>] [-o <file>]
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.
28 -------------------------------
30 -------------------------------
33 -- A debug printout-function
34 local function dbg(args
)
35 if not DEBUG
then return end
36 if type(args
) == 'table' then
47 -- This is only meant to be used when errors occur
48 local function oops(err
)
49 print('[!!] ERROR:', err
)
50 core
.clearCommandBuffer()
60 print(ansicolors
.cyan
..'Usage'..ansicolors
.reset
)
62 print(ansicolors
.cyan
..'Arguments'..ansicolors
.reset
)
64 print(ansicolors
.cyan
..'Example usage'..ansicolors
.reset
)
68 local function convert_to_ascii(hexdata
)
69 if string.len(hexdata
) % 32 ~= 0 then
70 return oops(('Bad data, length should be a multiple of 32 (was %d)'):format(string.len(hexdata
)))
74 for i
= 1, string.len(hexdata
),32 do
75 js
= js
.."'" ..string.sub(hexdata
,i
,i
+31).."',\n"
81 local function readdump(infile
)
82 t
= infile
:read('*all')
84 local len
,hex
= bin
.unpack(('H%d'):format(len
),t
)
88 local function convert_to_emulform(hexdata
)
89 if string.len(hexdata
) % 32 ~= 0 then
90 return oops(('Bad data, length should be a multiple of 32 (was %d)'):format(string.len(hexdata
)))
93 for i
= 1, string.len(hexdata
),32 do
94 ascii
= ascii
..string.sub(hexdata
,i
,i
+31)..'\n'
96 return string.sub(ascii
, 1, -2)
99 local function main(args
)
101 local input
= 'dumpdata.bin'
104 for o
, a
in getopt
.getopt(args
, 'i:o:h') do
105 if o
== 'h' then return help() end
106 if o
== 'i' then input
= a
end
107 if o
== 'o' then output
= a
end
109 -- Validate the parameters
111 local infile
= io
.open(input
, 'rb')
112 if infile
== nil then
113 return oops('Could not read file ', input
)
116 local dumpdata
= readdump(infile
)
117 -- The hex-data is now in ascii-format,
118 if dumpdata
== nil then return oops('Dumpfle not loaded') end
120 -- But first, check the uid
121 local uid
= string.sub(dumpdata
, 1, 8)
122 output
= output
or (uid
.. '.eml')
124 -- Format some linebreaks
125 dumpdata
= convert_to_emulform(dumpdata
)
126 if dumpdata
== nil then return oops('Dumpfle not loaded') end
128 local outfile
= io
.open(output
, 'w')
129 if outfile
== nil then
130 return oops('Could not write to file ', output
)
133 outfile
:write(dumpdata
:lower())
135 print(('[+] Wrote an emulator-dump to the file %s'):format(output
))
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.