This commit is contained in:
iceman1001 2020-04-05 14:53:32 +02:00
parent acfe18e7e9
commit 3a2723ac63

View file

@ -2,6 +2,7 @@ local utils = require('utils')
local cmds = require('commands')
local getopt = require('getopt')
local ansicolors = require('ansicolors')
--[[
script to create a clone-dump with new crc
Author: mosci
@ -17,18 +18,15 @@ local ansicolors = require('ansicolors')
simplest usage:
read a valid legic tag with 'hf legic reader'
save the dump with 'hf legic dump o orig'
place your 'empty' tag on the reader and run 'script run Legic_clone -i orig.bin -w'
save the dump with 'hf legic dump f orig'
place your 'empty' tag on the reader and run 'script run legic_clone -i orig.bin -w'
you will see some output like:
read 1024 bytes from orig.bin
place your empty tag onto the PM3 to read and display the MCD & MSN0..2
the values will be shown below
confirm when ready [y/n] ?y
#db# setting up legic card
#db# MIM 256 card found, reading card ...
#db# Card read, use 'hf legic decode' or
#db# 'data hexsamples 8' to view results
0b ad c0 de <- !! here you'll see the MCD & MSN of your empty tag, which has to be typed in manually as seen below !!
type in MCD as 2-digit value - e.g.: 00 (default: 79 )
> 0b
@ -93,18 +91,18 @@ author = 'Mosci'
version = 'v1.0.2'
desc = [[
This is a script which creates a clone-dump of a dump from a Legic Prime Tag (MIM256 or MIM1024)
(created with 'hf legic dump f my_dump')
Create a dump by running 'hf legic dump'.
]]
example = [[
script run legic_clone -i my_dump.bin -o my_clone.bin -c f8
script run legic_clone -i my_dump.bin -d -s
]]
usage = [[
script run legic_clone -h -i <file> -o <file> -c <crc> -d -s -w
script run legic_clone [-h] [-i <file>] [-o <file>] [-c <crc>] [-d] [-s] [-w]
]]
arguments = [[
required :
-i <input file> (file to read data from, must be in binary format (*.bin))
-i <input file> - file to read data from, must be in binary format (*.bin)
optional :
-h - Help text
@ -112,7 +110,7 @@ optional :
-c <new-tag crc> - requires option -o to be given
-d - Display content of found Segments
-s - Display summary at the end
-w - write directly to Tag - a file myLegicClone.bin will be generated also
-w - write directly to tag - a file hf-legic-UID-dump.bin will also be generated
e.g.:
hint: using the CRC '00' will result in a plain dump ( -c 00 )
@ -139,7 +137,20 @@ local function oops(err)
core.clearCommandBuffer()
return nil, err
end
---
-- Usage help
local function help()
print(copyright)
print(author)
print(version)
print(desc)
print(ansicolors.cyan..'Usage'..ansicolors.reset)
print(usage)
print(ansicolors.cyan..'Arguments'..ansicolors.reset)
print(arguments)
print(ansicolors.cyan..'Example usage'..ansicolors.reset)
print(example)
end
-- read LEGIC data
local function readlegicdata(offset, length, iv)
-- Read data
@ -156,30 +167,15 @@ local function readlegicdata( offset, length, iv )
return result
end
---
-- Usage help
local function help()
print(copyright)
print(author)
print(version)
print(desc)
print(ansicolors.cyan..'Usage'..ansicolors.reset)
print(usage)
print(ansicolors.cyan..'Arguments'..ansicolors.reset)
print(arguments)
print(ansicolors.cyan..'Example usage'..ansicolors.reset)
print(example)
end
-- Check availability of file
local function file_check(file_name)
local file_found = io.open(file_name, "r")
if not file_found then
file_found = false
local exists = io.open(file_name, "r")
if not exists then
exists = false
else
file_found = true
exists = true
end
return file_found
return exists
end
--- xor-wrapper
@ -241,7 +237,7 @@ local function xorBytes(inBytes, crc)
end
-- get raw segment-data
function getSegmentData(bytes, start, index)
local function getSegmentData(bytes, start, index)
local raw, len, valid, last, wrp, wrc, rd, crc
local segment = {}
segment[0] = bytes[start]..' '..bytes[start + 1]..' '..bytes[start + 2]..' '..bytes[start + 3]
@ -280,7 +276,7 @@ end
--- Kaba Group Header
-- checks if a segment does have a kghCRC
-- returns boolean false if no kgh has being detected or the kghCRC if a kgh was detected
function CheckKgh(bytes, segStart, segEnd)
local function CheckKgh(bytes, segStart, segEnd)
if (bytes[8] == '9f' and bytes[9] == 'ff' and bytes[13] == '11') then
local i
local data = {}
@ -308,7 +304,7 @@ function CheckKgh(bytes, segStart, segEnd)
end
-- get only the addresses of segemnt-crc's and the length of bytes
function getSegmentCrcBytes(bytes)
local function getSegmentCrcBytes(bytes)
local start = 23
local index = 0
local crcbytes = {}
@ -323,7 +319,7 @@ function getSegmentCrcBytes(bytes)
end
-- print segment-data (hf legic info like)
function displaySegments(bytes)
local function displaySegments(bytes)
--display segment header(s)
start = 23
index = '00'
@ -365,7 +361,7 @@ function displaySegments(bytes)
end
print(pld)
if (KGH) then
print("'Kaba Group Header' detected")
print(ansicolors.yellow.."'Kaba Group Header' detected"..ansicolors.reset)
end
start = start + Seg[4]
index = prepend_zero(tonumber(Seg[9]) + 1)
@ -374,7 +370,7 @@ function displaySegments(bytes)
end
-- print Segment values
function printSegment(SegmentData)
local function printSegment(SegmentData)
res = "\nSegment "..SegmentData[9]..": "
res = res.. "raw header="..SegmentData[0]..", "
res = res.. "flag="..SegmentData[1].." (valid="..SegmentData[2].." last="..SegmentData[3].."), "
@ -387,7 +383,7 @@ function printSegment(SegmentData)
end
-- write clone-data to tag
function writeToTag(plainBytes)
local function writeToTag(plainBytes)
local SegCrcs = {}
local output
local readbytes
@ -399,6 +395,7 @@ function writeToTag(plainBytes)
-- gather MCD & MSN from new Tag - this must be enterd manually
print("\nthese are the MCD MSN0 MSN1 MSN2 from the Tag that has being read:")
-- readbytes is a usbcommandOLD package, hence 32 bytes offset until data.
plainBytes[1] = ('%02x'):format(readbytes:byte(33))
plainBytes[2] = ('%02x'):format(readbytes:byte(34))
plainBytes[3] = ('%02x'):format(readbytes:byte(35))
@ -411,7 +408,7 @@ function writeToTag(plainBytes)
-- calculate crc8 over MCD & MSN
cmd = MCD..MSN0..MSN1..MSN2
MCC = ("%02x"):format(utils.Crc8Legic(cmd))
print("MCD:"..MCD..", MSN:"..MSN0.." "..MSN1.." "..MSN2..", MCC:"..MCC)
print("MCD:"..ansicolors.green..MCD..ansicolors.reset..", MSN:"..ansicolors.green..MSN0.." "..MSN1.." "..MSN2..ansicolors.reset..", MCC:"..MCC)
-- calculate new Segment-CRC for each valid segment
SegCrcs = getSegmentCrcBytes(plainBytes)
@ -439,15 +436,15 @@ function writeToTag(plainBytes)
bytes = xorBytes(plainBytes, MCC)
-- write data to file
if (writeOutputBytes(bytes, "myLegicClone.bin")) then
if (writeOutputBytes(bytes, "hf-legic-UID-dump.bin")) then
-- write pm3-buffer to Tag
cmd = ('hf legic restore f myLegicClone')
cmd = ('hf legic restore f hf-legic-UID-dump')
core.console(cmd)
end
end
-- main function
function main(args)
local function main(args)
-- some variables
local i = 0
local oldcrc, newcrc, infile, outfile
@ -468,14 +465,13 @@ function main(args)
-- input file
if o == 'i' then
infile = a
if (file_check(infile)==false) then
return oops('input file: '..infile..' not found')
else
if (file_check(infile) == false) then return oops('input file: '..infile..' not found') end
bytes = getInputBytes(infile)
oldcrc = bytes[5]
ifs = true
if (bytes == false) then return oops('couldnt get input bytes') end
end
i = i + 1
end
-- new crc
@ -515,12 +511,14 @@ function main(args)
res = "\n+-------------------------------------------- Summary -------------------------------------------+"
res = res .."\ncreated clone_dump from\n\t"..infile.." crc: "..oldcrc.."\ndump_file:"
res = res .."\n\t"..outfile.." crc: "..string.sub(newcrc, -2)
res = res .."\nyou may load the new file with: hf legic eload "..outfile
res = res .."\nyou may load the new file with:"
res = res ..ansicolors.yellow.."hf legic eload f "..outfile..ansicolors.reset
res = res .."\n\nif you don't write to tag immediately ('-w' switch) you will need to recalculate each segmentCRC"
res = res .."\nafter writing this dump to a tag!"
res = res .."\n\na segmentCRC gets calculated over MCD,MSN0..3, Segment-Header0..3"
res = res .."\ne.g. (based on Segment00 of the data from "..infile.."):"
res = res .."\nhf legic crc d "..bytes[1]..bytes[2]..bytes[3]..bytes[4]..bytes[23]..bytes[24]..bytes[25]..bytes[26].." u "..newcrc.." c 8"
res = res .."\n"
res = res ..ansicolors.yellow.."hf legic crc d "..bytes[1]..bytes[2]..bytes[3]..bytes[4]..bytes[23]..bytes[24]..bytes[25]..bytes[26].." u "..newcrc.." c 8"..ansicolors.reset
-- this can not be calculated without knowing the new MCD, MSN0..2
print(res)
end