Example #1
0
 def add_gadgets(self, module_name, module_id, module_address):
     hashes = {}
     props = {}
     
     c=0
     for r in self.instance.search(module_name):
         if self.max_gadgets and c >= self.max_gadgets:
             if self.debug:
                 self.imm.log("[*] Max gadgets count reached (%d)"%self.max_gadgets)
             break
         
         sa = SequenceAnalyzer(self.imm)
         
         #consider direction flag off, which is true 99.9% of the time and improves speed over 9000 times
         sa.state.flags["_DF"]=sa.state.solver.false
         addr = r[0]
         
         if self.debug:
             self.imm.log("[*] Analyzing gadget at 0x%08x"%addr, addr)
         
         if not sa.analyze(addr, depth=r[1], stopEIP=r[0]+r[2]):  #if the sequence analyzer failed, we cant use this gadget
             if not self.quiet: self.imm.log("[!] Sequence Analyzer failed for gadget 0x%x"%addr, addr)
             continue
         
         c+=1
         addr -= module_address #store offset, not address
         
         (regProps, flagProps)=sa.state.calcProperties()
         complexity=sa.state.calcComplexity(regProps, flagProps)
         
         for k,v in sa.state.hashState().iteritems():
             key=(k,v)
             if not hashes.has_key(key):
                 hashes[key]=set()
             hashes[key].add((complexity, addr))
         
         for k,v in regProps.iteritems():
             if not v:
                 continue
             key=(k,v)
             if not props.has_key(key):
                 props[key]=set()
             props[key].add((complexity, addr))
         
         if flagProps:
             key=("FLAGS",flagProps)
             if not props.has_key(key):
                 props[key]=set()
             props[key].add((complexity, addr))
         
         self.add_gadget_entry(addr, sa.state, complexity, module_id)
         self.db_connection.commit()
         del sa
     
     self.add_hashes(module_id, hashes)
     self.add_props(module_id, props)
     self.db_connection.commit()
     
     return c
Example #2
0
    def analyze(self, imm):
        self.sa = SequenceAnalyzer(imm)
        if not self.sa.analyze(self.addr,
                               depth=self.ins_cnt,
                               stopEIP=self.addr + self.byte_cnt):
            return False

        return True
Example #3
0
class Gadget:
    def __init__(self, addr, ins_cnt, byte_cnt):
        self.addr = addr
        self.ins_cnt = ins_cnt
        self.byte_cnt = byte_cnt
        self.sa = None
    
    def analyze(self, imm):
        self.sa = SequenceAnalyzer(imm)
        if not self.sa.analyze(self.addr, depth=self.ins_cnt, stopEIP=self.addr+self.byte_cnt):
            return False
        
        return True
Example #4
0
class Gadget:
    def __init__(self, addr, ins_cnt, byte_cnt):
        self.addr = addr
        self.ins_cnt = ins_cnt
        self.byte_cnt = byte_cnt
        self.sa = None

    def analyze(self, imm):
        self.sa = SequenceAnalyzer(imm)
        if not self.sa.analyze(self.addr,
                               depth=self.ins_cnt,
                               stopEIP=self.addr + self.byte_cnt):
            return False

        return True
Example #5
0
        return "You must specify one or more user defined registers"

    imm.log("Analyzing from %s to %s" % (hex(start_addr), hex(end_addr)))
    imm.log("Solving for %s %s %s" % (output_reg, relation, hex(output_val)))
    imm.log("Assuming %s are user controlled" % \
            (', '.join(user_regs)))

    r_model = imm.getRegs()
    for reg in user_regs:
        if reg in r_model:
            del r_model[reg]

    f_model = None
    m_model = True

    sa = SequenceAnalyzer(imm, r_model, f_model, m_model)
    solver = sa.state.solver
    sa._debug = DEBUG

    imm.markBegin()
    sa.analyze(start_addr, 100, stopEIP=end_addr)

    imm.log("Elapsed time: %d secs" % imm.markEnd())
    reg_exp = sa.state.regs[output_reg]
    const_exp = solver.constExpr(output_val, val_width)
    rel_exp = relationToExpr(sa, relation, reg_exp, const_exp, signed)

    res = solver.checkUnsat(rel_exp)

    if res == 0:
        imm.log("Result: SAT")
