Ejemplo n.º 1
0
def GenBareBonesA64():
    sec_null = elfhelper.Section.MakeSectionNull()

    sec_text = elfhelper.Section.MakeSectionText(1)
    sec_text.data = bytes(ALL_A64)
    sec_text.sh_size = len(sec_text.data)

    sec_shstrtab = elfhelper.Section.MakeSectionStrTab(".shstrtab")
    sec_shstrtab.data = elfhelper.MakeSecStrTabContents(
        [sec_null, sec_text, sec_shstrtab])
    sec_shstrtab.sh_size = len(sec_shstrtab.data)

    seg_exe = elfhelper.Segment.MakeExeSegment(65536)
    seg_exe.sections.append(sec_null)
    seg_exe.sections.append(sec_text)

    seg_pseudo = elfhelper.Segment.MakePseudoSegment()
    seg_pseudo.sections.append(sec_shstrtab)

    exe = elfhelper.Executable.MakeExecutableA64(
        0x400000, [sec_null, sec_text, sec_shstrtab],
        [seg_exe, seg_pseudo])
    exe.update_vaddrs_and_offset()
    print(f"PATCH ENTRY: {sec_text.sh_addr:x}")
    exe.ehdr.e_entry = sec_text.sh_addr
    print(f"PATCH INSTRUCTIONS: {sec_text.sh_addr:x}")
    # simplifying assumption - we stay on the same page so adrp
    # does not need patching only the add instruction following it
    msg_adr = sec_text.sh_addr + 9 * 4
    add_ins = 0x91035021 & 0xff0003ff | ((msg_adr & 0xfff) << 10)
    sec_text.data = (ALL_A64[:8] +
                     add_ins.to_bytes(4, "little") +
                     ALL_A64[12:])
    return exe
Ejemplo n.º 2
0
def GenBareBonesA32():
    sec_null = elfhelper.Section.MakeSectionNull()

    sec_text = elfhelper.Section.MakeSectionText(1)
    sec_text.data = bytes(ALL_A32)
    sec_text.sh_size = len(sec_text.data)

    sec_shstrtab = elfhelper.Section.MakeSectionStrTab(".shstrtab")
    sec_shstrtab.data = elfhelper.MakeSecStrTabContents([sec_null, sec_text, sec_shstrtab])
    sec_shstrtab.sh_size = len(sec_shstrtab.data)

    seg_exe = elfhelper.Segment.MakeExeSegment(65536)
    seg_exe.sections.append(sec_null)
    seg_exe.sections.append(sec_text)

    seg_pseudo = elfhelper.Segment.MakePseudoSegment()
    seg_pseudo.sections.append(sec_shstrtab)

    exe = elfhelper.Executable.MakeExecutableA32(
        0x20000, [sec_null, sec_text, sec_shstrtab],
        [seg_exe, seg_pseudo])
    exe.update_vaddrs_and_offset()
    print(f"PATCH ENTRY: {sec_text.sh_addr:x}")
    exe.ehdr.e_entry = sec_text.sh_addr
    return exe
Ejemplo n.º 3
0
def GenBareBonesX64() -> elfhelper.Executable:
    sec_null = elfhelper.Section.MakeSectionNull()

    sec_rodata = elfhelper.Section.MakeSectionRodata(1)
    sec_rodata.data = RODATA_X64
    sec_rodata.sh_size = len(sec_rodata.data)

    sec_text = elfhelper.Section.MakeSectionText(1)
    sec_text.data = bytes(TEXT_X64)
    sec_text.sh_size = len(sec_text.data)

    sec_shstrtab = elfhelper.Section.MakeSectionStrTab(".shstrtab")
    sec_shstrtab.data = elfhelper.MakeSecStrTabContents(
        [sec_null, sec_rodata, sec_text, sec_shstrtab])
    sec_shstrtab.sh_size = len(sec_shstrtab.data)

    seg_ro = elfhelper.Segment.MakeROSegment(4096)
    seg_exe = elfhelper.Segment.MakeExeSegment(4096)
    seg_pseudo = elfhelper.Segment.MakePseudoSegment()

    seg_ro.sections.append(sec_null)
    seg_ro.sections.append(sec_rodata)
    seg_exe.sections.append(sec_text)
    seg_pseudo.sections.append(sec_shstrtab)

    exe = elfhelper.Executable.MakeExecutableX64(
        0x400000,
        [sec_null, sec_rodata, sec_text, sec_shstrtab],
        [seg_ro, seg_exe, seg_pseudo])
    exe.update_vaddrs_and_offset()

    print(f"PATCH ENTRY: {sec_text.sh_addr:x}")
    exe.ehdr.e_entry = sec_text.sh_addr

    print(f"PATCH MSG: {sec_rodata.sh_addr:x}")
    # string address is at offset 14
    sec_text.data = (bytes(TEXT_X64[:17]) +
                     sec_rodata.sh_addr.to_bytes(4, "little") +
                     bytes(TEXT_X64[21:]))
    return exe
