Exemple #1
0
 def mk_instance(
         self,
         vd: "FnVarDictionary",
         ixval: IndexedTableValue,
         superclass: type) -> VdR:
     tag = ixval.tags[0]
     if (superclass, tag) not in self.register:
         raise UF.CHBError(
             "Unknown vardictionary type: "
             + tag
             + " with type "
             + str(superclass))
     instance = self.register[(superclass, tag)](vd, ixval)
     return cast(VdR, instance)
    def condition(self, src: str, tgt: str) -> Optional[XXpr]:
        """Returns the condition, if any, that leads from src to tgt."""

        if len(self.edges[src]) > 1:
            brinstr = self.branch_instruction(src)
            ftconditions = brinstr.ft_conditions
            if len(ftconditions) == 2:
                for i, t in enumerate(self.edges[src]):
                    if tgt == t:
                        return ftconditions[i]
            else:
                raise UF.CHBError("Error in Cfg.condition")

        return None
Exemple #3
0
 def to_xml(self, node: ET.Element) -> None:
     xsuccessors = ET.Element(self.name)
     node.append(xsuccessors)
     for srec in self.successors:
         if "ia" in srec:
             iaddr = cast(str, srec["ia"])
             if "sr" in srec:
                 addrs: List[str] = []
                 srange = cast(List[str], srec["sr"])
                 sa = int(srange[0], 16)
                 se = int(srange[1], 16)
                 for a in range(sa, se, 4):
                     addrs.append(hex(a))
                 xs = ET.Element("instr")
                 xs.set("ia", iaddr)
                 xs.set("ss", ",".join(addrs))
                 xsuccessors.append(xs)
             else:
                 raise UF.CHBError("Successor range field missing " +
                                   "from successor specification: " + iaddr)
         else:
             raise UF.CHBError("Instruction address (ia) missing " +
                               "from successor specification")
