2016-02-28 21:50:49 +08:00
--[[
2019-03-09 17:34:43 +08:00
script to create a clone - dump with new crc
2016-02-28 21:50:49 +08:00
Author : mosci
my Fork : https : // github.com / icsom / proxmark3.git
2019-03-09 17:34:43 +08:00
Upstream : https : // github.com / Proxmark / proxmark3.git
1. read tag - dump , xor byte 22. . end with byte 0x05 of the inputfile
2. write to outfile
3. set byte 0x05 to newcrc
4. until byte 0x21 plain like in inputfile
5. from 0x22. . end xored with newcrc
6. calculate new crc on each segment ( needs to know the new MCD & MSN0 .. 2 )
simplest usage :
read a valid legic tag with ' hf legic reader '
save the dump with ' hf legic save orig.hex '
2016-02-28 21:50:49 +08:00
place your ' empty ' tag on the reader and run ' script run Legic_clone -i orig.hex -w '
you will see some output like :
2019-03-09 17:34:43 +08:00
read 1024 bytes from legic_dumps / j_0000.hex
place your empty tag onto the PM3 to read and display the MCD & MSN0 .. 2
the values will be shown below
2019-10-07 20:57:53 +08:00
confirm when ready [ y / n ] ? y
2019-03-09 17:34:43 +08:00
# 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
0 b 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 )
> 0 b
type in MSN0 as 2 - digit value - e.g . : 01 ( default : 28 )
> ad
type in MSN1 as 2 - digit value - e.g . : 02 ( default : d1 )
> c0
type in MSN2 as 2 - digit value - e.g . : 03 ( default : 43 )
> de
MCD : 0 b , MSN : ad c0 de , MCC : 79 <- this crc is calculated from the MCD & MSN and must match the one on yout empty tag
wrote 1024 bytes to myLegicClone.hex
enter number of bytes to write ? ( default : 86 )
loaded 1024 samples
# db # setting up legic card
# db # MIM 256 card found , writing 0x00 - 0x01 ...
# db # write successful
...
# db # setting up legic card
# db # MIM 256 card found , writing 0x56 - 0x01 ...
# db # write successful
proxmark3 >
the default value ( number of bytes to write ) is calculated over all valid segments and should be ok - just hit enter , wait until write has finished
and your clone should be ready ( except there has to be a additional KGH - CRC to be calculated - which credentials are unknown until yet )
the ' -w ' switch will only work with my fork - it needs the binary legic_crc8 which is not part of the proxmark3 - master - branch
also the ability to write DCF is not possible with the proxmark3 - master - branch
but creating dumpfile - clone files will be possible ( without valid segment - crc - this has to done manually with )
( example ) Legic - Prime Layout with ' Kaba Group Header '
+----+----+----+----+----+----+----+----+
0x00 | MCD | MSN0 | MSN1 | MSN2 | MCC | 60 | ea | 9 f |
+----+----+----+----+----+----+----+----+
0x08 | ff | 00 | 00 | 00 | 11 | Bck0 | Bck1 | Bck2 |
+----+----+----+----+----+----+----+----+
0x10 | Bck3 | Bck4 | Bck5 | BCC | 00 | 00 | Seg0 | Seg1 |
+----+----+----+----+----+----+----+----+
0x18 | Seg2 | Seg3 | SegC | Stp0 | Stp1 | Stp2 | Stp3 | UID0 |
+----+----+----+----+----+----+----+----+
0x20 | UID1 | UID2 | kghC |
+----+----+----+
MCD = ManufacturerID ( 1 Byte )
MSN0 .. 2 = ManufactureSerialNumber ( 3 Byte )
MCC = CRC ( 1 Byte ) calculated over MCD , MSN0 .. 2
DCF = DecrementalField ( 2 Byte ) ' credential ' ( enduser - Tag ) seems to have always DCF - low = 0x60 DCF - high = 0xea
Bck0 .. 5 = Backup ( 6 Byte ) Bck0 ' dirty-flag ' , Bck1 .. 5 SegmentHeader - Backup
BCC = BackupCRC ( 1 Byte ) CRC calculated over Bck1 .. 5
Seg0 .. 3 = SegmentHeader ( on MIM 4 Byte )
SegC = SegmentCRC ( 1 Byte ) calculated over MCD , MSN0 .. 2 , Seg0 .. 3
Stp0 .. n = Stamp0 ... ( variable length ) length = Segment - Len - UserData - 1
UID0 .. n = UserDater ( variable length - with KGH hex 0x00 - 0x63 / dec 0 - 99 ) length = Segment - Len - WRP - WRC - 1
kghC = KabaGroupHeader ( 1 Byte + addr 0x0c must be 0x11 )
as seen on this example : addr 0x05. .0 x08 & 0x0c must have been set to this values - otherwise kghCRC will not be created by a official reader ( not accepted )
2016-02-28 21:50:49 +08:00
--]]
2019-05-08 06:07:20 +08:00
copyright = ' '
author = ' Mosci '
version = ' v1.0.1 '
desc = [ [
2019-10-07 20:57:53 +08:00
This is a script which creates a clone - dump of a dump from a Legic Prime Tag ( MIM256 or MIM1024 )
2019-03-09 17:34:43 +08:00
( created with ' hf legic save my_dump.hex ' )
2019-05-08 06:07:20 +08:00
] ]
example = [ [
script run legic_clone - i my_dump.hex - o my_clone.hex - c f8
script run legic_clone - i my_dump.hex - d - s
] ]
usage = [ [
script run legic_clone - h - i < file > - o < file > - c < crc > - d - s - w
2019-10-07 20:57:53 +08:00
required arguments :
2019-03-09 17:34:43 +08:00
- i < input file > ( file to read data from )
2016-02-28 21:50:49 +08:00
optional arguments :
2019-03-09 17:34:43 +08:00
- h - Help text
2019-10-07 20:57:53 +08:00
- o < output file > - requires option - c to be given
- c < new - tag crc > - requires option - o to be given
2019-03-09 17:34:43 +08:00
- d - Display content of found Segments
- s - Display summary at the end
- w - write directly to Tag - a file myLegicClone.hex wille be generated also
e.g . :
hint : using the CRC ' 00 ' will result in a plain dump ( - c 00 )
2016-02-28 21:50:49 +08:00
] ]
local utils = require ( ' utils ' )
local getopt = require ( ' getopt ' )
local bxor = bit32.bxor
-- we need always 2 digits
2019-05-08 06:07:20 +08:00
local function prepend_zero ( s )
2019-05-08 07:35:51 +08:00
if ( string.len ( s ) == 1 ) then
2019-05-08 06:07:20 +08:00
return ' 0 ' .. s
2019-03-09 17:34:43 +08:00
else
2019-05-08 07:35:51 +08:00
if ( string.len ( s ) == 0 ) then
2019-05-08 06:07:20 +08:00
return ' 00 '
else
return s
2019-03-09 17:34:43 +08:00
end
end
2016-02-28 21:50:49 +08:00
end
2019-03-09 17:34:43 +08:00
---
2016-02-28 21:50:49 +08:00
-- This is only meant to be used when errors occur
2019-05-08 06:07:20 +08:00
local function oops ( err )
print ( ' ERROR: ' , err )
core.clearCommandBuffer ( )
2019-03-09 17:34:43 +08:00
return nil , err
2016-02-28 21:50:49 +08:00
end
2019-03-09 17:34:43 +08:00
---
2016-02-28 21:50:49 +08:00
-- Usage help
2019-05-08 06:07:20 +08:00
local function help ( )
print ( copyright )
print ( author )
print ( version )
2019-03-09 17:34:43 +08:00
print ( desc )
2019-05-08 06:07:20 +08:00
print ( ' Example usage ' )
2019-03-09 17:34:43 +08:00
print ( example )
2019-05-08 06:07:20 +08:00
print ( usage )
2016-02-28 21:50:49 +08:00
end
-- Check availability of file
2019-05-08 06:07:20 +08:00
local function file_check ( file_name )
local file_found = io.open ( file_name , " r " )
if not file_found then
file_found = false
else
file_found = true
end
return file_found
2016-02-28 21:50:49 +08:00
end
--- xor-wrapper
-- xor all from addr 0x22 (start counting from 1 => 23)
2019-05-08 06:07:20 +08:00
local function xorme ( hex , xor , index )
2019-03-09 17:34:43 +08:00
if ( index >= 23 ) then
return ( ' %02x ' ) : format ( bxor ( tonumber ( hex , 16 ) , tonumber ( xor , 16 ) ) )
else
return hex
end
2016-02-28 21:50:49 +08:00
end
-- read input-file into array
2019-05-08 06:07:20 +08:00
local function getInputBytes ( infile )
2019-03-09 17:34:43 +08:00
local line
local bytes = { }
local fhi , err = io.open ( infile )
if err then print ( " OOps ... faild to read from file " .. infile ) ; return false ; end
2016-02-28 21:50:49 +08:00
2019-03-09 17:34:43 +08:00
while true do
line = fhi : read ( )
if line == nil then break end
2016-02-28 21:50:49 +08:00
2019-03-09 17:34:43 +08:00
for byte in line : gmatch ( " %w+ " ) do
table.insert ( bytes , byte )
end
end
2016-02-28 21:50:49 +08:00
2019-03-09 17:34:43 +08:00
fhi : close ( )
2016-02-28 21:50:49 +08:00
2019-03-09 17:34:43 +08:00
print ( " \n read " .. # bytes .. " bytes from " .. infile )
return bytes
2016-02-28 21:50:49 +08:00
end
-- write to file
2019-05-08 06:07:20 +08:00
local function writeOutputBytes ( bytes , outfile )
2019-03-09 17:34:43 +08:00
local line
2019-05-08 06:07:20 +08:00
local bcnt = 0
2019-03-09 17:34:43 +08:00
local fho , err = io.open ( outfile , " w " )
if err then print ( " OOps ... faild to open output-file " .. outfile ) ; return false ; end
for i = 1 , # bytes do
if ( bcnt == 0 ) then
2019-05-08 06:07:20 +08:00
line = bytes [ i ]
2019-03-09 17:34:43 +08:00
elseif ( bcnt <= 7 ) then
2019-05-08 06:07:20 +08:00
line = line .. " " .. bytes [ i ]
2019-03-09 17:34:43 +08:00
end
if ( bcnt == 7 ) then
-- write line to new file
fho : write ( line .. " \n " )
-- reset counter & line
2019-05-08 06:07:20 +08:00
bcnt = - 1
line = " "
2019-03-09 17:34:43 +08:00
end
2019-05-08 06:07:20 +08:00
bcnt = bcnt + 1
2019-03-09 17:34:43 +08:00
end
fho : close ( )
print ( " \n wrote " .. # bytes .. " bytes to " .. outfile )
return true
2016-02-28 21:50:49 +08:00
end
-- xore certain bytes
2019-05-08 06:07:20 +08:00
local function xorBytes ( inBytes , crc )
2019-03-09 17:34:43 +08:00
local bytes = { }
for index = 1 , # inBytes do
bytes [ index ] = xorme ( inBytes [ index ] , crc , index )
end
if ( # inBytes == # bytes ) then
-- replace crc
bytes [ 5 ] = string.sub ( crc , - 2 )
return bytes
else
print ( " error: byte-count missmatch " )
return false
end
2016-02-28 21:50:49 +08:00
end
-- get raw segment-data
function getSegmentData ( bytes , start , index )
2019-03-09 17:34:43 +08:00
local raw , len , valid , last , wrp , wrc , rd , crc
local segment = { }
2019-05-08 06:07:20 +08:00
segment [ 0 ] = bytes [ start ] .. ' ' .. bytes [ start + 1 ] .. ' ' .. bytes [ start + 2 ] .. ' ' .. bytes [ start + 3 ]
2019-03-09 17:34:43 +08:00
-- flag = high nibble of byte 1
segment [ 1 ] = string.sub ( bytes [ start + 1 ] , 0 , 1 )
2016-02-28 21:50:49 +08:00
2019-03-09 17:34:43 +08:00
-- valid = bit 6 of byte 1
2019-05-08 06:07:20 +08:00
segment [ 2 ] = tonumber ( bit32.extract ( ' 0x ' .. bytes [ start + 1 ] , 6 , 1 ) , 16 )
2016-02-28 21:50:49 +08:00
2019-03-09 17:34:43 +08:00
-- last = bit 7 of byte 1
2019-05-08 06:07:20 +08:00
segment [ 3 ] = tonumber ( bit32.extract ( ' 0x ' .. bytes [ start + 1 ] , 7 , 1 ) , 16 )
2016-02-28 21:50:49 +08:00
2019-03-09 17:34:43 +08:00
-- len = (byte 0)+(bit0-3 of byte 1)
2019-05-08 06:07:20 +08:00
segment [ 4 ] = tonumber ( ( ' %03x ' ) : format ( tonumber ( bit32.extract ( ' 0x ' .. bytes [ start + 1 ] , 0 , 3 ) , 16 ) .. tonumber ( bytes [ start ] , 16 ) ) , 16 )
2016-02-28 21:50:49 +08:00
2019-03-09 17:34:43 +08:00
-- wrp (write proteted) = byte 2
segment [ 5 ] = tonumber ( bytes [ start + 2 ] )
-- wrc (write control) - bit 4-6 of byte 3
2019-05-08 06:07:20 +08:00
segment [ 6 ] = tonumber ( bit32.extract ( ' 0x ' .. bytes [ start + 3 ] , 4 , 3 ) , 16 )
2016-02-28 21:50:49 +08:00
2019-03-09 17:34:43 +08:00
-- rd (read disabled) - bit 7 of byte 3
2019-05-08 06:07:20 +08:00
segment [ 7 ] = tonumber ( bit32.extract ( ' 0x ' .. bytes [ start + 3 ] , 7 , 1 ) , 16 )
2016-02-28 21:50:49 +08:00
2019-03-09 17:34:43 +08:00
-- crc byte 4
segment [ 8 ] = bytes [ start + 4 ]
2016-02-28 21:50:49 +08:00
2019-03-09 17:34:43 +08:00
-- segment index
segment [ 9 ] = index
2016-02-28 21:50:49 +08:00
2019-03-09 17:34:43 +08:00
-- # crc-byte
segment [ 10 ] = start + 4
2016-02-28 21:50:49 +08:00
return segment
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 )
2019-05-08 06:07:20 +08:00
if ( bytes [ 8 ] == ' 9f ' and bytes [ 9 ] == ' ff ' and bytes [ 13 ] == ' 11 ' ) then
local i
local data = { }
segStart = tonumber ( segStart , 10 )
segEnd = tonumber ( segEnd , 10 )
local dataLen = segEnd - segStart - 5
--- gather creadentials for verify
local WRP = bytes [ ( segStart + 2 ) ]
local WRC = ( " %02x " ) : format ( tonumber ( bit32.extract ( " 0x " .. bytes [ segStart + 3 ] , 4 , 3 ) , 16 ) )
local RD = ( " %02x " ) : format ( tonumber ( bit32.extract ( " 0x " .. bytes [ segStart + 3 ] , 7 , 1 ) , 16 ) )
local XX = " 00 "
cmd = bytes [ 1 ] .. bytes [ 2 ] .. bytes [ 3 ] .. bytes [ 4 ] .. WRP .. WRC .. RD .. XX
for i = ( segStart + 5 ) , ( segStart + 5 + dataLen - 2 ) do
cmd = cmd .. bytes [ i ]
end
local KGH = ( " %02x " ) : format ( utils.Crc8Legic ( cmd ) )
if ( KGH == bytes [ segEnd - 1 ] ) then
return KGH
else
return false
end
2016-02-28 21:50:49 +08:00
else
2019-05-08 06:07:20 +08:00
return false
2016-02-28 21:50:49 +08:00
end
end
-- get only the addresses of segemnt-crc's and the length of bytes
function getSegmentCrcBytes ( bytes )
2019-05-08 06:07:20 +08:00
local start = 23
local index = 0
2019-03-09 17:34:43 +08:00
local crcbytes = { }
repeat
seg = getSegmentData ( bytes , start , index )
2019-05-08 06:07:20 +08:00
crcbytes [ index ] = seg [ 10 ]
2019-03-09 17:34:43 +08:00
start = start + seg [ 4 ]
index = index + 1
until ( seg [ 3 ] == 1 or tonumber ( seg [ 9 ] ) == 126 )
crcbytes [ index ] = start
return crcbytes
2016-02-28 21:50:49 +08:00
end
-- print segment-data (hf legic decode like)
function displaySegments ( bytes )
2019-03-09 17:34:43 +08:00
--display segment header(s)
2019-05-08 06:07:20 +08:00
start = 23
index = ' 00 '
2019-03-09 17:34:43 +08:00
--repeat until last-flag ist set to 1 or segment-index has reached 126
repeat
2019-05-08 06:07:20 +08:00
wrc = ' '
wrp = ' '
pld = ' '
Seg = getSegmentData ( bytes , start , index )
KGH = CheckKgh ( bytes , start , ( start + tonumber ( Seg [ 4 ] , 10 ) ) )
2019-03-09 17:34:43 +08:00
printSegment ( Seg )
-- wrc
2019-05-08 06:07:20 +08:00
if ( Seg [ 6 ] > 0 ) then
2019-03-09 17:34:43 +08:00
print ( " WRC protected area: " )
-- length of wrc = wrc
for i = 1 , Seg [ 6 ] do
-- starts at (segment-start + segment-header + segment-crc)-1
2019-05-08 06:07:20 +08:00
wrc = wrc .. bytes [ ( start + 4 + 1 + i ) - 1 ] .. ' '
2019-03-09 17:34:43 +08:00
end
print ( wrc )
2019-05-08 06:07:20 +08:00
elseif ( Seg [ 5 ] > 0 ) then
2019-03-09 17:34:43 +08:00
print ( " Remaining write protected area: " )
-- length of wrp = (wrp-wrc)
for i = 1 , ( Seg [ 5 ] - Seg [ 6 ] ) do
-- starts at (segment-start + segment-header + segment-crc + wrc)-1
2019-05-08 06:07:20 +08:00
wrp = wrp .. bytes [ ( start + 4 + 1 + Seg [ 6 ] + i ) - 1 ] .. ' '
2019-03-09 17:34:43 +08:00
end
print ( wrp )
end
-- payload
print ( " Remaining segment payload: " )
--length of payload = segment-len - segment-header - segment-crc - wrp -wrc
for i = 1 , ( Seg [ 4 ] - 4 - 1 - Seg [ 5 ] - Seg [ 6 ] ) do
-- starts at (segment-start + segment-header + segment-crc + segment-wrp + segemnt-wrc)-1
2019-05-08 06:07:20 +08:00
pld = pld .. bytes [ ( start + 4 + 1 + Seg [ 5 ] + Seg [ 6 ] + i ) - 1 ] .. ' '
2019-03-09 17:34:43 +08:00
end
print ( pld )
2019-05-08 07:35:51 +08:00
if ( KGH ) then
2019-05-08 06:07:20 +08:00
print ( " 'Kaba Group Header' detected " )
end
2019-03-09 17:34:43 +08:00
start = start + Seg [ 4 ]
index = prepend_zero ( tonumber ( Seg [ 9 ] ) + 1 )
until ( Seg [ 3 ] == 1 or tonumber ( Seg [ 9 ] ) == 126 )
2016-02-28 21:50:49 +08:00
end
-- print Segment values
function printSegment ( SegmentData )
2019-03-09 17:34:43 +08:00
res = " \n Segment " .. SegmentData [ 9 ] .. " : "
res = res .. " raw header= " .. SegmentData [ 0 ] .. " , "
res = res .. " flag= " .. SegmentData [ 1 ] .. " (valid= " .. SegmentData [ 2 ] .. " last= " .. SegmentData [ 3 ] .. " ), "
res = res .. " len= " .. ( " %04d " ) : format ( SegmentData [ 4 ] ) .. " , "
res = res .. " WRP= " .. prepend_zero ( SegmentData [ 5 ] ) .. " , "
res = res .. " WRC= " .. prepend_zero ( SegmentData [ 6 ] ) .. " , "
res = res .. " RD= " .. SegmentData [ 7 ] .. " , "
res = res .. " crc= " .. SegmentData [ 8 ]
print ( res )
2016-02-28 21:50:49 +08:00
end
-- write clone-data to tag
function writeToTag ( plainBytes )
2019-03-09 17:34:43 +08:00
local SegCrcs = { }
if ( utils.confirm ( " \n place your empty tag onto the PM3 to read and display the MCD & MSN0..2 \n the values will be shown below \n confirm when ready " ) == false ) then
2016-02-28 21:50:49 +08:00
return
end
2019-03-09 17:34:43 +08:00
-- gather MCD & MSN from new Tag - this must be enterd manually
cmd = ' hf legic read 0x00 0x04 '
core.console ( cmd )
print ( " \n these are the MCD MSN0 MSN1 MSN2 from the Tag that has being read: " )
cmd = ' data hexsamples 4 '
core.console ( cmd )
2019-05-08 06:07:20 +08:00
print ( " ^^ use this values as input for the following answers (one 2-digit-value per question/answer): " )
2019-03-09 17:34:43 +08:00
-- enter MCD & MSN (in hex)
MCD = utils.input ( " type in MCD as 2-digit value - e.g.: 00 " , plainBytes [ 1 ] )
MSN0 = utils.input ( " type in MSN0 as 2-digit value - e.g.: 01 " , plainBytes [ 2 ] )
MSN1 = utils.input ( " type in MSN1 as 2-digit value - e.g.: 02 " , plainBytes [ 3 ] )
MSN2 = utils.input ( " type in MSN2 as 2-digit value - e.g.: 03 " , plainBytes [ 4 ] )
-- 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 )
-- calculate new Segment-CRC for each valid segment
SegCrcs = getSegmentCrcBytes ( plainBytes )
for i = 0 , ( # SegCrcs - 1 ) do
2016-02-28 21:50:49 +08:00
-- SegCrcs[i]-4 = address of first byte of segmentHeader (low byte segment-length)
2019-05-08 06:07:20 +08:00
segLen = tonumber ( ( " %1x " ) : format ( tonumber ( bit32.extract ( " 0x " .. plainBytes [ ( SegCrcs [ i ] - 3 ) ] , 0 , 3 ) , 16 ) ) .. ( " %02x " ) : format ( tonumber ( plainBytes [ SegCrcs [ i ] - 4 ] , 16 ) ) , 16 )
segStart = ( SegCrcs [ i ] - 4 )
segEnd = ( SegCrcs [ i ] - 4 + segLen )
KGH = CheckKgh ( plainBytes , segStart , segEnd )
2019-03-09 17:34:43 +08:00
if ( KGH ) then
2016-02-28 21:50:49 +08:00
print ( " 'Kaba Group Header' detected - re-calculate... " )
end
2019-03-09 17:34:43 +08:00
cmd = MCD .. MSN0 .. MSN1 .. MSN2 .. plainBytes [ SegCrcs [ i ] - 4 ] .. plainBytes [ SegCrcs [ i ] - 3 ] .. plainBytes [ SegCrcs [ i ] - 2 ] .. plainBytes [ SegCrcs [ i ] - 1 ]
p lainBytes [ SegCrcs [ i ] ] = ( " %02x " ) : format ( utils.Crc8Legic ( cmd ) )
end
-- apply MCD & MSN to plain data
plainBytes [ 1 ] = MCD
plainBytes [ 2 ] = MSN0
plainBytes [ 3 ] = MSN1
plainBytes [ 4 ] = MSN2
plainBytes [ 5 ] = MCC
-- prepare plainBytes for writing (xor plain data with new MCC)
bytes = xorBytes ( plainBytes , MCC )
-- write data to file
if ( writeOutputBytes ( bytes , " myLegicClone.hex " ) ) then
WriteBytes = utils.input ( " enter number of bytes to write? " , SegCrcs [ # SegCrcs ] )
-- load file into pm3-buffer
2019-05-08 06:07:20 +08:00
cmd = ' hf legic eload myLegicClone.hex '
2019-03-09 17:34:43 +08:00
core.console ( cmd )
-- write pm3-buffer to Tag
for i = 0 , WriteBytes do
if ( i < 5 or i > 6 ) then
2019-05-08 06:07:20 +08:00
cmd = ( ' hf legic write o %02x d 01 ' ) : format ( i )
2019-03-09 17:34:43 +08:00
core.console ( cmd )
elseif ( i == 6 ) then
-- write DCF in reverse order (requires 'mosci-patch')
2019-05-08 06:07:20 +08:00
cmd = ' hf legic write o 05 d 02 '
2019-03-09 17:34:43 +08:00
core.console ( cmd )
else
print ( " skipping byte 0x05 - will be written next step " )
end
utils.Sleep ( 0.2 )
end
end
2016-02-28 21:50:49 +08:00
end
-- main function
function main ( args )
2019-03-09 17:34:43 +08:00
-- some variables
2019-05-08 06:07:20 +08:00
local i = 0
2019-03-09 17:34:43 +08:00
local oldcrc , newcrc , infile , outfile
local bytes = { }
local segments = { }
-- parse arguments for the script
for o , a in getopt.getopt ( args , ' hwsdc:i:o: ' ) do
-- output file
2019-05-08 06:07:20 +08:00
if o == ' o ' then
2019-03-09 17:34:43 +08:00
outfile = a
ofs = true
if ( file_check ( a ) ) then
2019-10-07 20:57:53 +08:00
local answer = utils.confirm ( ' \n the output-file ' .. a .. ' already exists! \n this will delete the previous content! \n continue? ' )
2019-05-08 06:07:20 +08:00
if ( answer == false ) then return oops ( ' quiting ' ) end
2019-03-09 17:34:43 +08:00
end
end
-- input file
2019-05-08 06:07:20 +08:00
if o == ' i ' then
2019-03-09 17:34:43 +08:00
infile = a
if ( file_check ( infile ) == false ) then
2019-05-08 06:07:20 +08:00
return oops ( ' input file: ' .. infile .. ' not found ' )
2019-03-09 17:34:43 +08:00
else
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
2019-05-08 06:07:20 +08:00
if o == ' c ' then
2019-03-09 17:34:43 +08:00
newcrc = a
ncs = true
end
-- display segments switch
2019-05-08 06:07:20 +08:00
if o == ' d ' then ds = true ; end
2019-03-09 17:34:43 +08:00
-- display summary switch
2019-05-08 06:07:20 +08:00
if o == ' s ' then ss = true ; end
2019-03-09 17:34:43 +08:00
-- write to tag switch
2019-05-08 06:07:20 +08:00
if o == ' w ' then ws = true ; end
2019-03-09 17:34:43 +08:00
-- help
2019-05-08 06:07:20 +08:00
if o == ' h ' then return help ( ) end
2019-03-09 17:34:43 +08:00
end
2019-05-08 06:07:20 +08:00
if ( not ifs ) then return oops ( ' option -i <input file> is required but missing ' ) end
2019-03-09 17:34:43 +08:00
-- bytes to plain
bytes = xorBytes ( bytes , oldcrc )
-- show segments (works only on plain bytes)
if ( ds ) then
print ( " +------------------------------------------- Segments -------------------------------------------+ " )
displaySegments ( bytes ) ;
end
if ( ofs and ncs ) then
-- xor bytes with new crc
newBytes = xorBytes ( bytes , newcrc )
-- write output
if ( writeOutputBytes ( newBytes , outfile ) ) then
-- show summary if requested
if ( ss ) then
-- information
res = " \n +-------------------------------------------- Summary -------------------------------------------+ "
res = res .. " \n created clone_dump from \n \t " .. infile .. " crc: " .. oldcrc .. " \n dump_file: "
res = res .. " \n \t " .. outfile .. " crc: " .. string.sub ( newcrc , - 2 )
res = res .. " \n you may load the new file with: hf legic load " .. outfile
res = res .. " \n \n if you don't write to tag immediately ('-w' switch) you will need to recalculate each segmentCRC "
res = res .. " \n after writing this dump to a tag! "
res = res .. " \n \n a segmentCRC gets calculated over MCD,MSN0..3,Segment-Header0..3 "
res = res .. " \n e.g. (based on Segment00 of the data from " .. infile .. " ): "
res = res .. " \n hf legic crc8 " .. bytes [ 1 ] .. bytes [ 2 ] .. bytes [ 3 ] .. bytes [ 4 ] .. bytes [ 23 ] .. bytes [ 24 ] .. bytes [ 25 ] .. bytes [ 26 ]
-- this can not be calculated without knowing the new MCD, MSN0..2
print ( res )
end
end
else
if ( ss ) then
-- show why the output-file was not written
print ( " \n new file not written - some arguments are missing .. " )
print ( " output file: " .. ( ofs and outfile or " not given " ) )
print ( " new crc: " .. ( ncs and newcrc or " not given " ) )
end
end
-- write to tag
if ( ws and # bytes == 1024 ) then
writeToTag ( bytes )
end
2016-02-28 21:50:49 +08:00
end
-- call main with arguments
2019-03-12 07:12:26 +08:00
main ( args )