Example #6
0
def find_gadgets(imm, gadget_pkl_name, dest, src, val_start, val_end, 
        val_width=32, find_all=False, generic=True, 
        preserve_regs=None):
    gadget_cnt = 0
    shortest_gadget = None
    r_model = m_model = f_model = None
             
    if not generic:
        # Fix the current value of all registers
        r_model = imm.getRegs()
        # Use concrete memory values
        m_model = True
        # No flag modelling for now
        f_model = None

    dump_file = open(gadget_pkl_name, 'rb')
    gadget_cnt = 0
    useful_gadget_cnt = 0
    done_processing = False

    while not done_processing:
        try:
            gadgets = cPickle.load(dump_file)
            gadget_cnt += len(gadgets)
        except EOFError:
            break
            
        for gadget in gadgets:
            sa = SequenceAnalyzer(imm, r_model, f_model, m_model)
            sa._debug = DEBUG 
            solver = sa.state.solver
            
            in_regs = {}
            in_out_exprs = []
            preserve_expr = None
            
            if preserve_regs is not None:
                for reg in preserve_regs:
                    if reg not in VALID_REGISTERS:
                        imm.log(
                            "%s is not a valid preserve register" % \
                            reg)
                        return "Error. See log"
                    in_regs[reg] = sa.state.regs[reg]        

            src_expr = None
            if val_start is None:
                src_expr = get_location_expr(imm, sa, src, val_width)
                if src_expr is None:
                    msg = "%s is not a valid source" % src
                    imm.log("%s" % msg)
                    raise InvalidLocationException(msg)

            x = sa.analyze(gadget.addr, depth=gadget.ins_cnt)
            if not x:
                continue
            
            # If there are registers whos value we want preserved after 
            # the gadget has ran then build an expression for this
            if preserve_regs is not None:
                for reg in preserve_regs:
                    out_reg = sa.state.regs[reg]
                    expr = solver.eqExpr(out_reg, in_regs[reg])
                    in_out_exprs.append(expr)

                preserve_expr = in_out_exprs[0]
                for expr in in_out_exprs[1:]:
                    preserve_expr = solver.boolAndExpr(
                            preserve_expr, expr)

            dest_expr = get_location_expr(imm, sa, dest, val_width)
            if dest_expr is None:
                msg = "%s is not a valid destination" % dest
                imm.log("%s" % msg)
                raise InvalidLocationException(msg)
                
            rel_expr = None
            if src_expr is None:
                # We're using constants not a register/mem location
                if val_end is None:
                    # Single value
                    src_expr = solver.constExpr(val_start, val_width)
                    rel_expr = solver.eqExpr(dest_expr, src_expr)
                else:
                    # Range
                    start_expr = solver.geExpr(dest_expr,
                            solver.constExpr(val_start))
                    end_expr = solver.leExpr(dest_expr,
                            solver.constExpr(val_end))
                    rel_expr = solver.boolAndExpr(start_expr,
                            end_expr)
            else:
                # Equality with a register or mem location
                rel_expr = solver.eqExpr(dest_expr, src_expr)

            if preserve_expr is not None:
                rel_expr = solver.boolAndExpr(preserve_expr, 
                        rel_expr)

            if generic:
                # Check for validity.
                res = solver.queryFormula(rel_expr)
                if res == 1:
                    useful_gadget_cnt += 1
                    imm.log("Found gadget at %x of length %d" % \
                            (gadget.addr, gadget.ins_cnt), gadget.addr)
                    if not find_all:
                        imm.log("To find all gadgets specify -a")
                        done_processing = True
                        break
                    else:
                        if shortest_gadget is None:
                            shortest_gadget = gadget
                        else:
                            if gadget.ins_cnt < shortest_gadget.ins_cnt:
                                shortest_gadget = gadget
            else:
                # Check for satisfiability
                res = solver.checkUnsat(rel_expr)
                if res == 0:
                    useful_gadget_cnt += 1
                    imm.log("Found gadget at %x of length %d" % \
                            (gadget.addr, gadget.ins_cnt), gadget.addr)
                    if not find_all:
                        imm.log("To find all gadgets specify -a")
                        done_processing = True
                        break
                    else:
                        if shortest_gadget is None:
                            shortest_gadget = gadget
                        else:
                            if gadget.ins_cnt < shortest_gadget.ins_cnt:
                                shortest_gadget = gadget

    dump_file.close()
    imm.log("Processed %d gadgets" % gadget_cnt)

    return (useful_gadget_cnt, shortest_gadget) 
