53 lines
1.6 KiB
Python
53 lines
1.6 KiB
Python
#!/usr/bin/env python3
|
|
"""edp_carve.py — точная нарезка ELF из Emergency Payload (.edp) по program headers.
|
|
Использование: ./tools/edp_carve.py fw/dl/edp-archorg-1127.edp out-dir/
|
|
"""
|
|
import os
|
|
import struct
|
|
import sys
|
|
|
|
|
|
def elf_span(d, off):
|
|
assert d[off:off + 4] == b"\x7fELF", "not ELF"
|
|
entry = struct.unpack("<I", d[off + 24:off + 28])[0]
|
|
phoff = struct.unpack("<I", d[off + 28:off + 32])[0]
|
|
phnum = struct.unpack("<H", d[off + 44:off + 46])[0]
|
|
end = 0
|
|
segs = []
|
|
for i in range(phnum):
|
|
p = off + phoff + i * 32
|
|
ptype, poff, pv, pp, pfsz, pmsz, flg, al = struct.unpack("<IIIIIIII", d[p:p + 32])
|
|
if ptype == 1: # PT_LOAD
|
|
segs.append((pv, pfsz, pmsz, flg))
|
|
end = max(end, poff + pfsz)
|
|
return entry, segs, end
|
|
|
|
|
|
def main():
|
|
src, outdir = sys.argv[1], sys.argv[2]
|
|
d = open(src, "rb").read()
|
|
offs = []
|
|
i = 0
|
|
while True:
|
|
i = d.find(b"\x7fELF", i)
|
|
if i < 0:
|
|
break
|
|
offs.append(i)
|
|
i += 1
|
|
os.makedirs(outdir, exist_ok=True)
|
|
print(f"{len(offs)} ELFs")
|
|
for n, o in enumerate(offs):
|
|
try:
|
|
entry, segs, end = elf_span(d, o)
|
|
except Exception as e:
|
|
print(n, f"off={o} PARSE-FAIL {e}")
|
|
continue
|
|
open(f"{outdir}/img{n}.elf", "wb").write(d[o:o + end])
|
|
mem = sum(s[2] for s in segs)
|
|
print(f"img{n}: off={o} size={end} entry={entry:#x} mem={mem} "
|
|
+ " ".join(f"[{v:#x}+{ms:#x}{'X' if fl & 1 else ''}]" for v, fz, ms, fl in segs))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|