def init_impossible_REGtoREG(env): global INIT_LMAX, INIT_MAXDEPTH global baseAssertion # DEBUG #try: startTime = datetime.now() i = 0 impossible_count = 0 for reg1 in sorted(Arch.registers()): reg_name = Arch.r2n(reg1) if (len(reg_name) < 6): reg_name += " " * (6 - len(reg_name)) elif (len(reg_name) >= 6): reg_name = reg_name[:5] + "." for reg2 in Arch.registers(): i += 1 charging_bar(len(Arch.registers() * len(Arch.registers())), i, 30) if (reg2 == reg1 or reg2 == Arch.ipNum()): continue _search(QueryType.REGtoREG, reg1, (reg2, 0), env, n=1) if (env.checkImpossible_REGtoREG(reg1, reg2, 0)): impossible_count += 1 cTime = datetime.now() - startTime # Get how many impossible path we found impossible_rate = int(100 * (float(impossible_count) / float( (len(Arch.registers()) - 1) * len(Arch.registers())))) notify('Optimization rate : {}%'.format(impossible_rate)) notify("Computation time : " + str(cTime))
def init_impossible_REGtoREG(env): global INIT_LMAX, INIT_MAXDEPTH global baseAssertion try: startTime = datetime.now() i = 0 impossible_count = 0 for reg1 in sorted(Arch.registers()): reg_name = Arch.r2n(reg1) if (len(reg_name) < 6): reg_name += " " * (6 - len(reg_name)) elif (len(reg_name) >= 6): reg_name = reg_name[:5] + "." for reg2 in Arch.registers(): i += 1 charging_bar(len(Arch.registers() * len(Arch.registers())), i, 30) if (reg2 == reg1 or reg2 == Arch.ipNum()): continue _search(QueryType.REGtoREG, reg1, (reg2, 0), env, n=1) if (env.checkImpossible_REGtoREG(reg1, reg2, 0)): impossible_count += 1 cTime = datetime.now() - startTime # Get how many impossible path we found impossible_rate = int(100 * (float(impossible_count) / float( (len(Arch.registers()) - 1) * len(Arch.registers())))) notify('Optimization rate : {}%'.format(impossible_rate)) notify("Computation time : " + str(cTime)) except: print("\n") fatal("Exception caught, stopping Semantic Engine init process...\n") fatal("Search time might get very long !\n") env = SearchEnvironment(INIT_LMAX, Constraint(), baseAssertion, INIT_MAXDEPTH)
def build(pair_list): """ Takes a list of pairs (addr, raw_asm) corresponding to gagets (their address and their intructions as a byte string) Fills the 'gadgets' and 'db' global structures ;) """ def sigint_handler(signal, frame): global sigint sigint = True def timeout_handler(signum, frame): global sigalarm sigalarm = True signal.alarm(0) raise TimeOutException('Timeout') global gadgets, db, sigint gadgets = [] raw_to_gadget = dict() sigint = False original_sigint_handler = signal.getsignal(signal.SIGINT) signal.signal(signal.SIGINT, sigint_handler) signal.signal(signal.SIGALRM, timeout_handler) info(string_bold("Creating gadget database\n")) startTime = datetime.now() success = i = 0 # Create the gadgets list for (addr, raw) in pair_list: charging_bar(len(pair_list) - 1, i, 30) if (sigint): break if (raw in raw_to_gadget): gadgets[raw_to_gadget[raw]].addrList.append(addr) success += 1 else: try: signal.alarm(1) gadget = Gadget([addr], raw) signal.alarm(0) success += 1 gadgets.append(gadget) raw_to_gadget[raw] = len(gadgets) - 1 except (GadgetException, TimeOutException) as e: signal.alarm(0) if (isinstance(e, GadgetException)): log("Gadget ({}) : ".format('\\x'+'\\x'\ .join("{:02x}".format(ord(c)) for c in raw)) + str(e)) i += 1 # Find syscalls # TODO # Getting time cTime = datetime.now() - startTime signal.signal(signal.SIGINT, original_sigint_handler) if (sigint): print("\n") fatal( "SIGINT ended the analysis prematurely, gadget database might be incomplete\n" ) sigint = False notify("Gadgets analyzed : " + str(len(pair_list))) notify("Successfully translated : " + str(success)) notify("Computation time : " + str(cTime)) # Create the database db = Database(gadgets)
def __init__(self, gadgets=[]): # List of gadgets self.gadgets = gadgets # Different query types self.types = dict() self.types[QueryType.CSTtoREG] = dict() self.types[QueryType.REGtoREG] = dict() self.types[QueryType.MEMtoREG] = dict() self.types[QueryType.CSTtoMEM] = MEMDict() self.types[QueryType.REGtoMEM] = MEMDict() self.types[QueryType.MEMtoMEM] = MEMDict() self.types[QueryType.SYSCALL] = [] self.types[QueryType.INT80] = [] # Initialize them for r in range(0, Arch.ssaRegCount): self.types[QueryType.CSTtoREG][r] = CSTList() self.types[QueryType.REGtoREG][r] = REGList() self.types[QueryType.MEMtoREG][r] = MEMList() if (gadgets): info(string_bold("Sorting gadgets semantics\n")) # Fill them for i in range(0, len(gadgets)): charging_bar(len(gadgets) - 1, i, 30) gadget = gadgets[i] # Check for special gadgets (int 0x80 and syscall if (gadget.type == GadgetType.INT80): self.types[QueryType.INT80].append(i) continue elif (gadget.type == GadgetType.SYSCALL): self.types[QueryType.SYSCALL].append(i) continue # For XXXtoREG for reg, pairs in gadget.semantics.registers.iteritems(): # Check if it is the final semantic for the register if (reg.ind < gadget.graph.lastMod[reg.num]): # If not, skip this SSA register continue for p in pairs: # For REGtoREG if (isinstance(p.expr, SSAExpr)): self.types[QueryType.REGtoREG][reg.num].add( p.expr.reg.num, 0, i, p.cond) elif (isinstance(p.expr, OpExpr)): (isInc, num, inc) = p.expr.isRegIncrement(-1) if (isInc): self.types[QueryType.REGtoREG][reg.num].add( num, inc, i, p.cond) # For CSTtoREG elif (isinstance(p.expr, ConstExpr)): self.types[QueryType.CSTtoREG][reg.num].add( p.expr.value, i, p.cond) # For MEMtoREG elif (isinstance(p.expr, MEMExpr)): if (isinstance(p.expr.addr, SSAExpr)): self.types[QueryType.MEMtoREG][reg.num].add( p.expr.addr.reg.num, 0, i, p.cond) elif (isinstance(p.expr.addr, OpExpr)): (isInc, num, inc) = p.expr.addr.isRegIncrement(-1) if (isInc): self.types[QueryType.MEMtoREG][reg.num].add( num, inc, i, p.cond) # For XXXtoMEM for addr, pairs in gadget.semantics.memory.iteritems(): addr_reg = None addr_cst = None # Check if the address is of type REG + CST if (isinstance(addr, SSAExpr)): addr_reg = addr.reg.num addr_cst = 0 elif (isinstance(addr, OpExpr)): (isInc, addr_reg, addr_cst) = addr.isRegIncrement(-1) if (not isInc): continue else: continue # Going through spairs for p in pairs: # Check for integrity of the database if (not isinstance(p.expr, Expr)): raise Exception( "Invalid dependency in fillGadgetLookUp(): " + str(p.expr)) # For REGtoMEM if (isinstance(p.expr, SSAExpr)): self.types[QueryType.REGtoMEM].addExpr(addr_reg, \ addr_cst, p.expr.reg.num, 0, i, p.cond) elif (isinstance(p.expr, OpExpr)): (isInc, num, inc) = p.expr.isRegIncrement(-1) if (isInc): self.types[QueryType.REGtoMEM].addExpr(addr_reg,\ addr_cst, num, inc, i, p.cond) # For CSTtoMEM elif (isinstance(p.expr, ConstExpr)): self.types[QueryType.CSTtoMEM].addCst(addr_reg, \ addr_cst, p.expr.value, i, p.cond) # For MEMtoMEM elif (isinstance(p.expr, MEMExpr)): if (isinstance(p.expr.addr, SSAExpr)): self.types[QueryType.MEMtoMEM].addExpr(addr_reg,\ addr_cst, p.expr.addr.reg.num, 0, i, p.cond) elif (isinstance(p.expr.addr, OpExpr)): (isInc, num, inc) = p.expr.addr.isRegIncrement(-1) if (isInc): self.types[QueryType.MEMtoMEM].addExpr(addr_reg,\ addr_cst, num, inc, i, p.cond)