Exemplo n.º 1
0
def AddIns(unit: elf_unit.Unit, ins: a64.Ins):
    if ins.has_reloc():
        sym = unit.FindOrAddSymbol(ins.reloc_symbol, ins.is_local_sym)
        unit.AddReloc(ins.reloc_kind, unit.sec_text, sym,
                      ins.operands[ins.reloc_pos])
        ins.clear_reloc()
    unit.sec_text.AddData(a64.Assemble(ins).to_bytes(4, byteorder='little'))
Exemplo n.º 2
0
def AddStartUpCode(unit: elf_unit.Unit):
    """Add code for `_start` wrapper which calls main(()

    When Linux transfers control to a new A32 program is does not follow any calling
    convention so we need this shim.
    The initial execution env looks like this:
    0(sp)			argc
    8(sp)			    argv[0] # argv start
    16(sp)               argv[1]
    ...
    (8*argc)(sp)        NULL    # argv sentinel

    (8*(argc+1))(sp)    envp[0] # envp start
    (8*(argc+2))(sp)    envp[1]
    ...
                        NULL    # envp sentinel

    This feature is needed by CodeGenA64/
    """
    unit.FunStart("_start", 16, NOP_BYTES)
    for mnemonic, ops in [
        ("ldr_x_imm", "x0 sp 0"),
        ("add_x_imm", "x1 sp 8"),
        ("bl", "expr:call26:main"),
            # x0 contains result from main
        ("movz_x_imm", "x8 0x5d"),
        ("svc", "0"),
            # unreachable
        ("brk", "1")
    ]:
        HandleOpcode(mnemonic, ops.split(), unit)
    unit.FunEnd()
Exemplo n.º 3
0
def AddStartUpCode(unit: elf_unit.Unit):
    """Add code for `_start` wrapper which calls main(()

    When Linux transfers control to a new A32 program is does not follow any calling
    convention so we need this shim.
    The initial execution env looks like this:
    0(sp)			argc

    4(sp)			    argv[0] # argv start
    8(sp)               argv[1]
    ...
    (4*argc)(sp)        NULL    # argv sentinel

    (4*(argc+1))(sp)    envp[0] # envp start
    (4*(argc+2))(sp)    envp[1]
    ...
                        NULL    # envp sentinel

    This feature is needed by CodeGenA32/
    """
    unit.FunStart("_start", 16, NOP_BYTES)
    for mnemonic, ops in [("ldr_imm_add", "al r0 sp 0"),
                          ("add_imm", "al r1 sp 4"),
                          ("bl", "al expr:call:main"), ("movw", "al r7 1"),
                          ("svc", "al 0"), ("ud2", "al")]:
        HandleOpcode(mnemonic, ops.split(), unit)
    unit.FunEnd()
Exemplo n.º 4
0
def AddIns(unit: elf_unit.Unit, ins: a32.Ins):
    if ins.reloc_kind != elf_enum.RELOC_TYPE_ARM.NONE:
        sym = unit.FindOrAddSymbol(ins.reloc_symbol, ins.is_local_sym)
        unit.AddReloc(ins.reloc_kind, unit.sec_text, sym,
                      ins.operands[ins.reloc_pos])
        # clear reloc info before proceeding
        ins.reloc_kind = elf_enum.RELOC_TYPE_ARM.NONE
        ins.operands[ins.reloc_pos] = 0
    unit.sec_text.AddData(a32.Assemble(ins).to_bytes(4, byteorder='little'))
Exemplo n.º 5
0
def HandleOpcode(mnemonic, token: List[str], unit: elf_unit.Unit):
    ins = symbolic.InsFromSymbolized(mnemonic, token)
    if ins.reloc_kind != elf_enum.RELOC_TYPE_AARCH64.NONE:
        sym = unit.FindOrAddSymbol(ins.reloc_symbol, ins.is_local_sym)
        unit.AddReloc(ins.reloc_kind, unit.sec_text, sym,
                      ins.operands[ins.reloc_pos])
        # clear reloc info before proceeding
        ins.reloc_kind = elf_enum.RELOC_TYPE_AARCH64.NONE
        ins.operands[ins.reloc_pos] = 0
    unit.sec_text.AddData(a64.Assemble(ins).to_bytes(4, byteorder='little'))
Exemplo n.º 6
0
def AddIns(unit: elf_unit.Unit, ins: x64.Ins):
    if ins.has_reloc():
        sym = unit.FindOrAddSymbol(ins.reloc_symbol, ins.is_local_sym)
        kind = ins.reloc_kind
        addend = ins.operands[ins.reloc_pos]
        ins.clear_reloc()  # we need to clear the reloc info BEFORE assembling
        ins_data = bytes(x64.Assemble(
            ins))  # note we do not know the exact length because of prefixes
        distance_to_ins_end = _RelocFieldOffsetFromEndOfIns(ins.opcode)
        if kind in {enum_tab.RELOC_TYPE_X86_64.PC32}:
            addend -= distance_to_ins_end
        unit.AddReloc(kind, unit.sec_text, sym, addend,
                      len(ins_data) - distance_to_ins_end)
    else:
        ins_data = bytes(x64.Assemble(ins))
    unit.sec_text.AddData(ins_data)
Exemplo n.º 7
0
def AddStartUpCode(unit: elf_unit.Unit):
    """Add code for `_start` wrapper which calls main(()

    When Linux transfers control to a new A32 program is does not follow any calling
    convention so we need this shim.
    The initial execution env looks like this:
    0(sp)			    argc
    8(sp)			    argv[0] # argv start
    16(sp)               argv[1]
    ...
    (8*argc)(sp)        NULL    # argv sentinel

    (8*(argc+1))(sp)    envp[0] # envp start
    (8*(argc+2))(sp)    envp[1]
    ...
                        NULL    # envp sentinel

    This feature is needed by CodeGenA64/
    """
    unit.FunStart("_start", 16, NOP_BYTES)
    for mnemonic, ops in [
        ("mov_64_r_mbis8", "rdi rsp noindex 0 0"),  # argc
        ("lea_64_r_mbis8", "rsi rsp noindex 0 8"),  # argv
        ("lea_64_r_mbis8", "rdx rsp rdi 3 16"),  # envp
            # default mxcsr is 0x1f80
            # description: https://wiki.osdev.org/SSE
            # force "rounding down"
        ("stmxcsr_32_mbis8", "rsp noindex 0 -4"),
        ("and_32_mbis8_imm32", "rsp noindex 0 -4 0xffff9fff"),
        ("or_32_mbis8_imm32", "rsp noindex 0 -4 0x2000"),
        ("ldmxcsr_32_mbis8", "rsp noindex 0 -4"),
        ("call_32", "expr:pcrel32:main"),
            # edi contains result from main
        ("mov_32_r_imm32", "edi 0x0"),
        ("mov_64_mr_imm32", "rax 0x3c"),
        ("syscall", ""),
            # unreachable
        ("int3", "")
    ]:
        HandleOpcode(mnemonic, ops.split(), unit)
    unit.FunEnd()