예제 #1
0
    def assembly_ast(self, astree: AbstractSyntaxTree, iaddr: str,
                     bytestring: str,
                     xdata: InstrXData) -> List[AST.ASTInstruction]:
        regsop = self.operands[1]
        if not regsop.is_register_list:
            raise UF.CHBError("Argument to push is not a register list")

        (splval, _, _) = self.operands[0].ast_lvalue(astree)
        (sprval, _, _) = self.operands[0].ast_rvalue(astree)

        instrs: List[AST.ASTInstruction] = []
        registers = regsop.registers
        sp_decr = 4 * len(registers)
        sp_offset = sp_decr
        for r in registers:
            sp_offset_c = astree.mk_integer_constant(sp_offset)
            addr = astree.mk_binary_op("minus", sprval, sp_offset_c)
            lhs = astree.mk_memref_lval(addr)
            rhs = astree.mk_register_variable_expr(r)
            instrs.append(astree.mk_assign(lhs, rhs))
            sp_offset -= 4
        sp_decr_c = astree.mk_integer_constant(sp_decr)
        sp_rhs = astree.mk_binary_op("minus", sprval, sp_decr_c)
        instrs.append(astree.mk_assign(splval, sp_rhs))
        astree.add_instruction_span(instrs[0].id, iaddr, bytestring)
        return instrs
    def ast(self,
            astree: AbstractSyntaxTree,
            iaddr: str,
            bytestring: str,
            xdata: InstrXData) -> List[ASTInstruction]:
        lhs = xdata.vars[0]
        rhs1 = str(xdata.xprs[0])
        rhs2 = xdata.xprs[1]
        rhs3 = xdata.xprs[3]

        if lhs == "SP" and rhs1 == "SP" and rhs2.is_constant:
            return []

        lhsast = XU.xvariable_to_ast_lval(lhs, astree)
        if rhs1 == "SP" and rhs3.is_stack_address:
            rhs3 = cast("XprCompound", rhs3)
            stackoffset = rhs3.stack_address_offset()
            rhslval = astree.mk_stack_variable_lval(stackoffset)
            rhsast: ASTExpr = astree.mk_address_of(rhslval)

        elif rhs1 == "PC" or str(rhs2) == "PC":
            if rhs3.is_int_constant:
                rhsval = cast("XprConstant", rhs3).intvalue
                rhsast = astree.mk_integer_constant(rhsval)
            else:
                rhsast = XU.xxpr_to_ast_expr(rhs3, astree)

        else:
            rhsast = XU.xxpr_to_ast_expr(rhs3, astree)

        result = astree.mk_assign(lhsast, rhsast)
        astree.add_instruction_span(result.id, iaddr, bytestring)
        return [result]
 def ast(self, astree: AbstractSyntaxTree, iaddr: str, bytestring: str,
         xdata: InstrXData) -> List[AST.ASTInstruction]:
     rhs = XU.xxpr_to_ast_expr(xdata.xprs[1], astree)
     lhs = XU.xvariable_to_ast_lval(xdata.vars[0], astree)
     assign = astree.mk_assign(lhs, rhs)
     astree.add_instruction_span(assign.id, iaddr, bytestring)
     return [assign]
 def ast(self, astree: AbstractSyntaxTree, iaddr: str, bytestring: str,
         xdata: InstrXData) -> List[AST.ASTInstruction]:
     (rhs, _, _) = self.operands[0].ast_rvalue(astree)
     lhs = xdata.vars[0]
     lval = XU.xvariable_to_ast_lval(lhs, astree)
     assign = astree.mk_assign(lval, rhs)
     astree.add_instruction_span(assign.id, iaddr, bytestring)
     return [assign]
 def assembly_ast(self, astree: AbstractSyntaxTree, iaddr: str,
                  bytestring: str,
                  xdata: InstrXData) -> List[AST.ASTInstruction]:
     (rhs, preinstrs, postinstrs) = self.operands[1].ast_rvalue(astree)
     (lhs, _, _) = self.operands[0].ast_lvalue(astree)
     assign = astree.mk_assign(lhs, rhs)
     astree.add_instruction_span(assign.id, iaddr, bytestring)
     return preinstrs + [assign] + postinstrs