Example #7
0
def find_gadgets(imm,
                 gadget_pkl_name,
                 dest,
                 src,
                 val_start,
                 val_end,
                 val_width=32,
                 find_all=False,
                 generic=True,
                 preserve_regs=None):
    gadget_cnt = 0
    shortest_gadget = None
    r_model = m_model = f_model = None

    if not generic:
        # Fix the current value of all registers
        r_model = imm.getRegs()
        # Use concrete memory values
        m_model = True
        # No flag modelling for now
        f_model = None

    dump_file = open(gadget_pkl_name, 'rb')
    gadget_cnt = 0
    useful_gadget_cnt = 0
    done_processing = False

    while not done_processing:
        try:
            gadgets = cPickle.load(dump_file)
            gadget_cnt += len(gadgets)
        except EOFError:
            break

        for gadget in gadgets:
            sa = SequenceAnalyzer(imm, r_model, f_model, m_model)
            sa._debug = DEBUG
            solver = sa.state.solver

            in_regs = {}
            in_out_exprs = []
            preserve_expr = None

            if preserve_regs is not None:
                for reg in preserve_regs:
                    if reg not in VALID_REGISTERS:
                        imm.log(
                            "%s is not a valid preserve register" % \
                            reg)
                        return "Error. See log"
                    in_regs[reg] = sa.state.regs[reg]

            src_expr = None
            if val_start is None:
                src_expr = get_location_expr(imm, sa, src, val_width)
                if src_expr is None:
                    msg = "%s is not a valid source" % src
                    imm.log("%s" % msg)
                    raise InvalidLocationException(msg)

            x = sa.analyze(gadget.addr, depth=gadget.ins_cnt)
            if not x:
                continue

            # If there are registers whos value we want preserved after
            # the gadget has ran then build an expression for this
            if preserve_regs is not None:
                for reg in preserve_regs:
                    out_reg = sa.state.regs[reg]
                    expr = solver.eqExpr(out_reg, in_regs[reg])
                    in_out_exprs.append(expr)

                preserve_expr = in_out_exprs[0]
                for expr in in_out_exprs[1:]:
                    preserve_expr = solver.boolAndExpr(preserve_expr, expr)

            dest_expr = get_location_expr(imm, sa, dest, val_width)
            if dest_expr is None:
                msg = "%s is not a valid destination" % dest
                imm.log("%s" % msg)
                raise InvalidLocationException(msg)

            rel_expr = None
            if src_expr is None:
                # We're using constants not a register/mem location
                if val_end is None:
                    # Single value
                    src_expr = solver.constExpr(val_start, val_width)
                    rel_expr = solver.eqExpr(dest_expr, src_expr)
                else:
                    # Range
                    start_expr = solver.geExpr(dest_expr,
                                               solver.constExpr(val_start))
                    end_expr = solver.leExpr(dest_expr,
                                             solver.constExpr(val_end))
                    rel_expr = solver.boolAndExpr(start_expr, end_expr)
            else:
                # Equality with a register or mem location
                rel_expr = solver.eqExpr(dest_expr, src_expr)

            if preserve_expr is not None:
                rel_expr = solver.boolAndExpr(preserve_expr, rel_expr)

            if generic:
                # Check for validity.
                res = solver.queryFormula(rel_expr)
                if res == 1:
                    useful_gadget_cnt += 1
                    imm.log("Found gadget at %x of length %d" % \
                            (gadget.addr, gadget.ins_cnt), gadget.addr)
                    if not find_all:
                        imm.log("To find all gadgets specify -a")
                        done_processing = True
                        break
                    else:
                        if shortest_gadget is None:
                            shortest_gadget = gadget
                        else:
                            if gadget.ins_cnt < shortest_gadget.ins_cnt:
                                shortest_gadget = gadget
            else:
                # Check for satisfiability
                res = solver.checkUnsat(rel_expr)
                if res == 0:
                    useful_gadget_cnt += 1
                    imm.log("Found gadget at %x of length %d" % \
                            (gadget.addr, gadget.ins_cnt), gadget.addr)
                    if not find_all:
                        imm.log("To find all gadgets specify -a")
                        done_processing = True
                        break
                    else:
                        if shortest_gadget is None:
                            shortest_gadget = gadget
                        else:
                            if gadget.ins_cnt < shortest_gadget.ins_cnt:
                                shortest_gadget = gadget

    dump_file.close()
    imm.log("Processed %d gadgets" % gadget_cnt)

    return (useful_gadget_cnt, shortest_gadget)
