--[[ 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: - 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 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: - make_addr(addr, section) Build a firmware address from a raw address and a section ]]-- 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 -- 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