Ejemplo n.º 4
0
def Assemble(unit: elf_unit.Unit, create_sym_tab: bool) -> elf.Executable:
    sections = []
    segments = []

    seg_exe = elf.Segment.MakeExeSegment(65536)
    segments.append(seg_exe)

    sec_null = elf.Section.MakeSectionNull()
    sections.append(sec_null)
    seg_exe.sections.append(sec_null)
    #
    sec_text = unit.sec_text
    assert len(sec_text.data) > 0
    sections.append(sec_text)
    seg_exe.sections.append(sec_text)

    sec_rodata = unit.sec_rodata
    if len(sec_rodata.data) > 0:
        seg_ro = elf.Segment.MakeROSegment(65536)
        segments.append(seg_ro)
        #
        sections.append(sec_rodata)
        seg_ro.sections.append(sec_rodata)

    if len(unit.sec_data.data) + len(unit.sec_bss.data) > 0:
        seg_rw = elf.Segment.MakeRWSegment(65536)
        segments.append(seg_rw)

    sec_data = unit.sec_data
    if len(sec_data.data) > 0:
        sections.append(sec_data)
        seg_rw.sections.append(sec_data)

    sec_bss = unit.sec_bss
    if len(sec_bss.data) > 0:
        sections.append(sec_bss)
        seg_rw.sections.append(sec_bss)

    seg_pseudo = elf.Segment.MakePseudoSegment()
    segments.append(seg_pseudo)
    #

    if create_sym_tab:
        # we do not create the content here since we cannot really do this until
        # the section addresses are finalized
        which = elf_enum.EI_CLASS.X_64
        sec_symtab = elf.Section.MakeSectionSymTab(".symtab", which,
                                                   len(sections) + 1)
        sections.append(sec_symtab)
        sec_symtab.SetData(
            bytearray(len(unit.symbols) * elf.Symbol.SIZE[which]))
        seg_pseudo.sections.append(sec_symtab)
        # TODO: this is not quite right
        sec_symtab.sh_info = len(unit.symbols)

        sym_names = bytearray()
        sym_names += b"\0"
        for sym in unit.symbols:
            if sym.name:
                sym.st_name = len(sym_names)
                sym_names += (bytes(sym.name, "utf-8") + b"\0")
            else:
                sym.st_name = 0
        sec_symstrtab = elf.Section.MakeSectionStrTab(".strtab")
        sections.append(sec_symstrtab)
        sec_symstrtab.SetData(sym_names)
        seg_pseudo.sections.append(sec_symstrtab)

    sec_shstrtab = elf.Section.MakeSectionStrTab(".shstrtab")
    sections.append(sec_shstrtab)
    sec_shstrtab.SetData(elf.MakeSecStrTabContents(sections))
    seg_pseudo.sections.append(sec_shstrtab)

    exe = elf.Executable.MakeExecutableA64(0x400000, sections, segments)
    exe.update_vaddrs_and_offset()

    if False:
        for sym in unit.symbols:
            print("@@@SYMS", sym)
        for rel in unit.relocations:
            print("@@@REL", rel)

    for sym in unit.symbols:
        if sym.section:
            assert sym.section.sh_addr > 0
            assert sym.st_value != elf.TO_BE_FILLED_IN_LATER
            sym.st_value += sym.section.sh_addr
            sym.st_shndx = sym.section.index

    for rel in unit.relocations:
        _ApplyRelocation(rel)

    if create_sym_tab:
        # we only put dummiess in the symtable above - do it for real now
        sec_symtab.data = bytearray()
        for sym in unit.symbols:
            sec_symtab.AddData(sym.pack(which))

    sym_entry = unit.global_symbol_map["_start"]
    assert sym_entry and not sym_entry.is_undefined()
    entry_addr = sym_entry.st_value
    print(f"PATCH ENTRY: {entry_addr:x}")
    exe.ehdr.e_entry = entry_addr
    return exe