예제 #6
0
 def assembly_ast(self, astree: AbstractSyntaxTree, iaddr: str,
                  bytestring: str,
                  xdata: InstrXData) -> List[ASTInstruction]:
     (lhs, _, _) = self.operands[0].ast_lvalue(astree)
     (op1, _, _) = self.operands[1].ast_rvalue(astree)
     (op2, _, _) = self.operands[2].ast_rvalue(astree)
     binop = astree.mk_binary_op("minus", op1, op2)
     result = astree.mk_assign(lhs, binop)
     astree.add_instruction_span(result.id, iaddr, bytestring)
     return [result]
예제 #7
0
 def assembly_ast(self, astree: AbstractSyntaxTree, iaddr: str,
                  bytestring: str,
                  xdata: InstrXData) -> List[AST.ASTInstruction]:
     (rhs1, preinstrs1, postinstrs1) = self.operands[1].ast_rvalue(astree)
     (rhs2, preinstrs2, postinstrs2) = self.operands[2].ast_rvalue(astree)
     (lhs, _, _) = self.operands[0].ast_lvalue(astree)
     binop = astree.mk_binary_op("band", rhs1, rhs2)
     assign = astree.mk_assign(lhs, binop)
     astree.add_instruction_span(assign.id, iaddr, bytestring)
     return preinstrs1 + preinstrs2 + [assign] + postinstrs1 + postinstrs2
 def assembly_ast(self, astree: AbstractSyntaxTree, iaddr: str,
                  bytestring: str,
                  xdata: InstrXData) -> List[AST.ASTInstruction]:
     if len(xdata.vars) == 1 and len(xdata.xprs) == 1:
         lhs = astree.mk_variable_lval(str(xdata.vars[0]))
         rhs = XU.xxpr_to_ast_expr(xdata.xprs[0], astree)
         assign = astree.mk_assign(lhs, rhs)
         astree.add_instruction_span(assign.id, iaddr, bytestring)
         return [assign]
     else:
         return []
 def assembly_ast(self, astree: AbstractSyntaxTree, iaddr: str,
                  bytestring: str,
                  xdata: InstrXData) -> List[AST.ASTInstruction]:
     (lhs1, preinstrs1, postinstrs1) = self.operands[4].ast_lvalue(astree)
     (lhs2, preinstrs2, postinstrs2) = self.operands[5].ast_lvalue(astree)
     (rhs1, _, _) = self.operands[0].ast_rvalue(astree)
     (rhs2, _, _) = self.operands[1].ast_rvalue(astree)
     assign1 = astree.mk_assign(lhs1, rhs1)
     assign2 = astree.mk_assign(lhs2, rhs2)
     astree.add_instruction_span(assign1.id, iaddr, bytestring)
     return (preinstrs1 + preinstrs2 + [assign1, assign2] + postinstrs1 +
             postinstrs2)
