mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2024-12-26 18:12:34 +08:00
84 lines
2.6 KiB
Lua
84 lines
2.6 KiB
Lua
local cmds = require('commands')
|
|
local utils = require('utils')
|
|
local reader = require('read14a')
|
|
|
|
local Emulator = {
|
|
_VERSION = 'emulator.lua 0.1.0',
|
|
_DESCRIPTION = 'emulator memory interface',
|
|
BLOCK_SZ = 512,
|
|
BLOCK_COUNT = 512 / 16
|
|
}
|
|
|
|
function Emulator:set_mem (data, clear_first)
|
|
if clear_first then
|
|
-- Clear out the emulator memory first
|
|
local emuMemclearCmd = Command:new{cmd = cmds.CMD_MIFARE_EML_MEMCLR, arg1 = 0, arg2 = 0, arg3 = 0}
|
|
|
|
local _, err = reader.sendToDevice(emuMemclearCmd)
|
|
if err then
|
|
print('Failed to clear emulator memory:', err)
|
|
return false
|
|
else
|
|
print('Cleared emulator memory')
|
|
end
|
|
end
|
|
|
|
-- Can fit 32 16 byte blocks per command (512 total bytes max)
|
|
for i = 0, (data:len() / self.BLOCK_SZ) do
|
|
local cur_out_block = data:sub((i*self.BLOCK_SZ) + 1, (i*self.BLOCK_SZ) + self.BLOCK_SZ)
|
|
print(string.format('Transmission #%u: %u bytes', i, cur_out_block:len()))
|
|
|
|
-- arg1: start block number
|
|
-- arg2: block count
|
|
local emuMemsetCmd = Command:new{cmd = cmds.CMD_MIFARE_EML_MEMSET,
|
|
data = utils.hexlify(cur_out_block),
|
|
arg1 = i * self.BLOCK_COUNT,
|
|
arg2 = self.BLOCK_COUNT}
|
|
|
|
-- Send command and wait for response
|
|
local _, err = reader.sendToDevice(emuMemsetCmd)
|
|
if err then
|
|
print('Failed setting memory', err)
|
|
return false
|
|
end
|
|
end
|
|
|
|
print('Emulator memory set')
|
|
return true
|
|
end
|
|
|
|
-- Read <size> bytes from emulator memory
|
|
function Emulator:get_mem (size)
|
|
local MAX_BLOCKS = 4
|
|
local result = ''
|
|
|
|
-- We can request a maximum of 4 blocks (16 bytes each) per command,
|
|
-- according to mifarecmd.c
|
|
for i = 0, (size / (MAX_BLOCKS * 16)) do
|
|
-- arg1: start block number
|
|
-- arg2: block count (max 4)
|
|
local emuMemGetCmd = Command:new{cmd = cmds.CMD_MIFARE_EML_MEMGET,
|
|
arg1 = i * MAX_BLOCKS,
|
|
arg2 = MAX_BLOCKS,
|
|
arg3 = 0}
|
|
|
|
local response, err = reader.sendToDevice(emuMemGetCmd)
|
|
if err then
|
|
print('Failed getting memory:', err)
|
|
return false
|
|
end
|
|
|
|
-- USB data begins after four 64-bit values
|
|
local data_begin = ((64/8) * 4) + 1
|
|
response = string.sub(response, data_begin)
|
|
|
|
-- Truncate to the received 16 byte blocks
|
|
response = string.sub(response, 1, 16 * MAX_BLOCKS)
|
|
|
|
result = result .. response
|
|
end
|
|
|
|
return string.sub(result, 1, size)
|
|
end
|
|
|
|
return Emulator
|