Example #1
0
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))
Example #2
0
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)
Example #3
0
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)
Example #4
0
    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)