示例#1
0
def evaluate_lines(instr, lines, in_str):
    # Run the emulation of the basic bloc
    machine = mapper()

    def print_machine(machine):
        return sorted(str(machine).split("\n"))

    # Emulation with amoco is too slow
    # For 'movsd' tests depending of 'df' are not simplified, therefore there
    # are too many nested tests
    # For 'cmovXX' tests are not simplified either
    perf_count = {'movsd': 0, 'cmov': 0}
    for line in lines:
        # rip is kept symbolic
        if line.opname in ('call', 'jmp'):
            machine[env.rip] = env.rip
        else:
            machine[env.rip] = env.rip - line.bytelen
        if line.opname == 'movsd':
            perf_count['movsd'] += 1
            if perf_count['movsd'] >= 3:
                return (('Emulated too slow (movsd)', line,
                         print_machine(machine)), [None])
        if line.opname.startswith('cmov'):
            perf_count['cmov'] += 1
            if perf_count['cmov'] >= 3:
                return (('Emulated too slow (cmov)', line,
                         print_machine(machine)), [None])
        try:
            log.debug("EVAL %-20r %s", line.amoco.bytes, line)
            line.amoco(machine)
        except NotImplementedError:
            return (('Not implemented', line, print_machine(machine)), [None])
        except NameError:
            return (('Cannot be emulated (name)', line,
                     print_machine(machine)), [None])
        except amoco.arch.core.InstructionError:
            return (('Cannot be emulated', line, print_machine(machine)),
                    [None])
        except TypeError:
            return (('Not callable', line, print_machine(machine)), [None])
        if line.opname == 'call':
            # amoco emulation pushes rip+i.length
            # we prefer to push the label of the next basic bloc
            label = instr.symbols.find_symbol(section=line.section,
                                              address=line.offset +
                                              line.amoco.length)
            machine[env.mem(env.rsp,
                            cpu_addrsize)] = expressions.lab(label,
                                                             size=cpu_addrsize)
    retval = machine[env.rip]
    msg, val = evaluate(retval, machine, instr.symbols.find_symbols, instr,
                        in_str)
    if val is None:
        return ((str(retval.__class__), retval, print_machine(machine)),
                [None])
    elif val == [None]:
        return ((msg, retval, print_machine(machine)), [None])
    else:
        return (msg, val)
示例#2
0
def test_mapper_001():
    # create three instructions
    # movq    %rax, (%rip)
    # movl    %eax, (%rip)
    # movq    -16(%rbp), %rcx
    i0 = cpu.disassemble(b"\x48\x89\x05\x00\x00\x00\x00")
    i1 = cpu.disassemble(b"\x89\x05\x00\x00\x00\x00")
    i2 = cpu.disassemble(b"\x48\x8b\x4d\xf0")
    # modify the first two instructions to insert a label
    # movq    %rax, foo(%rip)
    i0.operands[0].a.disp = expressions.lab('foo', size=64)
    # movb    %eax, bar(%rip)
    i1.operands[0].a.disp = expressions.lab('bar', size=64)
    # evaluate those three instructions
    m = mapper()
    i0(m)
    i1(m)
    i2(m)
    assert str(m[rcx]) == 'M64(rbp-16)'
示例#3
0
def test_mapper_000():
    # create two instructions
    # movq    %rcx, (%rip)
    # movq    (%rip), %rcx
    i0 = cpu.disassemble(b"\x48\x89\x0d\x00\x00\x00\x00")
    i1 = cpu.disassemble(b"\x48\x8b\x0d\x00\x00\x00\x00")
    # modify the first instruction to insert a label, e.g. because
    # there is a relocation
    # movq    %rcx, foo(%rip)
    i0.operands[0].a.disp = expressions.lab('foo', size=64)
    # evaluate those two instructions
    m = mapper()
    i0(m)
    i1(m)
    assert str(m[rcx]) == 'M64(rip+14)'
示例#4
0
 def action_term(toks):
     if isinstance(toks[0], str):
         return expressions.lab(toks[0],size=att_syntax.cpu_addrsize)