1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
--[[
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(obj, filename) Save a firmware to a file
- read(obj, addr, len) Read data from a firmware
- write(obj, addr, data) Write data to a firmware
- section_info(obj, sec) Return information about a section in a table (or nil)
- md5sum(filename) Compute the MD5 sum of a file
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
]]--
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
|