diff options
Diffstat (limited to 'miasm2/arch')
| -rw-r--r-- | miasm2/arch/arm/arch.py | 72 | ||||
| -rw-r--r-- | miasm2/arch/mips32/arch.py | 30 | ||||
| -rw-r--r-- | miasm2/arch/msp430/arch.py | 25 | ||||
| -rw-r--r-- | miasm2/arch/msp430/ira.py | 2 | ||||
| -rw-r--r-- | miasm2/arch/sh4/arch.py | 12 | ||||
| -rw-r--r-- | miasm2/arch/x86/arch.py | 82 | ||||
| -rw-r--r-- | miasm2/arch/x86/regs.py | 7 |
7 files changed, 161 insertions, 69 deletions
diff --git a/miasm2/arch/arm/arch.py b/miasm2/arch/arm/arch.py index 740fd1df..a70718d9 100644 --- a/miasm2/arch/arm/arch.py +++ b/miasm2/arch/arm/arch.py @@ -9,6 +9,7 @@ from collections import defaultdict from miasm2.core.bin_stream import bin_stream import miasm2.arch.arm.regs as regs_module from miasm2.arch.arm.regs import * +from miasm2.core.asmbloc import asm_label # A1 encoding @@ -167,7 +168,7 @@ int_or_expr = base_expr def ast_id2expr(t): if not t in mn_arm.regs.all_regs_ids_byname: - r = ExprId(t) + r = ExprId(asm_label(t)) else: r = mn_arm.regs.all_regs_ids_byname[t] return r @@ -362,9 +363,9 @@ class instruction_arm(instruction): if not isinstance(e, ExprInt): return if self.name == 'BLX': - ad = e.arg + 8 + self.offset + ad = e.arg + self.offset else: - ad = e.arg + 8 + self.offset + ad = e.arg + self.offset l = symbol_pool.getby_offset_create(ad) s = ExprId(l, e.size) self.args[0] = s @@ -405,8 +406,7 @@ class instruction_arm(instruction): if not isinstance(e, ExprInt): log.debug('dyn dst %r', e) return - # Can't find the +4 reason in doc - off = e.arg - (self.offset + 4 + self.l) + off = e.arg - self.offset if int(off % 4): raise ValueError('strange offset! %r' % off) self.args[0] = ExprInt32(off) @@ -415,9 +415,9 @@ class instruction_arm(instruction): args = [a for a in self.args] return args - def get_asm_offset(self, x): + def get_asm_offset(self, expr): # LDR XXX, [PC, offset] => PC is self.offset+8 - return ExprInt_from(x, self.offset+8) + return ExprInt_from(expr, self.offset+8) class instruction_armt(instruction_arm): @@ -437,9 +437,9 @@ class instruction_armt(instruction_arm): if not isinstance(e, ExprInt): return if self.name == 'BLX': - ad = e.arg + 4 + (self.offset & 0xfffffffc) + ad = e.arg + (self.offset & 0xfffffffc) else: - ad = e.arg + 4 + self.offset + ad = e.arg + self.offset l = symbol_pool.getby_offset_create(ad) s = ExprId(l, e.size) if self.name in ["CBZ", "CBNZ"]: @@ -479,11 +479,15 @@ class instruction_armt(instruction_arm): # The first +2 is to compensate instruction len, but strangely, 32 bits # thumb2 instructions len is 2... For the second +2, didn't find it in # the doc. - off = e.arg - (self.offset + 2 + 2) + off = e.arg - self.offset if int(off % 2): raise ValueError('strange offset! %r' % off) self.args[0] = ExprInt32(off) + def get_asm_offset(self, expr): + # ADR XXX, PC, imm => PC is 4 aligned + imm + new_offset = ((self.offset+self.l)/4)*4 + return ExprInt_from(expr, new_offset) class mn_arm(cls_mn): @@ -500,6 +504,7 @@ class mn_arm(cls_mn): sp = {'l':SP, 'b':SP} instruction = instruction_arm max_instruction_len = 4 + alignment = 4 @classmethod def getpc(cls, attrib = None): @@ -598,7 +603,8 @@ class mn_armt(cls_mn): pc = PC sp = SP instruction = instruction_armt - max_instruction_len = 8 + max_instruction_len = 4 + alignment = 4 @classmethod def getpc(cls, attrib = None): @@ -780,9 +786,16 @@ class arm_offs(arm_imm): return ExprInt_fromsize(self.intsize, v) def decodeval(self, v): - return v << 2 + v <<= 2 + # Add pipeline offset + v += 8 + return v def encodeval(self, v): + if v%4 != 0: + return False + # Remove pipeline offset + v -= 8 return v >> 2 def decode(self, v): @@ -1193,13 +1206,16 @@ class arm_offs_blx(arm_imm): v = v & self.lmask v = (v << 2) + (self.parent.lowb.value << 1) v = sign_ext(v, 26, 32) + # Add pipeline offset + v += 8 self.expr = ExprInt32(v) return True def encode(self): if not isinstance(self.expr, ExprInt): return False - v = self.expr.arg.arg + # Remove pipeline offset + v = int(self.expr.arg - 8) if v & 0x80000000: v &= (1 << 26) - 1 self.parent.lowb.value = (v >> 1) & 1 @@ -1626,28 +1642,17 @@ class arm_offsp(arm_offpc): class arm_offspc(arm_offs): def decodeval(self, v): - return v << 1 - - def encodeval(self, v): - return v >> 1 - - -class arm_offspchl(arm_offs): - - def decodeval(self, v): - if self.parent.hl.value == 0: - return v << 12 - else: - return v << 1 + v = v << 1 + # Add pipeline offset + v += 2 + 2 + return v def encodeval(self, v): - if v > (1 << 12): - self.parent.hl.value = 0 - v >>= 12 - else: - self.parent.hl.value = 1 - v >>= 1 - return v + # Remove pipeline offset + v -= 2 + 2 + if v % 2 == 0: + return v >> 1 + return False class arm_off8sppc(arm_imm): @@ -1898,7 +1903,6 @@ rbl_wb = bs(l=3, cls=(armt_reg_wb,), fname='rb') offs8 = bs(l=8, cls=(arm_offspc,), fname="offs") offs11 = bs(l=11, cls=(arm_offspc,), fname="offs") -offs11hl = bs(l=11, cls=(arm_offspchl,), fname="offs") hl = bs(l=1, prio=default_prio + 1, fname='hl') off8sppc = bs(l=8, cls=(arm_off8sppc,), fname="off") diff --git a/miasm2/arch/mips32/arch.py b/miasm2/arch/mips32/arch.py index 50dc1c86..12f4ff8e 100644 --- a/miasm2/arch/mips32/arch.py +++ b/miasm2/arch/mips32/arch.py @@ -10,7 +10,7 @@ from miasm2.expression.expression import ExprMem, ExprInt, ExprInt32, ExprId from miasm2.core.bin_stream import bin_stream import miasm2.arch.mips32.regs as regs import miasm2.core.cpu as cpu - +from miasm2.core.asmbloc import asm_label log = logging.getLogger("mips32dis") console_handler = logging.StreamHandler() @@ -48,6 +48,26 @@ deref_nooff = Group(LPARENTHESIS + gpregs.parser + \ deref = deref_off | deref_nooff +variable, operand, base_expr = cpu.gen_base_expr() + +int_or_expr = base_expr + + +def ast_id2expr(t): + if not t in mn_mips32.regs.all_regs_ids_byname: + r = ExprId(asm_label(t)) + else: + r = mn_mips32.regs.all_regs_ids_byname[t] + return r + + +def ast_int2expr(a): + return ExprInt32(a) + + +my_var_parser = cpu.parse_ast(ast_id2expr, ast_int2expr) +base_expr.setParseAction(my_var_parser) + class additional_info: def __init__(self): self.except_on_instr = False @@ -159,7 +179,7 @@ class instruction_mips32(cpu.instruction): raise ValueError('symbol not resolved %s' % self.l) if not isinstance(e, ExprInt): return - off = e.arg - (self.offset + self.l) + off = e.arg - self.offset print "diff", e, hex(self.offset) print hex(off) if int(off % 4): @@ -307,13 +327,15 @@ class mips32_soff_noarg(mips32_imm): v = v & self.lmask v <<= 2 v = cpu.sign_ext(v, 16+2, 32) - self.expr = ExprInt32(v) + # Add pipeline offset + self.expr = ExprInt32(v + 4) return True def encode(self): if not isinstance(self.expr, ExprInt): return False - v = self.expr.arg.arg + # Remove pipeline offset + v = int(self.expr.arg - 4) if v & 0x80000000: nv = v & ((1 << 16+2) - 1) assert( v == cpu.sign_ext(nv, 16+2, 32)) diff --git a/miasm2/arch/msp430/arch.py b/miasm2/arch/msp430/arch.py index 2f543843..2cac7260 100644 --- a/miasm2/arch/msp430/arch.py +++ b/miasm2/arch/msp430/arch.py @@ -9,6 +9,7 @@ from collections import defaultdict from miasm2.core.bin_stream import bin_stream import miasm2.arch.msp430.regs as regs_module from miasm2.arch.msp430.regs import * +from miasm2.core.asmbloc import asm_label log = logging.getLogger("armdis") console_handler = logging.StreamHandler() @@ -73,7 +74,7 @@ PINC = Suppress("+") def ast_id2expr(t): if not t in mn_msp430.regs.all_regs_ids_byname: - r = ExprId(t, 16) + r = ExprId(asm_label(t), 16) else: r = mn_msp430.regs.all_regs_ids_byname[t] return r @@ -143,7 +144,7 @@ class instruction_msp430(instruction): if self.name == "call": ad = e.arg else: - ad = e.arg + int(self.offset) + self.l + ad = e.arg + int(self.offset) l = symbol_pool.getby_offset_create(ad) s = ExprId(l, e.size) @@ -187,8 +188,11 @@ class instruction_msp430(instruction): # raise ValueError('dst must be int or label') log.warning('dynamic dst %r', e) return - # return ExprInt32(e.arg - (self.offset + self.l)) - self.args[0] = ExprInt_fromsize(16, e.arg - (self.offset + self.l)) + + # Call argument is an absolute offset + # Other offsets are relative to instruction offset + if self.name != "call": + self.args[0] = ExprInt_fromsize(16, e.arg - self.offset) def get_info(self, c): pass @@ -522,9 +526,16 @@ class msp430_offs(imm_noarg, m_arg): return ExprInt_fromsize(16, v) def decodeval(self, v): - return v << 1 + v <<= 1 + v += self.parent.l + return v def encodeval(self, v): + plen = self.parent.l + self.l + assert(plen % 8 == 0) + v -= plen / 8 + if v % 2 != 0: + return False return v >> 1 def decode(self, v): @@ -574,8 +585,8 @@ bs_f2_nobw = bs_name(l=3, name={'swpb': 1, 'sxt': 3, 'call': 5}) addop("f2_2", [bs('000100'), bs_f2_nobw, bs('0'), a_s, sreg, off_s]) - -offimm = bs(l=10, cls=(msp430_offs,), fname="offs") +# Offset must be decoded in last position to have final instruction len +offimm = bs(l=10, cls=(msp430_offs,), fname="offs", order=-1) bs_f2_jcc = bs_name(l=3, name={'jnz': 0, 'jz': 1, 'jnc': 2, 'jc': 3, 'jn': 4, 'jge': 5, 'jl': 6, 'jmp': 7}) diff --git a/miasm2/arch/msp430/ira.py b/miasm2/arch/msp430/ira.py index ea8bdc2c..26a53a1e 100644 --- a/miasm2/arch/msp430/ira.py +++ b/miasm2/arch/msp430/ira.py @@ -65,7 +65,7 @@ class ir_a_msp430(ir_a_msp430_base): lbl = bloc.get_next() new_lbl = self.gen_label() irs = self.call_effects(pc_val) - irs.append([ExprAff(IRDst, ExprId(lbl, size=self.pc.size))]) + irs.append([ExprAff(self.IRDst, ExprId(lbl, size=self.pc.size))]) nbloc = irbloc(new_lbl, irs) nbloc.lines = [l] self.blocs[new_lbl] = nbloc diff --git a/miasm2/arch/sh4/arch.py b/miasm2/arch/sh4/arch.py index a102a37b..7039016c 100644 --- a/miasm2/arch/sh4/arch.py +++ b/miasm2/arch/sh4/arch.py @@ -5,8 +5,9 @@ from pyparsing import * from miasm2.core.cpu import * from miasm2.expression.expression import * from collections import defaultdict +import miasm2.arch.sh4.regs as regs_module from miasm2.arch.sh4.regs import * - +from miasm2.core.asmbloc import asm_label jra = ExprId('jra') jrb = ExprId('jrb') @@ -35,8 +36,12 @@ def parse_pcandimmimm(t): t = t[0] return (t[0] & t[1]) + t[2] -def ast_id2expr(a): - return ExprId(a, 32) +def ast_id2expr(t): + if not t in mn_sh4.regs.all_regs_ids_byname: + r = ExprId(asm_label(t)) + else: + r = mn_sh4.regs.all_regs_ids_byname[t] + return r def ast_int2expr(a): return ExprInt32(a) @@ -465,6 +470,7 @@ class instruction_sh4(instruction): class mn_sh4(cls_mn): bintree = {} + regs = regs_module num = 0 all_mn = [] all_mn_mode = defaultdict(list) diff --git a/miasm2/arch/x86/arch.py b/miasm2/arch/x86/arch.py index 238567ac..f168d9cb 100644 --- a/miasm2/arch/x86/arch.py +++ b/miasm2/arch/x86/arch.py @@ -9,6 +9,7 @@ from collections import defaultdict import miasm2.arch.x86.regs as regs_module from miasm2.arch.x86.regs import * from miasm2.ir.ir import * +from miasm2.core.asmbloc import asm_label log = logging.getLogger("x86_arch") console_handler = logging.StreamHandler() @@ -225,7 +226,7 @@ variable, operand, base_expr = gen_base_expr() def ast_id2expr(t): if not t in mn_x86.regs.all_regs_ids_byname: - r = ExprId(t) + r = ExprId(asm_label(t)) else: r = mn_x86.regs.all_regs_ids_byname[t] return r @@ -486,12 +487,11 @@ class instruction_x86(instruction): if self.additional_info.g1.value & 6 and self.name in repeat_mn: return e = self.args[0] - if isinstance(e, ExprId) and not e.name in all_regs_ids_byname: - l = symbol_pool.getby_name_create(e.name) - s = ExprId(l, e.size) - self.args[0] = s + if isinstance(e, ExprId): + if not isinstance(e.name, asm_label) and e not in all_regs_ids: + raise ValueError("ExprId must be a label or a register") elif isinstance(e, ExprInt): - ad = e.arg + int(self.offset) + self.l + ad = e.arg + int(self.offset) l = symbol_pool.getby_offset_create(ad) s = ExprId(l, e.size) self.args[0] = s @@ -558,7 +558,7 @@ class instruction_x86(instruction): return # return ExprInt32(e.arg - (self.offset + self.l)) self.args[0] = ExprInt_fromsize( - self.mode, e.arg - (self.offset + self.l)) + self.mode, e.arg - self.offset) def get_info(self, c): self.additional_info.g1.value = c.g1.value @@ -846,9 +846,9 @@ class mn_x86(cls_mn): def post_asm(self, v): return v - def encodefields(self, decoded): - v = super(mn_x86, self).encodefields(decoded) + def gen_prefix(self): + v = "" rex = 0x40 if self.g1.value is None: self.g1.value = 0 @@ -890,9 +890,15 @@ class mn_x86(cls_mn): if hasattr(self, 'no_xmm_pref'): return None v = "\x66" + v - return v + def encodefields(self, decoded): + v = super(mn_x86, self).encodefields(decoded) + prefix = self.gen_prefix() + if prefix is None: + return None + return prefix + v + def getnextflow(self, symbol_pool): raise NotImplementedError('not fully functional') @@ -2834,19 +2840,54 @@ class bs_rel_off(bs_cond_imm): # m_arg): # else: # self.l = 32 l = offsize(self.parent) + prefix = self.parent.gen_prefix() + parent_len = len(prefix) * 8 + self.parent.l + self.l + assert(parent_len % 8 == 0) - # l = self.parent.v_opmode()#self.parent.args[0].expr.size - # print 'imm enc', l, self.parent.rex_w.value + v = int(self.expr.arg - parent_len/8) + if prefix is None: + raise StopIteration + mask = ((1 << self.l) - 1) + if self.l > l: + raise StopIteration + if v != sign_ext(v & mask, self.l, l): + raise StopIteration + self.value = swap_uint(self.l, v & ((1 << self.l) - 1)) + yield True + + def decode(self, v): + v = swap_uint(self.l, v) + size = offsize(self.parent) + v = sign_ext(v, self.l, size) + v += self.parent.l + v = ExprInt_fromsize(size, v) + self.expr = v + return True + +class bs_s08(bs_rel_off): + parser = int_or_expr + + @classmethod + def flen(cls, mode, v): + return 8 + + def encode(self): + if not isinstance(self.expr, ExprInt): + raise StopIteration + arg0_expr = self.parent.args[0].expr + if self.l != 0: + l = self.l + else: + l = self.parent.v_opmode() + self.l = l + l = offsize(self.parent) v = int(self.expr.arg) mask = ((1 << self.l) - 1) - # print 'ext', self.l, l, hex(v), hex(sign_ext(v & ((1<<self.l)-1), - # self.l, l)) if self.l > l: raise StopIteration if v != sign_ext(v & mask, self.l, l): raise StopIteration self.value = swap_uint(self.l, v & ((1 << self.l) - 1)) - # print hex(self.value) yield True def decode(self, v): @@ -2855,7 +2896,6 @@ class bs_rel_off(bs_cond_imm): # m_arg): v = sign_ext(v, self.l, size) v = ExprInt_fromsize(size, v) self.expr = v - # print self.expr, repr(self.expr) return True @@ -3002,7 +3042,6 @@ class bs_msegoff(m_arg): except StopIteration: return None, None e = v[0] - print "XXX", e if e is None: log.debug('cannot fromstring int %r', s) return None, None @@ -3075,6 +3114,7 @@ sib_base = bs(l=3, cls=(bs_cond_index,), fname = "sib_base") disp = bs(l=0, cls=(bs_cond_disp,), fname = "disp") +s08 = bs(l=8, cls=(bs_s08, )) u08 = bs(l=8, cls=(x86_08, m_arg)) u07 = bs(l=7, cls=(x86_08, m_arg)) @@ -3130,8 +3170,10 @@ d_ss = bs(l=0, cls=(bs_ss, ), fname='ss') d_fs = bs(l=0, cls=(bs_fs, ), fname='fs') d_gs = bs(l=0, cls=(bs_gs, ), fname='gs') -rel_off = bs(l=0, cls=(bs_rel_off,), fname="off") -rel_off08 = bs(l=8, cls=(bs_rel_off08,), fname="off") +# Offset must be decoded in last position to have final instruction len +rel_off = bs(l=0, cls=(bs_rel_off,), fname="off", order=-1) +# Offset must be decoded in last position to have final instruction len +rel_off08 = bs(l=8, cls=(bs_rel_off08,), fname="off", order=-1) moff = bs(l=0, cls=(bs_moff,), fname="off") msegoff = bs(l=16, cls=(bs_msegoff,), fname="mseg") movoff = bs(l=0, cls=(bs_movoff,), fname="off") @@ -3737,7 +3779,7 @@ addop("prefetchnta", [bs8(0x0f), bs8(0x18)] + rmmod(d0, rm_arg_m08)) addop("push", [bs8(0xff), stk] + rmmod(d6)) addop("push", [bs("01010"), stk, reg]) -addop("push", [bs8(0x6a), rel_off08, stk]) +addop("push", [bs8(0x6a), s08, stk]) addop("push", [bs8(0x68), d_imm, stk]) addop("push", [bs8(0x0e), stk, d_cs]) addop("push", [bs8(0x16), stk, d_ss]) diff --git a/miasm2/arch/x86/regs.py b/miasm2/arch/x86/regs.py index 1bf6969d..31f55483 100644 --- a/miasm2/arch/x86/regs.py +++ b/miasm2/arch/x86/regs.py @@ -388,6 +388,10 @@ all_regs_ids = [ float_stack_ptr, mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7, + XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, + XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, + + exception_flags, ] + fltregs32_expr @@ -406,6 +410,9 @@ all_regs_ids_no_alias = [ dr0, dr1, dr2, dr3, dr4, dr5, dr6, dr7, float_stack_ptr, mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7, + XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, + XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, + exception_flags, ] + fltregs32_expr |