Files

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()