Beispiel #1
0
def emul_lines(machine, lines):
    my_eip = None
    for l in lines:
        my_eip = ExprInt(uint32(l.offset))

        args = []
        my_eip.arg += uint32(l.l)
        ex = get_instr_expr(l, my_eip, args)
        my_eip, mem_dst = emul_full_expr(ex, l, my_eip, None, machine)

        for k in machine.pool:
            machine.pool[k] = expr_simp(machine.pool[k])

    return my_eip
Beispiel #2
0
def x86_machine(mem_read_wrap=None, mem_write_wrap=None):
    init_reg_new = init_regs.copy()
    init_reg_new.update({
        cs: ExprInt(uint32(9)),
        dr7: ExprInt(uint32(0)),
        cr0: init_cr0,
        #my_ret_addr:my_ret_addri
    })
    machine = eval_abs(
        init_reg_new,
        mem_read_wrap,
        mem_write_wrap,
    )
    return machine
    def eval_instr(self, exprs):
        tmp_ops = self.get_instr_mod(exprs)
        mem_dst = []
        for op in tmp_ops:
            if isinstance(op, ExprMem):
                ov = self.get_mem_overlapping(op)
                for off, x in ov:
                    diff_mem = self.substract_mems(x, op)
                    del (self.pool[x])
                    for xx, yy in diff_mem:
                        self.pool[xx] = yy
                tmp = expr_simp(tmp_ops[op])

                if isinstance(expr_simp(op.arg), ExprTop):
                    raise ValueError('xx')
            else:
                tmp = tmp_ops[op]
                tmp = expr_simp(tmp)

            if isinstance(tmp, ExprInt) and isinstance(
                    op, ExprId) and op.name in [
                        'zf', 'nf', 'pf', 'of', 'cf', 'df'
                    ]:
                tmp = ExprInt(uint32(tmp.arg))
            self.pool[op] = tmp
            if isinstance(op, ExprMem):
                mem_dst.append(op)

        return mem_dst
Beispiel #4
0
def p_brackets_6(t):
    '''brackets : MINUS NUMBER PLUS symbol LBRA expression RBRA %prec UMINUS'''
    if not x86_afs.ad in t[6]:
        t[6][x86_afs.ad] = True
    t[0] = t[6]
    for f in t[4]:
        t[0][f] = t[4][f]
    t[0][x86_afs.imm] = - int(int32(uint32(int(t[2]))))