예제 #10
0
 def assembly_ast_condition(self, astree: AbstractSyntaxTree, iaddr: str,
                            bytestring: str,
                            xdata: InstrXData) -> Optional[ASTExpr]:
     ftconds = self.ft_conditions(xdata)
     if len(ftconds) == 2:
         tcond = ftconds[1]
         if tcond.is_constant:
             astcond = XU.xxpr_to_ast_expr(xdata.xprs[2], astree)
         else:
             astcond = XU.xxpr_to_ast_expr(tcond, astree)
         astree.add_instruction_span(astcond.id, iaddr, bytestring)
         return astcond
     else:
         return None
 def assembly_ast(
         self,
         astree: AbstractSyntaxTree,
         iaddr: str,
         bytestring: str,
         xdata: InstrXData) -> List[AST.ASTInstruction]:
     if xdata.instruction_is_subsumed():
         return []
     else:
         (lhs, _, _) = self.operands[0].ast_lvalue(astree)
         (rhs, _, _) = self.operands[1].ast_rvalue(astree)
         assign = astree.mk_assign(lhs, rhs)
         astree.add_instruction_span(assign.id, iaddr, bytestring)
         return [assign]
 def ast(self, astree: AbstractSyntaxTree, iaddr: str, bytestring: str,
         xdata: InstrXData) -> List[AST.ASTInstruction]:
     (rhs1, _, _) = self.operands[0].ast_rvalue(astree)
     (rhs2, _, _) = self.operands[1].ast_rvalue(astree)
     lhs1 = str(xdata.vars[0])
     lhs2 = str(xdata.vars[1])
     if lhs1.endswith("[0]"):
         lhs1 = "*" + lhs1[:-3]
     lval1 = astree.mk_variable_lval(lhs1)
     lval2 = astree.mk_variable_lval(lhs2)
     assign1 = astree.mk_assign(lval1, rhs1)
     assign2 = astree.mk_assign(lval2, rhs2)
     astree.add_instruction_span(assign1.id, iaddr, bytestring)
     astree.add_instruction_span(assign2.id, iaddr, bytestring)
     return [assign1, assign2]
 def ast(
         self,
         astree: AbstractSyntaxTree,
         iaddr: str,
         bytestring: str,
         xdata: InstrXData) -> List[AST.ASTInstruction]:
     if xdata.instruction_is_subsumed():
         return []
     else:
         lhs = XU.xvariable_to_ast_lval(xdata.vars[0], astree)
         rhs = XU.xxpr_to_ast_expr(xdata.xprs[0], astree)
         # (lhs, _, _) = self.operands[0].ast_lvalue(astree)
         # (rhs, _, _) = self.operands[1].ast_rvalue(astree)
         assign = astree.mk_assign(lhs, rhs)
         astree.add_instruction_span(assign.id, iaddr, bytestring)
         return [assign]
예제 #14
0
 def assembly_ast(self, astree: AbstractSyntaxTree, iaddr: str,
                  bytestring: str,
                  xdata: InstrXData) -> List[ASTInstruction]:
     lhs = astree.mk_register_variable_lval("R0")
     tgt = self.operands[0]
     if tgt.is_absolute:
         tgtaddr = cast(ARMAbsoluteOp, tgt.opkind)
         if self.app.has_function_name(tgtaddr.address.get_hex()):
             faddr = tgtaddr.address.get_hex()
             fnsymbol = self.app.function_name(faddr)
             tgtxpr: ASTExpr = astree.mk_global_variable_expr(
                 fnsymbol, globaladdress=int(str(tgtaddr.address), 16))
         else:
             (tgtxpr, _, _) = self.operands[0].ast_rvalue(astree)
     else:
         (tgtxpr, _, _) = self.operands[0].ast_rvalue(astree)
     call = astree.mk_call(lhs, tgtxpr, [])
     astree.add_instruction_span(call.id, iaddr, bytestring)
     return [call]
