2014-06-24 16:04:17 +00:00
|
|
|
--[[
|
|
|
|
hwpatcher library
|
|
|
|
|
|
|
|
The C code provides the following functions.
|
|
|
|
|
|
|
|
At global level:
|
|
|
|
- quit() Quit the interactive mode
|
|
|
|
- exit() Same as quit()
|
|
|
|
|
|
|
|
In the hwp table:
|
2014-08-13 10:46:45 +00:00
|
|
|
- load_file(filename) Load a firmware and guess type
|
|
|
|
- load_elf_file(filename) Load a firmware as ELF
|
|
|
|
- load_sb_file(filename) Load a firmware as SB
|
|
|
|
- load_sb1_file(filename) Load a firmware as SB1
|
|
|
|
- load_bin_file(filename) Load a firmware as binary
|
|
|
|
- save_file(fw, filename) Save a firmware to a file
|
|
|
|
- read(fw, addr, len) Read data from a firmware
|
|
|
|
- write(fw, addr, data) Write data to a firmware
|
|
|
|
- section_info(fw, sec) Return information about a section in a table (or nil)
|
|
|
|
- md5sum(filename) Compute the MD5 sum of a file
|
|
|
|
- crc_buf(crc_type, buf) Compute the CRC of a byte buffer and return a byte buffer
|
|
|
|
- crc(crc_type, fw, addr, len) Compute the CRC of a firmware part
|
|
|
|
|
|
|
|
The list of CRCs available is available the hwp.CRC table:
|
|
|
|
- RKW
|
2014-06-24 16:04:17 +00:00
|
|
|
|
|
|
|
Data read/written from/to a firmware must must be an array of bytes.
|
|
|
|
The address must be a table of the following fields:
|
|
|
|
- address: contain the address
|
|
|
|
- section: optional section name
|
|
|
|
Data section information is a table with the following fields:
|
|
|
|
- address: first address if the section
|
|
|
|
- size: size of the section
|
|
|
|
We provide the following functions to help dealing with addresses:
|
2014-08-13 10:46:45 +00:00
|
|
|
- make_addr(addr, section) Build a firmware address from a raw address and a section
|
2014-06-24 16:04:17 +00:00
|
|
|
|
|
|
|
]]--
|
|
|
|
|
|
|
|
function hwp.deepcopy(o, seen)
|
|
|
|
seen = seen or {}
|
|
|
|
if o == nil then return nil end
|
|
|
|
if seen[o] then return seen[o] end
|
|
|
|
|
|
|
|
local no
|
|
|
|
if type(o) == 'table' then
|
|
|
|
no = {}
|
|
|
|
seen[o] = no
|
|
|
|
|
|
|
|
for k, v in next, o, nil do
|
|
|
|
no[hwp.deepcopy(k, seen)] = hwp.deepcopy(v, seen)
|
|
|
|
end
|
|
|
|
setmetatable(no, hwp.deepcopy(getmetatable(o), seen))
|
|
|
|
else -- number, string, boolean, etc
|
|
|
|
no = o
|
|
|
|
end
|
|
|
|
return no
|
|
|
|
end
|
|
|
|
|
|
|
|
function hwp.make_addr(addr, section)
|
|
|
|
local t = {addr = addr, section = section}
|
|
|
|
local addr_to_string = function(self)
|
|
|
|
if self.section == nil then
|
|
|
|
return string.format("%#x", self.addr)
|
|
|
|
else
|
|
|
|
return string.format("%#x@%s", self.addr, self.section)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
setmetatable(t, {__tostring = addr_to_string})
|
|
|
|
return t
|
|
|
|
end
|
|
|
|
|
|
|
|
function hwp.inc_addr(addr, amount)
|
|
|
|
return hwp.make_addr(addr.addr + amount, addr.section)
|
|
|
|
end
|
|
|
|
|
|
|
|
-- pack an array of bytes in a integer (little-endian)
|
|
|
|
function hwp.pack(arr)
|
|
|
|
local v = 0
|
|
|
|
for i = #arr, 1, -1 do
|
|
|
|
v = bit32.bor(bit32.lshift(v, 8),bit32.band(arr[i], 0xff))
|
|
|
|
end
|
|
|
|
return v
|
|
|
|
end
|
|
|
|
|
|
|
|
-- do the converse
|
|
|
|
function hwp.unpack(v, n)
|
|
|
|
local t = {}
|
|
|
|
for i = 1, n do
|
|
|
|
t[i] = bit32.band(v, 0xff)
|
|
|
|
v = bit32.rshift(v, 8)
|
|
|
|
end
|
|
|
|
return t
|
|
|
|
end
|
|
|
|
|
|
|
|
-- read a 32-bit value
|
|
|
|
function hwp.read32(obj, addr)
|
|
|
|
return hwp.pack(hwp.read(obj, addr, 4))
|
|
|
|
end
|
|
|
|
|
|
|
|
-- write a 32-bit value
|
|
|
|
function hwp.write32(obj, addr, v)
|
|
|
|
return hwp.write(obj, addr, hwp.unpack(v, 4))
|
|
|
|
end
|
|
|
|
|
|
|
|
-- convert a MD5 hash to a string
|
|
|
|
function hwp.md5str(md5)
|
|
|
|
local s = ""
|
|
|
|
for i = 1, #md5 do
|
|
|
|
s = s .. string.format("%02x", md5[i])
|
|
|
|
end
|
|
|
|
return s
|
|
|
|
end
|
2014-08-13 10:46:45 +00:00
|
|
|
|
|
|
|
-- compute the CRC of a firmware part
|
|
|
|
function hwp.crc(crc_type, fw, addr, len)
|
|
|
|
return hwp.crc_buf(crc_type, hwp.read(fw, addr, len))
|
|
|
|
end
|