]> cvs.zerfleddert.de Git - proxmark3-svn/commitdiff
REN: renamed tnp3.lua to tnp3dump.lua since that name is more explainatory
authoriceman1001 <iceman@iuse.se>
Fri, 14 Nov 2014 12:24:45 +0000 (13:24 +0100)
committericeman1001 <iceman@iuse.se>
Fri, 14 Nov 2014 12:24:45 +0000 (13:24 +0100)
ADD: added tnp3sim.lua  a script which loads a dump and sends it to the pm3 device memory.

client/cmdhfmf.c
client/scripts/test.lua [deleted file]
client/scripts/tnp3.lua [deleted file]
client/scripts/tnp3dump.lua [new file with mode: 0644]
client/scripts/tnp3sim.lua [new file with mode: 0644]

index 901ccd4921a3b7d0231c19751de6edbec5b52914..35bf2a001dfb09189a028157ade2226d22fa69d8 100644 (file)
@@ -1623,6 +1623,7 @@ int CmdHF14AMfEKeyPrn(const char *Cmd)
                if (mfEmlGetMem(data, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1)) {\r
                        PrintAndLog("error get block %d", FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1);\r
                        break;\r
                if (mfEmlGetMem(data, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1)) {\r
                        PrintAndLog("error get block %d", FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1);\r
                        break;\r
+                       break;\r
                }\r
                keyA = bytes_to_num(data, 6);\r
                keyB = bytes_to_num(data + 10, 6);\r
                }\r
                keyA = bytes_to_num(data, 6);\r
                keyB = bytes_to_num(data + 10, 6);\r
