def function_to_patch_locations(self, ff):
        # TODO tail-call is handled lazily just by considering jumping out functions as not sane
        if cfg_utils.is_sane_function(ff) and cfg_utils.detect_syscall_wrapper(self.patcher,ff) == None \
                and not cfg_utils.is_floatingpoint_function(self.patcher,ff) and not ff.addr in self.safe_functions:
            if cfg_utils.is_longjmp(self.patcher, ff):
                self.found_longjmp = ff.addr
            elif cfg_utils.is_setjmp(self.patcher, ff):
                self.found_setjmp = ff.addr
            else:
                start = ff.startpoint
                ends = set()
                for ret_site in ff.ret_sites:
                    bb = self.patcher.project.factory.fresh_block(
                        ret_site.addr, ret_site.size)
                    last_instruction = bb.capstone.insns[-1]
                    if last_instruction.mnemonic != u"ret":
                        msg = "bb at %s does not terminate with a ret in function %s"
                        l.debug(msg % (hex(int(bb.addr)), ff.name))
                        break
                    else:
                        ends.add(last_instruction.address)
                else:
                    if len(ends) == 0:
                        l.debug("cannot find any ret in function %s" % ff.name)
                    else:
                        return int(start.addr), map(
                            int, ends)  #avoid "long" problems

        l.debug("function %s has problems and cannot be patched" % ff.name)
        return None, None
示例#2
0
def test_setlongjmp_detection():
    solutions = [
            ("CADET_00003",0x80486c8,0x80486e3),
            ("CROMU_00008",0x804C3AC,0x804C3C7),
            ("Ofast/CROMU_00008",0x804ABD7,0x804ABF2),

    ]

    for tbin, setjmp, longjmp in solutions:
        filepath = os.path.join(bin_location, tbin)
        backend = DetourBackend(filepath)
        cfg = backend.cfg

        for k,ff in cfg.functions.items():
            msg = "detection failure in %s (%#x vs %#x)"
            if cfg_utils.is_setjmp(backend,ff):
                nose.tools.assert_equal(setjmp,ff.addr,"setjmp " + msg %(tbin,setjmp,ff.addr))
            elif cfg_utils.is_longjmp(backend,ff):
                nose.tools.assert_equal(longjmp,ff.addr,"longjmp " + msg %(tbin,setjmp,ff.addr))