Summary
ElfSynthesizer._assembleFile builds the section header table from
named_sections = [s for s in sections if s["name"]] (ElfSynthesizer.py:~329).
A stripped ELF — where SMDA recovers real VA ranges but every code_sections entry has name == "" — therefore synthesizes to a file with e_shnum == 2 (the null section plus .shstrtab) even though the real ranges are still emitted as PT_LOADs. Re-loading that file gives base_addr = 0 and loses functions.
Reproduction
tests/mirai_x64_xored on master (4.4.1), with the section names cleared to model the stripped case:
report.code_sections = [("", s, e) for _, s, e in report.code_sections]
synth = report.synthesizeBinary(output_format="ELF", with_strings=False)
all-unnamed code_sections -> e_shnum = 2 | names: ['', '.shstrtab']
PT_LOADs emitted: 4
re-loaded: 145 functions (original 151), base 0x0 (original 0x400000)
Four PT_LOADs describing the real layout, but no section headers describing them; 6 of 151 functions are lost on re-disassembly and the base address is wrong.
(For contrast, the unmodified fixture has 9 of 10 sections named and synthesizes with e_shnum == 10.)
Suggested direction
Fabricating names for unnamed ranges (.smda0, .smda1, …) would preserve the section header table and keep the synthesized file self-describing. That also removes the base_addr = 0 case, which is one of the two paths into the wrong-base problem filed separately.
Found during a whole-repo audit of src/smda/** and re-verified against master before filing. Synthesis is documented as experimental, so filing rather than patching.
Summary
ElfSynthesizer._assembleFilebuilds the section header table fromnamed_sections = [s for s in sections if s["name"]](ElfSynthesizer.py:~329).A stripped ELF — where SMDA recovers real VA ranges but every
code_sectionsentry hasname == ""— therefore synthesizes to a file withe_shnum == 2(the null section plus.shstrtab) even though the real ranges are still emitted as PT_LOADs. Re-loading that file givesbase_addr = 0and loses functions.Reproduction
tests/mirai_x64_xoredonmaster(4.4.1), with the section names cleared to model the stripped case:Four PT_LOADs describing the real layout, but no section headers describing them; 6 of 151 functions are lost on re-disassembly and the base address is wrong.
(For contrast, the unmodified fixture has 9 of 10 sections named and synthesizes with
e_shnum == 10.)Suggested direction
Fabricating names for unnamed ranges (
.smda0,.smda1, …) would preserve the section header table and keep the synthesized file self-describing. That also removes thebase_addr = 0case, which is one of the two paths into the wrong-base problem filed separately.Found during a whole-repo audit of
src/smda/**and re-verified againstmasterbefore filing. Synthesis is documented as experimental, so filing rather than patching.