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
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]
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)
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]
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]
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