Ejemplo n.º 1
0
    def prehook(self, emu, op, eip):
        if op.mnem == "out":  #FIXME arch specific. see above idea.
            emu.stopEmu()
            raise Exception("Out instruction...")

        if op in self.badops:
            emu.stopEmu()
            raise v_exc.BadOpBytes(op.va)

        if op.iflags & envi.IF_RET:
            self.hasret = True
            emu.stopEmu()

        self.lastop = op
        # Make sure we didn't run into any other
        # defined locations...
        if self.vw.isFunction(eip):
            emu.stopEmu()
            # FIXME: this is a problem.  many time legit code falls into other functions...  "hydra" functions are more and more common.
            raise v_exc.BadOpBytes(op.va)

        loc = self.vw.getLocation(eip)
        if loc != None:
            va, size, ltype, linfo = loc
            if ltype != vivisect.LOC_OP:
                emu.stopEmu()
                raise Exception("HIT LOCTYPE %d AT %.8x" % (ltype, va))

        cnt = self.mndist.get(op.mnem, 0)
        self.mndist[op.mnem] = cnt + 1
        self.insn_count += 1
Ejemplo n.º 2
0
    def prehook(self, emu, op, eip):
        if op.mnem == "out":  # FIXME arch specific. see above idea.
            emu.stopEmu()
            raise v_exc.BadOutInstruction(op.va)

        if op in self.badops:
            emu.stopEmu()
            raise v_exc.BadOpBytes(op.va)

        if op.iflags & envi.IF_RET:
            self.hasret = True
            emu.stopEmu()

        self.lastop = op

        loc = self.vw.getLocation(eip)
        if loc is not None:
            va, size, ltype, linfo = loc
            if ltype != vivisect.LOC_OP:
                emu.stopEmu()
                raise Exception("HIT LOCTYPE %d AT 0x%.8x" % (ltype, va))

        cnt = self.mndist.get(op.mnem, 0)
        self.mndist[op.mnem] = cnt + 1
        self.insn_count += 1
        if self.vw.isNoReturnVa(eip):
            self.hasret = True
            emu.stopEmu()
Ejemplo n.º 3
0
    def prehook(self, emu, op, starteip):
        if op in self.badops:
            raise v_exc.BadOpBytes(op.va)

        viv_imp_monitor.AnalysisMonitor.prehook(self, emu, op, starteip)

        if op.opcode == e_i386const.INS_LEA:  # x86 only
            i = 1
            o = op.opers[i]
            discrete = o.isDiscrete()
            operva = o.getOperAddr(op, emu)
            # keep track of the max here, but save it for later too...
            stackoff = emu.getStackOffset(operva)
            if stackoff and stackoff >= 0:
                self.stackmax = max(self.stackmax, stackoff)
                self.stackargs[stackoff] = True

            self.operrefs.append(
                (starteip, i, operva, o.tsize, stackoff, discrete))

        # Do return related stuff before we execute the opcode
        if op.isReturn():
            self.endstack = emu.getStackCounter()
            if len(op.opers):
                self.retbytes = op.opers[0].imm
Ejemplo n.º 4
0
    def prehook(self, emu, op, starteip):

        if op in self.badops:
            raise v_exc.BadOpBytes(op.va)

        viv_monitor.AnalysisMonitor.prehook(self, emu, op, starteip)

        if op.iflags & envi.IF_RET:
            if len(op.opers):
                self.retbytes = op.opers[0].imm
Ejemplo n.º 5
0
    def prehook(self, emu, op, starteip):
        if op in self.badops:
            raise v_exc.BadOpBytes(op.va)

        viv_imp_monitor.AnalysisMonitor.prehook(self, emu, op, starteip)

        # Do return related stuff before we execute the opcode
        if op.isReturn():
            self.endstack = emu.getStackCounter()
            if len(op.opers):
                self.retbytes = op.opers[0].imm
Ejemplo n.º 6
0
    def prehook(self, emu, op, eip):
        if op in self.badops:
            emu.stopEmu()
            raise v_exc.BadOpBytes(op.va)

        if op.mnem in STOS:
            if self.arch == 'i386':
                reg = emu.getRegister(envi.archs.i386.REG_EDI)
            elif self.arch == 'amd64':
                reg = emu.getRegister(envi.archs.amd64.REG_RDI)
            if self.vw.isValidPointer(reg):
                self.vw.makePointer(reg, follow=True)
