diff options
| author | Pierre Lalet <pierre@droids-corp.org> | 2015-02-18 20:55:26 +0100 |
|---|---|---|
| committer | Pierre Lalet <pierre@droids-corp.org> | 2015-02-18 20:55:26 +0100 |
| commit | 736befb2b6fab02e601eae392a9969ac91f2caa3 (patch) | |
| tree | 66b6208ca4ca21ac8efb3606930ffb664ecddc69 | |
| parent | 5b3589b4735024e96becb5dbd8d25de4416f7cfb (diff) | |
| parent | df19d375b8552406de77290c95ff41ef366b76c6 (diff) | |
| download | miasm-736befb2b6fab02e601eae392a9969ac91f2caa3.tar.gz miasm-736befb2b6fab02e601eae392a9969ac91f2caa3.zip | |
Merge pull request #76 from commial/pylinting
Pylinting (thanks for this work!)
| -rw-r--r-- | miasm2/analysis/debugging.py | 2 | ||||
| -rw-r--r-- | miasm2/analysis/machine.py | 2 | ||||
| -rw-r--r-- | miasm2/arch/mips32/arch.py | 427 | ||||
| -rw-r--r-- | miasm2/arch/mips32/ira.py | 4 | ||||
| -rw-r--r-- | miasm2/arch/mips32/regs.py | 8 | ||||
| -rw-r--r-- | miasm2/arch/x86/arch.py | 18 | ||||
| -rw-r--r-- | miasm2/arch/x86/sem.py | 9 | ||||
| -rw-r--r-- | miasm2/core/asmbloc.py | 52 | ||||
| -rw-r--r-- | miasm2/core/bin_stream.py | 4 | ||||
| -rw-r--r-- | miasm2/core/cpu.py | 413 | ||||
| -rw-r--r-- | miasm2/core/interval.py | 124 | ||||
| -rw-r--r-- | miasm2/core/parse_asm.py | 86 | ||||
| -rw-r--r-- | miasm2/core/utils.py | 4 | ||||
| -rw-r--r-- | miasm2/expression/simplifications_cond.py | 16 | ||||
| -rw-r--r-- | miasm2/ir/analysis.py | 2 | ||||
| -rw-r--r-- | miasm2/jitter/loader/pe.py | 8 | ||||
| -rw-r--r-- | miasm2/os_dep/linux_stdlib.py | 12 | ||||
| -rw-r--r-- | miasm2/os_dep/win_api_x86_32.py | 8 |
18 files changed, 506 insertions, 693 deletions
diff --git a/miasm2/analysis/debugging.py b/miasm2/analysis/debugging.py index 61e2ed95..57f30181 100644 --- a/miasm2/analysis/debugging.py +++ b/miasm2/analysis/debugging.py @@ -77,7 +77,7 @@ class Debugguer(object): def init_memory_breakpoint(self): "Set exception handler on EXCEPT_BREAKPOINT_INTERN" - self.myjit.exception_handler + raise NotImplementedError("Not implemented") def add_memory_breakpoint(self, addr, size, read=False, write=False): "add mem bp @[addr, addr + size], on read/write/both" diff --git a/miasm2/analysis/machine.py b/miasm2/analysis/machine.py index d714dbb9..81ef4e9e 100644 --- a/miasm2/analysis/machine.py +++ b/miasm2/analysis/machine.py @@ -51,10 +51,8 @@ class Machine(object): mn = arch.mn_armt from miasm2.arch.arm.ira import ir_a_armtb as ira elif machine_name == "sh4": - from miasm2.arch.sh4.disasm import dis_sha4 as dis_engine from miasm2.arch.sh4 import arch mn = arch.mn_sh4 - from miasm2.arch.sh4.ira import ir_a_sh4 as ira elif machine_name == "x86_16": from miasm2.arch.x86.disasm import dis_x86_16 as dis_engine from miasm2.arch.x86 import arch, jit diff --git a/miasm2/arch/mips32/arch.py b/miasm2/arch/mips32/arch.py index eb163daa..50dc1c86 100644 --- a/miasm2/arch/mips32/arch.py +++ b/miasm2/arch/mips32/arch.py @@ -2,13 +2,14 @@ #-*- coding:utf-8 -*- import logging -from pyparsing import * -from miasm2.expression.expression import * -from miasm2.core.cpu import * from collections import defaultdict + +from pyparsing import Literal, Group, Optional + +from miasm2.expression.expression import ExprMem, ExprInt, ExprInt32, ExprId from miasm2.core.bin_stream import bin_stream -import miasm2.arch.mips32.regs as regs_module -from miasm2.arch.mips32.regs import * +import miasm2.arch.mips32.regs as regs +import miasm2.core.cpu as cpu log = logging.getLogger("mips32dis") @@ -18,7 +19,7 @@ log.addHandler(console_handler) log.setLevel(logging.DEBUG) -gpregs = reg_info(regs32_str, regs32_expr) +gpregs = cpu.reg_info(regs.regs32_str, regs.regs32_expr) @@ -38,12 +39,12 @@ def deref2expr_nooff(s, l, t): raise NotImplementedError("TODO") return ExprMem(t[1]) -my_var_parser = parse_ast(ast_id2expr, ast_int2expr) -base_expr.setParseAction(my_var_parser) - +base_expr = cpu.base_expr -deref_off = Group(Optional(base_expr) + LPARENTHESIS + gpregs.parser + RPARENTHESIS).setParseAction(deref2expr) -deref_nooff = Group(LPARENTHESIS + gpregs.parser + RPARENTHESIS).setParseAction(deref2expr_nooff) +deref_off = Group(Optional(cpu.base_expr) + LPARENTHESIS + gpregs.parser + \ + RPARENTHESIS).setParseAction(deref2expr) +deref_nooff = Group(LPARENTHESIS + gpregs.parser + \ + RPARENTHESIS).setParseAction(deref2expr_nooff) deref = deref_off | deref_nooff @@ -56,7 +57,7 @@ br_1 = ['BGEZ', 'BLTZ', 'BGTZ', 'BLEZ', 'BC1T', 'BC1F'] br_2 = ['BEQ', 'BEQL', 'BNE'] -class instruction_mips32(instruction): +class instruction_mips32(cpu.instruction): delayslot = 1 def __init__(self, *args, **kargs): @@ -155,7 +156,7 @@ class instruction_mips32(instruction): e = self.args[ndx] print 'FIX', ndx, e, self.offset, self.l if self.offset is None: - raise ValueError('symbol not resolved %s' % l) + raise ValueError('symbol not resolved %s' % self.l) if not isinstance(e, ExprInt): return off = e.arg - (self.offset + self.l) @@ -171,42 +172,42 @@ class instruction_mips32(instruction): return args -class mn_mips32(cls_mn): +class mn_mips32(cpu.cls_mn): delayslot = 0 name = "mips32" - regs = regs_module + regs = regs bintree = {} num = 0 all_mn = [] all_mn_mode = defaultdict(list) all_mn_name = defaultdict(list) all_mn_inst = defaultdict(list) - pc = {'l':PC, 'b':PC} - sp = {'l':SP, 'b':SP} + pc = {'l':regs.PC, 'b':regs.PC} + sp = {'l':regs.SP, 'b':regs.SP} instruction = instruction_mips32 max_instruction_len = 4 @classmethod def getpc(cls, attrib = None): - return PC + return regs.PC @classmethod def getsp(cls, attrib = None): - return SP + return regs.SP def additional_info(self): info = additional_info() return info @classmethod - def getbits(cls, bs, attrib, start, n): + def getbits(cls, bitstream, attrib, start, n): if not n: return 0 o = 0 while n: offset = start / 8 n_offset = cls.endian_offset(attrib, offset) - c = cls.getbytes(bs, n_offset, 1) + c = cls.getbytes(bitstream, n_offset, 1) if not c: raise IOError c = ord(c) @@ -263,7 +264,7 @@ def mips32op(name, fields, args=None, alias=False): #type(name, (mn_mips32b,), dct) -class mips32_reg(reg_noarg, m_arg): +class mips32_reg(cpu.reg_noarg, cpu.m_arg): pass class mips32_gpreg(mips32_reg): @@ -271,22 +272,22 @@ class mips32_gpreg(mips32_reg): parser = reg_info.parser class mips32_fltpreg(mips32_reg): - reg_info = fltregs + reg_info = regs.fltregs parser = reg_info.parser class mips32_fccreg(mips32_reg): - reg_info = fccregs + reg_info = regs.fccregs parser = reg_info.parser -class mips32_imm(imm_noarg): - parser = base_expr +class mips32_imm(cpu.imm_noarg): + parser = cpu.base_expr class mips32_s16imm_noarg(mips32_imm): def decode(self, v): v = v & self.lmask - v = sign_ext(v, 16, 32) + v = cpu.sign_ext(v, 16, 32) self.expr = ExprInt32(v) return True @@ -296,7 +297,7 @@ class mips32_s16imm_noarg(mips32_imm): v = self.expr.arg.arg if v & 0x80000000: nv = v & ((1 << 16) - 1) - assert( v == sign_ext(nv, 16, 32)) + assert( v == cpu.sign_ext(nv, 16, 32)) v = nv self.value = v return True @@ -305,7 +306,7 @@ class mips32_soff_noarg(mips32_imm): def decode(self, v): v = v & self.lmask v <<= 2 - v = sign_ext(v, 16+2, 32) + v = cpu.sign_ext(v, 16+2, 32) self.expr = ExprInt32(v) return True @@ -315,20 +316,20 @@ class mips32_soff_noarg(mips32_imm): v = self.expr.arg.arg if v & 0x80000000: nv = v & ((1 << 16+2) - 1) - assert( v == sign_ext(nv, 16+2, 32)) + assert( v == cpu.sign_ext(nv, 16+2, 32)) v = nv self.value = v>>2 return True -class mips32_s16imm(mips32_s16imm_noarg, m_arg): +class mips32_s16imm(mips32_s16imm_noarg, cpu.m_arg): pass -class mips32_soff(mips32_soff_noarg, m_arg): +class mips32_soff(mips32_soff_noarg, cpu.m_arg): pass -class mips32_instr_index(mips32_imm, m_arg): +class mips32_instr_index(mips32_imm, cpu.m_arg): def decode(self, v): v = v & self.lmask self.expr = ExprInt32(v<<2) @@ -347,7 +348,7 @@ class mips32_instr_index(mips32_imm, m_arg): return True -class mips32_u16imm(mips32_imm, m_arg): +class mips32_u16imm(mips32_imm, cpu.m_arg): def decode(self, v): v = v & self.lmask self.expr = ExprInt32(v) @@ -361,7 +362,7 @@ class mips32_u16imm(mips32_imm, m_arg): self.value = v return True -class mips32_dreg_imm(m_arg): +class mips32_dreg_imm(cpu.m_arg): parser = deref def decode(self, v): imm = self.parent.imm.expr @@ -394,7 +395,7 @@ class mips32_dreg_imm(m_arg): assert(len(arg.args) == 2 and arg.op == '+') return "%s(%s)"%(arg.args[1], arg.args[0]) -class mips32_esize(mips32_imm, m_arg): +class mips32_esize(mips32_imm, cpu.m_arg): def decode(self, v): v = v & self.lmask self.expr = ExprInt32(v+1) @@ -408,7 +409,7 @@ class mips32_esize(mips32_imm, m_arg): self.value = v return True -class mips32_eposh(mips32_imm, m_arg): +class mips32_eposh(mips32_imm, cpu.m_arg): def decode(self, v): self.expr = ExprInt32(v-int(self.parent.epos.expr.arg)+1) return True @@ -425,60 +426,61 @@ class mips32_imm(mips32_imm): pass -class mips32_cpr(m_arg): - parser = regs_cpr0_info.parser +class mips32_cpr(cpu.m_arg): + parser = regs.regs_cpr0_info.parser def decode(self, v): index = int(self.parent.cpr0.expr.arg) << 3 index += v - self.expr = regs_cpr0_expr[index] + self.expr = regs.regs_cpr0_expr[index] return True def encode(self): e = self.expr - if not e in regs_cpr0_expr: + if not e in regs.regs_cpr0_expr: return False - index = regs_cpr0_expr.index(e) + index = regs.regs_cpr0_expr.index(e) self.value = index & 7 index >>=2 self.parent.cpr0.value = index return True -rs = bs(l=5, cls=(mips32_gpreg,)) -rt = bs(l=5, cls=(mips32_gpreg,)) -rd = bs(l=5, cls=(mips32_gpreg,)) -ft = bs(l=5, cls=(mips32_fltpreg,)) -fs = bs(l=5, cls=(mips32_fltpreg,)) -fd = bs(l=5, cls=(mips32_fltpreg,)) +rs = cpu.bs(l=5, cls=(mips32_gpreg,)) +rt = cpu.bs(l=5, cls=(mips32_gpreg,)) +rd = cpu.bs(l=5, cls=(mips32_gpreg,)) +ft = cpu.bs(l=5, cls=(mips32_fltpreg,)) +fs = cpu.bs(l=5, cls=(mips32_fltpreg,)) +fd = cpu.bs(l=5, cls=(mips32_fltpreg,)) -s16imm = bs(l=16, cls=(mips32_s16imm,)) -u16imm = bs(l=16, cls=(mips32_u16imm,)) -sa = bs(l=5, cls=(mips32_u16imm,)) -base = bs(l=5, cls=(mips32_dreg_imm,)) -soff = bs(l=16, cls=(mips32_soff,)) +s16imm = cpu.bs(l=16, cls=(mips32_s16imm,)) +u16imm = cpu.bs(l=16, cls=(mips32_u16imm,)) +sa = cpu.bs(l=5, cls=(mips32_u16imm,)) +base = cpu.bs(l=5, cls=(mips32_dreg_imm,)) +soff = cpu.bs(l=16, cls=(mips32_soff,)) -cpr0 = bs(l=5, cls=(mips32_imm,), fname="cpr0") -cpr = bs(l=3, cls=(mips32_cpr,)) +cpr0 = cpu.bs(l=5, cls=(mips32_imm,), fname="cpr0") +cpr = cpu.bs(l=3, cls=(mips32_cpr,)) -s16imm_noarg = bs(l=16, cls=(mips32_s16imm_noarg,), fname="imm", +s16imm_noarg = cpu.bs(l=16, cls=(mips32_s16imm_noarg,), fname="imm", order=-1) -hint = bs(l=5, default_val="00000") -fcc = bs(l=3, cls=(mips32_fccreg,)) +hint = cpu.bs(l=5, default_val="00000") +fcc = cpu.bs(l=3, cls=(mips32_fccreg,)) -sel = bs(l=3, cls=(mips32_u16imm,)) +sel = cpu.bs(l=3, cls=(mips32_u16imm,)) -code = bs(l=20, cls=(mips32_u16imm,)) +code = cpu.bs(l=20, cls=(mips32_u16imm,)) -esize = bs(l=5, cls=(mips32_esize,)) -epos = bs(l=5, cls=(mips32_u16imm,), fname="epos", +esize = cpu.bs(l=5, cls=(mips32_esize,)) +epos = cpu.bs(l=5, cls=(mips32_u16imm,), fname="epos", order=-1) -eposh = bs(l=5, cls=(mips32_eposh,)) +eposh = cpu.bs(l=5, cls=(mips32_eposh,)) -instr_index = bs(l=26, cls=(mips32_instr_index,)) -bs_fmt = bs_mod_name(l=5, fname='fmt', mn_mod={0x10: '.S', 0x11: '.D', 0x14: '.W', - 0x15: '.L', 0x16: '.PS'}) -class bs_cond(bs_mod_name): +instr_index = cpu.bs(l=26, cls=(mips32_instr_index,)) +bs_fmt = cpu.bs_mod_name(l=5, fname='fmt', mn_mod={0x10: '.S', 0x11: '.D', + 0x14: '.W', 0x15: '.L', + 0x16: '.PS'}) +class bs_cond(cpu.bs_mod_name): mn_mod = ['.F', '.UN', '.EQ', '.UEQ', '.OLT', '.ULT', '.OLE', '.ULE', '.SF', '.NGLE', '.SEQ', '.NGL', @@ -486,11 +488,10 @@ class bs_cond(bs_mod_name): ] def modname(self, name, f_i): - fds - return name + self.args['mn_mod'][f_i] + raise NotImplementedError("Not implemented") -class bs_cond_name(bs_divert): +class bs_cond_name(cpu.bs_divert): prio = 2 mn_mod = [['.F', '.UN', '.EQ', '.UEQ', '.OLT', '.ULT', '.OLE', '.ULE'], @@ -498,7 +499,7 @@ class bs_cond_name(bs_divert): '.LT', '.NGE', '.LE', '.NGT'] ] - def divert(self, i, candidates): + def divert(self, index, candidates): out = [] for candidate in candidates: cls, name, bases, dct, fields = candidate @@ -508,11 +509,11 @@ class bs_cond_name(bs_divert): mm = self.mn_mod[cond1.value] for value, new_name in enumerate(mm): nfields = fields[:] - s = int2bin(value, self.args['l']) + s = cpu.int2bin(value, self.args['l']) args = dict(self.args) args.update({'strbits': s}) - f = bs(**args) - nfields[i] = f + f = cpu.bs(**args) + nfields[index] = f ndct = dict(dct) ndct['name'] = name + new_name out.append((cls, new_name, bases, ndct, nfields)) @@ -520,7 +521,7 @@ class bs_cond_name(bs_divert): -class bs_cond_mod(bs_mod_name): +class bs_cond_mod(cpu.bs_mod_name): prio = 1 bs_cond = bs_cond_mod(l=4, @@ -531,162 +532,200 @@ bs_cond = bs_cond_mod(l=4, -bs_arith = bs_name(l=6, name={'ADDU':0b100001, - 'SUBU':0b100011, - 'OR':0b100101, - 'AND':0b100100, - 'SLTU':0b101011, - 'XOR':0b100110, - 'SLT':0b101010, - 'SUBU':0b100011, - 'NOR':0b100111, - 'MOVN':0b001011, - 'MOVZ':0b001010, - }) - -bs_shift = bs_name(l=6, name={'SLL':0b000000, - 'SRL':0b000010, - 'SRA':0b000011, - }) - -bs_shift1 = bs_name(l=6, name={'SLLV':0b000100, - 'SRLV':0b000110, - 'SRAV':0b000111, - }) - - -bs_arithfmt = bs_name(l=6, name={'ADD':0b000000, - 'SUB':0b000001, - 'MUL':0b000010, - 'DIV':0b000011, - }) - -bs_s_l = bs_name(l=6, name = {"SW": 0b101011, - "SH": 0b101001, - "SB": 0b101000, - "LW": 0b100011, - "LH": 0b100001, - "LB": 0b100000, - "LHU": 0b100101, - "LBU": 0b100100, - "LWL": 0b100010, - "LWR": 0b100110, - - "SWL": 0b101010, - "SWR": 0b101110, - }) - - -bs_oax = bs_name(l=6, name = {"ORI": 0b001101, - "ANDI": 0b001100, - "XORI": 0b001110, - }) - -bs_bcc = bs_name(l=5, name = {"BGEZ": 0b00001, - "BGEZL": 0b00011, - "BGEZAL": 0b10001, - "BGEZALL": 0b10011, - "BLTZ": 0b00000, - "BLTZL": 0b00010, - "BLTZAL": 0b10000, - "BLTZALL": 0b10010, - }) - - - -mips32op("addi", [bs('001000'), rs, rt, s16imm], [rt, rs, s16imm]) -mips32op("addiu", [bs('001001'), rs, rt, s16imm], [rt, rs, s16imm]) -mips32op("nop", [bs('0'*32)], alias = True) -mips32op("lui", [bs('001111'), bs('00000'), rt, u16imm]) +bs_arith = cpu.bs_name(l=6, name={'ADDU':0b100001, + 'SUBU':0b100011, + 'OR':0b100101, + 'AND':0b100100, + 'SLTU':0b101011, + 'XOR':0b100110, + 'SLT':0b101010, + 'SUBU':0b100011, + 'NOR':0b100111, + 'MOVN':0b001011, + 'MOVZ':0b001010, + }) + +bs_shift = cpu.bs_name(l=6, name={'SLL':0b000000, + 'SRL':0b000010, + 'SRA':0b000011, + }) + +bs_shift1 = cpu.bs_name(l=6, name={'SLLV':0b000100, + 'SRLV':0b000110, + 'SRAV':0b000111, + }) + + +bs_arithfmt = cpu.bs_name(l=6, name={'ADD':0b000000, + 'SUB':0b000001, + 'MUL':0b000010, + 'DIV':0b000011, + }) + +bs_s_l = cpu.bs_name(l=6, name = {"SW": 0b101011, + "SH": 0b101001, + "SB": 0b101000, + "LW": 0b100011, + "LH": 0b100001, + "LB": 0b100000, + "LHU": 0b100101, + "LBU": 0b100100, + "LWL": 0b100010, + "LWR": 0b100110, + + "SWL": 0b101010, + "SWR": 0b101110, + }) + + +bs_oax = cpu.bs_name(l=6, name = {"ORI": 0b001101, + "ANDI": 0b001100, + "XORI": 0b001110, + }) + +bs_bcc = cpu.bs_name(l=5, name = {"BGEZ": 0b00001, + "BGEZL": 0b00011, + "BGEZAL": 0b10001, + "BGEZALL": 0b10011, + "BLTZ": 0b00000, + "BLTZL": 0b00010, + "BLTZAL": 0b10000, + "BLTZALL": 0b10010, + }) + + + +mips32op("addi", [cpu.bs('001000'), rs, rt, s16imm], [rt, rs, s16imm]) +mips32op("addiu", [cpu.bs('001001'), rs, rt, s16imm], [rt, rs, s16imm]) +mips32op("nop", [cpu.bs('0'*32)], alias = True) +mips32op("lui", [cpu.bs('001111'), cpu.bs('00000'), rt, u16imm]) mips32op("oax", [bs_oax, rs, rt, u16imm], [rt, rs, u16imm]) -mips32op("arith", [bs('000000'), rs, rt, rd, bs('00000'), bs_arith], [rd, rs, rt]) -mips32op("shift1", [bs('000000'), rs, rt, rd, bs('00000'), bs_shift1], [rd, rt, rs]) +mips32op("arith", [cpu.bs('000000'), rs, rt, rd, cpu.bs('00000'), bs_arith], + [rd, rs, rt]) +mips32op("shift1", [cpu.bs('000000'), rs, rt, rd, cpu.bs('00000'), bs_shift1], + [rd, rt, rs]) -mips32op("shift", [bs('000000'), bs('00000'), rt, rd, sa, bs_shift], [rd, rt, sa]) +mips32op("shift", [cpu.bs('000000'), cpu.bs('00000'), rt, rd, sa, bs_shift], + [rd, rt, sa]) -mips32op("rotr", [bs('000000'), bs('00001'), rt, rd, sa, bs('000010')], [rd, rt, sa]) +mips32op("rotr", [cpu.bs('000000'), cpu.bs('00001'), rt, rd, sa, + cpu.bs('000010')], [rd, rt, sa]) -mips32op("mul", [bs('011100'), rs, rt, rd, bs('00000'), bs('000010')], [rd, rs, rt]) -mips32op("div", [bs('000000'), rs, rt, bs('0000000000'), bs('011010')]) +mips32op("mul", [cpu.bs('011100'), rs, rt, rd, cpu.bs('00000'), + cpu.bs('000010')], [rd, rs, rt]) +mips32op("div", [cpu.bs('000000'), rs, rt, cpu.bs('0000000000'), + cpu.bs('011010')]) mips32op("s_l", [bs_s_l, base, rt, s16imm_noarg], [rt, base]) #mips32op("mfc0", [bs('010000'), bs('00000'), rt, rd, bs('00000000'), sel]) -mips32op("mfc0", [bs('010000'), bs('00000'), rt, cpr0, bs('00000000'), cpr]) -mips32op("mfc1", [bs('010001'), bs('00000'), rt, fs, bs('00000000000')]) +mips32op("mfc0", [cpu.bs('010000'), cpu.bs('00000'), rt, cpr0, + cpu.bs('00000000'), cpr]) +mips32op("mfc1", [cpu.bs('010001'), cpu.bs('00000'), rt, fs, + cpu.bs('00000000000')]) -mips32op("ldc1", [bs('110101'), base, ft, s16imm_noarg], [ft, base]) +mips32op("ldc1", [cpu.bs('110101'), base, ft, s16imm_noarg], [ft, base]) -mips32op("mov", [bs('010001'), bs_fmt, bs('00000'), fs, fd, bs('000110')], [fd, fs]) +mips32op("mov", [cpu.bs('010001'), bs_fmt, cpu.bs('00000'), fs, fd, + cpu.bs('000110')], [fd, fs]) -mips32op("add", [bs('010001'), bs_fmt, ft, fs, fd, bs_arithfmt], [fd, fs, ft]) +mips32op("add", [cpu.bs('010001'), bs_fmt, ft, fs, fd, bs_arithfmt], + [fd, fs, ft]) -mips32op("divu", [bs('000000'), rs, rt, bs('0000000000'), bs('011011')]) -mips32op("mult", [bs('000000'), rs, rt, bs('0000000000'), bs('011000')]) -mips32op("multu", [bs('000000'), rs, rt, bs('0000000000'), bs('011001')]) -mips32op("mflo", [bs('000000'), bs('0000000000'), rd, bs('00000'), bs('010010')]) -mips32op("mfhi", [bs('000000'), bs('0000000000'), rd, bs('00000'), bs('010000')]) +mips32op("divu", [cpu.bs('000000'), rs, rt, cpu.bs('0000000000'), + cpu.bs('011011')]) +mips32op("mult", [cpu.bs('000000'), rs, rt, cpu.bs('0000000000'), + cpu.bs('011000')]) +mips32op("multu", [cpu.bs('000000'), rs, rt, cpu.bs('0000000000'), + cpu.bs('011001')]) +mips32op("mflo", [cpu.bs('000000'), cpu.bs('0000000000'), rd, + cpu.bs('00000'), cpu.bs('010010')]) +mips32op("mfhi", [cpu.bs('000000'), cpu.bs('0000000000'), rd, + cpu.bs('00000'), cpu.bs('010000')]) -mips32op("b", [bs('000100'), bs('00000'), bs('00000'), soff], alias = True) -mips32op("bne", [bs('000101'), rs, rt, soff]) -mips32op("beq", [bs('000100'), rs, rt, soff]) +mips32op("b", [cpu.bs('000100'), cpu.bs('00000'), cpu.bs('00000'), soff], + alias = True) +mips32op("bne", [cpu.bs('000101'), rs, rt, soff]) +mips32op("beq", [cpu.bs('000100'), rs, rt, soff]) -mips32op("blez", [bs('000110'), rs, bs('00000'), soff]) +mips32op("blez", [cpu.bs('000110'), rs, cpu.bs('00000'), soff]) -mips32op("bcc", [bs('000001'), rs, bs_bcc, soff]) +mips32op("bcc", [cpu.bs('000001'), rs, bs_bcc, soff]) -mips32op("bgtz", [bs('000111'), rs, bs('00000'), soff]) -mips32op("bal", [bs('000001'), bs('00000'), bs('10001'), soff], alias = True) +mips32op("bgtz", [cpu.bs('000111'), rs, cpu.bs('00000'), soff]) +mips32op("bal", [cpu.bs('000001'), cpu.bs('00000'), cpu.bs('10001'), soff], + alias = True) -mips32op("slti", [bs('001010'), rs, rt, s16imm], [rt, rs, s16imm]) -mips32op("sltiu", [bs('001011'), rs, rt, s16imm], [rt, rs, s16imm]) +mips32op("slti", [cpu.bs('001010'), rs, rt, s16imm], [rt, rs, s16imm]) +mips32op("sltiu", [cpu.bs('001011'), rs, rt, s16imm], [rt, rs, s16imm]) -mips32op("j", [bs('000010'), instr_index]) -mips32op("jal", [bs('000011'), instr_index]) -mips32op("jalr", [bs('000000'), rs, bs('00000'), rd, hint, bs('001001')]) -mips32op("jr", [bs('000000'), rs, bs('0000000000'), hint, bs('001000')]) +mips32op("j", [cpu.bs('000010'), instr_index]) +mips32op("jal", [cpu.bs('000011'), instr_index]) +mips32op("jalr", [cpu.bs('000000'), rs, cpu.bs('00000'), rd, hint, + cpu.bs('001001')]) +mips32op("jr", [cpu.bs('000000'), rs, cpu.bs('0000000000'), hint, + cpu.bs('001000')]) -mips32op("lwc1", [bs('110001'), base, ft, s16imm_noarg], [ft, base]) +mips32op("lwc1", [cpu.bs('110001'), base, ft, s16imm_noarg], [ft, base]) #mips32op("mtc0", [bs('010000'), bs('00100'), rt, rd, bs('00000000'), sel]) -mips32op("mtc0", [bs('010000'), bs('00100'), rt, cpr0, bs('00000000'), cpr]) -mips32op("mtc1", [bs('010001'), bs('00100'), rt, fs, bs('00000000000')]) +mips32op("mtc0", [cpu.bs('010000'), cpu.bs('00100'), rt, cpr0, + cpu.bs('00000000'), cpr]) +mips32op("mtc1", [cpu.bs('010001'), cpu.bs('00100'), rt, fs, + cpu.bs('00000000000')]) # XXXX TODO CFC1 -mips32op("cfc1", [bs('010001'), bs('00010'), rt, fs, bs('00000000000')]) +mips32op("cfc1", [cpu.bs('010001'), cpu.bs('00010'), rt, fs, + cpu.bs('00000000000')]) # XXXX TODO CTC1 -mips32op("ctc1", [bs('010001'), bs('00110'), rt, fs, bs('00000000000')]) +mips32op("ctc1", [cpu.bs('010001'), cpu.bs('00110'), rt, fs, + cpu.bs('00000000000')]) -mips32op("break", [bs('000000'), code, bs('001101')]) -mips32op("syscall", [bs('000000'), code, bs('001100')]) +mips32op("break", [cpu.bs('000000'), code, cpu.bs('001101')]) +mips32op("syscall", [cpu.bs('000000'), code, cpu.bs('001100')]) -mips32op("c", [bs('010001'), bs_fmt, ft, fs, fcc, bs('0'), bs('0'), bs('11'), bs_cond], [fcc, fs, ft]) +mips32op("c", [cpu.bs('010001'), bs_fmt, ft, fs, fcc, cpu.bs('0'), + cpu.bs('0'), cpu.bs('11'), bs_cond], [fcc, fs, ft]) -mips32op("bc1t", [bs('010001'), bs('01000'), fcc, bs('0'), bs('1'), soff]) -mips32op("bc1f", [bs('010001'), bs('01000'), fcc, bs('0'), bs('0'), soff]) +mips32op("bc1t", [cpu.bs('010001'), cpu.bs('01000'), fcc, cpu.bs('0'), + cpu.bs('1'), soff]) +mips32op("bc1f", [cpu.bs('010001'), cpu.bs('01000'), fcc, cpu.bs('0'), + cpu.bs('0'), soff]) -mips32op("swc1", [bs('111001'), base, ft, s16imm_noarg], [ft, base]) +mips32op("swc1", [cpu.bs('111001'), base, ft, s16imm_noarg], [ft, base]) -mips32op("cvt.d", [bs('010001'), bs_fmt, bs('00000'), fs, fd, bs('100001')], [fd, fs]) -mips32op("cvt.w", [bs('010001'), bs_fmt, bs('00000'), fs, fd, bs('100100')], [fd, fs]) -mips32op("cvt.s", [bs('010001'), bs_fmt, bs('00000'), fs, fd, bs('100000')], [fd, fs]) +mips32op("cvt.d", [cpu.bs('010001'), bs_fmt, cpu.bs('00000'), fs, fd, + cpu.bs('100001')], [fd, fs]) +mips32op("cvt.w", [cpu.bs('010001'), bs_fmt, cpu.bs('00000'), fs, fd, + cpu.bs('100100')], [fd, fs]) +mips32op("cvt.s", [cpu.bs('010001'), bs_fmt, cpu.bs('00000'), fs, fd, + cpu.bs('100000')], [fd, fs]) -mips32op("ext", [bs('011111'), rs, rt, esize, epos, bs('000000')], [rt, rs, epos, esize]) -mips32op("ins", [bs('011111'), rs, rt, eposh, epos, bs('000100')], [rt, rs, epos, eposh]) +mips32op("ext", [cpu.bs('011111'), rs, rt, esize, epos, cpu.bs('000000')], + [rt, rs, epos, esize]) +mips32op("ins", [cpu.bs('011111'), rs, rt, eposh, epos, cpu.bs('000100')], + [rt, rs, epos, eposh]) -mips32op("seb", [bs('011111'), bs('00000'), rt, rd, bs('10000'), bs('100000')], [rd, rt]) -mips32op("seh", [bs('011111'), bs('00000'), rt, rd, bs('11000'), bs('100000')], [rd, rt]) -mips32op("wsbh", [bs('011111'), bs('00000'), rt, rd, bs('00010'), bs('100000')], [rd, rt]) +mips32op("seb", [cpu.bs('011111'), cpu.bs('00000'), rt, rd, cpu.bs('10000'), + cpu.bs('100000')], [rd, rt]) +mips32op("seh", [cpu.bs('011111'), cpu.bs('00000'), rt, rd, cpu.bs('11000'), + cpu.bs('100000')], [rd, rt]) +mips32op("wsbh", [cpu.bs('011111'), cpu.bs('00000'), rt, rd, cpu.bs('00010'), + cpu.bs('100000')], [rd, rt]) -mips32op("di", [bs('010000'), bs('01011'), rt, bs('01100'), bs('00000'), bs('0'), bs('00'), bs('000')]) -mips32op("ei", [bs('010000'), bs('01011'), rt, bs('01100'), bs('00000'), bs('1'), bs('00'), bs('000')]) +mips32op("di", [cpu.bs('010000'), cpu.bs('01011'), rt, cpu.bs('01100'), + cpu.bs('00000'), cpu.bs('0'), cpu.bs('00'), cpu.bs('000')]) +mips32op("ei", [cpu.bs('010000'), cpu.bs('01011'), rt, cpu.bs('01100'), + cpu.bs('00000'), cpu.bs('1'), cpu.bs('00'), cpu.bs('000')]) -mips32op("tlbp", [bs('010000'), bs('1'), bs('0'*19), bs('001000')]) -mips32op("tlbwi", [bs('010000'), bs('1'), bs('0'*19), bs('000010')]) +mips32op("tlbp", [cpu.bs('010000'), cpu.bs('1'), cpu.bs('0'*19), + cpu.bs('001000')]) +mips32op("tlbwi", [cpu.bs('010000'), cpu.bs('1'), cpu.bs('0'*19), + cpu.bs('000010')]) diff --git a/miasm2/arch/mips32/ira.py b/miasm2/arch/mips32/ira.py index c070b4ba..f88172fb 100644 --- a/miasm2/arch/mips32/ira.py +++ b/miasm2/arch/mips32/ira.py @@ -49,8 +49,8 @@ class ir_a_mips32l(ir_mips32l, ira): #print 'TEST', l, hex(lr_val.arg), hex(l.offset + 8) #print lr_val.arg, hex(l.offset + l.l) if lr_val.arg != l.offset + 8: - fds - continue + raise ValueError("Wrong arg") + # print 'IS CALL!' lbl = bloc.get_next() new_lbl = self.gen_label() diff --git a/miasm2/arch/mips32/regs.py b/miasm2/arch/mips32/regs.py index 64df4b98..7c049cd9 100644 --- a/miasm2/arch/mips32/regs.py +++ b/miasm2/arch/mips32/regs.py @@ -1,7 +1,7 @@ #!/usr/bin/env python #-*- coding:utf-8 -*- -from miasm2.expression.expression import * +from miasm2.expression.expression import ExprId from miasm2.core.cpu import gen_reg, gen_regs @@ -53,9 +53,11 @@ regs_flt_expr, regs_flt_init, fltregs = gen_regs(regs_flt_str, globals(), sz=64) regs_fcc_expr, regs_fcc_init, fccregs = gen_regs(regs_fcc_str, globals()) -all_regs_ids = [PC, PC_FETCH, R_LO, R_HI] + gpregs_expr + regs_flt_expr + regs_fcc_expr +all_regs_ids = [PC, PC_FETCH, R_LO, R_HI] + gpregs_expr + regs_flt_expr + \ + regs_fcc_expr all_regs_ids_byname = dict([(x.name, x) for x in all_regs_ids]) -all_regs_ids_init = [PC_init, PC_FETCH_init, R_LO_init, R_HI_init] + gpregs_init + regs_flt_init + regs_fcc_init +all_regs_ids_init = [PC_init, PC_FETCH_init, R_LO_init, R_HI_init] + \ + gpregs_init + regs_flt_init + regs_fcc_init all_regs_ids_no_alias = all_regs_ids[:] regs_init = {} diff --git a/miasm2/arch/x86/arch.py b/miasm2/arch/x86/arch.py index 2e858756..c5535153 100644 --- a/miasm2/arch/x86/arch.py +++ b/miasm2/arch/x86/arch.py @@ -2564,15 +2564,15 @@ class bs_cl1(bsi, m_arg): def sib_cond(cls, mode, v): - if admode_prefix((mode, v["opmode"], v["admode"])) == 16: - return None - if v['mod'] == 0b11: - return None - elif v['rm'] == 0b100: - return cls.ll - else: - return None - return v['rm'] == 0b100 + if admode_prefix((mode, v["opmode"], v["admode"])) == 16: + return None + if v['mod'] == 0b11: + return None + elif v['rm'] == 0b100: + return cls.ll + else: + return None + return v['rm'] == 0b100 class bs_cond_scale(bs_cond): diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py index 6e22e66d..bc98baf3 100644 --- a/miasm2/arch/x86/sem.py +++ b/miasm2/arch/x86/sem.py @@ -1845,18 +1845,15 @@ def ficom(ir, instr, a, b = None): def fcomi(ir, instr, a): - # Invalid emulation - InvalidEmulation + raise NotImplementedError("Invalid emulation") def fcomip(ir, instr, a): - # Invalid emulation - InvalidEmulation + raise NotImplementedError("Invalid emulation") def fucomi(ir, instr, a): - # Invalid emulation - InvalidEmulation + raise NotImplementedError("Invalid emulation") def fucomip(ir, instr, a, b): diff --git a/miasm2/core/asmbloc.py b/miasm2/core/asmbloc.py index cb8423f6..4770b597 100644 --- a/miasm2/core/asmbloc.py +++ b/miasm2/core/asmbloc.py @@ -70,7 +70,7 @@ class asm_label: def __eq__(self, a): if isinstance(a, asm_label): - return self._hash == a._hash + return self._hash == hash(a) else: return False @@ -154,7 +154,7 @@ class asm_bloc: self.lines.append(l) def addto(self, c): - assert(type(self.bto) is set) + assert type(self.bto) is set self.bto.add(c) def split(self, offset, l): @@ -274,21 +274,21 @@ class asm_symbol_pool: """ if isinstance(obj, asm_label): if obj.name in self.s: - del(self.s[obj.name]) + del self.s[obj.name] if obj.offset is not None and obj.offset in self.s_offset: - del(self.s_offset[obj.offset]) + del self.s_offset[obj.offset] else: offset = int(obj) if offset in self.s_offset: obj = self.s_offset[offset] - del(self.s_offset[offset]) + del self.s_offset[offset] if obj.name in self.s: - del(self.s[obj.name]) + del self.s[obj.name] def del_offset(self, l=None): if l is not None: if l.offset in self.s_offset: - del(self.s_offset[l.offset]) + del self.s_offset[l.offset] l.offset = None else: self.s_offset = {} @@ -317,7 +317,7 @@ class asm_symbol_pool: if not s.name in self.s: log_asmbloc.warn('unk symb') return - del(self.s[s.name]) + del self.s[s.name] s.name = newname self.s[s.name] = s @@ -327,7 +327,7 @@ class asm_symbol_pool: if not label.name in self.s: raise ValueError('label %s not in symbol pool' % label) if not isinstance(label.offset, list) and label.offset in self.s_offset: - del(self.s_offset[label.offset]) + del self.s_offset[label.offset] label.offset = offset if not isinstance(label.offset, list): self.s_offset[label.offset] = label @@ -440,7 +440,8 @@ def dis_bloc(mnemo, pool_bin, cur_bloc, offset, job_done, symbol_pool, dst = instr.getdstflow(symbol_pool) dstn = [] for d in dst: - if isinstance(d, m2_expr.ExprId) and isinstance(d.name, asm_label): + if isinstance(d, m2_expr.ExprId) and \ + isinstance(d.name, asm_label): dstn.append(d.name) dst = dstn if (not instr.is_subcall()) or follow_call: @@ -699,7 +700,7 @@ def group_blocs(blocs): continue if c.label in groups_bloc: b += groups_bloc[c.label] - del(groups_bloc[c.label]) + del groups_bloc[c.label] groups_bloc[b[0].label] = b found_in_group = True break @@ -784,7 +785,8 @@ def gen_non_free_mapping(group_bloc, dont_erase=[]): return non_free_mapping -def resolve_symbol(group_bloc, symbol_pool, dont_erase=[], max_offset=0xFFFFFFFF): +def resolve_symbol(group_bloc, symbol_pool, dont_erase=[], + max_offset=0xFFFFFFFF): """ place all asmblocs """ @@ -824,7 +826,7 @@ def resolve_symbol(group_bloc, symbol_pool, dont_erase=[], max_offset=0xFFFFFFFF log_asmbloc.debug( "consumed %d rest: %d" % (g.total_max_l, int(tmp))) free_interval[g] = tmp - del(free_interval[x]) + del free_interval[x] symbol_pool.set_offset( g, [group_bloc[x][-1].label, group_bloc[x][-1], 1]) g.fixedblocs = True @@ -853,7 +855,7 @@ def resolve_symbol(group_bloc, symbol_pool, dont_erase=[], max_offset=0xFFFFFFFF log_asmbloc.debug( "consumed %d rest: %d" % (g.total_max_l, int(tmp))) free_interval[g] = tmp - del(free_interval[k]) + del free_interval[k] g.fixedblocs = True break @@ -910,8 +912,6 @@ def calc_symbol_offset(symbol_pool): for label in symbol_pool.items(): if label.offset is None: - # raise ValueError("symbol missing?", label) - #print "symbol missing?? %s" % label label.offset_g = None continue if not is_int(label.offset): @@ -935,7 +935,8 @@ def calc_symbol_offset(symbol_pool): s_to_use.add(l) -def asmbloc_final(mnemo, blocs, symbol_pool, symb_reloc_off=None, conservative = False): +def asmbloc_final(mnemo, blocs, symbol_pool, symb_reloc_off=None, + conservative=False): log_asmbloc.info("asmbloc_final") if symb_reloc_off is None: symb_reloc_off = {} @@ -954,7 +955,6 @@ def asmbloc_final(mnemo, blocs, symbol_pool, symb_reloc_off=None, conservative = symbols = asm_symbol_pool() for s, v in symbol_pool.s.items(): symbols.add_label(s, v.offset_g) - # print symbols # test if bad encoded relative for bloc in blocs: @@ -986,7 +986,6 @@ def asmbloc_final(mnemo, blocs, symbol_pool, symb_reloc_off=None, conservative = c, candidates = conservative_asm( mnemo, instr, symbol_reloc_off, conservative) - # print candidates for i, e in enumerate(sav_a): instr.args[i] = e @@ -1016,12 +1015,10 @@ def asmbloc_final(mnemo, blocs, symbol_pool, symb_reloc_off=None, conservative = if my_s is not None: my_symb_reloc_off[bloc.label].append(offset_i + my_s) offset_i += instr.l - assert(len(instr.data) == instr.l) + assert len(instr.data) == instr.l # we have fixed all relative values # recompute good offsets for label in symbol_pool.items(): - # if label.offset_g is None: - # fdfd symbol_pool.set_offset(label, label.offset_g) for a, b in my_symb_reloc_off.items(): @@ -1044,7 +1041,7 @@ def asm_resolve_final(mnemo, blocs, symbol_pool, dont_erase=[], for bloc in resolved_b: offset = bloc.label.offset for line in bloc.lines: - assert(line.data is not None) + assert line.data is not None patches[offset] = line.data for cur_pos in xrange(line.l): if offset + cur_pos in written_bytes: @@ -1232,10 +1229,9 @@ def bloc_merge(blocs, dont_merge=[]): # and parent has only one son if len(bp.bto) != 1: continue - """ - and will not create next loop composed of constraint_next from son to - parent - """ + # and will not create next loop composed of constraint_next from son to + # parent + path = bloc_find_path_next(blocs, blocby_label, b, bp) if path: continue @@ -1266,7 +1262,7 @@ def bloc_merge(blocs, dont_merge=[]): bp.lines += b.lines bp.bto = b.bto - del(blocs[i]) + del blocs[i] i = -1 diff --git a/miasm2/core/bin_stream.py b/miasm2/core/bin_stream.py index 19614661..6e158061 100644 --- a/miasm2/core/bin_stream.py +++ b/miasm2/core/bin_stream.py @@ -96,9 +96,9 @@ class bin_stream_str(bin_stream): class bin_stream_file(bin_stream): - def __init__(self, bin, offset=0L, shift=0): + def __init__(self, binary, offset=0L, shift=0): bin_stream.__init__(self) - self.bin = bin + self.bin = binary self.bin.seek(0, 2) self.shift = shift self.l = self.bin.tell() diff --git a/miasm2/core/cpu.py b/miasm2/core/cpu.py index ce6cf288..f8fdb4ff 100644 --- a/miasm2/core/cpu.py +++ b/miasm2/core/cpu.py @@ -4,10 +4,12 @@ import re import struct import logging -from pyparsing import * -from miasm2.expression.expression import * -from miasm2.core import asmbloc from collections import defaultdict + +import pyparsing + +import miasm2.expression.expression as m2_expr +from miasm2.core import asmbloc from miasm2.core.bin_stream import bin_stream, bin_stream_str from miasm2.core.utils import Disasm_Exception from miasm2.expression.simplifications import expr_simp @@ -18,8 +20,6 @@ console_handler.setFormatter(logging.Formatter("%(levelname)-5s: %(message)s")) log.addHandler(console_handler) log.setLevel(logging.WARN) -# size2int = {8:ExprInt8, 16:ExprInt16, 32:ExprInt32,64:ExprInt64} - class bitobj: @@ -81,9 +81,9 @@ def literal_list(l): l = l[:] l.sort() l = l[::-1] - o = Literal(l[0]) + o = pyparsing.Literal(l[0]) for x in l[1:]: - o |= Literal(x) + o |= pyparsing.Literal(x) return o @@ -118,7 +118,7 @@ def gen_reg(rname, env, sz=32): """ rnamel = rname.lower() - r = ExprId(rname, sz) + r = m2_expr.ExprId(rname, sz) reg_str = [rname] reg_expr = [r] regi = reg_info(reg_str, reg_expr) @@ -137,8 +137,8 @@ def gen_regs(rnames, env, sz=32): regs_expr = [] regs_init = [] for rname in rnames: - r = ExprId(rname, sz) - r_init = ExprId(rname+'_init', sz) + r = m2_expr.ExprId(rname, sz) + r_init = m2_expr.ExprId(rname+'_init', sz) regs_str.append(rname) regs_expr.append(r) regs_init.append(r_init) @@ -148,26 +148,23 @@ def gen_regs(rnames, env, sz=32): return regs_expr, regs_init, reginfo -LPARENTHESIS = Literal("(") -RPARENTHESIS = Literal(")") - - -# +LPARENTHESIS = pyparsing.Literal("(") +RPARENTHESIS = pyparsing.Literal(")") def int2expr(t): v = t[0] - return (ExprInt, v) + return (m2_expr.ExprInt, v) def parse_op(t): v = t[0] - return (ExprOp, v) + return (m2_expr.ExprOp, v) def parse_id(t): v = t[0] - return (ExprId, v) + return (m2_expr.ExprId, v) def ast_parse_op(t): @@ -175,14 +172,14 @@ def ast_parse_op(t): return t[0] if len(t) == 2: if t[0] in ['-', '+', '!']: - return ExprOp(t[0], t[1]) + return m2_expr.ExprOp(t[0], t[1]) if len(t) == 3: args = [t[0], t[2]] if t[1] == '-': # a - b => a + (-b) t[1] = '+' t[2] = - t[2] - return ExprOp(t[1], t[0], t[2]) + return m2_expr.ExprOp(t[1], t[0], t[2]) t = t[::-1] while len(t) >= 3: o1, op, o2 = t.pop(), t.pop(), t.pop() @@ -190,7 +187,7 @@ def ast_parse_op(t): # a - b => a + (-b) op = '+' o2 = - o2 - e = ExprOp(op, o1, o2) + e = m2_expr.ExprOp(op, o1, o2) t.append(e) if len(t) != 1: raise NotImplementedError('strange op') @@ -198,20 +195,20 @@ def ast_parse_op(t): def ast_id2expr(a): - return ExprId(a, 32) + return m2_expr.ExprId(a, 32) def ast_int2expr(a): - return ExprInt32(a) + return m2_expr.ExprInt32(a) def ast_raw2expr(a, my_id2expr, my_int2expr): assert(isinstance(a, tuple)) - if a[0] is ExprId: + if a[0] is m2_expr.ExprId: e = my_id2expr(a[1]) - elif a[0] is ExprInt: + elif a[0] is m2_expr.ExprInt: e = my_int2expr(a[1]) - elif a[0] is ExprOp: + elif a[0] is m2_expr.ExprOp: out = [] for x in a[1]: if isinstance(x, tuple): @@ -225,11 +222,11 @@ def ast_raw2expr(a, my_id2expr, my_int2expr): def ast_get_ids(a): assert(isinstance(a, tuple)) - if a[0] is ExprId: + if a[0] is m2_expr.ExprId: return set([a[1]]) - elif a[0] is ExprInt: + elif a[0] is m2_expr.ExprInt: return set() - elif a[0] is ExprOp: + elif a[0] is m2_expr.ExprOp: out = set() for x in a[1]: if isinstance(x, tuple): @@ -240,9 +237,9 @@ def ast_get_ids(a): def _extract_ast_core(a): assert(isinstance(a, tuple)) - if a[0] in [ExprInt, ExprId]: + if a[0] in [m2_expr.ExprInt, m2_expr.ExprId]: return a - elif a[0] is ExprOp: + elif a[0] is m2_expr.ExprOp: out = [] for x in a[1]: if isinstance(x, tuple): @@ -256,16 +253,14 @@ def _extract_ast_core(a): def extract_ast_core(v, my_id2expr, my_int2expr): ast_tokens = _extract_ast_core(v) ids = ast_get_ids(ast_tokens) - # print 'IDS', ids ids_expr = [my_id2expr(x) for x in ids] - # print 'IDS_expr', ids_expr sizes = set([i.size for i in ids_expr]) - # print "SIZE", sizes + if len(sizes) == 0: pass elif len(sizes) == 1: size = sizes.pop() - my_int2expr = lambda x: ExprInt_fromsize(size, x) + my_int2expr = lambda x: m2_expr.ExprInt_fromsize(size, x) else: raise ValueError('multiple sizes in ids') e = ast_raw2expr(ast_tokens, my_id2expr, my_int2expr) @@ -281,7 +276,7 @@ class parse_ast: def __call__(self, v): v = v[0] - if isinstance(v, Expr): + if isinstance(v, m2_expr.Expr): return v return self.extract_ast_core(v, self.id2expr, self.int2expr) @@ -291,34 +286,42 @@ def neg_int(t): return x -integer = Word(nums).setParseAction(lambda s, l, t: int(t[0])) -hex_int = Combine(Literal('0x') + Word(hexnums)).setParseAction( - lambda s, l, t: int(t[0], 16)) +integer = pyparsing.Word(pyparsing.nums).setParseAction(lambda _a, _b, t: + int(t[0])) +hex_word = pyparsing.Literal('0x') + pyparsing.Word(pyparsing.hexnums) +hex_int = pyparsing.Combine(hex_word).setParseAction(lambda _a, _b, t: + int(t[0], 16)) # str_int = (Optional('-') + (hex_int | integer)) str_int_pos = (hex_int | integer) -str_int_neg = (Suppress('-') + (hex_int | integer)).setParseAction(neg_int) +str_int_neg = (pyparsing.Suppress('-') + \ + (hex_int | integer)).setParseAction(neg_int) str_int = str_int_pos | str_int_neg str_int.setParseAction(int2expr) -logicop = oneOf('& | ^ >> << <<< >>>') -signop = oneOf('+ -') -multop = oneOf('* / %') -plusop = oneOf('+ -') +logicop = pyparsing.oneOf('& | ^ >> << <<< >>>') +signop = pyparsing.oneOf('+ -') +multop = pyparsing.oneOf('* / %') +plusop = pyparsing.oneOf('+ -') def gen_base_expr(): - variable = Word(alphas + "_$.", alphanums + "_") + variable = pyparsing.Word(pyparsing.alphas + "_$.", + pyparsing.alphanums + "_") variable.setParseAction(parse_id) operand = str_int | variable - base_expr = operatorPrecedence(operand, - [("!", 1, opAssoc.RIGHT, parse_op), - (logicop, 2, opAssoc.RIGHT, parse_op), - (signop, 1, opAssoc.RIGHT, parse_op), - (multop, 2, opAssoc.LEFT, parse_op), - (plusop, 2, opAssoc.LEFT, parse_op), ] - ) + base_expr = pyparsing.operatorPrecedence(operand, + [("!", 1, pyparsing.opAssoc.RIGHT, parse_op), + (logicop, 2, pyparsing.opAssoc.RIGHT, + parse_op), + (signop, 1, pyparsing.opAssoc.RIGHT, + parse_op), + (multop, 2, pyparsing.opAssoc.LEFT, + parse_op), + (plusop, 2, pyparsing.opAssoc.LEFT, + parse_op), + ]) return variable, operand, base_expr @@ -327,9 +330,6 @@ variable, operand, base_expr = gen_base_expr() my_var_parser = parse_ast(ast_id2expr, ast_int2expr) base_expr.setParseAction(my_var_parser) -# - - default_prio = 0x1337 @@ -357,11 +357,7 @@ class bs(object): def __init__(self, strbits=None, l=None, cls=None, fname=None, order=0, flen=None, **kargs): if fname is None: - # fname = hex(id((strbits, l, cls, fname, order, flen, kargs))) - # fname = hex(id((strbits, l, fname, order, flen))) - # print str((strbits, l, cls, fname, order, flen, kargs)) fname = hex(id(str((strbits, l, cls, fname, order, flen, kargs)))) - # print fname if strbits is None: strbits = "" # "X"*l elif l is None: @@ -388,8 +384,6 @@ class bs(object): fmask |= 1 lmask = (1 << l) - 1 # gen conditional field - # if flen is None: - # flen = lambda mode, v:l if cls: for b in cls: if 'flen' in b.__dict__: @@ -429,7 +423,6 @@ class bs(object): # bsi added at end of list # used to use first function of added class bases += [bsi] - # new_c = type(c_name, tuple(bases), {}) k = c_name, tuple(bases) if k in self.all_new_c: new_c = self.all_new_c[k] @@ -485,7 +478,6 @@ class bsi(object): return True def encode(self): - # self.value = v&self.lmask return True def clone(self): @@ -507,7 +499,7 @@ class bsi(object): l = [self.strbits, self.l, self.cls, self.fname, self.order, self.lmask, self.fbits, self.fmask, self.value] # + kargs - # l = [self.value] + return hash(tuple(l)) @@ -567,9 +559,7 @@ class bs_mod_name(bs_divert): f = bs(**args) nfields[i] = f ndct = dict(dct) - # new_name = ndct['name'] + new_name ndct['name'] = self.modname(ndct['name'], value) - # ndct['name'] = new_name out.append((cls, new_name, bases, ndct, nfields)) return out @@ -584,7 +574,6 @@ class bs_cond(bsi): class bs_swapargs(bs_divert): def divert(self, i, candidates): - # print candidates out = [] for cls, name, bases, dct, fields in candidates: # args not permuted @@ -602,7 +591,6 @@ class bs_swapargs(bs_divert): a = ap.pop(0) b = ap.pop(0) ndct['args_permut'] = [b, a] + ap - # print ndct['args_permut'] # gen fix field f = gen_bsint(1, self.args['l'], self.args) nfields[i] = f @@ -728,7 +716,6 @@ def factor_one_bit(tree): if len(tree) == 1: return tree for k, v in tree.items(): - # print k, v if k == "mn": new_keys[k] = v continue @@ -742,7 +729,6 @@ def factor_one_bit(tree): nfbits = fbits & ((1 << (l - 1)) - 1) ck = 1, cfmask, cfbits, None, flen nk = l - 1, nfmask, nfbits, fname, flen - # print ck if nk in new_keys[ck]: raise NotImplementedError('not fully functional') new_keys[ck][nk] = v @@ -824,8 +810,6 @@ def graph_tree(tree): digraph G { """ for a, b in nodes: - # print a, id(a) - # print b, id(b) if b == 'mn': continue out += "%s -> %s;\n" % (id(a), id(b)) @@ -838,13 +822,7 @@ def add_candidate_to_tree(tree, c): for f in c.fields: if f.l == 0: continue - # print len(bits), f.l - # if f.flen: - # pass - # print f node = f.l, f.fmask, f.fbits, f.fname, f.flen - # node = f.strbits, f.l, f.cls, f.fname, f.order, f.lmask, f.fbits, - # f.fmask, f.value#, tuple(f.kargs.items()) if not node in branch: branch[node] = {} @@ -878,10 +856,8 @@ class metamn(type): if name == "cls_mn" or name.startswith('mn_'): return type.__new__(mcs, name, bases, dct) alias = dct.get('alias', False) - # fields = [bm_cond]+dct['fields'] + fields = bases[0].mod_fields(dct['fields']) - # print 'f1', dct['fields'] - # print 'f2', fields if not 'name' in dct: dct["name"] = bases[0].getmn(name) if 'args' in dct: @@ -901,9 +877,7 @@ class metamn(type): f_ordered.sort(key=lambda x: (x[1].prio, x[0])) candidates = bases[0].gen_modes(mcs, name, bases, dct, fields) for i, fc in f_ordered: - # print fc, isinstance(fc, bs_divert) if isinstance(fc, bs_divert): - # print 'iiii', fc candidates = fc.divert(i, candidates) for cls, name, bases, dct, fields in candidates: ndct = dict(dct) @@ -917,10 +891,6 @@ class metamn(type): bases[0].num += 1 bases[0].all_mn.append(c) mode = dct['mode'] - # print 'add mnemo', c.name, c.mode, len(bases[0].all_mn_mode[mode]) - # print fields - # if 'args_permut' in dct: - # print dct['args_permut'] bases[0].all_mn_mode[mode].append(c) bases[0].all_mn_name[c.name].append(c) i = c() @@ -935,10 +905,7 @@ class metamn(type): raise ValueError('f is not bsi') if f.l == 0: continue - # if f.fmask: o += f.strbits - # print o, len(o) - # fd return c @@ -957,10 +924,8 @@ class instruction(object): def __str__(self): o = "%-10s " % self.name args = [] - #args_str = self.args_str - #for arg, arg_str in zip(self.args, args_str): for i, arg in enumerate(self.args): - if not isinstance(arg, Expr): + if not isinstance(arg, m2_expr.Expr): raise ValueError('zarb arg type') x = self.arg2str(arg, pos = i) args.append(x) @@ -968,7 +933,7 @@ class instruction(object): return o def get_asm_offset(self, x): - return ExprInt_from(x, self.offset) + return m2_expr.ExprInt_from(x, self.offset) def resolve_args_with_symbols(self, symbols=None): if symbols is None: @@ -977,7 +942,7 @@ class instruction(object): for a in self.args: e = a # try to resolve symbols using symbols (0 for default value) - ids = get_expr_ids(e) + ids = m2_expr.get_expr_ids(e) fixed_ids = {} for x in ids: if isinstance(x.name, asmbloc.asm_label): @@ -994,20 +959,18 @@ class instruction(object): continue if symbols[name].offset is None: default_size = self.get_symbol_size(x, symbols) - value = ExprInt_fromsize(default_size, 0) # default value + # default value + value = m2_expr.ExprInt_fromsize(default_size, 0) else: size = x.size if size is None: default_size = self.get_symbol_size(x, symbols) size = default_size - value = ExprInt_fromsize(size, symbols[name].offset) + value = m2_expr.ExprInt_fromsize(size, symbols[name].offset) fixed_ids[x] = value e = e.replace_expr(fixed_ids) - # print 'replaced e', e, fixed_ids e = expr_simp(e) - # print 'replaced e simp', e, fixed_ids args_out.append(e) - # print "args out", [str(x) for x in args_out] return args_out def get_info(self, c): @@ -1033,39 +996,30 @@ class cls_mn(object): bs_l = bs.getlen() else: bs_l = len(bs) - # print fname_values for fname_values, branch, offset_b in todo: (l, fmask, fbits, fname, flen), vals = branch cpt += 1 - # print bvalo, 'len', l, fmask, fbits, fname, flen, 'TTT', bs_l * 8, offset_b, l + if flen is not None: - # print 'flen' l = flen(attrib, fname_values) - # print 'len', fname, l if l is not None: - # print fname, hex(bs_l), l - # print hex(offset_b) try: v = cls.getbits(bs, attrib, offset_b, l) except IOError: # Raised if offset is out of bound continue - # print 'TEST', bval, fname, offset_b, cpt, (l, fmask, fbits), - # hex(v), hex(v & fmask), hex(fbits), v & fmask == fbits offset_b += l if v & fmask != fbits: continue if fname is not None and not fname in fname_values: - # print "YY", fname_values, fname, bval fname_values[fname] = v - # print vals for nb, v in vals.items(): if 'mn' in nb: candidates.update(v) else: todo.append((dict(fname_values), (nb, v), offset_b)) - candidates = [c for c in candidates] # if c.attrib == attrib] + candidates = [c for c in candidates] if not candidates: raise Disasm_Exception('cannot disasm (guess) at %X' % offset) @@ -1074,17 +1028,12 @@ class cls_mn(object): def reset_class(self): for f in self.fields_order: if f.strbits and isbin(f.strbits): - # print 'a', f.value = int(f.strbits, 2) elif 'default_val' in f.kargs: - # print 'b', f.value = int(f.kargs['default_val'], 2) else: - # print 'c', f.value = None - # print "reset", f.fname, f.value if f.fname: - # print 'SET asm', f.fname setattr(self, f.fname, f) def init_class(self): @@ -1101,11 +1050,8 @@ class cls_mn(object): if isinstance(f, m_arg): args.append(f) - # print f, fc.fname if f.fname: - # print 'SET asm', f.fname setattr(self, f.fname, f) - # print args if hasattr(self, 'args_permut'): args = [args[self.args_permut[i]] for i in xrange(len(self.args_permut))] @@ -1145,18 +1091,13 @@ class cls_mn(object): def dis(cls, bs_o, mode_o = None, offset=0): if not isinstance(bs_o, bin_stream): bs_o = bin_stream_str(bs_o) - loggg = False - # bs_o == 'fg\x11\x90\x00\x00'#False#'\x48\x15\x44\x33\x22\x11'==bs_o - # print 'disfunc', repr(bs_o) + offset_o = offset - # print 'DIS', hex(offset), mode_o#repr(bs_o.bin) pre_dis_info, bs, mode, offset, prefix_len = cls.pre_dis( bs_o, mode_o, offset) candidates = cls.guess_mnemo(bs, mode, pre_dis_info, offset) - # print 'guess', repr(v), mode, prefix.rex_w out = [] out_c = [] - # print 'DIS CAND', len(candidates), mode if hasattr(bs, 'getlen'): bs_l = bs.getlen() else: @@ -1164,54 +1105,36 @@ class cls_mn(object): alias = False for c in candidates: - # print 'RRR' - if loggg: - print "*" * 40, mode, c.mode - print c.fields - # c.mode_o = mode_o - # off = c.parse_prefix(mode_o, v) - # bits = bin_stream(v)#[:c.mn_len/8]) - - # c = c() - # c.init_class() + log.debug("*" * 40, mode, c.mode) + log.debug(c.fields) + c = cls.all_mn_inst[c][0] - # c.init_class() + c.reset_class() c.mode = mode - # for f in c.fields_order: print f.is_present - if not c.add_pre_dis_info(pre_dis_info): # = prefix#cls.mnprefix() - continue - # print "zz", c.rex_w.value - """ - if prefix.opmode != c.mp[1]: + if not c.add_pre_dis_info(pre_dis_info): continue - if prefix.admode != c.mp[2]: - continue - """ args = [] todo = {} getok = True fname_values = dict(pre_dis_info) offset_b = offset * 8 - # print pre_dis_info + total_l = 0 for i, f in enumerate(c.fields_order): - # print 'XX', i, f, id(f) - # print 'ZZ', c.rex_x.value if f.flen is not None: l = f.flen(mode, fname_values) else: l = f.l - # print 'len', l - # print "zz", c.rex_w, c.rex_w.value if l is not None: total_l += l f.l = l f.is_present = True - if loggg: - print "FIELD", f.__class__, f.fname, offset_b, l + log.debug("FIELD %s %s %s %s" % (f.__class__, + f.fname, + offset_b, l)) if bs_l * 8 - offset_b < l: getok = False break @@ -1224,19 +1147,12 @@ class cls_mn(object): f.is_present = False todo[i] = None - # print "decode", id(f), f.fname, - # print "l", l, "off", offset_b, "v", todo[i] - # print "zzz", c.rex_w, c.rex_w.value - if not getok: continue - # print 'PRIOdec', [(x[0], x[1].order) for x in c.to_decode] for i in c.to_decode: f = c.fields_order[i] if f.is_present: - # print "zz", f.fname, f.is_present, c.rex_w.value, - # c.rex_b.value, c.rex_x.value ret = f.decode(todo[i]) if not ret: log.debug("cannot decode %r" % (f)) @@ -1246,7 +1162,7 @@ class cls_mn(object): continue for a in c.args: a.expr = expr_simp(a.expr) - # print offset, offset_o, total_l + c.l = prefix_len + total_l / 8 c.b = cls.getbytes(bs, offset, total_l / 8) c.offset = offset_o @@ -1260,7 +1176,6 @@ class cls_mn(object): instr.b = cls.getbytes(bs, offset, total_l / 8) instr.offset = offset_o instr.get_info(c) - # instr = c.post_dis() if c.alias: alias = True out.append(instr) @@ -1276,10 +1191,6 @@ class cls_mn(object): if o.alias: return out[i] raise NotImplementedError('not fully functional') - # for xx in out: - # print xx - # if xx.name == "ADC": - # pass return out[0] @classmethod @@ -1289,25 +1200,15 @@ class cls_mn(object): if not name: raise ValueError('cannot find name', s) name = name[0] - # print "mnemo_name", name + if not name in cls.all_mn_name: raise ValueError('unknown name', name) - clist = [x for x in cls.all_mn_name[name]] # if x.mode == mode] + clist = [x for x in cls.all_mn_name[name]] out = [] out_args = [] parsers = defaultdict(dict) - # print 'ASM CAND', len(clist), name for cc in clist: - #""" - # c = cc() - # c.init_class() - #""" - """ - c = cls.all_mn_inst[cc][0] - c.reset_class() - c.mode = mode - """ for c in cls.get_cls_instance(cc, mode): args_expr = [] args_str = s[len(name):].strip(' ') @@ -1318,7 +1219,6 @@ class cls_mn(object): for i, f in enumerate(c.args): start_i = len_o - len(args_str) - # print i, "will parse", repr(args_str) if type(f.parser) == tuple: parser = f.parser else: @@ -1328,9 +1228,7 @@ class cls_mn(object): continue try: total_scans += 1 - # print type(p) v, start, stop = p.scanString(args_str).next() - # print "pp", args_str, v, start, stop except StopIteration: v, start, stop = [None], None, None if start != 0: @@ -1338,16 +1236,12 @@ class cls_mn(object): parsers[(i, start_i)][p] = v[0], start, stop start, stop = f.fromstring(args_str, parsers[(i, start_i)]) - # print args_str, start, stop#, f.expr - # if start is not None: print f.expr if start != 0: log.debug("cannot fromstring %r" % (args_str)) cannot_parse = True - # print "cannot_parse1" break if f.expr is None: raise NotImplementedError('not fully functional') - # print "f expr", repr(f.expr) f.expr = expr_simp(f.expr) args_expr.append(f.expr) a = args_str[start:stop] @@ -1356,21 +1250,10 @@ class cls_mn(object): args_str = args_str[1:] args_str = args_str.strip(' ') if args_str: - # print "cannot_parse", repr(args_str) - cannot_parse = True - if cannot_parse: - continue - # print [x for x in c.args] - # print [str(x) for x in c.args] - """ - try: - c.value() - except Exception, e: - log.debug("cannot encode %r\n%s"%(e, traceback.format_exc())) cannot_parse = True if cannot_parse: continue - """ + out.append(c) out_args.append(args_expr) break @@ -1384,21 +1267,6 @@ class cls_mn(object): instr = cls.instruction(c.name, mode, c_args, additional_info=c.additional_info()) - # instruction(name, attrib, args, args_str, additional_info): - # c = c() - # c.init_class() - # re parse instruction - """ - args_str = s[len(name):].strip(' ') - for i, f in enumerate(c.args): - if isinstance(f, m_arg): - start, stop = f.fromstring(args_str) - args_str = args_str[stop:].strip(' ') - if args_str.startswith(','): - args_str = args_str[1:] - args_str = args_str.strip(' ') - """ - return instr def dup_info(self, infos): @@ -1417,71 +1285,29 @@ class cls_mn(object): @classmethod def asm(cls, instr, symbols=None): - # t = time.time() """ Re asm instruction by searching mnemo using name and args. We then can modify args and get the hex of a modified instruction """ clist = cls.all_mn_name[instr.name] - clist = [x for x in clist] # if x.mode == instr.mode] - # print 'ASM CAN', len(clist) + clist = [x for x in clist] vals = [] candidates = [] - # print "resolve" args = instr.resolve_args_with_symbols(symbols) - # print "ok", [str(x) for x in args] - """ - args = [] - for i, f in enumerate(cls.args): - e = f.expr - # try to resolve symbols using symbols (0 for default value) - if symbols: - #print 'origine', e - ids = get_expr_ids(e) - fixed_ids = {} - for x in ids: - if not x.name in symbols: - #print 'not IN', x - continue - if symbols[x.name].offset is None: - value = ExprInt32(0) # default value - else: - value = ExprInt_fromsize(x.size, symbols[x.name].offset) - fixed_ids[x] = value - e = e.replace_expr(fixed_ids) - #print 'replaced e', e, fixed_ids - e = expr_simp(e) - #print 'replaced e simp', e, fixed_ids - args.append(e) - """ + for cc in clist: - # if cc.mode != cls.mode: - # continue - """ - c = c() - c.init_class() - """ + for c in cls.get_cls_instance( cc, instr.mode, instr.additional_info): - # c = cls.all_mn_inst[cc][0] - # c = cc() - # c.init_class() - cannot_parse = False if len(c.args) != len(instr.args): continue - # print c.mode, c.mp, c.fields[6:] - # print "eee", c.fields - # print [str(x.expr) for x in cls.args] + # only fix args expr for i in xrange(len(c.args)): c.args[i].expr = args[i] - # print 'ARGS', [str(x) for x in args] - # for a in c.args: - # print a.expr, - # print - # print instr.mode + v = c.value(instr.mode) if not v: log.debug("cannot encode %r" % (c)) @@ -1495,18 +1321,8 @@ class cls_mn(object): (instr.name, [str(x) for x in instr.args])) if len(vals) != 1: log.debug('asm multiple args ret default') - # raise ValueError("cannot parse %r (%d cand)"%(s, len(out))) - """ - for x in out: - print repr(x.value()) - print [str(a.expr) for a in x.args] - """ - vals = cls.filter_asm_candidates(instr, candidates) - # vals = list(set(vals)) - # vals.sort(key=lambda x:len(x)) - # dt = time.time() - t - # print 'TIME', dt, str(cls) + vals = cls.filter_asm_candidates(instr, candidates) return vals @classmethod @@ -1518,36 +1334,25 @@ class cls_mn(object): return o def value(self, mode): - # print 'PRIOenc', [(x, self.fields_order[x].order) for x in - # self.to_decode[::-1]] todo = [(0, [(x, self.fields_order[x]) for x in self.to_decode[::-1]])] - # print todo + result = [] done = [] cpt = 0 - # print 'VALUE'#, self.fields[6:] while todo: index, to_decode = todo.pop() # TEST XXX for i, f in to_decode: setattr(self, f.fname, f) - # print 'todo:', len(todo), index, to_decode - # print "OOOOOOO" - # if (index, hash(tuple(to_decode))) in done: if (index, [x[1].value for x in to_decode]) in done: - # print 'skip', to_decode continue done.append((index, [x[1].value for x in to_decode])) - # done.append((index, to_decode)) cpt += 1 can_encode = True for i, f in to_decode[index:]: - # print 'before', f.value, repr(f) ret = f.encode() - # print 'encode', len(todo), index, f.fname, f.value, f.l, ret - # print 'ret', ret if not ret: log.debug('cannot encode %r' % f) can_encode = False @@ -1556,7 +1361,6 @@ class cls_mn(object): if ret is True: continue - # print ret, index gcpt = 0 for i in ret: gcpt += 1 @@ -1570,13 +1374,12 @@ class cls_mn(object): o.append((p, fnew)) todo.append((index, o)) can_encode = False - # print 'gcpt', gcpt + break if not can_encode: continue result.append(to_decode) - # print 'CPT', cpt - # print "HEX", len(result), result + return self.decoded2bytes(result) def encodefields(self, decoded): @@ -1587,8 +1390,7 @@ class cls_mn(object): if f.value is None: continue bits.putbits(f.value, f.l) - # if f.l: - # print f.l, hex(f.value), len(bits.bits), bits.bits + xx = bits.tostring() return bits.tostring() @@ -1599,7 +1401,7 @@ class cls_mn(object): out = [] for decoded in result: decoded.sort() - # print [f.value for p, f in decoded] + o = self.encodefields(decoded) if o is None: continue @@ -1615,7 +1417,8 @@ class cls_mn(object): args = [] for arg in self.args: # XXX todo test - if not (isinstance(arg, Expr) or isinstance(arg.expr, Expr)): + if not (isinstance(arg, m2_expr.Expr) or + isinstance(arg.expr, m2_expr.Expr)): raise ValueError('zarb arg type') x = str(arg) args.append(x) @@ -1626,7 +1429,8 @@ class cls_mn(object): args = [] for arg in self.args: # XXX todo test - if not (isinstance(arg, Expr) or isinstance(arg.expr, Expr)): + if not (isinstance(arg, m2_expr.Expr) or + isinstance(arg.expr, m2_expr.Expr)): raise ValueError('zarb arg type') x = str(arg) args.append(x) @@ -1641,10 +1445,10 @@ class cls_mn(object): dst = self.getdstflow(symbol_pool) args = [] for d in dst: - if isinstance(d, ExprInt): + if isinstance(d, m2_expr.ExprInt): l = symbol_pool.getby_offset_create(int(d.arg)) - # print l - a = ExprId(l.name, d.size) + + a = m2_expr.ExprId(l.name, d.size) else: a = d args.append(a) @@ -1655,21 +1459,18 @@ class cls_mn(object): class imm_noarg(object): - # parser = str_int intsize = 32 intmask = (1 << intsize) - 1 - # expr2int = lambda self,x:int(self.expr.arg&self.lmask) def int2expr(self, v): if (v & ~self.intmask) != 0: return None - return ExprInt_fromsize(self.intsize, v) + return m2_expr.ExprInt_fromsize(self.intsize, v) def expr2int(self, e): - if not isinstance(e, ExprInt): + if not isinstance(e, m2_expr.ExprInt): return None v = int(e.arg) - # print "testimm2", hex(v), hex(self.intmask) if v & ~self.intmask != 0: return None return v @@ -1684,11 +1485,11 @@ class imm_noarg(object): return None, None if e is None: return None, None - # print 'fromstring', hex(e), self.int2expr - assert(isinstance(e, Expr)) + + assert(isinstance(e, m2_expr.Expr)) if isinstance(e, tuple): self.expr = self.int2expr(e[1]) - elif isinstance(e, Expr): + elif isinstance(e, m2_expr.Expr): self.expr = e else: raise TypeError('zarb expr') @@ -1726,19 +1527,19 @@ class imm_noarg(object): class imm08_noarg(object): - int2expr = lambda self, x: ExprInt08(x) + int2expr = lambda self, x: m2_expr.ExprInt08(x) class imm16_noarg(object): - int2expr = lambda self, x: ExprInt16(x) + int2expr = lambda self, x: m2_expr.ExprInt16(x) class imm32_noarg(object): - int2expr = lambda self, x: ExprInt32(x) + int2expr = lambda self, x: m2_expr.ExprInt32(x) class imm64_noarg(object): - int2expr = lambda self, x: ExprInt64(x) + int2expr = lambda self, x: m2_expr.ExprInt64(x) class int32_noarg(imm_noarg): @@ -1752,7 +1553,7 @@ class int32_noarg(imm_noarg): return True def encode(self): - if not isinstance(self.expr, ExprInt): + if not isinstance(self.expr, m2_expr.ExprInt): return False v = int(self.expr.arg) if sign_ext(v & self.lmask, self.l, self.intsize) != v: diff --git a/miasm2/core/interval.py b/miasm2/core/interval.py index cd2a793e..d76cbd15 100644 --- a/miasm2/core/interval.py +++ b/miasm2/core/interval.py @@ -1,59 +1,62 @@ -INT_EQ = 0 -INT_B_IN_A = 1 -INT_A_IN_B = -1 -INT_DISJOIN = 2 -INT_JOIN = 3 -INT_JOIN_AB = 4 -INT_JOIN_BA = 5 - -# 0 => eq -# 1 => b in a -# -1 => a in b -# 2 => disjoin -# 3 => join -# 4 => join a,b touch -# 5 => join b,a touch - - -def cmp_interval(a, b): - if a == b: +INT_EQ = 0 # Equivalent +INT_B_IN_A = 1 # B in A +INT_A_IN_B = -1 # A in B +INT_DISJOIN = 2 # Disjoint +INT_JOIN = 3 # Overlap +INT_JOIN_AB = 4 # B starts at the end of A +INT_JOIN_BA = 5 # A starts at the end of B + + +def cmp_interval(inter1, inter2): + """Compare @inter1 and @inter2 and returns the associated INT_* case + @inter1, @inter2: interval instance + """ + if inter1 == inter2: return INT_EQ - a1, a2 = a - b1, b2 = b - if a1 <= b1 and a2 >= b2: - return INT_B_IN_A - if b1 <= a1 and b2 >= a2: - return INT_A_IN_B - if a2 + 1 == b1: - return INT_JOIN_AB - if b2 + 1 == a1: - return INT_JOIN_BA - if a1 > b2 + 1 or b1 > a2 + 1: - return INT_DISJOIN - return INT_JOIN - -# interval is: [a, b] - - -class interval: - - def __init__(self, a=None): - if a is None: - a = [] - if isinstance(a, interval): - a = a.intervals + + inter1_start, inter1_stop = inter1 + inter2_start, inter2_stop = inter2 + result = INT_JOIN + if inter1_start <= inter2_start and inter1_stop >= inter2_stop: + result = INT_B_IN_A + if inter2_start <= inter1_start and inter2_stop >= inter1_stop: + result = INT_A_IN_B + if inter1_stop + 1 == inter2_start: + result = INT_JOIN_AB + if inter2_stop + 1 == inter1_start: + result = INT_JOIN_BA + if inter1_start > inter2_stop + 1 or inter2_start > inter1_stop + 1: + result = INT_DISJOIN + return result + + +class interval(object): + """Stands for intervals with integer bounds + + Offers common methods to work with interval""" + + def __init__(self, bounds=None): + """Instance an interval object + @bounds: (optional) list of (int, int) and/or interval instance + """ + if bounds is None: + bounds = [] + elif isinstance(bounds, interval): + bounds = bounds.intervals self.is_cannon = False - self.intervals = a + self.intervals = bounds self.cannon() def __iter__(self): - for x in self.intervals: - yield x + """Iterate on intervals""" + for inter in self.intervals: + yield inter - @classmethod - def cannon_list(cls, tmp): + @staticmethod + def cannon_list(tmp): """ Return a cannonizes list of intervals + @tmp: list of (int, int) """ tmp = sorted([x for x in tmp if x[0] <= x[1]]) out = [] @@ -63,7 +66,7 @@ class interval: while tmp: x = tmp.pop() rez = cmp_interval(out[-1], x) - # print out[-1], x, rez + if rez == INT_EQ: continue elif rez == INT_DISJOIN: @@ -83,6 +86,7 @@ class interval: return out[::-1] def cannon(self): + "Apply .cannon_list() on self contained intervals" if self.is_cannon is True: return self.intervals = interval.cannon_list(self.intervals) @@ -130,12 +134,12 @@ class interval: i += 1 x = to_test[i] if x[0] > x[1]: - del(to_test[i]) + del to_test[i] i -= 1 continue while to_del and to_del[0][1] < x[0]: - del(to_del[0]) + del to_del[0] for y in to_del: if y[0] > x[1]: @@ -144,15 +148,15 @@ class interval: if rez == INT_DISJOIN: continue elif rez == INT_EQ: - del(to_test[i]) + del to_test[i] i -= 1 break elif rez == INT_A_IN_B: - del(to_test[i]) + del to_test[i] i -= 1 break elif rez == INT_B_IN_A: - del(to_test[i]) + del to_test[i] i1 = (x[0], y[0] - 1) i2 = (y[1] + 1, x[1]) to_test[i:i] = [i1, i2] @@ -161,7 +165,7 @@ class interval: elif rez in [INT_JOIN_AB, INT_JOIN_BA]: continue elif rez == INT_JOIN: - del(to_test[i]) + del to_test[i] if x[0] < y[0]: to_test[i:i] = [(x[0], y[0] - 1)] else: @@ -175,13 +179,11 @@ class interval: def __and__(self, v): out = [] for x in self.intervals: - # print "x", x if x[0] > x[1]: continue for y in v.intervals: - # print 'y', y rez = cmp_interval(x, y) - # print x, y, rez + if rez == INT_DISJOIN: continue elif rez == INT_EQ: @@ -208,13 +210,14 @@ class interval: return interval(out) def hull(self): + "Return the first and the last bounds of intervals" if not self.intervals: return None, None return self.intervals[0][0], self.intervals[-1][1] def show(self, img_x=1350, img_y=20, dry_run=False): """ - show image representing the itnerval + show image representing the interval """ try: import Image @@ -229,8 +232,7 @@ class interval: print hex(i_min), hex(i_max) - def addr2x(addr): - return (addr - i_min) * img_x / (i_max - i_min) + addr2x = lambda addr: (addr - i_min) * img_x / (i_max - i_min) for a, b in self.intervals: draw.rectangle((addr2x(a), 0, addr2x(b), img_y), (200, 0, 0)) diff --git a/miasm2/core/parse_asm.py b/miasm2/core/parse_asm.py index dba097fa..09003ed9 100644 --- a/miasm2/core/parse_asm.py +++ b/miasm2/core/parse_asm.py @@ -1,11 +1,11 @@ #!/usr/bin/env python #-*- coding:utf-8 -*- - import re + import miasm2.expression.expression as m2_expr -from miasm2.core.asmbloc import * -from miasm2.core.utils import pck +import miasm2.core.asmbloc as asmbloc from miasm2.core.cpu import gen_base_expr, parse_ast + declarator = {'byte': 8, 'word': 16, 'dword': 32, @@ -33,12 +33,15 @@ def guess_next_new_label(symbol_pool, gen_label_index=0): def parse_txt(mnemo, attrib, txt, symbol_pool=None, gen_label_index=0): if symbol_pool is None: - symbol_pool = asm_symbol_pool() + symbol_pool = asmbloc.asm_symbol_pool() lines_text = [] lines_data = [] lines_bss = [] + C_NEXT = asmbloc.asm_constraint.c_next + C_TO = asmbloc.asm_constraint.c_to + lines = lines_text # parse each line for line in txt.split('\n'): @@ -79,36 +82,36 @@ def parse_txt(mnemo, attrib, txt, symbol_pool=None, gen_label_index=0): raw = raw.decode('string_escape') if directive == 'string': raw += "\x00" - lines.append(asm_raw(raw)) + lines.append(asmbloc.asm_raw(raw)) continue if directive == 'ustring': # XXX HACK line = line.replace(r'\n', '\n').replace(r'\r', '\r') raw = line[line.find(r'"') + 1:line.rfind(r"'")] + "\x00" raw = raw.decode('string_escape') - raw = "".join(map(lambda x: x + '\x00', raw)) - lines.append(asm_raw(raw)) + raw = "".join([string + '\x00' for string in raw]) + lines.append(asmbloc.asm_raw(raw)) continue if directive in declarator: data_raw = line[r.end():].split(' ', 1)[1] data_raw = data_raw.split(',') size = declarator[directive] data_int = [] - has_symb = False # parser - variable, operand, base_expr = gen_base_expr() - my_var_parser = parse_ast(lambda x:m2_expr.ExprId(x, size), - lambda x:m2_expr.ExprInt_fromsize(size, x)) + base_expr = gen_base_expr()[2] + my_var_parser = parse_ast(lambda x: m2_expr.ExprId(x, size), + lambda x: + m2_expr.ExprInt_fromsize(size, x)) base_expr.setParseAction(my_var_parser) for b in data_raw: b = b.strip() x = base_expr.parseString(b)[0] data_int.append(x.canonize()) - p = size2pck[size] + raw = data_int - x = asm_raw(raw) + x = asmbloc.asm_raw(raw) x.element_size = size lines.append(x) continue @@ -116,12 +119,12 @@ def parse_txt(mnemo, attrib, txt, symbol_pool=None, gen_label_index=0): # TODO continue if directive == 'split': # custom command - x = asm_raw() + x = asmbloc.asm_raw() x.split = True lines.append(x) continue if directive == 'dontsplit': # custom command - lines.append(asm_raw(line.strip())) + lines.append(asmbloc.asm_raw(line.strip())) continue if directive in ['file', 'intel_syntax', 'globl', 'local', 'type', 'size', 'align', 'ident', 'section']: @@ -148,12 +151,12 @@ def parse_txt(mnemo, attrib, txt, symbol_pool=None, gen_label_index=0): instr.dstflow2label(symbol_pool) lines.append(instr) - log_asmbloc.info("___pre asm oki___") + asmbloc.log_asmbloc.info("___pre asm oki___") # make blocs - # gen_label_index = 0 blocs_sections = [] bloc_num = 0 + b = None for lines in [lines_text, lines_data, lines_bss]: state = 0 i = 0 @@ -162,81 +165,58 @@ def parse_txt(mnemo, attrib, txt, symbol_pool=None, gen_label_index=0): bloc_to_nlink = None block_may_link = False while i < len(lines): - # print 'DEAL', lines[i], state # no current bloc if state == 0: - if not isinstance(lines[i], asm_label): + if not isinstance(lines[i], asmbloc.asm_label): l = guess_next_new_label(symbol_pool) lines[i:i] = [l] else: l = lines[i] - b = asm_bloc(l) + b = asmbloc.asm_bloc(l) b.bloc_num = bloc_num bloc_num += 1 blocs.append(b) state = 1 i += 1 if bloc_to_nlink: - # print 'nlink!' - bloc_to_nlink.addto( - asm_constraint(b.label, asm_constraint.c_next)) + bloc_to_nlink.addto(asmbloc.asm_constraint(b.label, + C_NEXT)) bloc_to_nlink = None # in bloc elif state == 1: - # asm_raw - if isinstance(lines[i], asm_raw): + if isinstance(lines[i], asmbloc.asm_raw): if hasattr(lines[i], 'split'): state = 0 block_may_link = False i += 1 - else: #if lines[i].raw.startswith('.dontsplit'): - # raw asm are link by default - # print 'dontsplit' + else: state = 1 block_may_link = True b.addline(lines[i]) i += 1 - """ - else: - b.addline(lines[i]) - i += 1 - """ - # asm_label - elif isinstance(lines[i], asm_label): + # asmbloc.asm_label + elif isinstance(lines[i], asmbloc.asm_label): if block_may_link: - # print 'nlink!' b.addto( - asm_constraint(lines[i], asm_constraint.c_next)) + asmbloc.asm_constraint(lines[i], C_NEXT)) block_may_link = False state = 0 # instruction else: b.addline(lines[i]) if lines[i].dstflow(): - ''' - mydst = lines[i].args - if len(mydst)==1 and mnemo.get_symbols(mydst[0]): - arg = dict(mydst[0]) - symbs = mnemo.get_symbols(arg) - """ - TODO XXX redo this (as many miasm parts) - """ - l = symbs[0][0] - lines[i].setdstflow([l]) - b.addto(asm_constraint(l, asm_constraint.c_to)) - ''' for x in lines[i].getdstflow(symbol_pool): if not isinstance(x, m2_expr.ExprId): continue if x in mnemo.regs.all_regs_ids: continue - b.addto(asm_constraint(x, asm_constraint.c_to)) + b.addto(asmbloc.asm_constraint(x, C_TO)) # TODO XXX redo this really if not lines[i].breakflow() and i + 1 < len(lines): - if isinstance(lines[i + 1], asm_label): + if isinstance(lines[i + 1], asmbloc.asm_label): l = lines[i + 1] else: l = guess_next_new_label(symbol_pool) @@ -253,7 +233,7 @@ def parse_txt(mnemo, attrib, txt, symbol_pool=None, gen_label_index=0): i += 1 - for b in blocs_sections[0]: - log_asmbloc.info(b) + for block in blocs_sections[0]: + asmbloc.log_asmbloc.info(block) return blocs_sections, symbol_pool diff --git a/miasm2/core/utils.py b/miasm2/core/utils.py index 360deb8d..b2ddff2b 100644 --- a/miasm2/core/utils.py +++ b/miasm2/core/utils.py @@ -27,10 +27,10 @@ def hexdump(src, length=16): lines = [] for c in xrange(0, len(src), length): chars = src[c:c + length] - hex = ' '.join(["%02x" % ord(x) for x in chars]) + hexa = ' '.join(["%02x" % ord(x) for x in chars]) printable = ''.join( ["%s" % ((ord(x) <= 127 and FILTER[ord(x)]) or '.') for x in chars]) - lines.append("%04x %-*s %s\n" % (c, length * 3, hex, printable)) + lines.append("%04x %-*s %s\n" % (c, length * 3, hexa, printable)) print ''.join(lines) # stackoverflow.com/questions/2912231 diff --git a/miasm2/expression/simplifications_cond.py b/miasm2/expression/simplifications_cond.py index e021ffc2..e6c890ab 100644 --- a/miasm2/expression/simplifications_cond.py +++ b/miasm2/expression/simplifications_cond.py @@ -146,14 +146,14 @@ def expr_simp_inverse(expr_simp, e): # Check for 2 symetric cases if r is False: - to_match = (ExprOp_inf_signed(jok1, jok2) ^ jok_small) - r = __MatchExprWrap(e, - to_match, - [jok1, jok2, jok_small]) - - if r is False: - return e - cur_sig = TOK_INF_SIGNED + to_match = (ExprOp_inf_signed(jok1, jok2) ^ jok_small) + r = __MatchExprWrap(e, + to_match, + [jok1, jok2, jok_small]) + + if r is False: + return e + cur_sig = TOK_INF_SIGNED else: cur_sig = TOK_INF_UNSIGNED diff --git a/miasm2/ir/analysis.py b/miasm2/ir/analysis.py index 037d1f4b..202f7631 100644 --- a/miasm2/ir/analysis.py +++ b/miasm2/ir/analysis.py @@ -322,8 +322,6 @@ class ira: eqs.append(ExprAff(n_w, v)) print '*' * 40 print irb - for eq in eqs: - eq irb.irs = [eqs] irb.lines = [None] diff --git a/miasm2/jitter/loader/pe.py b/miasm2/jitter/loader/pe.py index f7e93c52..a3834d03 100644 --- a/miasm2/jitter/loader/pe.py +++ b/miasm2/jitter/loader/pe.py @@ -354,10 +354,10 @@ class libimp_pe(libimp): self.fad2cname[ad] = c_name self.fad2info[ad] = libad, imp_ord_or_name - def gen_new_lib(self, target_pe, filter=lambda _: True): + def gen_new_lib(self, target_pe, flt=lambda _: True): """Gen a new DirImport description @target_pe: PE instance - @filter: (boolean f(address)) restrict addresses to keep + @flt: (boolean f(address)) restrict addresses to keep """ new_lib = [] @@ -369,8 +369,8 @@ class libimp_pe(libimp): for func_name, dst_addresses in self.lib_imp2dstad[ad].items(): out_ads.update({addr:func_name for addr in dst_addresses}) - # Filter available addresses according to @filter - all_ads = [addr for addr in out_ads.keys() if filter(addr)] + # Filter available addresses according to @flt + all_ads = [addr for addr in out_ads.keys() if flt(addr)] log.debug('ads: %s' % map(hex, all_ads)) if not all_ads: continue diff --git a/miasm2/os_dep/linux_stdlib.py b/miasm2/os_dep/linux_stdlib.py index 9dbc6c60..57424995 100644 --- a/miasm2/os_dep/linux_stdlib.py +++ b/miasm2/os_dep/linux_stdlib.py @@ -54,18 +54,18 @@ def xxx_snprintf(jitter): writes to string str according to format format and at most size bytes. ''' - ret_addr, (str, size, format) = jitter.func_args_stdcall(3) + ret_addr, (string, size, fmt) = jitter.func_args_stdcall(3) curarg, output = 3, '' while True: - c = jitter.vm.get_mem(format, 1) - format += 1 + c = jitter.vm.get_mem(fmt, 1) + fmt += 1 if c == '\x00': break if c == '%': token = '%' while True: - c = jitter.vm.get_mem(format, 1) - format += 1 + c = jitter.vm.get_mem(fmt, 1) + fmt += 1 token += c if c in '%cdfsux': break @@ -74,5 +74,5 @@ def xxx_snprintf(jitter): output += c output = output[:size - 1] ret = len(output) - jitter.vm.set_mem(str, output + '\x00') + jitter.vm.set_mem(string, output + '\x00') return jitter.func_ret_stdcall(ret_addr, ret) diff --git a/miasm2/os_dep/win_api_x86_32.py b/miasm2/os_dep/win_api_x86_32.py index e47c6024..cac03905 100644 --- a/miasm2/os_dep/win_api_x86_32.py +++ b/miasm2/os_dep/win_api_x86_32.py @@ -561,7 +561,7 @@ def kernel32_CreateFile(jitter, funcname, get_str): if stat.S_ISDIR(s.st_mode): ret = winobjs.handle_pool.add(f, 0x1337) else: - h = open(f, 'rb+') + h = open(f, 'r+b') ret = winobjs.handle_pool.add(f, h) else: log.warning("FILE %r DOES NOT EXIST!" % fname) @@ -573,7 +573,7 @@ def kernel32_CreateFile(jitter, funcname, get_str): winobjs.lastwin32error = 80 else: open(f, 'w') - h = open(f, 'rb+') + h = open(f, 'r+b') ret = winobjs.handle_pool.add(f, h) elif args.dwcreationdisposition == 4: # open_always @@ -582,7 +582,7 @@ def kernel32_CreateFile(jitter, funcname, get_str): if stat.S_ISDIR(s.st_mode): ret = winobjs.handle_pool.add(f, 0x1337) else: - h = open(f, 'rb+') + h = open(f, 'r+b') ret = winobjs.handle_pool.add(f, h) else: raise NotImplementedError("Untested case") @@ -601,7 +601,7 @@ def kernel32_CreateFile(jitter, funcname, get_str): # open dir ret = winobjs.handle_pool.add(f, 0x1337) else: - h = open(f, 'rb+') + h = open(f, 'r+b') ret = winobjs.handle_pool.add(f, h) else: raise NotImplementedError("Untested case") # to test |