Exemplo n.º 1
0
 def action_bis(toks):
     if len(toks) == 3:
         addr = toks[1]
     elif len(toks) == 5 and toks[2] == ',':
         addr = expressions.op('+', toks[1], toks[3])
         if att_syntax.env.internals.get('keep_order'): addr.prop |= 16
     elif len(toks) == 6 and toks[1] == ',' and toks[3] == ',':
         toks[4].size = toks[2].size # cst size set to register size
         addr = expressions.oper('*', toks[2], toks[4])
     elif len(toks) == 7 and toks[2] == ',' and toks[4] == ',':
         toks[5].size = toks[3].size # cst size set to register size
         addr = expressions.op('+', toks[1], expressions.oper('*', toks[3], toks[5]))
         if att_syntax.env.internals.get('keep_order'): addr.prop |= 16
     else:
         NEVER
     return addr
Exemplo n.º 2
0
def test_switch_array(address):
    if not address._is_eqn:
        return None
    # Expression of the form idx+(rip+L)
    # L is the label of the table
    # idx is a sign-extended 32-bit index
    if (address.op.symbol == '+'
            # right part is rip+L
            and address.r._is_ptr and check_pic_data(address.r.base) and
            address.r.disp._is_lab
            # left part is a sign-extended 32-bit address
            and address.l._is_cmp
            and sorted(address.l.parts.keys()) == [(0, 32), (32, 64)]
            and address.l.parts[(32, 64)]._is_tst
            and address.l.parts[(32, 64)].l._is_cst
            and address.l.parts[(32, 64)].r._is_cst
            and int(address.l.parts[(32, 64)].l) == -1
            and int(address.l.parts[(32, 64)].r) == 0
            and address.l.parts[(32, 64)].tst._is_slc):
        L = address.r.disp.ref
        idx = address.l.parts[(0, 32)]
        r1 = idx.a.base
        if r1.l._is_ptr and r1.l.disp == 0:
            NON_REGRESSION_FOUND
            r1 = expressions.op(r1.op.symbol, r1.l.base, r1.r)
        # idx is of the form M32[(val*4)+(rip+L)]
        if (idx.a.disp == 0 and r1._is_eqn and r1.op.symbol == '+'
                and r1.r._is_ptr and check_pic_data(r1.r.base)
                and r1.r.disp._is_lab and r1.r.disp.ref is address.r.disp.ref
                and r1.l._is_eqn and r1.l.op.symbol == '*' and r1.l.r._is_cst
                and int(r1.l.r) == 4):
            log.debug("SWITCH TABLE %s [%s*4]", L, r1.l.l)
            return r1, L
    return None
Exemplo n.º 3
0
 def action_bis(toks):
     if len(toks) == 3:
         addr = toks[1]
     elif len(toks) == 5 and toks[2] == ",":
         addr = expressions.op("+", toks[1], toks[3])
         if env.internals.get("keep_order"):
             addr.prop |= 16
     elif len(toks) == 6 and toks[1] == "," and toks[3] == ",":
         toks[4].size = toks[2].size  # cst size set to register size
         addr = expressions.oper("*", toks[2], toks[4])
     elif len(toks) == 7 and toks[2] == "," and toks[4] == ",":
         toks[5].size = toks[3].size  # cst size set to register size
         addr = expressions.op("+", toks[1],
                               expressions.oper("*", toks[3], toks[5]))
         if env.internals.get("keep_order"):
             addr.prop |= 16
     else:
         NEVER
     return addr
Exemplo n.º 4
0
def getModRM(obj, Mod, RM, data):
    opdsz = obj.misc['opdsz'] or env.internals['mode']
    adrsz = obj.misc['adrsz'] or env.internals['mode']
    seg = obj.misc['segreg']
    if seg is None: seg = ''
    # r/16/32 case:
    if Mod == 0b11:
        op1 = env.getreg(RM, opdsz)
        return op1, data
    # 32-bit SIB cases:
    if adrsz == 32 and RM == 0b100:
        # read SIB byte in data:
        if data.size < 8: raise InstructionError(obj)
        sib, data = data[0:8], data[8:data.size]
        # add sib byte:
        obj.bytes += pack(sib)
        # decode base & scaled index
        b = env.getreg(sib[0:3].int(), adrsz)
        i = env.getreg(sib[3:6].int(), adrsz)
        ss = 1 << (sib[6:8].int())
        s = i * ss if not i.ref in ('esp', 'sp') else 0
    else:
        s = 0
        if adrsz == 32:
            b = env.getreg(RM, adrsz)
        else:
            b = (env.bx + env.si, env.bx + env.di, env.bp + env.si,
                 env.bp + env.di, env.si, env.di, env.bp, env.bx)[RM]
    # check [disp16/32] case:
    if (b is env.ebp or b is env.bp) and Mod == 0:
        Mod = 0b10
        bs = s + env.cst(0, adrsz)
    elif s is 0:
        bs = b
    elif env.internals.get('keep_order'):
        # Instead of doing bs = b+s, which will reorder arguments, we do
        # the addition manually, and change 'prop' so the many future calls
        # to 'simplify' does not reorder the arguments
        from amoco.cas import expressions
        bs = expressions.op('+', b, s)
        bs.prop |= 16
    else:
        bs = b + s
    # now read displacement bytes:
    if Mod == 0b00:
        d = 0
    elif Mod == 0b01:
        if data.size < 8: raise InstructionError(obj)
        d = data[0:8]
        data = data[8:data.size]
        obj.bytes += pack(d)
        d = d.signextend(adrsz).int(-1)
    elif Mod == 0b10:
        if data.size < adrsz: raise InstructionError(obj)
        d = data[0:adrsz]
        obj.bytes += pack(d)
        data = data[adrsz:data.size]
        d = d.int(-1)
    if bs._is_cst and bs.v == 0x0:
        bs.size = adrsz
        bs.v = d & bs.mask
        d = 0
    return env.mem(bs, opdsz, seg, d), data
