summaryrefslogtreecommitdiff
path: root/utils/hwpatcher/generic_stmp.lua
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2014-06-24 18:04:17 +0200
committerAmaury Pouly <amaury.pouly@gmail.com>2014-06-24 18:07:56 +0200
commitc9a028cc183d638c16ca9a8858b783b1830be16f (patch)
tree1bd29843ec0b8d3eb80a6209d1c4e32144175dfe /utils/hwpatcher/generic_stmp.lua
parent761f59c9e3be0ffd77d2dc1b8095a3b877badeda (diff)
downloadrockbox-c9a028cc183d638c16ca9a8858b783b1830be16f.tar.gz
rockbox-c9a028cc183d638c16ca9a8858b783b1830be16f.zip
Introduce hwpatcher, a tool to patch binaries
This tool is a scriptable (lua) tool to patch binaries, it supports: - raw binary - ELF - SB(v1/v2) It also contains some basic routines to parse and generate useful arm/thumb code like jump or register load/store. This is very useful to take a firmware and patch an interrupt vector or some code to jump to an extra payload added to the binary. Examples are provided for several STMP based target which the payload is expected to be hwstub, and also for the Sansa View. A typical patcher usually requires three elements: - the lua patcher itself - the payload (hwstub for example) - (optional) a small stub either to jump properly to the payload or determine under which circumstance to do the jump (hold a key for example) Change-Id: I6d36020a3bc9e636615ac8221b7591ade5f251e3
Diffstat (limited to 'utils/hwpatcher/generic_stmp.lua')
-rw-r--r--utils/hwpatcher/generic_stmp.lua108
1 files changed, 108 insertions, 0 deletions
diff --git a/utils/hwpatcher/generic_stmp.lua b/utils/hwpatcher/generic_stmp.lua
new file mode 100644
index 0000000000..538e269e60
--- /dev/null
+++ b/utils/hwpatcher/generic_stmp.lua
@@ -0,0 +1,108 @@
1--[[
2Generic STMP hacking
3required argument (in order):
4- path to firmware
5- path to output firmware
6- path to blob
7- path to stub
8]]--
9require("lib")
10require("arm")
11
12if #arg < 4 then
13 error("usage: <fw file> <out file> <blob> <stub>")
14end
15
16-- compute MD5
17print("Computing MD5 sum of the firmware...")
18local md5 = hwp.md5sum(arg[1])
19print("=> " .. hwp.md5str(md5))
20
21local md5_db =
22{
23 ["d0047f8a87d456a0032297b3c802a1ff"] =
24 {
25 model = "Sony NWZ-E3600 1.0.0",
26 irq_addr_pool = 0x40A314E4,
27 irq_addr_pool_sec = "play.1",
28 -- proxy_addr = 0x4005C1E0,
29 -- proxy_addr_sec = "play.1"
30 proxy_addr = 0x4007C258,
31 proxy_addr_sec = "play.1",
32 -- stub_addr = 0x1971C8,
33 -- stub_addr_virt = 0x2971C8,
34 -- stub_addr_sec = "pvmi",
35 },
36 ["f42742d4d90d88e2fb6ff468c1389f5f"] =
37 {
38 model = "Creative ZEN X-Fi Style 1.03.04",
39 irq_addr_pool = 0x402D3A64,
40 irq_addr_pool_sec = "play.1",
41 proxy_addr = 0x402E076C,
42 proxy_addr_sec = "play.1"
43 },
44 ["c180f57e2b2d62620f87a1d853f349ff"] =
45 {
46 model = "Creative ZEN X-Fi3 1.00.25e",
47 irq_addr_pool = 0x405916f0,
48 proxy_addr = 0x40384674,
49 }
50}
51
52local db_entry = md5_db[hwp.md5str(md5)]
53if db_entry == nil then
54 error("Cannot find device in the DB")
55 os.exit(1)
56end
57print("Model: " .. db_entry.model)
58
59local fw = hwp.load_file(arg[1])
60local irq_addr_pool = hwp.make_addr(db_entry.irq_addr_pool, db_entry.irq_addr_pool_sec)
61local proxy_addr = arm.to_arm(hwp.make_addr(db_entry.proxy_addr, db_entry.proxy_addr_sec))
62-- read old IRQ address pool
63local old_irq_addr = hwp.make_addr(hwp.read32(fw, irq_addr_pool))
64print(string.format("Old IRQ address: %s", old_irq_addr))
65-- put stub at the beginning of the proxy
66local stub = hwp.load_bin_file(arg[4])
67local stub_info = hwp.section_info(stub, "")
68local stub_data = hwp.read(stub, hwp.make_addr(stub_info.addr, ""), stub_info.size)
69local stub_addr = nil
70local stub_addr_virt = nil
71if db_entry.stub_addr ~= nil then
72 stub_addr = arm.to_arm(hwp.make_addr(db_entry.stub_addr, db_entry.stub_addr_sec))
73 if db_entry.stub_addr_virt ~= nil then
74 stub_addr_virt = arm.to_arm(hwp.make_addr(db_entry.stub_addr_virt, db_entry.stub_addr_sec))
75 else
76 stub_addr_virt = stub_addr
77 end
78 hwp.write(fw, stub_addr, stub_data)
79else
80 stub_addr = proxy_addr
81 stub_addr_virt = stub_addr
82 hwp.write(fw, stub_addr, stub_data)
83 proxy_addr = hwp.inc_addr(proxy_addr, stub_info.size)
84end
85-- modify irq
86hwp.write32(fw, irq_addr_pool, proxy_addr.addr)
87print(string.format("New IRQ address: %s", proxy_addr))
88-- in proxy, save registers
89arm.write_save_regs(fw, proxy_addr)
90proxy_addr = hwp.inc_addr(proxy_addr, 4)
91-- load blob
92local blob = hwp.load_bin_file(arg[3])
93local blob_info = hwp.section_info(blob, "")
94-- patch blob with stub address
95hwp.write32(blob, hwp.make_addr(blob_info.addr + 4, ""), stub_addr_virt.addr)
96-- write it !
97local blob_data = hwp.read(blob, hwp.make_addr(blob_info.addr, ""), blob_info.size)
98hwp.write(fw, proxy_addr, blob_data)
99proxy_addr = hwp.inc_addr(proxy_addr, blob_info.size)
100-- restore registers
101arm.write_restore_regs(fw, proxy_addr)
102proxy_addr = hwp.inc_addr(proxy_addr, 4)
103-- branch to old code
104local branch_to_old = arm.make_branch(old_irq_addr, false)
105arm.write_branch(fw, proxy_addr, branch_to_old, hwp.inc_addr(proxy_addr, 4))
106-- save
107hwp.save_file(fw, arg[2])
108