1 local getopt
= require('getopt')
2 local utils
= require('utils')
3 local ac
= require('ansicolors')
4 local os
= require('os')
6 line
= '-------------------------------------------------------------------------'
7 mod = " ELECTRA or EM410x fob cloning SCRIPT "
8 version
= " v1.1.17 02/09/2023 made by jareckib "
11 Cloning new ELECTRA tags or EM410x to T5577 tag. This script changes
12 block 0. Additional data is written to block 3 and 4. The last
13 ELECTRA ID can be accessed through the option ---> "-c". For copy
14 directly from the original ELECTRA tag, ---> option "-e". For copy
15 from input, EM410X ID ---> option "-s". Next option for cloning simple
16 EM4102 ---> option "-m". If press <Enter> it, which writes an ID.
17 If press <n> ---> exit the script.
20 -------------------------------------------------------------------------------
22 --------------- cloning ELECTRA tag from input ID to T5577 tag ----------------
24 script run lf_electra -s 11AA22BB55
26 ----------------- continue cloning from last cloned ELECTRA -------------------
28 script run lf_electra -c
30 ---------------------- ELECTRA cloning from the original TAG -----------------
32 script run lf_electra -e
34 ----------------------------- simple EM4102 cloning ---------------------------
36 script run lf_electra -m
38 -------------------------------------------------------------------------------
41 script run lf_electra.lua [-e] [-h] [-c] [-m] [-s <ID HEX number>]
45 -c : continue cloning from last ID used
46 -s : ELECTRA - EM410x ID HEX number
47 -e : Read original ELECTRA from Proxmark3 device
50 --------------------------------------Path to logs files
52 local dir
= os
.getenv('HOME')..'/.proxmark3/logs/'
53 local LAST_ID
= os
.getenv('HOME')..'/.proxmark3/logs/last_id.txt'
54 local ID_STATUS
= (io
.popen('dir /a-d /o-d /tw /b/s "'..dir
..'" 2>nul:'):read("*a"):match
"%C+")
56 error"No files in this directory"
58 -------------------------------------------A debug printout-function
59 local function dbg(args
)
60 if not DEBUG
then return end
61 if type(args
) == 'table' then
71 ------------------------------------------------- errors
72 local function oops(err
)
74 print( string.rep('--',39) )
75 print( string.rep('--',39) )
76 print(ac
.red
..' ERROR:'..ac
.reset
.. err
)
77 print( string.rep('--',39) )
78 print( string.rep('--',39) )
81 -----------------------------------------------sleep
82 local function sleep(n
)
83 os
.execute("sleep " ..tonumber(n
))
85 --------------------wait
89 until os
.clock() > t
+ msec
* 1e-3
91 ----------------------------------------------time wait
92 local function timer(n
)
94 io
.write(ac
.cyan
.." ::::: "..ac
.yellow
.. tonumber(n
) ..ac
.yellow
.." sec "..ac
.cyan
..":::::\r"..ac
.reset
)
100 ----------------------------------------------------- help
101 local function help()
102 core
.console('clear')
104 print(ac
.cyan
..mod..ac
.reset
)
105 print(ac
.cyan
..version
..ac
.reset
)
106 print(ac
.yellow
..desc
..ac
.reset
)
108 print(ac
.cyan
..' Usage'..ac
.reset
)
110 print(ac
.cyan
..' Arguments'..ac
.reset
)
114 core
.console('clear')
115 print(ac
.cyan
..' Example usage'..ac
.reset
)
118 ------------------------------------ Exit message
119 local function exitMsg(msg
)
120 print( string.rep('--',39) )
121 print( string.rep('--',39) )
125 --------------------------------- idsearch EM ID
127 local f
= assert(io
.open(ID_STATUS
, "r"))
128 for line
in f
:lines() do
129 id
= line
:match
"^%[%+%] EM 410x ID (%x+)"
133 local f
= io
.open(ID_STATUS
, "w+")
136 local f
= io
.open(ID_STATUS
, "r")
137 local t
= f
:read("*all")
139 local hex_hi
= tonumber(t
:sub(1, 2), 16)
140 local hex_low
= tonumber(t
:sub(3, 10), 16)
141 return hex_hi
, hex_low
143 ---------------------------------------read file
144 local function readfile()
145 local f
= io
.open(ID_STATUS
, "r")
146 for line
in f
:lines() do
147 id
= line
:match
"^(%x+)"
152 return oops (" ....No ID found in file") end
153 local f
= io
.open(ID_STATUS
, "r")
154 local t
= f
:read("*all")
156 local hex_hi
= tonumber(t
:sub(1, 2), 16)
157 local hex_low
= tonumber(t
:sub(3, 10), 16)
158 return hex_hi
, hex_low
160 ----------------------------------------last ID
161 local function IDsaved()
162 local f
= io
.open(LAST_ID
, "r")
163 for line
in f
:lines() do
164 id
= line
:match
"^(%x+)"
169 return oops (" ....No ID found in file") end
170 local f
= io
.open(LAST_ID
, "r")
171 local t
= f
:read("*all")
173 local hex_hi
= tonumber(t
:sub(1, 2), 16)
174 local hex_low
= tonumber(t
:sub(3, 10), 16)
175 return hex_hi
, hex_low
177 ----------------------------------------write file
178 local function writefile(hex_hi
, hex_low
)
179 local f
= io
.open(ID_STATUS
, "w+")
180 local g
= io
.open(LAST_ID
, 'w+')
181 f
:write(("%02X%08X\n"):format(hex_hi
, hex_low
))
183 g
:write(("%02X%08X\n"):format(hex_hi
, hex_low
))
185 print((' Saved EM410x ID '..ac
.green
..'%02X%08X'..ac
.reset
..' to TXT file:'):format(hex_hi
, hex_low
))
186 print((ac
.yellow
..' %s'..ac
.reset
):format(LAST_ID
))
189 ---------------replace line
191 function txt_change(str
)
192 io
.write(('\b \b'):rep(#last_str
)) -- old line
193 io
.write(str
) -- new line
197 ---------------------------------------- main
198 local function main(args
)
199 print( string.rep('--',39) )
200 print( string.rep('--',39) )
202 if #args
== 0 then return help() end
203 local saved_id
= false
204 local id_original
= false
205 local emarine
= false
207 for o
, a
in getopt
.getopt(args
, 'hems:c') do
208 if o
== 'h' then return help() end
209 if o
== 'e' then id_original
= true end
210 if o
== 'm' then emarine
= true end
211 if o
== 's' then input_id
= a
end
212 if o
== 'c' then saved_id
= true end
214 --------------------check -id
215 if not saved_id
and not id_original
and not emarine
then
216 if input_id
== nil then return oops(' empty EM410x ID string') end
217 if #input_id
== 0 then return oops(' empty EM410x ID string') end
218 if #input_id
< 10 then return oops(' EM410x ID too short. Must be 5 hex bytes') end
219 if #input_id
> 10 then return oops(' EM410x ID too long. Must be 5 hex bytes') end
221 core
.console('clear')
222 print( string.rep('--',39) )
223 print(ac
.green
..' ....... OFF THE HINTS WILL BE LESS ON THE SCREEN'..ac
.reset
)
224 print( string.rep('--',39) )
225 core
.console('pref set hint --off')
226 print( string.rep('--',39) )
228 core
.console('clear')
229 local hi
= tonumber(input_id
:sub(1, 2), 16)
230 local low
= tonumber(input_id
:sub(3, 10), 16)
233 print( string.rep('--',39) )
234 print( string.rep('--',39) )
236 print(ac
.green
..' ......Continue cloning from last saved ID'..ac
.reset
)
238 print( string.rep('--',39) )
241 print( string.rep('--',39) )
242 print( string.rep('--',39) )
244 print(ac
.green
..' Put the ELECTRA tag on the coil PM3 to read '..ac
.reset
)
246 print( string.rep('--',39))
247 print(string.rep('--',39))
250 print( string.rep('--',39) )
251 print( string.rep('--',39) )
253 print(ac
.green
..' Put the EM4102 tag on the coil PM3 to read '..ac
.reset
)
255 print( string.rep('--',39) )
256 print( string.rep('--',39) )
258 if emarine
or id_original
then
259 io
.write(' Press'..ac
.yellow
..' Enter'..ac
.reset
..' to continue ... ');io
.read()
260 txt_change(' Readed TAG : ')
261 core
.console(' lf em 410x read')
262 print( string.rep('--',39) )
265 core
.console('clear')
266 print( string.rep('--',39) )
267 print( string.rep('--',39) )
269 print(ac
.green
..' Continuation of the cloning process....'..ac
.reset
)
271 print( string.rep('--',39) )
273 if not emarine
and not id_original
and not saved_id
then
274 print( string.rep('--',39) )
275 print( string.rep('--',39) )
277 print(ac
.green
..' ........ ELECTRA cloning from Entered EM-ELECTRA ID'..ac
.reset
)
279 print( string.rep('--',39) )
286 local template
= ((d
)..ac
.green
..'%02X%08X'..ac
.reset
)
287 for i
= low
, low
+ 100, 1 do
288 local msg
= (template
):format(hi
, low
)
289 print( string.rep('--',39) )
291 print((' TAGs created: '..ac
.green
..'%s'..ac
.reset
):format(count
))
292 print( string.rep('--',39) )
294 print((' %s >>>>>> cloning to '..ac
.cyan
..'T5577 -'..ac
.yellow
..' Enter'..ac
.reset
..' for yes or '..ac
.yellow
..'n'..ac
.reset
..' for exit'):format(msg
))
295 print(' Before confirming the cloning operation, put a blank '..ac
.cyan
..'T5577'..ac
.reset
..' tag on coil'..ac
.cyan
..' PM3'..ac
.reset
..' !')
296 print( string.rep('--',39) )
297 io
.write(' Continue with this operation'..ac
.yellow
..' (Enter/n)'..ac
.reset
..' ? > ')
299 if answer
== 'n' then
300 core
.console('clear')
301 print( string.rep('--',39) )
302 print(ac
.red
..' USER ABORTED'..ac
.reset
)
303 print( string.rep('--',39) )
306 core
.console('clear')
307 print( string.rep('--',39) )
309 core
.console( ('lf em 410x clone --id %02X%08X'):format(hi
, low
) )
311 core
.console( ('lf em 410x clone --id %02X%08X'):format(hi
, low
) )
312 core
.console('lf t55 write -b 0 -d 00148080')
313 core
.console('lf t55 write -b 3 -d 7E1EAAAA')
314 core
.console('lf t55 write -b 4 -d AAAAAAAA')
319 core
.console('pref set hint --on')
320 print( string.rep('--',39) )
322 print((' TAGs created: '..ac
.green
..'%s'..ac
.reset
):format(count
))
323 print( string.rep('--',39) )