Exemplo n.º 5
0
def asmhelper(i):
    for idx, a in enumerate(i.operands):
        if a._is_mem:
            i.operands[idx] = a.a
    # Add implicit arguments
    if i.mnemonic in ['inc', 'dec'] and len(i.operands) == 1:
        i.operands.insert(0, cst(1))
    # Expand reduced forms
    if i.mnemonic == 'bset':
        i.mnemonic = 'or'
        i.operands.insert(0, i.operands[1])
    elif i.mnemonic == 'mov':
        i.mnemonic = 'or'
        i.operands.insert(0, env.g0)
    elif i.mnemonic == 'retl':
        i.mnemonic = 'jmpl'
        i.operands.insert(0, op('+', env.o7, cst(8)))
        i.operands.insert(1, env.g0)
    elif i.mnemonic == 'jmp':
        i.mnemonic = 'jmpl'
        i.operands.insert(1, env.g0)
    elif i.mnemonic == 'clr' and i.operands[0]._is_reg:
        i.mnemonic = 'or'
        i.operands.insert(0, env.g0)
        i.operands.insert(0, env.g0)
    elif i.mnemonic == 'clr':
        i.mnemonic = 'st'
        i.operands.insert(0, env.g0)
    elif i.mnemonic == 'inc':
        i.mnemonic = 'add'
        i.operands.insert(0, i.operands[1])
    elif i.mnemonic == 'dec':
        i.mnemonic = 'sub'
        i.operands.insert(0, i.operands[1])
    elif i.mnemonic == 'cmp':
        i.mnemonic = 'subcc'
        i.operands.insert(2, env.g0)
    elif i.mnemonic == 'btst':
        i.mnemonic = 'andcc'
        i.operands.insert(2, env.g0)
        i.operands[0:2] = [i.operands[1], i.operands[0]]
    elif i.mnemonic == 'nop':
        i.mnemonic = 'sethi'
        i.operands = [cst(0, 22), env.g0]
    elif i.mnemonic == 'restore' and len(i.operands) == 0:
        i.operands = [env.g0, env.g0, env.g0]
    # Branches and cc
    if i.mnemonic.endswith(
            'cc') and not i.mnemonic in ['taddcc', 'tsubcc', 'mulscc']:
        i.mnemonic = i.mnemonic[:-2]
        i.misc['icc'] = True
    if i.mnemonic.endswith(',a'):
        i.misc['annul'] = True
        i.mnemonic = i.mnemonic.rstrip(',a')
    if i.mnemonic in b_synonyms:
        i.mnemonic = b_synonyms[i.mnemonic]
    if i.mnemonic in b_cond:
        i.cond = b_cond[i.mnemonic]
        i.mnemonic = 'b'
    if i.mnemonic in t_synonyms:
        i.mnemonic = t_synonyms[i.mnemonic]
    if i.mnemonic in t_cond:
        i.cond = t_cond[i.mnemonic]
        i.mnemonic = 't'
    if i.mnemonic == 'call':
        if len(i.operands) > 1 and i.operands[1] != cst(0):
            raise ValueError('call has a non-zero second argument')
        i.operands = [i.operands[0]]
    # Additional internal tweaks
    if i.mnemonic == 'sethi' and i.operands[0]._is_cst:
        i.operands[0].size = 22
    elif i.mnemonic == 'std':
        i.rd = env.r.index(i.operands[0])
    elif i.mnemonic == 'ldd':
        i.rd = env.r.index(i.operands[1])
    i.spec = spec_table[i.mnemonic]
    i.bytes = (0, 0, 0, 0)  # To have i.length == 4, for pc_npc emulation
    return i