Ejemplo n.º 7
0
    def prehook(self, emu, op, starteip):

        try:
            tmode = emu.getFlag(PSR_T_bit)
            self.last_tmode = tmode
            if op in self.badops:
                emu.stopEmu()
                raise v_exc.BadOpBytes(op.va)

            viv_monitor.AnalysisMonitor.prehook(self, emu, op, starteip)

            loctup = emu.vw.getLocation(starteip)
            if loctup is None:
                # logger.debug("emulation: prehook: new LOC_OP  fva: 0x%x     starteip: 0x%x  flags: 0x%x", self.fva, starteip, op.iflags)
                arch = (envi.ARCH_ARMV7,
                        envi.ARCH_THUMB)[(starteip & 1) | tmode]
                emu.vw.makeCode(starteip & -2, arch=arch)

            elif loctup[2] != LOC_OP:
                logger.info(
                    "ARG! emulation found opcode in an existing NON-OPCODE location  (0x%x):  0x%x: %s",
                    loctup[0], op.va, op)
                emu.stopEmu()

            elif loctup[0] != starteip:
                logger.info(
                    "ARG! emulation found opcode in a location at the wrong address (0x%x):  0x%x: %s",
                    loctup[0], op.va, op)
                emu.stopEmu()

            if op.iflags & envi.IF_RET:
                self.returns = True
                if len(op.opers):
                    if hasattr(op.opers, 'imm'):
                        self.retbytes = op.opers[0].imm

            # ARM gives us nice switchcase handling instructions
            # FIXME: wrap TB-handling into getBranches(emu) which is called by checkBranches during emulation
            if op.opcode in (INS_TBH, INS_TBB):
                if emu.vw.getVaSetRow('SwitchCases', op.va) is None:
                    base, tbl = analyzeTB(emu, op, starteip, self)
                    if None not in (base, tbl):
                        count = len(tbl)
                        self.switchcases += 1
                        emu.vw.setVaSetRow('SwitchCases',
                                           (op.va, op.va, count))

            elif op.opcode == INS_MOV:
                if len(op.opers) >= 2:
                    oper0 = op.opers[0]
                    oper1 = op.opers[1]

                    if isinstance(oper0,
                                  e_arm.ArmRegOper) and oper0.reg == REG_LR:
                        if isinstance(
                                oper1,
                                e_arm.ArmRegOper) and oper1.reg == REG_PC:
                            self.last_lr_pc = starteip

            elif op.opcode == INS_BX:
                if starteip - self.last_lr_pc <= 4:
                    # this is a call.  the compiler updated lr
                    logger.info("CALL by mov lr, pc; bx <foo> at 0x%x",
                                starteip)
                    tgtva = op.opers[-1].getOperValue(op)
                    self.vw.makeFunction(tgtva)

            elif op.opcode == INS_ADD and op.opers[0].reg == REG_PC:
                # simple branch code
                if emu.vw.getVaSetRow('SwitchCases', op.va) is None:
                    base, tbl = analyzeADDPC(emu, op, starteip, self)
                    if None not in (base, tbl):
                        count = len(tbl)
                        self.switchcases += 1
                        emu.vw.setVaSetRow('SwitchCases',
                                           (op.va, op.va, count))

            elif op.opcode == INS_SUB and isinstance(
                    op.opers[0],
                    e_arm.ArmRegOper) and op.opers[0].reg == REG_PC:
                # simple branch code
                if emu.vw.getVaSetRow('SwitchCases', op.va) is None:
                    base, tbl = analyzeSUBPC(emu, op, starteip, self)
                    if None not in (base, tbl):
                        count = len(tbl)
                        self.switchcases += 1
                        emu.vw.setVaSetRow('SwitchCases',
                                           (op.va, op.va, count))

            if op.iflags & envi.IF_BRANCH:
                try:
                    tgt = op.getOperValue(0, emu)

                    if tgt == op.va:
                        logger.info(
                            "0x%x: +++++++++++++++ infinite loop +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++",
                            op.va)
                        if op.va not in self.infloops:
                            self.infloops.append(op.va)
                            if 'InfiniteLoops' not in vw.getVaSetNames():
                                vw.addVaSet(
                                    'InfiniteLoops',
                                    (('va', vivisect.VASET_ADDRESS, 'function',
                                      vivisect.VASET_STRING)))
                            self.vw.setVaSetRow('InfiniteLoops',
                                                (op.va, self.fva))

                except Exception as e:
                    self.logAnomaly(emu, self.fva,
                                    "0x%x: (%r) ERROR: %s" % (op.va, op, e))
                    logger.info("0x%x: (%r) ERROR: %s", op.va, op, e)

        except Exception as e:
            self.logAnomaly(emu, self.fva,
                            "0x%x: (%r) ERROR: %s" % (op.va, op, e))
            logger.warning("0x%x: (%r)  ERROR: %s", op.va, op, e)