109 lines
3.4 KiB
Lua
109 lines
3.4 KiB
Lua
|
--[[
|
||
|
Generic STMP hacking
|
||
|
required argument (in order):
|
||
|
- path to firmware
|
||
|
- path to output firmware
|
||
|
- path to blob
|
||
|
- path to stub
|
||
|
]]--
|
||
|
require("lib")
|
||
|
require("arm")
|
||
|
|
||
|
if #arg < 4 then
|
||
|
error("usage: <fw file> <out file> <blob> <stub>")
|
||
|
end
|
||
|
|
||
|
-- compute MD5
|
||
|
print("Computing MD5 sum of the firmware...")
|
||
|
local md5 = hwp.md5sum(arg[1])
|
||
|
print("=> " .. hwp.md5str(md5))
|
||
|
|
||
|
local md5_db =
|
||
|
{
|
||
|
["d0047f8a87d456a0032297b3c802a1ff"] =
|
||
|
{
|
||
|
model = "Sony NWZ-E3600 1.0.0",
|
||
|
irq_addr_pool = 0x40A314E4,
|
||
|
irq_addr_pool_sec = "play.1",
|
||
|
-- proxy_addr = 0x4005C1E0,
|
||
|
-- proxy_addr_sec = "play.1"
|
||
|
proxy_addr = 0x4007C258,
|
||
|
proxy_addr_sec = "play.1",
|
||
|
-- stub_addr = 0x1971C8,
|
||
|
-- stub_addr_virt = 0x2971C8,
|
||
|
-- stub_addr_sec = "pvmi",
|
||
|
},
|
||
|
["f42742d4d90d88e2fb6ff468c1389f5f"] =
|
||
|
{
|
||
|
model = "Creative ZEN X-Fi Style 1.03.04",
|
||
|
irq_addr_pool = 0x402D3A64,
|
||
|
irq_addr_pool_sec = "play.1",
|
||
|
proxy_addr = 0x402E076C,
|
||
|
proxy_addr_sec = "play.1"
|
||
|
},
|
||
|
["c180f57e2b2d62620f87a1d853f349ff"] =
|
||
|
{
|
||
|
model = "Creative ZEN X-Fi3 1.00.25e",
|
||
|
irq_addr_pool = 0x405916f0,
|
||
|
proxy_addr = 0x40384674,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
local db_entry = md5_db[hwp.md5str(md5)]
|
||
|
if db_entry == nil then
|
||
|
error("Cannot find device in the DB")
|
||
|
os.exit(1)
|
||
|
end
|
||
|
print("Model: " .. db_entry.model)
|
||
|
|
||
|
local fw = hwp.load_file(arg[1])
|
||
|
local irq_addr_pool = hwp.make_addr(db_entry.irq_addr_pool, db_entry.irq_addr_pool_sec)
|
||
|
local proxy_addr = arm.to_arm(hwp.make_addr(db_entry.proxy_addr, db_entry.proxy_addr_sec))
|
||
|
-- read old IRQ address pool
|
||
|
local old_irq_addr = hwp.make_addr(hwp.read32(fw, irq_addr_pool))
|
||
|
print(string.format("Old IRQ address: %s", old_irq_addr))
|
||
|
-- put stub at the beginning of the proxy
|
||
|
local stub = hwp.load_bin_file(arg[4])
|
||
|
local stub_info = hwp.section_info(stub, "")
|
||
|
local stub_data = hwp.read(stub, hwp.make_addr(stub_info.addr, ""), stub_info.size)
|
||
|
local stub_addr = nil
|
||
|
local stub_addr_virt = nil
|
||
|
if db_entry.stub_addr ~= nil then
|
||
|
stub_addr = arm.to_arm(hwp.make_addr(db_entry.stub_addr, db_entry.stub_addr_sec))
|
||
|
if db_entry.stub_addr_virt ~= nil then
|
||
|
stub_addr_virt = arm.to_arm(hwp.make_addr(db_entry.stub_addr_virt, db_entry.stub_addr_sec))
|
||
|
else
|
||
|
stub_addr_virt = stub_addr
|
||
|
end
|
||
|
hwp.write(fw, stub_addr, stub_data)
|
||
|
else
|
||
|
stub_addr = proxy_addr
|
||
|
stub_addr_virt = stub_addr
|
||
|
hwp.write(fw, stub_addr, stub_data)
|
||
|
proxy_addr = hwp.inc_addr(proxy_addr, stub_info.size)
|
||
|
end
|
||
|
-- modify irq
|
||
|
hwp.write32(fw, irq_addr_pool, proxy_addr.addr)
|
||
|
print(string.format("New IRQ address: %s", proxy_addr))
|
||
|
-- in proxy, save registers
|
||
|
arm.write_save_regs(fw, proxy_addr)
|
||
|
proxy_addr = hwp.inc_addr(proxy_addr, 4)
|
||
|
-- load blob
|
||
|
local blob = hwp.load_bin_file(arg[3])
|
||
|
local blob_info = hwp.section_info(blob, "")
|
||
|
-- patch blob with stub address
|
||
|
hwp.write32(blob, hwp.make_addr(blob_info.addr + 4, ""), stub_addr_virt.addr)
|
||
|
-- write it !
|
||
|
local blob_data = hwp.read(blob, hwp.make_addr(blob_info.addr, ""), blob_info.size)
|
||
|
hwp.write(fw, proxy_addr, blob_data)
|
||
|
proxy_addr = hwp.inc_addr(proxy_addr, blob_info.size)
|
||
|
-- restore registers
|
||
|
arm.write_restore_regs(fw, proxy_addr)
|
||
|
proxy_addr = hwp.inc_addr(proxy_addr, 4)
|
||
|
-- branch to old code
|
||
|
local branch_to_old = arm.make_branch(old_irq_addr, false)
|
||
|
arm.write_branch(fw, proxy_addr, branch_to_old, hwp.inc_addr(proxy_addr, 4))
|
||
|
-- save
|
||
|
hwp.save_file(fw, arg[2])
|
||
|
|