diff --git a/client/scripts/test.lua b/client/scripts/test.lua
deleted file mode 100644 (file)
index 76adc98..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-local foo = "This shows how to use some standard libraries"
-print(foo)
-local answer
-repeat
-       io.write("Continue with this operation (y/n)? ")
-       io.flush()
-       answer=io.read()
-until answer=="y" or answer=="n"
-local x = "Ok then, %s"
-print (x:format("whatever"))
\ No newline at end of file
diff --git a/client/scripts/tnp3.lua b/client/scripts/tnp3.lua
deleted file mode 100644 (file)
index 77de766..0000000
+++ /dev/null
@@ -1,273 +0,0 @@
-local cmds = require('commands')
-local getopt = require('getopt')
-local bin = require('bin')
-local lib14a = require('read14a')
-local utils = require('utils')
-local md5 = require('md5')
-local dumplib = require('html_dumplib')
-local toyNames = require('default_toys')
-
-example =[[
-       1. script run tnp3
-       2. script run tnp3 -n
-       3. script run tnp3 -k aabbccddeeff
-       4. script run tnp3 -k aabbccddeeff -n
-       5. script run tnp3 -o myfile 
-       6. script run tnp3 -n -o myfile 
-       7. script run tnp3 -k aabbccddeeff -n -o myfile 
-]]
-author = "Iceman"
-usage = "script run tnp3 -k <key> -n -o <filename>"
-desc =[[
-This script will try to dump the contents of a Mifare TNP3xxx card.
-It will need a valid KeyA in order to find the other keys and decode the card.
-Arguments:
-       -h             : this help
-       -k <key>       : Sector 0 Key A.
-       -n             : Use the nested cmd to find all keys
-       -o             : filename for the saved dumps
-]]
-
-local HASHCONSTANT = '20436F707972696768742028432920323031302041637469766973696F6E2E20416C6C205269676874732052657365727665642E20'
-
-local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
-local DEBUG = false -- the debug flag
-local numBlocks = 64
-local numSectors = 16
---- 
--- A debug printout-function
-function dbg(args)
-       if not DEBUG then
-               return
-       end
-       
-    if type(args) == "table" then
-               local i = 1
-               while result[i] do
-                       dbg(result[i])
-                       i = i+1
-               end
-       else
-               print("###", args)
-       end     
-end    
---- 
--- This is only meant to be used when errors occur
-function oops(err)
-       print("ERROR: ",err)
-end
---- 
--- Usage help
-function help()
-       print(desc)
-       print("Example usage")
-       print(example)
-end
---
--- Exit message
-function ExitMsg(msg)
-       print( string.rep('--',20) )
-       print( string.rep('--',20) )
-       print(msg)
-       print()
-end
-
-local function readdumpkeys(infile)
-        t = infile:read("*all")
-        len = string.len(t)
-        local len,hex = bin.unpack(("H%d"):format(len),t)
-        return hex
-end
-
-local function waitCmd()
-       local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
-       if response then
-               local count,cmd,arg0 = bin.unpack('LL',response)
-               if(arg0==1) then
-                       local count,arg1,arg2,data = bin.unpack('LLH511',response,count)
-                       return data:sub(1,32)
-               else
-                       return nil, "Couldn't read block.." 
-               end
-       end
-       return nil, "No response from device"
-end
-
-local function computeCrc16(s)
-       local hash = core.crc16(utils.ConvertHexToAscii(s))     
-       return hash
-end
-
-local function reverseCrcBytes(crc)
-       crc2 = crc:sub(3,4)..crc:sub(1,2)
-       return tonumber(crc2,16)
-end
-
-local function main(args)
-
-       print( string.rep('--',20) )
-       print( string.rep('--',20) )
-       
-       local keyA
-       local cmd
-       local err
-       local useNested = false
-       local cmdReadBlockString = 'hf mf rdbl %d A %s'
-       local input = "dumpkeys.bin"
-       local outputTemplate = os.date("toydump_%Y-%m-%d_%H%M%S");
-
-       -- Arguments for the script
-       for o, a in getopt.getopt(args, 'hk:no:') do
-               if o == "h" then return help() end              
-               if o == "k" then keyA = a end
-               if o == "n" then useNested = true end
-               if o == "o" then outputTemplate = a end         
-       end
-
-       -- validate input args.
-       keyA =  keyA or '4b0b20107ccb'
-       if #(keyA) ~= 12 then
-               return oops( string.format('Wrong length of write key (was %d) expected 12', #keyA))
-       end
-
-       -- Turn off Debug
-       local cmdSetDbgOff = "hf mf dbg 0"
-       core.console( cmdSetDbgOff) 
-       
-       result, err = lib14a.read1443a(false)
-       if not result then
-               return oops(err)
-       end
-
-       core.clearCommandBuffer()
-       
-       if 0x01 ~= result.sak then -- NXP MIFARE TNP3xxx
-               return oops('This is not a TNP3xxx tag. aborting.')
-       end     
-
-       -- Show tag info
-       print((' Found tag : %s'):format(result.name))
-       print(('Using keyA : %s'):format(keyA))
-
-       --Trying to find the other keys
-       if useNested then
-         core.console( ('hf mf nested 1 0 A %s d'):format(keyA) )
-       end
-       
-       core.clearCommandBuffer()
-       
-       -- Loading keyfile
-       print('Loading dumpkeys.bin')
-       local hex, err = utils.ReadDumpFile(input)
-       if not hex then
-               return oops(err)
-       end
-
-       local akeys = hex:sub(0,12*16)
-
-       -- Read block 0
-       cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = 0,arg2 = 0,arg3 = 0, data = keyA}
-       err = core.SendCommand(cmd:getBytes())
-       if err then return oops(err) end
-       local block0, err = waitCmd()
-       if err then return oops(err) end
-       
-       -- Read block 1
-       cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = 1,arg2 = 0,arg3 = 0, data = keyA}
-       err = core.SendCommand(cmd:getBytes())
-       if err then return oops(err) end
-       local block1, err = waitCmd()
-       if err then return oops(err) end
-
-       local key
-       local pos = 0
-       local blockNo
-       local blocks = {}
-
-       print('Reading card data')
-       core.clearCommandBuffer()
-               
-       -- main loop
-       io.write('Decrypting blocks > ')
-       for blockNo = 0, numBlocks-1, 1 do
-
-               if core.ukbhit() then
-                       print("aborted by user")
-                       break
-               end
-       
-               pos = (math.floor( blockNo / 4 ) * 12)+1
-               key = akeys:sub(pos, pos + 11 )
-               cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = blockNo ,arg2 = 0,arg3 = 0, data = key}
-               local err = core.SendCommand(cmd:getBytes())
-               if err then return oops(err) end
-               local blockdata, err = waitCmd()
-               if err then return oops(err) end                
-
-               if  blockNo%4 ~= 3 then
-                       if blockNo < 8 then
-                               -- Block 0-7 not encrypted
-                               blocks[blockNo+1] = ('%02d  :: %s'):format(blockNo,blockdata) 
-                       else
-                               local base = ('%s%s%02x%s'):format(block0, block1, blockNo, HASHCONSTANT)       
-                               local baseStr = utils.ConvertHexToAscii(base)
-                               local md5hash = md5.sumhexa(baseStr)
-                               local aestest = core.aes(md5hash, blockdata)
-
-                               local hex = utils.ConvertAsciiToBytes(aestest)
-                               hex = utils.ConvertBytesToHex(hex)
-                               --local _,hex = bin.unpack(("H%d"):format(16),aestest)
-
-                               -- blocks with zero not encrypted.
-                               if string.find(blockdata, '^0+$') then
-                                       blocks[blockNo+1] = ('%02d  :: %s'):format(blockNo,blockdata) 
-                               else
-                                       blocks[blockNo+1] = ('%02d  :: %s'):format(blockNo,hex)
-                                       io.write( blockNo..',')
-                               end             
-                       end
-               else
-                       -- Sectorblocks, not encrypted
-                       blocks[blockNo+1] = ('%02d  :: %s%s'):format(blockNo,key,blockdata:sub(13,32)) 
-               end
-       end
-       io.write('\n')
-       
-       core.clearCommandBuffer()
-               
-       -- Print results
-       local bindata = {}
-       local emldata = ''
-
-       for _,s in pairs(blocks) do
-               local slice = s:sub(8,#s)
-               local str = utils.ConvertBytesToAscii(
-                                utils.ConvertHexToBytes(slice)
-                               )
-               emldata = emldata..slice..'\n'
-               for c in (str):gmatch('.') do
-                       bindata[#bindata+1] = c
-               end
-       end 
-       
-       -- Write dump to files
-       if not DEBUG then
-               local foo = dumplib.SaveAsBinary(bindata, outputTemplate..'.bin')
-               print(("Wrote a BIN dump to the file %s"):format(foo))
-               local bar = dumplib.SaveAsText(emldata, outputTemplate..'.eml')
-               print(("Wrote a EML dump to the file %s"):format(bar))
-       end
-
-       local uid = block0:sub(1,8)
-       local itemtype = block1:sub(1,4)
-       local cardid = block1:sub(9,24)
-
-       -- Show info 
-       print( string.rep('--',20) )
-       print( (' ITEM TYPE : 0x%s - %s'):format(itemtype, toyNames[itemtype]) )
-       print( ('       UID : 0x%s'):format(uid) )
-       print( ('    CARDID : 0x%s'):format(cardid ) )  
-       print( string.rep('--',20) )
-
-end
-main(args)
\ No newline at end of file
diff --git a/client/scripts/tnp3dump.lua b/client/scripts/tnp3dump.lua
new file mode 100644 (file)
index 0000000..520161b
--- /dev/null
@@ -0,0 +1,272 @@
+local cmds = require('commands')
+local getopt = require('getopt')
+local bin = require('bin')
+local lib14a = require('read14a')
+local utils = require('utils')
+local md5 = require('md5')
+local dumplib = require('html_dumplib')
+local toyNames = require('default_toys')
+
+example =[[
+       1. script run tnp3dump
+       2. script run tnp3dump -n
+       3. script run tnp3dump -k aabbccddeeff
+       4. script run tnp3dump -k aabbccddeeff -n
+       5. script run tnp3dump -o myfile 
+       6. script run tnp3dump -n -o myfile 
+       7. script run tnp3dump -k aabbccddeeff -n -o myfile 
+]]
+author = "Iceman"
+usage = "script run tnp3dump -k <key> -n -o <filename>"
+desc =[[
+This script will try to dump the contents of a Mifare TNP3xxx card.
+It will need a valid KeyA in order to find the other keys and decode the card.
+Arguments:
+       -h             : this help
+       -k <key>       : Sector 0 Key A.
+       -n             : Use the nested cmd to find all keys
+       -o             : filename for the saved dumps
+]]
+
+local HASHCONSTANT = '20436F707972696768742028432920323031302041637469766973696F6E2E20416C6C205269676874732052657365727665642E20'
+
+local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
+local DEBUG = false -- the debug flag
+local numBlocks = 64
+local numSectors = 16
+--- 
+-- A debug printout-function
+function dbg(args)
+       if not DEBUG then
+               return
+       end
+       
+    if type(args) == "table" then
+               local i = 1
+               while result[i] do
+                       dbg(result[i])
+                       i = i+1
+               end
+       else
+               print("###", args)
+       end     
+end    
+--- 
+-- This is only meant to be used when errors occur
+function oops(err)
+       print("ERROR: ",err)
+end
+--- 
+-- Usage help
+function help()
+       print(desc)
+       print("Example usage")
+       print(example)
+end
+--
+-- Exit message
+function ExitMsg(msg)
+       print( string.rep('--',20) )
+       print( string.rep('--',20) )
+       print(msg)
+       print()
+end
+
+local function readdumpkeys(infile)
+        t = infile:read("*all")
+        len = string.len(t)
+        local len,hex = bin.unpack(("H%d"):format(len),t)
+        return hex
+end
+
+local function waitCmd()
+       local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
+       if response then
+               local count,cmd,arg0 = bin.unpack('LL',response)
+               if(arg0==1) then
+                       local count,arg1,arg2,data = bin.unpack('LLH511',response,count)
+                       return data:sub(1,32)
+               else
+                       return nil, "Couldn't read block.." 
+               end
+       end
+       return nil, "No response from device"
+end
+
+local function computeCrc16(s)
+       local hash = core.crc16(utils.ConvertHexToAscii(s))     
+       return hash
+end
+
+local function reverseCrcBytes(crc)
+       crc2 = crc:sub(3,4)..crc:sub(1,2)
+       return tonumber(crc2,16)
+end
+
+local function main(args)
+
+       print( string.rep('--',20) )
+       print( string.rep('--',20) )
+       
+       local keyA
+       local cmd
+       local err
+       local useNested = false
+       local cmdReadBlockString = 'hf mf rdbl %d A %s'
+       local input = "dumpkeys.bin"
+       local outputTemplate = os.date("toydump_%Y-%m-%d_%H%M%S");
+
+       -- Arguments for the script
+       for o, a in getopt.getopt(args, 'hk:no:') do
+               if o == "h" then return help() end              
+               if o == "k" then keyA = a end
+               if o == "n" then useNested = true end
+               if o == "o" then outputTemplate = a end         
+       end
+
+       -- validate input args.
+       keyA =  keyA or '4b0b20107ccb'
+       if #(keyA) ~= 12 then
+               return oops( string.format('Wrong length of write key (was %d) expected 12', #keyA))
+       end
+
+       -- Turn off Debug
+       local cmdSetDbgOff = "hf mf dbg 0"
+       core.console( cmdSetDbgOff) 
+       
+       result, err = lib14a.read1443a(false)
+       if not result then
+               return oops(err)
+       end
+
+       core.clearCommandBuffer()
+       
+       if 0x01 ~= result.sak then -- NXP MIFARE TNP3xxx
+               return oops('This is not a TNP3xxx tag. aborting.')
+       end     
+
+       -- Show tag info
+       print((' Found tag : %s'):format(result.name))
+       print(('Using keyA : %s'):format(keyA))
+
+       --Trying to find the other keys
+       if useNested then
+         core.console( ('hf mf nested 1 0 A %s d'):format(keyA) )
+       end
+       
+       core.clearCommandBuffer()
+       
+       -- Loading keyfile
+       print('Loading dumpkeys.bin')
+       local hex, err = utils.ReadDumpFile(input)
+       if not hex then
+               return oops(err)
+       end
+
+       local akeys = hex:sub(0,12*16)
+
+       -- Read block 0
+       cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = 0,arg2 = 0,arg3 = 0, data = keyA}
+       err = core.SendCommand(cmd:getBytes())
+       if err then return oops(err) end
+       local block0, err = waitCmd()
+       if err then return oops(err) end
+       
+       -- Read block 1
+       cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = 1,arg2 = 0,arg3 = 0, data = keyA}
+       err = core.SendCommand(cmd:getBytes())
+       if err then return oops(err) end
+       local block1, err = waitCmd()
+       if err then return oops(err) end
+
+       local key
+       local pos = 0
+       local blockNo
+       local blocks = {}
+
+       print('Reading card data')
+       core.clearCommandBuffer()
+               
+       -- main loop
+       io.write('Decrypting blocks > ')
+       for blockNo = 0, numBlocks-1, 1 do
+
+               if core.ukbhit() then
+                       print("aborted by user")
+                       break
+               end
+       
+               pos = (math.floor( blockNo / 4 ) * 12)+1
+               key = akeys:sub(pos, pos + 11 )
+               cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = blockNo ,arg2 = 0,arg3 = 0, data = key}
+               local err = core.SendCommand(cmd:getBytes())
+               if err then return oops(err) end
+               local blockdata, err = waitCmd()
+               if err then return oops(err) end                
+
+               if  blockNo%4 ~= 3 then
+                       if blockNo < 8 then
+                               -- Block 0-7 not encrypted
+                               blocks[blockNo+1] = ('%02d  :: %s'):format(blockNo,blockdata) 
+                       else
+                               local base = ('%s%s%02x%s'):format(block0, block1, blockNo, HASHCONSTANT)       
+                               local baseStr = utils.ConvertHexToAscii(base)
+                               local md5hash = md5.sumhexa(baseStr)
+                               local aestest = core.aes(md5hash, blockdata)
+
+                               local hex = utils.ConvertAsciiToBytes(aestest)
+                               hex = utils.ConvertBytesToHex(hex)
+
+                               -- blocks with zero not encrypted.
+                               if string.find(blockdata, '^0+$') then
+                                       blocks[blockNo+1] = ('%02d  :: %s'):format(blockNo,blockdata) 
+                               else
+                                       blocks[blockNo+1] = ('%02d  :: %s'):format(blockNo,hex)
+                                       io.write( blockNo..',')
+                               end             
+                       end
+               else
+                       -- Sectorblocks, not encrypted
+                       blocks[blockNo+1] = ('%02d  :: %s%s'):format(blockNo,key,blockdata:sub(13,32)) 
+               end
+       end
+       io.write('\n')
+       
+       core.clearCommandBuffer()
+               
+       -- Print results
+       local bindata = {}
+       local emldata = ''
+
+       for _,s in pairs(blocks) do
+               local slice = s:sub(8,#s)
+               local str = utils.ConvertBytesToAscii(
+                                utils.ConvertHexToBytes(slice)
+                               )
+               emldata = emldata..slice..'\n'
+               for c in (str):gmatch('.') do
+                       bindata[#bindata+1] = c
+               end
+       end 
+       
+       -- Write dump to files
+       if not DEBUG then
+               local foo = dumplib.SaveAsBinary(bindata, outputTemplate..'.bin')
+               print(("Wrote a BIN dump to the file %s"):format(foo))
+               local bar = dumplib.SaveAsText(emldata, outputTemplate..'.eml')
+               print(("Wrote a EML dump to the file %s"):format(bar))
+       end
+
+       local uid = block0:sub(1,8)
+       local itemtype = block1:sub(1,4)
+       local cardid = block1:sub(9,24)
+
+       -- Show info 
+       print( string.rep('--',20) )
+       print( (' ITEM TYPE : 0x%s - %s'):format(itemtype, toyNames[itemtype]) )
+       print( ('       UID : 0x%s'):format(uid) )
+       print( ('    CARDID : 0x%s'):format(cardid ) )  
+       print( string.rep('--',20) )
+
+end
+main(args)
\ No newline at end of file
diff --git a/client/scripts/tnp3sim.lua b/client/scripts/tnp3sim.lua
new file mode 100644 (file)
index 0000000..ce77202
--- /dev/null
@@ -0,0 +1,383 @@
+local cmds = require('commands')
+local getopt = require('getopt')
+local bin = require('bin')
+local lib14a = require('read14a')
+local utils = require('utils')
+local md5 = require('md5')
+local toyNames = require('default_toys')
+
+example =[[
+       1. script run tnp3sim
+       2. script run tnp3sim -m
+       3. script run tnp3sim -m -i myfile
+]]
+author = "Iceman"
+usage = "script run tnp3sim -h -m -i <filename>"
+desc =[[
+This script will try to dump the contents of a Mifare TNP3xxx card.
+It will need a valid KeyA in order to find the other keys and decode the card.
+Arguments:
+       -h             : this help
+       -m             : Maxed out item
+       -i             : filename for the datadump to read (bin)
+]]
+
+local HASHCONSTANT = '20436F707972696768742028432920323031302041637469766973696F6E2E20416C6C205269676874732052657365727665642E20'
+
+local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
+local DEBUG = true -- the debug flag
+--- 
+-- A debug printout-function
+function dbg(args)
+       if not DEBUG then
+               return
+       end
+       
+    if type(args) == "table" then
+               local i = 1
+               while result[i] do
+                       dbg(result[i])
+                       i = i+1
+               end
+       else
+               print("###", args)
+       end     
+end    
+--- 
+-- This is only meant to be used when errors occur
+function oops(err)
+       print("ERROR: ",err)
+end
+--- 
+-- Usage help
+function help()
+       print(desc)
+       print("Example usage")
+       print(example)
+end
+--
+-- Exit message
+function ExitMsg(msg)
+       print( string.rep('--',20) )
+       print( string.rep('--',20) )
+       print(msg)
+       print()
+end
+
+local function writedumpfile(infile)
+        t = infile:read("*all")
+        len = string.len(t)
+        local len,hex = bin.unpack(("H%d"):format(len),t)
+        return hex
+end
+-- blocks with data
+-- there are two dataareas, in block 8 or block 36,   ( 1==8 ,
+-- checksum type =  0, 1, 2, 3
+local function GetCheckSum(blocks, dataarea, chksumtype)
+
+       local crc
+       local area = 36
+       if  dataarea == 1 then
+               area = 8
+       end
+       
+       if chksumtype == 0 then
+               crc = blocks[1]:sub(29,32)
+       elseif chksumtype == 1 then
+               crc = blocks[area]:sub(29,32)
+       elseif chksumtype == 2 then     
+               crc = blocks[area]:sub(25,28)
+       elseif chksumtype == 3 then
+               crc = blocks[area]:sub(21,24)           
+       end
+       return utils.SwapEndianness(crc,16)
+end
+
+local function SetCheckSum(blocks, chksumtype)
+
+       if blocks == nil then return nil, 'Argument \"blocks\" nil' end
+       local newcrc
+       local area1 = 8
+       local area2 = 36
+       
+       if chksumtype == 0 then
+               newcrc = ('%04X'):format(CalcCheckSum(blocks,1,0))      
+               blocks[1] = blocks[1]:sub(1,28)..newcrc:sub(3,4)..newcrc:sub(1,2)
+       elseif chksumtype == 1 then
+               newcrc = ('%04X'):format(CalcCheckSum(blocks,1,1))      
+               blocks[area1] = blocks[area1]:sub(1,28)..newcrc:sub(3,4)..newcrc:sub(1,2)
+               newcrc = ('%04X'):format(CalcCheckSum(blocks,2,1))      
+               blocks[area2] = blocks[area2]:sub(1,28)..newcrc:sub(3,4)..newcrc:sub(1,2)
+       elseif chksumtype == 2 then     
+               newcrc = ('%04X'):format(CalcCheckSum(blocks,1,2))      
+               blocks[area1] = blocks[area1]:sub(1,24)..newcrc:sub(3,4)..newcrc:sub(1,2)..blocks[area1]:sub(29,32)
+               newcrc = ('%04X'):format(CalcCheckSum(blocks,2,2))      
+               blocks[area2] = blocks[area2]:sub(1,24)..newcrc:sub(3,4)..newcrc:sub(1,2)..blocks[area2]:sub(29,32)
+       elseif chksumtype == 3 then
+               newcrc = ('%04X'):format(CalcCheckSum(blocks,1,3))      
+               blocks[area1] = blocks[area1]:sub(1,20)..newcrc:sub(3,4)..newcrc:sub(1,2)..blocks[area1]:sub(25,32)
+               newcrc = ('%04X'):format(CalcCheckSum(blocks,2,3))      
+               blocks[area2] = blocks[area2]:sub(1,20)..newcrc:sub(3,4)..newcrc:sub(1,2)..blocks[area2]:sub(25,32)
+       end
+end
+
+function CalcCheckSum(blocks, dataarea, chksumtype)
+       local area = 36
+       if dataarea == 1 then
+               area = 8
+       end
+       
+       if chksumtype == 0 then
+               data = blocks[0]..blocks[1]:sub(1,28)
+       elseif chksumtype == 1 then
+               data = blocks[area]:sub(1,28)..'0500'
+       elseif chksumtype == 2 then     
+               data =  blocks[area+1]..blocks[area+2]..blocks[area+4]
+       elseif chksumtype == 3 then
+               data =  blocks[area+5]..blocks[area+6]..blocks[area+8]..string.rep('00',0xe0)   
+       end
+       return utils.Crc16(data)
+end
+
+local function ValidateCheckSums(blocks)
+
+       local isOk, crc, calc
+       -- Checksum Type 0
+       crc = GetCheckSum(blocks,1,0)
+       calc = CalcCheckSum(blocks, 1, 0)
+       if crc == calc then isOk='Ok' else isOk = 'Error' end
+       io.write( ('TYPE 0       : %04x = %04x -- %s\n'):format(crc,calc,isOk))
+
+       -- Checksum Type 1 (DATAAREAHEADER 1)
+       crc = GetCheckSum(blocks,1,1)
+       calc = CalcCheckSum(blocks,1,1)
+       if crc == calc then isOk='Ok' else isOk = 'Error' end
+       io.write( ('TYPE 1 area 1: %04x = %04x -- %s\n'):format(crc,calc,isOk))
+       
+       -- Checksum Type 1 (DATAAREAHEADER 2)
+       crc = GetCheckSum(blocks,2,1)
+       calc = CalcCheckSum(blocks,2,1)
+       if crc == calc then isOk='Ok' else isOk = 'Error' end
+       io.write( ('TYPE 1 area 2: %04x = %04x -- %s\n'):format(crc,calc,isOk))
+       
+       -- Checksum Type 2 (DATAAREA 1)
+       crc = GetCheckSum(blocks,1,2)
+       calc = CalcCheckSum(blocks,1,2)
+       if crc == calc then isOk='Ok' else isOk = 'Error' end   
+       io.write( ('TYPE 2 area 1: %04x = %04x -- %s\n'):format(crc,calc,isOk))
+
+       -- Checksum Type 2 (DATAAREA 2)
+       crc = GetCheckSum(blocks,2,2)
+       calc = CalcCheckSum(blocks,2,2)
+       if crc == calc then isOk='Ok' else isOk = 'Error' end   
+       io.write( ('TYPE 2 area 2: %04x = %04x -- %s\n'):format(crc,calc,isOk))
+
+       -- Checksum Type 3 (DATAAREA 1)
+       crc = GetCheckSum(blocks,1,3)
+       calc = CalcCheckSum(blocks,1,3)
+       if crc == calc then isOk='Ok' else isOk = 'Error' end   
+       io.write( ('TYPE 3 area 1: %04x = %04x -- %s\n'):format(crc,calc,isOk))
+
+       -- Checksum Type 3 (DATAAREA 2)
+       crc = GetCheckSum(blocks,2,3)
+       calc = CalcCheckSum(blocks,2,3)
+       if crc == calc then isOk='Ok' else isOk = 'Error' end   
+       io.write( ('TYPE 3 area 2: %04x = %04x -- %s\n'):format(crc,calc,isOk))
+end
+
+-- function EncryptData()
+       -- local HASHCONSTANT = '20436F707972696768742028432920323031302041637469766973696F6E2E20416C6C205269676874732052657365727665642E20'
+               -- if  blockNo%4 ~= 3 then
+                       -- if blockNo < 8 then
+                               -- -- Block 0-7 not encrypted
+                               -- blocks[blockNo+1] = ('%02d  :: %s'):format(blockNo,blockdata) 
+                       -- else
+                               -- local base = ('%s%s%02x%s'):format(block0, block1, blockNo, HASHCONSTANT)    
+                               -- local baseStr = utils.ConvertHexToAscii(base)
+                               -- local md5hash = md5.sumhexa(baseStr)
+                               -- local aestest = core.aes(md5hash, blockdata)
+
+                               -- local hex = utils.ConvertAsciiToBytes(aestest)
+                               -- hex = utils.ConvertBytesToHex(hex)
+                               -- --local _,hex = bin.unpack(("H%d"):format(16),aestest)
+
+                               -- -- blocks with zero not encrypted.
+                               -- if string.find(blockdata, '^0+$') then
+                                       -- blocks[blockNo+1] = ('%02d  :: %s'):format(blockNo,blockdata) 
+                               -- else
+                                       -- blocks[blockNo+1] = ('%02d  :: %s'):format(blockNo,hex)
+                                       -- io.write( blockNo..',')
+                               -- end          
+                       -- end
+               -- else
+                       -- -- Sectorblocks, not encrypted
+                       -- blocks[blockNo+1] = ('%02d  :: %s%s'):format(blockNo,key,blockdata:sub(13,32)) 
+               -- end
+
+-- end
+
+local function LoadEmulator(blocks)
+       local HASHCONSTANT = '20436F707972696768742028432920323031302041637469766973696F6E2E20416C6C205269676874732052657365727665642E20'
+       local cmd
+       local blockdata
+       for _,b in pairs(blocks) do 
+               
+               blockdata = b
+               
+               if  _%4 ~= 3 then
+                       if (_ >= 8 and _<=21)  or  (_ >= 36 and _<=49) then
+                               local base = ('%s%s%02x%s'):format(blocks[0], blocks[1], _ , HASHCONSTANT)      
+                               local baseStr = utils.ConvertHexToAscii(base)
+                               local key = md5.sumhexa(baseStr)
+                               local enc = core.aes(key, blockdata)
+                               local hex = utils.ConvertAsciiToBytes(enc)
+                               hex = utils.ConvertBytesToHex(hex)
+                       
+                               blockdata = hex
+                               io.write( _..',')
+                       end
+               end
+
+               cmd = Command:new{cmd = cmds.CMD_MIFARE_EML_MEMSET, arg1 = _ ,arg2 = 1,arg3 = 0, data = blockdata}
+               local err = core.SendCommand(cmd:getBytes())
+               if err then 
+                       return err
+               end
+       end
+       io.write('\n')
+end
+
+local function main(args)
+
+       print( string.rep('--',20) )
+       print( string.rep('--',20) )
+       
+       local result, err, hex
+       local maxed = false
+       local inputTemplate = "dumpdata.bin"
+       local outputTemplate = os.date("toydump_%Y-%m-%d_%H%M");
+       
+               -- Arguments for the script
+       for o, a in getopt.getopt(args, 'hmi:o:') do
+               if o == "h" then return help() end              
+               if o == "m" then maxed = true end
+               if o == "o" then outputTemplate = a end         
+               if o == "i" then inputTemplate = a end
+       end
+       
+       -- Turn off Debug
+       local cmdSetDbgOff = "hf mf dbg 0"
+       core.console( cmdSetDbgOff) 
+       
+       -- Look for tag present on reader,
+       result, err = lib14a.read1443a(false)
+       if not result then return oops(err)     end
+
+       core.clearCommandBuffer()
+       
+       if 0x01 ~= result.sak then -- NXP MIFARE TNP3xxx
+               return oops('This is not a TNP3xxx tag. aborting.')
+       end     
+
+       -- Show tag info
+       print((' Found tag : %s'):format(result.name))
+       
+       -- Load dump.bin file
+       print( (' Load data from %s'):format(inputTemplate))
+       hex, err = utils.ReadDumpFile(inputTemplate)
+       if not hex then return oops(err) end
+       
+       local blocks = {}
+       local blockindex = 0
+       for i = 1, #hex, 32 do
+               blocks[blockindex] = hex:sub(i,i+31)
+               blockindex = blockindex + 1
+       end
+
+       if DEBUG then
+               print('Validating checksums in the loaded datadump')
+               ValidateCheckSums(blocks)
+       end
+       
+       --
+       print( string.rep('--',20) )    
+       print(' Gathering info')
+       local uid = blocks[0]:sub(1,8)
+       local itemtype = blocks[1]:sub(1,4)
+       local cardid = blocks[1]:sub(9,24)
+
+       -- Show info 
+       print( string.rep('--',20) )
+       print( (' ITEM TYPE : 0x%s - %s'):format(itemtype, toyNames[itemtype]) )
+       print( ('       UID : 0x%s'):format(uid) )
+       print( ('    CARDID : 0x%s'):format(cardid ) )  
+       print( string.rep('--',20) )
+
+       -- lets do something.
+       -- 
+       local experience = blocks[8]:sub(1,6)
+       print(('Experience  : %d'):format(utils.SwapEndianness(experience,24)))
+       local money = blocks[8]:sub(7,10)
+       print(('Money       : %d'):format(utils.SwapEndianness(money,16)))
+       local fairy = blocks[9]:sub(1,8)
+       --FD0F = Left, FF0F = Right
+       local path = 'not choosen'
+       if fairy:sub(2,2) == 'D' then
+               path = 'Left'
+       elseif fairy:sub(2,2) == 'F' then
+               path = 'Right'
+       end
+       print(('Fairy       : %d [Path: %s] '):format(utils.SwapEndianness(fairy,24),path))
+       
+       local hat = blocks[9]:sub(8,11)
+       print(('Hat         : %d'):format(utils.SwapEndianness(hat,16)))
+       
+       --0x0D    0x29    0x0A    0x02    16-bit hero points value. Maximum 100.
+       local heropoints = blocks[13]:sub(20,23)
+       print(('Hero points : %d'):format(utils.SwapEndianness(heropoints,16)))
+
+       --0x10    0x2C    0x0C    0x04    32 bit flag value indicating heroic challenges completed.
+       local challenges = blocks[16]:sub(25,32)
+       print(('Finished hero challenges : %d'):format(utils.SwapEndianness(challenges,32)))
+       
+       if maxed then
+               print('Lets try to max out some values')
+               -- max out money, experience
+               --print (blocks[8])
+               blocks[8] = 'FFFFFF'..'FFFF'..blocks[8]:sub(11,32)
+               blocks[36] = 'FFFFFF'..'FFFF'..blocks[36]:sub(11,32)
+               --print (blocks[8])
+       
+               -- max out hero challenges
+               --print (blocks[16])
+               blocks[16] = blocks[16]:sub(1,24)..'FFFFFFFF'
+               blocks[44] = blocks[44]:sub(1,24)..'FFFFFFFF'
+               --print (blocks[16])
+               
+               -- max out heropoints
+               --print (blocks[13])
+               blocks[13] = blocks[13]:sub(1,19)..'0064'..blocks[13]:sub(24,32)
+               blocks[41] = blocks[41]:sub(1,19)..'0064'..blocks[41]:sub(24,32)
+               --print (blocks[13])
+       
+               -- Update Checksums
+               print('Updating all checksums')
+               SetCheckSum(blocks, 3)
+               SetCheckSum(blocks, 2)
+               SetCheckSum(blocks, 1)
+               SetCheckSum(blocks, 0)
+       
+               print('Validating all checksums')       
+               ValidateCheckSums(blocks)
+       end
+       
+       --Load dumpdata to emulator memory
+       if DEBUG then
+               print('Sending dumpdata to emulator memory')
+               err = LoadEmulator(blocks)
+               if err then return oops(err) end        
+               core.clearCommandBuffer()
+               print('The simulation is now prepared. run \"hf mf sim\" ')
+       end
+end
+main(args)
\ No newline at end of file
Impressum, Datenschutz