local getopt = require('getopt') local utils = require('utils') local ac = require('ansicolors') local os = require('os') local count = 0 line = '-------------------------------------------------------------------------' mod = " ELECTRA or EM410x fob cloning SCRIPT " version = " v1.1.17 02/09/2023 made by jareckib " desc = [[ Cloning new ELECTRA tags or EM410x to T5577 tag. This script changes block 0. Additional data is written to block 3 and 4. The last ELECTRA ID can be accessed through the option ---> "-c". For copy directly from the original ELECTRA tag, ---> option "-e". For copy from input, EM410X ID ---> option "-s". Next option for cloning simple EM4102 ---> option "-m". If press it, which writes an ID. If press ---> exit the script. ]] example = [[ ------------------------------------------------------------------------------- --------------- cloning ELECTRA tag from input ID to T5577 tag ---------------- script run lf_electra -s 11AA22BB55 ----------------- continue cloning from last cloned ELECTRA ------------------- script run lf_electra -c ---------------------- ELECTRA cloning from the original TAG ----------------- script run lf_electra -e ----------------------------- simple EM4102 cloning --------------------------- script run lf_electra -m ------------------------------------------------------------------------------- ]] usage = [[ script run lf_electra.lua [-e] [-h] [-c] [-m] [-s ] ]] arguments = [[ -h : this help -c : continue cloning from last ID used -s : ELECTRA - EM410x ID HEX number -e : Read original ELECTRA from Proxmark3 device -m : EM410x cloning ]] --------------------------------------Path to logs files local DEBUG = false local dir = os.getenv('HOME')..'/.proxmark3/logs/' local LAST_ID = os.getenv('HOME')..'/.proxmark3/logs/last_id.txt' local ID_STATUS = (io.popen('dir /a-d /o-d /tw /b/s "'..dir..'" 2>nul:'):read("*a"):match"%C+") if not ID_STATUS then error"No files in this directory" end -------------------------------------------A debug printout-function local function dbg(args) if not DEBUG then return end if type(args) == 'table' then local i = 1 while args[i] do dbg(args[i]) i = i+1 end else print('###', args) end end ------------------------------------------------- errors local function oops(err) core.console('clear') print( string.rep('--',39) ) print( string.rep('--',39) ) print(ac.red..' ERROR:'..ac.reset.. err) print( string.rep('--',39) ) print( string.rep('--',39) ) return nil, err end -----------------------------------------------sleep local function sleep(n) os.execute("sleep " ..tonumber(n)) end --------------------wait function wait(msec) local t = os.clock() repeat until os.clock() > t + msec * 1e-3 end ----------------------------------------------time wait local function timer(n) while n > 0 do io.write(ac.cyan.." ::::: "..ac.yellow.. tonumber(n) ..ac.yellow.." sec "..ac.cyan..":::::\r"..ac.reset) sleep(1) io.flush() n = n-1 end end ----------------------------------------------------- help local function help() core.console('clear') print(line) print(ac.cyan..mod..ac.reset) print(ac.cyan..version..ac.reset) print(ac.yellow..desc..ac.reset) print(line) print(ac.cyan..' Usage'..ac.reset) print(usage) print(ac.cyan..' Arguments'..ac.reset) print(arguments) print(line) timer(30) core.console('clear') print(ac.cyan..' Example usage'..ac.reset) print(example) end ------------------------------------ Exit message local function exitMsg(msg) print( string.rep('--',39) ) print( string.rep('--',39) ) print(msg) print() end --------------------------------- idsearch EM ID local function id() local f = assert(io.open(ID_STATUS, "r")) for line in f:lines() do id = line:match"^%[%+%] EM 410x ID (%x+)" if id then break end end f:close() local f= io.open(ID_STATUS, "w+") f:write(id) f:close() local f= io.open(ID_STATUS, "r") local t = f:read("*all") f:close() local hex_hi = tonumber(t:sub(1, 2), 16) local hex_low = tonumber(t:sub(3, 10), 16) return hex_hi, hex_low end ---------------------------------------read file local function readfile() local f = io.open(ID_STATUS, "r") for line in f:lines() do id = line:match"^(%x+)" if id then break end end f:close() if not id then return oops (" ....No ID found in file") end local f= io.open(ID_STATUS, "r") local t = f:read("*all") f:close() local hex_hi = tonumber(t:sub(1, 2), 16) local hex_low = tonumber(t:sub(3, 10), 16) return hex_hi, hex_low end ----------------------------------------last ID local function IDsaved() local f = io.open(LAST_ID, "r") for line in f:lines() do id = line:match"^(%x+)" if id then break end end f:close() if not id then return oops (" ....No ID found in file") end local f= io.open(LAST_ID, "r") local t = f:read("*all") f:close() local hex_hi = tonumber(t:sub(1, 2), 16) local hex_low = tonumber(t:sub(3, 10), 16) return hex_hi, hex_low end ----------------------------------------write file local function writefile(hex_hi, hex_low) local f = io.open(ID_STATUS, "w+") local g = io.open(LAST_ID, 'w+') f:write(("%02X%08X\n"):format(hex_hi, hex_low)) f:close() g:write(("%02X%08X\n"):format(hex_hi, hex_low)) g:close() print((' Saved EM410x ID '..ac.green..'%02X%08X'..ac.reset..' to TXT file:'):format(hex_hi, hex_low)) print((ac.yellow..' %s'..ac.reset):format(LAST_ID)) return true, 'Ok' end ---------------replace line local last_str = '' function txt_change(str) io.write(('\b \b'):rep(#last_str)) -- old line io.write(str) -- new line io.flush() last_str = str end ---------------------------------------- main local function main(args) print( string.rep('--',39) ) print( string.rep('--',39) ) print() if #args == 0 then return help() end local saved_id = false local id_original = false local emarine = false local input_id = '' for o, a in getopt.getopt(args, 'hems:c') do if o == 'h' then return help() end if o == 'e' then id_original = true end if o == 'm' then emarine = true end if o == 's' then input_id = a end if o == 'c' then saved_id = true end end --------------------check -id if not saved_id and not id_original and not emarine then if input_id == nil then return oops(' empty EM410x ID string') end if #input_id == 0 then return oops(' empty EM410x ID string') end if #input_id < 10 then return oops(' EM410x ID too short. Must be 5 hex bytes') end if #input_id > 10 then return oops(' EM410x ID too long. Must be 5 hex bytes') end end core.console('clear') print( string.rep('--',39) ) print(ac.green..' ....... OFF THE HINTS WILL BE LESS ON THE SCREEN'..ac.reset) print( string.rep('--',39) ) core.console('pref set hint --off') print( string.rep('--',39) ) timer(4) core.console('clear') local hi = tonumber(input_id:sub(1, 2), 16) local low = tonumber(input_id:sub(3, 10), 16) if saved_id then hi, low = IDsaved() print( string.rep('--',39) ) print( string.rep('--',39) ) print('') print(ac.green..' ......Continue cloning from last saved ID'..ac.reset) print('') print( string.rep('--',39) ) end if id_original then print( string.rep('--',39) ) print( string.rep('--',39) ) print('') print(ac.green..' Put the ELECTRA tag on the coil PM3 to read '..ac.reset) print('') print( string.rep('--',39)) print(string.rep('--',39)) end if emarine then print( string.rep('--',39) ) print( string.rep('--',39) ) print('') print(ac.green..' Put the EM4102 tag on the coil PM3 to read '..ac.reset) print('') print( string.rep('--',39) ) print( string.rep('--',39) ) end if emarine or id_original then io.write(' Press'..ac.yellow..' Enter'..ac.reset..' to continue ... ');io.read() txt_change(' Readed TAG : ') core.console(' lf em 410x read') print( string.rep('--',39) ) hi, low = id() timer(7) core.console('clear') print( string.rep('--',39) ) print( string.rep('--',39) ) print('') print(ac.green..' Continuation of the cloning process....'..ac.reset) print('') print( string.rep('--',39) ) end if not emarine and not id_original and not saved_id then print( string.rep('--',39) ) print( string.rep('--',39) ) print('') print(ac.green..' ........ ELECTRA cloning from Entered EM-ELECTRA ID'..ac.reset) print('') print( string.rep('--',39) ) end if emarine then d = ('EM4102 ID ') else d =('ELECTRA ID ') end local template = ((d)..ac.green..'%02X%08X'..ac.reset) for i = low, low + 100, 1 do local msg = (template):format(hi, low) print( string.rep('--',39) ) if count > 0 then print((' TAGs created: '..ac.green..'%s'..ac.reset):format(count)) print( string.rep('--',39) ) end print((' %s >>>>>> cloning to '..ac.cyan..'T5577 -'..ac.yellow..' Enter'..ac.reset..' for yes or '..ac.yellow..'n'..ac.reset..' for exit'):format(msg)) print(' Before confirming the cloning operation, put a blank '..ac.cyan..'T5577'..ac.reset..' tag on coil'..ac.cyan..' PM3'..ac.reset..' !') print( string.rep('--',39) ) io.write(' Continue with this operation'..ac.yellow..' (Enter/n)'..ac.reset..' ? > ') answer = io.read() if answer == 'n' then core.console('clear') print( string.rep('--',39) ) print(ac.red..' USER ABORTED'..ac.reset) print( string.rep('--',39) ) break end core.console('clear') print( string.rep('--',39) ) if emarine then core.console( ('lf em 410x clone --id %02X%08X'):format(hi, low) ) else core.console( ('lf em 410x clone --id %02X%08X'):format(hi, low) ) core.console('lf t55 write -b 0 -d 00148080') core.console('lf t55 write -b 3 -d 7E1EAAAA') core.console('lf t55 write -b 4 -d AAAAAAAA') end count = count+1 end writefile(hi, low) core.console('pref set hint --on') print( string.rep('--',39) ) if count > 0 then print((' TAGs created: '..ac.green..'%s'..ac.reset):format(count)) print( string.rep('--',39) ) end end main(args)