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") imm.log("Model:") model = solver.getConcreteModel()
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)
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") imm.log("Model:") model = solver.getConcreteModel()