Example #8
0
 def analyze(self, imm):
     self.sa = SequenceAnalyzer(imm)
     if not self.sa.analyze(self.addr, depth=self.ins_cnt, stopEIP=self.addr+self.byte_cnt):
         return False
     
     return True
Example #9
0
    imm.log("Analyzing from %s to %s" % (hex(start_addr),
                                         hex(end_addr)))
    imm.log("Solving for %s %s %s" % (output_reg, relation,
                                      hex(output_val)))
    imm.log("Assuming %s are user controlled" % \
            (', '.join(user_regs)))
    
    r_model = imm.getRegs()
    for reg in user_regs:
        if reg in r_model:
            del r_model[reg]
            
    f_model = None
    m_model = True
    
    sa = SequenceAnalyzer(imm, r_model, f_model, m_model)
    solver = sa.state.solver
    sa._debug = DEBUG

    imm.markBegin()
    sa.analyze(start_addr, 100, stopEIP=end_addr)   
    
    imm.log("Elapsed time: %d secs" % imm.markEnd())
    reg_exp = sa.state.regs[output_reg]
    const_exp = solver.constExpr(output_val, val_width)
    rel_exp = relationToExpr(sa, relation, reg_exp, const_exp, signed)

    res = solver.checkUnsat(rel_exp)

    if res == 0:
        imm.log("Result: SAT")
Example #10
0
    for reg in user_regs:
        if reg in r_model:
            del r_model[reg]
            
    f_model = None
    m_model = True
    
    imm.markBegin()
    
    imm.log("Conversion to SMT done in %d secs" % imm.markEnd())

    sat_ranges = []
    unsat_ranges = []
    ranges_to_test = []
    ranges_to_test.append(AddressRange(lower, upper))
    sa = SequenceAnalyzer(imm, r_model, f_model, m_model)
    solver = sa.state.solver
    sa._debug = DEBUG 
    sa.analyze(start_addr, stopEIP=end_addr)

    total_queries = 0
    start = time.time()
    while True:
        if timeout is not None and time.time() - start >= timeout:
            imm.log("Timeout of %d seconds expired during first phase" % timeout)
            break
        
        # Preserve solver state
        sa.push()
        
        reg_expr = sa.state.regs[output_reg]
Example #11
0
    def add_gadgets(self, module_name, module_id, module_address):
        hashes = {}
        props = {}

        c = 0
        for r in self.instance.search(module_name):
            if self.max_gadgets and c >= self.max_gadgets:
                if self.debug:
                    self.imm.log("[*] Max gadgets count reached (%d)" %
                                 self.max_gadgets)
                break

            sa = SequenceAnalyzer(self.imm)

            #consider direction flag off, which is true 99.9% of the time and improves speed over 9000 times
            sa.state.flags["_DF"] = sa.state.solver.false
            addr = r[0]

            if self.debug:
                self.imm.log("[*] Analyzing gadget at 0x%08x" % addr, addr)

            if not sa.analyze(
                    addr, depth=r[1], stopEIP=r[0] + r[2]
            ):  #if the sequence analyzer failed, we cant use this gadget
                if not self.quiet:
                    self.imm.log(
                        "[!] Sequence Analyzer failed for gadget 0x%x" % addr,
                        addr)
                continue

            c += 1
            addr -= module_address  #store offset, not address

            (regProps, flagProps) = sa.state.calcProperties()
            complexity = sa.state.calcComplexity(regProps, flagProps)

            for k, v in sa.state.hashState().iteritems():
                key = (k, v)
                if not hashes.has_key(key):
                    hashes[key] = set()
                hashes[key].add((complexity, addr))

            for k, v in regProps.iteritems():
                if not v:
                    continue
                key = (k, v)
                if not props.has_key(key):
                    props[key] = set()
                props[key].add((complexity, addr))

            if flagProps:
                key = ("FLAGS", flagProps)
                if not props.has_key(key):
                    props[key] = set()
                props[key].add((complexity, addr))

            self.add_gadget_entry(addr, sa.state, complexity, module_id)
            self.db_connection.commit()
            del sa

        self.add_hashes(module_id, hashes)
        self.add_props(module_id, props)
        self.db_connection.commit()

        return c