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
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
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
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
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