Exemple #4
0
    def get_strings(self, minlen: int = 3) -> Generator[
            Tuple[int, List[int]], None, None]:
        """Yield sequences of printable characters of mimimum length minlen."""
        def makestream(s: str) -> Generator[Tuple[int, int], None, None]:
            c = 0
            for w in s.split():
                for i in range(0, len(w), 2):
                    yield((c*8) + i, int(w[i:i+2], 16))
                c += 1

        def is_printable(i: int) -> bool:
            return (i >= 32 and i < 127)

        result: List[int] = []
        for b in self.hex_data.findall("ablock"):
            for a in b.findall("aline"):
                xva = a.get("va")
                if xva:
                    va = int(xva, 16)
                    xbytes = a.get("bytes")
                    if xbytes:
                        for (offset, i) in makestream(xbytes):
                            if is_printable(i):
                                result.append(i)
                            else:
                                if len(result) >= minlen:
                                    strva = (va + (offset // 2)) - len(result)
                                    strval = result[:]
                                    result = []
                                    yield (strva, strval)
                                else:
                                    result = []
                    else:
                        raise UF.CHBError(
                            "Raw section line without bytes")
                else:
                    raise UF.CHBError("Raw section line without virtual address")
Exemple #5
0
 def to_xml(self, node: ET.Element) -> None:
     xswitchpoints = ET.Element(self.name)
     node.append(xswitchpoints)
     for p in self.switchpoints:
         if p.endswith(":A") or p.endswith(":T"):
             iaddr = p[:-2]
             tgt = p[-1]
             xs = ET.Element("switch")
             xs.set("ia", iaddr)
             xs.set("tgt", tgt)
             xswitchpoints.append(xs)
         else:
             raise UF.CHBError("Error in thumb switch point: " +
                               "Expected format <addr>:A or <addr>:T . " +
                               "Found: " + p)
    def _read_summary(self, dll, fname):
        def isref(xnode):
            return (not (xnode.find('refer-to') is None))

        xnode = self.get_summary_xnode(dll, fname)
        if xnode is None:
            raise UF.CHBError('Summary for ' + dll + ':' + fname +
                              ' may be corrupted')
        if isref(xnode):
            refnode = xnode.find('refer-to')
            self.dllsummaries[(dll,
                               fname)] = DllSummaryRef(self.models, refnode,
                                                       dll, fname)
        else:
            self.dllsummaries[(dll, fname)] = DllSummary(self.models, xnode)
Exemple #7
0
 def get_call_facts(self):
     if not self.is_call_instruction():
         raise UF.CHBError("Not a call instruction: " + str(self))
     xdata = self.idictionary.read_xml_instrx(self.xnode)
     opcode = self.mipsdictionary.read_xml_mips_opcode(self.xnode)
     result = {}
     callargs = self.get_annotated_call_arguments()
     if callargs:
         result['args'] = callargs
     tgt = self.get_call_target()
     if tgt == 'call-target:u':
         result['t'] = '?'
     else:
         result['t'] = str(tgt)
     return result
Exemple #8
0
def xxpr_to_ast_expr(xpr: X.XXpr, astree: AbstractSyntaxTree) -> AST.ASTExpr:
    """Convert an XXpr expression into an AST Expr node."""

    if xpr.is_constant:
        return xconstant_to_ast_expr(cast(X.XprConstant, xpr), astree)

    elif xpr.is_var:
        return xprvariable_to_ast_expr(cast(X.XprVariable, xpr), astree)

    elif xpr.is_compound:
        return xcompound_to_ast_expr(cast(X.XprCompound, xpr), astree)

    else:
        raise UF.CHBError("AST conversion of xxpr " + str(xpr) +
                          " not yet supported")
Exemple #9
0
 def reset_to_checkpoint(self) -> int:
     """Remove all entries added since the checkpoint was set."""
     cp = self.checkpoint
     if cp is None:
         raise UF.CHBError("Cannot reset non-existent checkpoint")
     for i in range(cp, self.next):
         if i in self.reserved:
             continue
         self.indextable.pop(i)
     for k in self.keytable.keys():
         if self.keytable[k] >= cp:
             self.keytable.pop(k)
     self.checkpoint = None
     self.reserved = []
     self.next = cp
     return cp
Exemple #10
0
 def instructions(self) -> Mapping[str, ARMAssemblyInstruction]:
     if len(self._instructions) == 0:
         for b in self.xnode.findall("b"):
             for n in b.findall("i"):
                 iaddr = n.get("ia")
                 if iaddr is None:
                     raise UF.CHBError("Instruction without address")
                 opcode = self.app.armdictionary.read_xml_arm_opcode(n)
                 stat = n.get("stat", "")
                 self._instructions[iaddr] = ARMAssemblyInstruction(
                     iaddr, opcode, stat)
         self.sorted_instructions = (
             sorted(int(k, 16) for k in self._instructions.keys()))
         self.revsorted_instructions = sorted(
             self.sorted_instructions, reverse=True)
     return self._instructions
Exemple #11
0
 def roles(self) -> Sequence[ParameterRole]:
     if "roles" in self.xnode.attrib:
         xrolesattr = self.xnode.get("roles")
         if xrolesattr:
             if xrolesattr == "none":
                 return []
             else:
                 raise UF.CHBError("Roles attribute not recognized: "
                                   + str(xrolesattr))
         else:
             return []
     xroles = self.xnode.find('roles')
     if xroles:
         return [ParameterRole(self, r) for r in xroles.findall("role")]
     else:
         return []
Exemple #12
0
 def invariants(self) -> Mapping[str, Sequence[InvariantFact]]:
     if len(self._invariants) == 0:
         xinvnode = UF.get_function_invs_xnode(
             self.path, self.filename, self.faddr)
         xfacts = xinvnode.find("locations")
         if xfacts is None:
             raise UF.CHBError("Location invariants element not found")
         for xloc in xfacts.findall("loc"):
             xaddr = xloc.get("a")
             xifacts = xloc.get("ifacts")
             if xaddr is not None and xifacts is not None:
                 ifacts = [int(i) for i in xifacts.split(",")]
                 self._invariants[xaddr] = []
                 for ix in ifacts:
                     self._invariants[xaddr].append(
                         self.invdictionary.invariant_fact(ix))
     return self._invariants
Exemple #13
0
def xtyped_expr_to_ast_expr(op: str, op1: AST.ASTExpr, op2: AST.ASTExpr,
                            astree: AbstractSyntaxTree) -> AST.ASTExpr:
    """Determine if expression needs different representation based on type."""

    if op1.ctype is None:
        raise UF.CHBError("Expression is not typed: " + str(op1))

    if op1.ctype.is_pointer and op2.is_integer_constant:
        op2 = cast(AST.ASTIntegerConstant, op2)
        tgttype = cast("BCTypPtr", op1.ctype).tgttyp
        if tgttype.is_struct:
            compinfo = cast("BCTypComp", tgttype).compinfo
            fieldoffset = field_at_offset(compinfo, op2.cvalue, astree)
            lval = astree.mk_memref_lval(op1, fieldoffset)
            return astree.mk_address_of(lval)

    return astree.mk_binary_op(op, op1, op2)
 def initialize(self, xnode: ET.Element) -> None:
     for t in self.tables:
         t.reset()
         xtable = xnode.find(t.name)
         if xtable is not None:
             t.read_xml(xtable, "n")
         else:
             if t.name.startswith("arm") and (not self.app.is_arm):
                 pass
             else:
                 raise UF.CHBError("Error reading table " + t.name)
     self.string_table.reset()
     xstable = xnode.find(self.string_table.name)
     if xstable is not None:
         self.string_table.read_xml(xstable)
     else:
         raise UF.CHError("Error reading stringtable " +
                          self.string_table.name)
Exemple #15
0
 def to_xml(self, node: ET.Element) -> None:
     xjumps = ET.Element(self.name)
     node.append(xjumps)
     for r in self.jumps:
         if "fa" in r and "ia" in r and "targets" in r:
             fa = cast(str, r["fa"])
             ia = cast(str, r["ia"])
             tgts = cast(List[str], r["targets"])
             xj = ET.Element("jumpinstr")
             xjumps.append(xj)
             xj.set("fa", fa)
             xj.set("ia", ia)
             for tgt in tgts:
                 xtgt = ET.Element("tgt")
                 xj.append(xtgt)
                 xtgt.set("a", tgt)
         else:
             raise UF.CHBError("Invalid format for indirect jump: " +
                               "expected to find fa, ia, and targets")
def mk_user_btype(d: Union[str, Dict[str, Any]]) -> T.UserBType:
    if isinstance(d, str) or "name" in d:
        name: str = d if isinstance(d, str) else d["name"]
        if name in opaque_types:
            return T.UserNamedBType(name)
        elif user_type_store.has_size_of(name):
            size = user_type_store.size_of(name)
            return T.UserNamedBType(name, size=size)
        else:
            raise UF.CHBError("Cannot determine size of named type " + name)
    elif "key" in d:
        if d["key"] == "ptr":
            if "tgt" in d:
                try:
                    return T.UserPointerBType(mk_user_btype(d["tgt"]))
                except UF.CHBError as e:
                    raise UF.CHBError("Error in pointer target type: " + str(e))
            else:
                raise UF.CHBError("Expected tgt field for pointer type")
        elif d["key"] == "struct":
            if "fields" in d:
                return T.UserStructBType(mk_field_infos(d["fields"]))
            else:
                raise UF.CHBError("Expected fields field for struct type")
        elif d["key"] == "array":
            if "tgt" in d and "size" in d:
                try:
                    return T.UserArrayBType(mk_user_btype(d["tgt"]), d["size"])
                except UF.CHBError as e:
                    raise UF.CHBError("Error in array target type: " + str(e))
            else:
                raise UF.CHBError("Expected tgt and size for array type")
        else:
            raise UF.CHBError("Key " + d["key"] + " not recognized for btype")
    else:
        raise UF.CHBError("Expected name or key field in btype")
Exemple #17
0
 def get_zero_blocks(self, hexva: str, align: int = 32) -> List[Tuple[str, str]]:
     s = ""
     offsetalign = 2 * align
     z = "0" * offsetalign
     qalign = int(align / 4)
     qoffsetalign = int(offsetalign / 4)
     qz = "0" * qoffsetalign
     for b in self.hex_data.findall("block"):
         for a in b.findall("aline"):
             xbytes = a.get("bytes")
             if xbytes:
                 s += xbytes.replace(" ", "")
             else:
                 raise UF.CHBError("Raw section line without bytes")
     va = int(hexva, 16)
     offset = 0
     slen = len(s)
     result = []
     while (va % align) > 0:
         va += 1
         offset += 2
     while offset < slen - offsetalign:
         while s[offset:offset+offsetalign] != z:
             va += align
             offset += offsetalign
             if offset > slen - offsetalign:
                 break
         if offset > slen - qoffsetalign:
             break
         dbstart = hex(va)
         while (s[offset:offset+qoffsetalign] == qz):
             va += qalign
             offset += qoffsetalign
             if offset > slen - qoffsetalign:
                 break
         dbend = hex(va)
         result.append((dbstart, dbend))
     return result
Exemple #18
0
    def subu(self, simval: SV.SimValue) -> SV.SimValue:
        """Unsigned subtraction.

        This may be either subtraction of another stackaddress, resulting
        in a scalar, or subtraction of a scalar, resulting in another
        stack address.
        """

        if simval.is_literal and simval.is_defined:
            simval = cast(SV.SimLiteralValue, simval)
            return self.add_offset(-simval.value)
        elif simval.is_symbolic:
            simval = cast(SimSymbolicValue, simval)
            if simval.is_stack_address:
                simval = cast("SimStackAddress", simval)
                return SV.mk_simvalue(self.offsetvalue - simval.offsetvalue,
                                      size=4)
            else:
                raise UF.CHBError(
                    "Illegal subtraction from stack address with: " +
                    str(simval))
        else:
            return SV.simUndefinedDW
 def name(self) -> str:
     raise UF.CHBError(
         "Method name only applicable to named type, not to " + self.kind)
 def faddr(self) -> str:
     xfaddr = self.xnode.get("fa")
     if xfaddr is not None:
         return xfaddr
     else:
         raise UF.CHBError("Function address missing from stack adjustment")
 def unresolved_call_target_expr(self) -> XXpr:
     if self.has_global_value_unresolved_call_target():
         opc = cast(X86Call, self.opcode)
         return opc.unresolved_call_target_expr(self.xdata)
     else:
         raise UF.CHBError("Instruction is not an unresolved call")
 def call_arguments(self) -> List[XXpr]:
     if self.opcode.is_call:
         opc = cast(X86Call, self.opcode)
         return opc.arguments(self.xdata)
     else:
         raise UF.CHBError("Instruction is not a call instruction")
 def call_target(self) -> CallTarget:
     if self.opcode.is_call:
         opc = cast(X86Call, self.opcode)
         return opc.call_target(self.xdata)
     else:
         raise UF.CHBError("Instruction is not a call instruction")
 def addr(self) -> str:
     xaddr = self.xnode.get("a")
     if xaddr is not None:
         return xaddr
     else:
         raise UF.CHBError("Address missing from function name")
 def jumptable_targets(self) -> List[str]:
     if self.is_indirect_jump():
         opc = cast(X86IndirectJmp, self.opcode)
         return opc.targets(self.xdata)
     else:
         raise UF.CHBError("Instruction is not an indirect jump: " + str(self))
 def branch_predicate(self) -> XXpr:
     if self.has_branch_predicate():
         return self.opcode.predicate(self.xdata)
     else:
         raise UF.CHBError("Instruction does not have a branch predicate: "
                           + str(self))
Exemple #27
0
 def call_target(self, xdata: InstrXData) -> "CallTarget":
     if self.is_call(xdata):
         return xdata.call_target(self.ixd)
     else:
         raise UF.CHBError("Instruction is not a call: " + str(self))
 def selector_expr(self) -> XXpr:
     if self.is_indirect_jump():
         return self.opcode.selector_expr(self.xdata)
     else:
         raise UF.CHBError("Instruction is not an indirect jump: " + str(self))
 def name(self) -> str:
     xname = self.xnode.get("n")
     if xname is not None:
         return xname
     else:
         raise UF.CHBError("Name missing from function name")
 def branch_condition(self) -> XXpr:
     if self.has_branch_condition():
         return self.xdata.xprs[0]
     else:
         raise UF.CHBError('Instruction does not have a branch condition: '
                           + str(self))