예제 #15
0
 def ast(self,
         astree: AbstractSyntaxTree,
         iaddr: str,
         bytestring: str,
         xdata: InstrXData) -> List[ASTInstruction]:
     tgtx = str(xdata.xprs[0])
     if tgtx == "$ra_in":
         return []
     elif self.is_call(xdata) and xdata.has_call_target():
         calltarget = xdata.call_target(self.ixd)
         tgtname = calltarget.name
         tgtxpr = self.target_expr_ast(astree, xdata)
         (lhs, assigns) = self.lhs_ast(astree, iaddr, xdata)
         args = self.arguments(xdata)
         argxprs: List[ASTExpr] = []
         for arg in args:
             if XU.is_struct_field_address(arg, astree):
                 addr = XU.xxpr_to_struct_field_address_expr(arg, astree)
             elif arg.is_string_reference:
                 xpr = XU.xxpr_to_ast_expr(arg, astree)
                 cstr = arg.constant.string_reference()
                 saddr = hex(arg.constant.value)
                 argxprs.append(astree.mk_string_constant(xpr, cstr, saddr))
             elif arg.is_argument_value:
                 argindex = arg.argument_index()
                 funarg = astree.function_argument(argindex)
                 if funarg:
                     astxpr = astree.mk_register_variable_expr(
                         funarg.name, vtype=funarg.typ, parameter=argindex)
                     argxprs.append(astxpr)
                 else:
                     astxpr = XU.xxpr_to_ast_expr(arg, astree)
                     argxprs.append(astxpr)
             else:
                 astxpr = XU.xxpr_to_ast_expr(arg, astree)
                 argxprs.append(astxpr)
         if lhs.is_ignored:
             call: ASTInstruction = astree.mk_call(lhs, tgtxpr, argxprs)
             astree.add_instruction_span(call.id, iaddr, bytestring)
             return [call]
         else:
             call = cast(ASTInstruction, astree.mk_call(lhs, tgtxpr, argxprs))
             astree.add_instruction_span(call.id, iaddr, bytestring)
             for assign in assigns:
                 astree.add_instruction_span(assign.id, iaddr, bytestring)
             return [call] + assigns
     else:
         #  TODO: accomodate indirect jumps
         return []
 def ast(self,
         astree: AbstractSyntaxTree,
         iaddr: str,
         bytestring: str,
         xdata: InstrXData) -> List[ASTInstruction]:
     if self.is_call(xdata) and xdata.has_call_target():
         calltarget = xdata.call_target(self.ixd)
         tgtname = calltarget.name
         tgtxpr = self.target_expr_ast(astree, xdata)
         (lhs, assigns) = self.lhs_ast(astree, iaddr, xdata)
         args = self.arguments(xdata)
         argregs = ["R0", "R1", "R2", "R3"]
         callargs = argregs[:len(args)]
         argxprs: List[ASTExpr] = []
         for (reg, arg) in zip(callargs, args):
             if XU.is_struct_field_address(arg, astree):
                 addr = XU.xxpr_to_struct_field_address_expr(arg, astree)
                 argxprs.append(addr)
             elif arg.is_string_reference:
                 regast = astree.mk_register_variable_expr(reg)
                 cstr = arg.constant.string_reference()
                 saddr = hex(arg.constant.value)
                 argxprs.append(astree.mk_string_constant(regast, cstr, saddr))
             elif arg.is_argument_value:
                 argindex = arg.argument_index()
                 funarg = astree.function_argument(argindex)
                 if funarg:
                     astxpr = astree.mk_register_variable_expr(
                         funarg.name, vtype=funarg.typ, parameter=argindex)
                     argxprs.append(astxpr)
                 else:
                     argxprs.append(astree.mk_register_variable_expr(reg))
             else:
                 argxprs.append(astree.mk_register_variable_expr(reg))
         if len(args) > 4:
             for a in args[4:]:
                 argxprs.append(XU.xxpr_to_ast_expr(a, astree))
         if lhs.is_ignored:
             call: ASTInstruction = astree.mk_call(lhs, tgtxpr, argxprs)
             astree.add_instruction_span(call.id, iaddr, bytestring)
             return [call]
         else:
             call = cast(ASTInstruction, astree.mk_call(lhs, tgtxpr, argxprs))
             astree.add_instruction_span(call.id, iaddr, bytestring)
             for assign in assigns:
                 astree.add_instruction_span(assign.id, iaddr, bytestring)
             return [call] + assigns
     else:
         return self.assembly_ast(astree, iaddr, bytestring, xdata)
 def assembly_ast_condition(self, astree: AbstractSyntaxTree, iaddr: str,
                            bytestring: str,
                            xdata: InstrXData) -> Optional[ASTExpr]:
     ftconds = self.ft_conditions(xdata)
     if len(ftconds) == 2:
         tcond = ftconds[1]
         astcond = XU.xxpr_to_ast_expr(tcond, astree)
         if xdata.has_condition_setter():
             csetter = xdata.get_condition_setter()
             cbytestr = xdata.get_condition_setter_bytestring()
             if int(csetter, 16) + (len(cbytestr) // 2) == int(iaddr, 16):
                 newaddr = hex(int(iaddr, 16) - (len(cbytestr) // 2))
                 astree.add_instruction_span(astcond.id, newaddr,
                                             cbytestr + bytestring)
             else:
                 astree.add_instruction_span(astcond.id, iaddr, bytestring)
         else:
             astree.add_instruction_span(astcond.id, iaddr, bytestring)
         return astcond
     else:
         return None