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
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
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
(', '.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") imm.log("Model:") model = solver.getConcreteModel() strip_p = '[()=]' strip_r = re.compile(strip_p)
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)
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)
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