summaryrefslogtreecommitdiff
path: root/utils/hwpatcher/rkwpatch.lua
diff options
context:
space:
mode:
authorMarcin Bukat <marcin.bukat@gmail.com>2014-09-02 22:31:21 +0200
committerMarcin Bukat <marcin.bukat@gmail.com>2014-09-02 22:35:26 +0200
commit21373e9043c1ecb1d961ff8a55da09395d439dc7 (patch)
tree5ec02c6a6bb1e3cb05e28a024196e5a68ba8505a /utils/hwpatcher/rkwpatch.lua
parent0a66545487cf2457c6f483c288d02fc23ec705bb (diff)
downloadrockbox-21373e9043c1ecb1d961ff8a55da09395d439dc7.tar.gz
rockbox-21373e9043c1ecb1d961ff8a55da09395d439dc7.zip
hwpatcher: add generic RKW file patching script
This script is handy hacking tool to patch RKW file with arbitrary binary and put jump into implanted code. It also shows how to use hwstub crc routine. Change-Id: I89b5086dc1ddaca3dbc03df26a85472d8a20d51e
Diffstat (limited to 'utils/hwpatcher/rkwpatch.lua')
-rw-r--r--utils/hwpatcher/rkwpatch.lua126
1 files changed, 126 insertions, 0 deletions
diff --git a/utils/hwpatcher/rkwpatch.lua b/utils/hwpatcher/rkwpatch.lua
new file mode 100644
index 0000000000..85237b69a4
--- /dev/null
+++ b/utils/hwpatcher/rkwpatch.lua
@@ -0,0 +1,126 @@
1--[[
2RKW patching tool
3required argument (in order):
4- path to rkw
5- path to stub
6- physical address where to put bin blob
7- physical address where to put jump
8- path to output patched firmware
9]]--
10require("lib")
11require("arm")
12
13function printf(...)
14 io.write(string.format(...))
15end
16
17if #arg < 5 then
18 printf("Arguments: source.rkw blob.bin blob_address jump_address output.rkw\n")
19 printf("source.rkw\tRKW file to be patched\n")
20 printf("blob.bin\tArbitrary binary to be implanted (e.g hwstub.bin)\n")
21 printf("blob_address\tPhysical address where to implant blob (e.g 0x6008300c)\n")
22 printf("jump_address\tPhysical address where to put jump to implanted binary (e.g 0x60097f2c)\n")
23 printf("output.rkw\tResulting RKW file\n")
24 os.exit(1)
25end
26
27-- return rkw file offset based on physical runtime mem addr
28-- sdram base address is 0x60000000 and rkw header is 0x2c long
29function addr2rkw(addr)
30 return (addr + 0x2c - 0x60000000)
31end
32
33-- read input file
34local fw = hwp.load_file(arg[1])
35
36-- read and check RKW magic number
37local rkw_magic = hwp.read32(fw, hwp.make_addr(0))
38
39if rkw_magic ~= 0x4c44524b then
40 printf("error: wrong RKW magic number\n")
41 os.exit(1)
42end
43
44-- check RKW header size
45local rkw_header_size = hwp.read32(fw, hwp.make_addr(0x04))
46
47if rkw_header_size ~= 0x2c then
48 printf("error: RKW header size 0x%0x should be 0x2c!\n", rkw_header_size)
49 os.exit(1)
50end
51
52-- check RKW header CRC
53local header_crc = hwp.crc(RKW, fw, hwp.make_addr(0), 0x28)
54
55if hwp.read32(fw, hwp.make_addr(0x28)) ~= header_crc then
56 printf("error: RKW header CRC mismatch\n")
57 os.exit(1)
58end
59
60local firmware_blob = hwp.make_addr(rkw_header_size)
61local blob_size = hwp.read32(fw, hwp.make_addr(0x10)) - hwp.read32(fw, hwp.make_addr(0x8))
62local rkw_crc = 0
63
64-- check if blob has CRC attached
65if blob_size < hwp.section_info(fw, "").size then
66 rkw_crc = hwp.crc(RKW, fw, firmware_blob, blob_size)
67
68 if hwp.read32(fw, hwp.make_addr(blob_size+rkw_header_size)) ~= rkw_crc then
69 printf("error: RKW CRC mismatch\n")
70 os.exit(1)
71 end
72else
73 printf("error: blob reported size: 0x%0x >= actual blob size: 0x%0x\n", blob_size, hwp.section_info(fw, "").size)
74 os.exit(1)
75end
76
77printf("RKW sanity checks passed\n")
78printf("RKW magic:\t0x%0x\n", rkw_magic)
79printf("Header size:\t0x%0x\n", rkw_header_size)
80printf("Image Base:\t0x%0x\n", hwp.read32(fw, hwp.make_addr(0x8)))
81printf("Load Base:\t0x%0x\n", hwp.read32(fw, hwp.make_addr(0xc)))
82printf("Load Limit:\t0x%0x\n", hwp.read32(fw, hwp.make_addr(0x10)))
83printf("ZI Base:\t0x%0x\n", hwp.read32(fw, hwp.make_addr(0x14)))
84printf("Entry point:\t0x%0x\n", hwp.read32(fw, hwp.make_addr(0x20)))
85printf("Load flags:\t0x%0x\n", hwp.read32(fw, hwp.make_addr(0x24)))
86printf("Header crc:\t0x%0x\n", header_crc)
87printf("Blob crc:\t0x%0x\n", rkw_crc)
88
89-- branch instruction
90local jump_instr_addr = hwp.make_addr(addr2rkw(arg[4]))
91if (jump_instr_addr == nil) then
92 printf("error: invalid jump instruction address\n")
93 os.exit(1)
94end
95
96local stub_addr = hwp.make_addr(addr2rkw(arg[3])) -- some decoder stuff
97if (stub_addr == nil) then
98 printf("error: invalid blob implant address\n")
99 os.exit(1)
100end
101
102-- put stub at the right place
103local stub = hwp.load_bin_file(arg[2])
104if (stub == nil) then
105 printf("error: can't load blob file: %s\n", arg[2])
106 os.exit(1)
107end
108
109local stub_info = hwp.section_info(stub, "")
110local stub_data = hwp.read(stub, hwp.make_addr(stub_info.addr, ""), stub_info.size)
111hwp.write(fw, stub_addr, stub_data)
112printf("Implanting blob at: 0x%0x\n", arg[3])
113
114-- patch jump
115local branch_to_stub = arm.make_branch(arm.to_arm(stub_addr), false)
116arm.write_branch(fw, jump_instr_addr, branch_to_stub, hwp.inc_addr(stub_addr, stub_info.size))
117printf("Patching jump instruction at: 0x%0x\n", arg[4])
118
119-- patch rkw crc
120rkw_crc = hwp.crc(RKW, fw, firmware_blob, blob_size)
121printf("Patching RKW with new CRC: 0x%0x\n", rkw_crc)
122hwp.write32(fw, hwp.make_addr(blob_size+rkw_header_size), rkw_crc)
123
124-- save
125hwp.save_file(fw, arg[5])
126printf("Saving output to: '%s'\n", arg[5])