Beispiel #5
0
def p_brackets_5(t):
    '''brackets : NUMBER PLUS symbol LBRA expression RBRA '''
    if not x86_afs.ad in t[5]:
        t[5][x86_afs.ad] = True
    t[0] = t[5]
    for f in t[3]:
        t[0][f] = t[3][f]
    t[0][x86_afs.imm] = int(int32(uint32(int(t[1]))))
    def substract_mems(self, a, b):
        ex = ExprOp('-', b.arg, a.arg)
        ex = expr_simp(self.eval_expr(ex, {}))
        if not isinstance(ex, ExprInt):
            return None
        ptr_diff = int(int32(ex.arg))
        out = []
        if ptr_diff < 0:
            #    [a     ]
            #[b      ]XXX

            sub_size = b.size + ptr_diff * 8
            if sub_size >= a.size:
                pass
            else:
                ex = ExprOp('+', a.arg, ExprInt(uint32(sub_size / 8)))
                ex = expr_simp(self.eval_expr(ex, {}))

                rest_ptr = ex
                rest_size = a.size - sub_size

                val = self.pool[a][sub_size:a.size]
                out = [(ExprMem(rest_ptr, rest_size), val)]
        else:
            #[a         ]
            #XXXX[b   ]YY

            #[a     ]
            #XXXX[b     ]

            out = []
            #part X
            if ptr_diff > 0:
                val = self.pool[a][0:ptr_diff * 8]
                out.append((ExprMem(a.arg, ptr_diff * 8), val))
            #part Y
            if ptr_diff * 8 + b.size < a.size:

                ex = ExprOp('+', b.arg, ExprInt(uint32(b.size / 8)))
                ex = expr_simp(self.eval_expr(ex, {}))

                val = self.pool[a][ptr_diff * 8 + b.size:a.size]
                out.append((ExprMem(ex, val.get_size()), val))

        return out
    def get_mem_overlapping(self, e, eval_cache={}):
        if not isinstance(e, ExprMem):
            raise ValueError('mem overlap bad arg')
        ov = []
        """
        for k in self.pool:
            if not isinstance(k, ExprMem):
                continue
            ex = ExprOp('-', k.arg, e.arg)
            ex = expr_simp(self.eval_expr(ex, {}))
            if not isinstance(ex, ExprInt):
                continue
            ptr_diff = int32(ex.arg)
            if ptr_diff >=0 and ptr_diff < e.size/8:
                ov.append((-ptr_diff, k))
            elif ptr_diff <0 and ptr_diff + k.size/8>0:
                ov.append((-ptr_diff, k))
        """
        # suppose max mem size is 64 bytes, compute all reachable addresses
        to_test = []
        #comp = {}
        #print("FINDING %s" % e)
        for i in range(-7, e.size // 8):
            ex = expr_simp(
                self.eval_expr(e.arg + ExprInt(uint32(i)), eval_cache))
            #print("%s %s"%(i, ex))
            to_test.append((i, ex))

        for i, x in to_test:
            if not x in self.pool.pool_mem:
                continue

            ex = expr_simp(self.eval_expr(e.arg - x, eval_cache))
            if not isinstance(ex, ExprInt):
                raise ValueError("%s should be ExprInt instead of %s" %
                                 (ex, ex.__class__.__name__))
            ptr_diff = int32(ex.arg)
            #print("ptrdiff %s %s'%(ptr_diff, i))
            if ptr_diff >= self.pool.pool_mem[x][1].get_size() / 8:
                #print("too long!")
                continue
            ov.append((i, self.pool.pool_mem[x][0]))
        #"""
        """
        print(ov)
        if len(ov)>0:
            print("XXXX %s" % [(x[0], str(x[1])) for x in ov])
        """
        return ov
Beispiel #8
0
from miasmX.expression.expression import ExprOp, ExprSlice, ExprCompose, \
    ExprCond, ExprInt, ExprMem
from miasmX.expression.expression import canonize_expr_list

tab_size_int = {
    1: uint1,
    8: uint8,
    16: uint16,
    32: uint32,
    64: uint64,
}

tab_max_uint = {
    8: uint8(0xFF),
    16: uint16(0xFFFF),
    32: uint32(uint32.limit - 1),
    64: uint64(uint64.limit - 1)
}


def parity(a):
    tmp = (a) & 0xFF
    cpt = 1
    while tmp != 0:
        cpt ^= tmp & 1
        tmp >>= 1
    return cpt


def merge_sliceto_slice(args):
    sources = {}
Beispiel #9
0
def p_brackets_4(t):
    '''brackets : MINUS NUMBER LBRA expression RBRA'''
    if not x86_afs.ad in t[4]:
        t[4][x86_afs.ad] = True
    t[0] = t[4]
    t[0][x86_afs.imm] = - int(int32(uint32(int(t[2]))))
Beispiel #10
0
def p_brackets_3(t):
    '''brackets : NUMBER LBRA expression RBRA '''
    if not x86_afs.ad in t[3]:
        t[3][x86_afs.ad] = True
    t[0] = t[3]
    t[0][x86_afs.imm] = int(int32(uint32(int(t[1]))))
Beispiel #11
0
def p_expression_5(t):
    '''expression : NUMBER'''
    t[0] = {x86_afs.imm:int(int32(uint32(int(t[1]))))}
Beispiel #12
0
def emul_full_expr(e, l, my_eip, env, machine):
    if ((not 0xF2 in l.prefix) and (not 0xF3 in l.prefix)) or \
           "MMX" in l.m.name or \
           not l.m.name[:-1] in ["ins", "outs", "movs", "lods", "stos", "cmps", "scas"]:
        my_eip, mem_dst = emul_expr(machine, e, my_eip)
    else:
        #rep mnemo
        #XXX HACK 16 bit
        tsc_inc = 0
        if 0x66 in l.prefix and l.m.name[-1] == "d":
            raise ValueError("not impl 16 bit string")
        if l.m.name[:-1] in ["cmps", "scas"]:  # repz or repnz
            zf_w = False
            for x in e:
                if zf in x.get_w():
                    zf_w = True
        else:  # rep
            zf_w = False

        def expr_depth(f):
            if isinstance(f, ExprOp) or isinstance(f, ExprCompose):
                depth = 1
                for a in f.args:
                    depth += expr_depth(a)
                return depth
            elif isinstance(f, ExprMem):
                return 1 + expr_depth(f.arg)
            elif isinstance(f, ExprCond):
                return expr_depth(f.cond) + expr_depth(f.src1) + expr_depth(
                    f.src2)
            else:
                return 0

        while True:

            my_ecx = machine.eval_expr(machine.pool[ecx], {})
            if not isinstance(my_ecx, ExprInt):
                raise ValueError('Emulation fails for "%s". ECX value is %s' %
                                 (l, str(machine.pool[ecx])))
            if l.mnemo_mode == x86_afs.u16:
                my_ecx.arg &= 0xFFFF
            if my_ecx.arg == 0:
                break

            my_edi = machine.eval_expr(machine.pool[edi], {})
            if expr_depth(my_edi) > 100:
                raise ValueError(
                    'Emulation fails for "%s". EDI value is too complicated' %
                    l)
            tmp, mem_dst = emul_expr(machine, e, my_eip)
            if my_ecx.arg > 0x1000:
                # This is not a valid emulation, but we don't want to loop forever
                break

            info = l.opmode, l.admode
            machine.eval_instr(
                mov(info, ecx, ExprOp('-', my_ecx, ExprInt(uint32(1)))))
            machine.eval_expr(machine.pool[ecx], {})

            if zf_w:
                my_zf = machine.eval_expr(machine.pool[zf], {})
                if 0xF3 in l.prefix and my_zf == 0:
                    break
                if 0xF2 in l.prefix and my_zf == 1:
                    break

            tsc_inc += 1
        # serpillere included an emulation of TSC incrementation,
        # why here and nowhere else?
        if isinstance(machine.pool[tsc1], ExprInt):
            machine.pool[tsc1].arg += tsc_inc

    return my_eip, mem_dst
Beispiel #13
0
    def eval_ExprMem(self, e, eval_cache={}):
        a_val = expr_simp(self.eval_expr(e.arg, eval_cache))
        if isinstance(a_val, ExprTop):
            #XXX hack test
            ee = ExprMem(e.arg, e.size)
            ee.is_term = True
            return ee
        a = expr_simp(ExprMem(a_val, size=e.size))
        if a in self.pool:
            return self.pool[a]
        tmp = None
        #test if mem lookup is known
        """
        for k in self.pool:
            if not isinstance(k, ExprMem):
                continue
            if a_val == k.arg:
                tmp = k
                break
        """
        if a_val in self.pool.pool_mem:
            tmp = self.pool.pool_mem[a_val][0]
        """
        for k in self.pool:
            if not isinstance(k, ExprMem):
                continue
            if a_val == k.arg:
                tmp = k
                break
        """
        if tmp is None:

            v = self.find_mem_by_addr(a_val)
            if not v:
                out = []
                ov = self.get_mem_overlapping(a, eval_cache)
                off_base = 0
                ov.sort()
                ov.reverse()
                for off, x in ov:
                    off_base = off * 8
                    if off >= 0:
                        m = min(a.get_size() - off_base, x.get_size())
                        ee = ExprSlice(self.pool[x], 0, m)
                        ee = expr_simp(ee)
                        out.append((ee, off_base, off_base + ee.get_size()))
                        off_base += ee.get_size()
                    else:
                        m = min(a.get_size() - off * 8, x.get_size())
                        ee = ExprSlice(self.pool[x], -off * 8, m)
                        ee = expr_simp(ee)
                        out.append((ee, off_base, off_base + ee.get_size()))
                        off_base += ee.get_size()
                if out:
                    missing_slice = self.rest_slice(out, 0, a.get_size())
                    for sa, sb in missing_slice:
                        ptr = expr_simp(a_val + ExprInt32(sa / 8))
                        out.append((ExprMem(ptr, size=sb - sa), sa, sb))
                    out = sorted(out, key=lambda x: x[1])
                    #for e, sa, sb in out:
                    #    print("%s %s %s"%(e, sa, sb))
                    ee = ExprSlice(ExprCompose(out), 0, a.get_size())
                    ee = expr_simp(ee)
                    return ee
            if self.func_read and isinstance(a.arg, ExprInt):
                return self.func_read(self, a)
            else:
                #XXX hack test
                a.is_term = True
                return a
        #eq lookup
        if a.size == tmp.size:
            return self.pool[tmp]
        #bigger lookup
        if a.size > tmp.size:
            rest = a.size
            ptr = a_val
            out = []
            ptr_index = 0
            while rest:
                v = self.find_mem_by_addr(ptr)
                if v is None:
                    #raise ValueError("cannot find %s in mem"%str(ptr))
                    val = ExprMem(ptr, 8)
                    v = val
                    diff_size = 8
                elif rest >= v.size:
                    val = self.pool[v]
                    diff_size = v.size
                else:
                    diff_size = rest
                    val = self.pool[v][0:diff_size]
                val = (val, ptr_index, ptr_index + diff_size)
                out.append(val)
                ptr_index += diff_size
                rest -= diff_size
                ptr = expr_simp(
                    self.eval_expr(
                        ExprOp('+', ptr, ExprInt(uint32(v.size / 8))),
                        eval_cache))
            e = expr_simp(ExprCompose(out))
            return e
        #part lookup
        tmp = expr_simp(ExprSlice(self.pool[tmp], 0, a.size))
        return tmp
Beispiel #14
0
def ExprInt32(i):
    return ExprInt(uint32(i))