diff options
| -rw-r--r-- | example/ida/ctype_propagation.py | 13 | ||||
| -rw-r--r-- | miasm2/analysis/data_flow.py | 1 | ||||
| -rw-r--r-- | miasm2/arch/aarch64/sem.py | 12 | ||||
| -rw-r--r-- | miasm2/arch/arm/arch.py | 4 | ||||
| -rw-r--r-- | miasm2/arch/arm/ira.py | 61 | ||||
| -rw-r--r-- | miasm2/arch/mips32/ira.py | 5 | ||||
| -rw-r--r-- | miasm2/arch/ppc/ira.py | 37 | ||||
| -rw-r--r-- | miasm2/arch/x86/arch.py | 2 | ||||
| -rw-r--r-- | miasm2/arch/x86/ira.py | 31 | ||||
| -rw-r--r-- | miasm2/core/cpu.py | 2 | ||||
| -rw-r--r-- | miasm2/ir/analysis.py | 27 | ||||
| -rw-r--r-- | test/arch/x86/unit/test_asm_x86_64.py | 30 | ||||
| -rwxr-xr-x | test/test_all.py | 1 |
13 files changed, 167 insertions, 59 deletions
diff --git a/example/ida/ctype_propagation.py b/example/ida/ctype_propagation.py index e8b52e3e..3c8a745a 100644 --- a/example/ida/ctype_propagation.py +++ b/example/ida/ctype_propagation.py @@ -230,11 +230,14 @@ def get_ira_call_fixer(ira): stk_after = idc.GetSpd(instr.offset + instr.l) stk_diff = stk_after - stk_before print hex(stk_diff) - return [AssignBlock([ExprAff(self.ret_reg, ExprOp('call_func_ret', ad)), - ExprAff(self.sp, self.sp + ExprInt(stk_diff, self.sp.size)) - ], - instr - )] + call_assignblk = AssignBlock( + [ + ExprAff(self.ret_reg, ExprOp('call_func_ret', ad)), + ExprAff(self.sp, self.sp + ExprInt(stk_diff, self.sp.size)) + ], + instr + ) + return [call_assignblk], [] return iraCallStackFixer diff --git a/miasm2/analysis/data_flow.py b/miasm2/analysis/data_flow.py index 62176bb1..bba598e0 100644 --- a/miasm2/analysis/data_flow.py +++ b/miasm2/analysis/data_flow.py @@ -229,6 +229,7 @@ def dead_simp_useful_assignblks(irarch, defuse, reaching_defs): for lval, rval in assignblk.iteritems(): if (lval.is_mem() or irarch.IRDst == lval or + lval.is_id("exception_flags") or rval.is_function_call()): useful.add(AssignblkNode(block_lbl, index, lval)) diff --git a/miasm2/arch/aarch64/sem.py b/miasm2/arch/aarch64/sem.py index a17c0f14..646065f4 100644 --- a/miasm2/arch/aarch64/sem.py +++ b/miasm2/arch/aarch64/sem.py @@ -637,8 +637,10 @@ def cbnz(arg1, arg2): @sbuild.parse def tbz(arg1, arg2, arg3): bitmask = m2_expr.ExprInt(1, arg1.size) << arg2 - dst = m2_expr.ExprId( - ir.get_next_loc_key(instr), 64) if arg1 & bitmask else arg3 + dst = m2_expr.ExprLoc( + ir.get_next_loc_key(instr), + 64 + ) if arg1 & bitmask else arg3 PC = dst ir.IRDst = dst @@ -646,8 +648,10 @@ def tbz(arg1, arg2, arg3): @sbuild.parse def tbnz(arg1, arg2, arg3): bitmask = m2_expr.ExprInt(1, arg1.size) << arg2 - dst = arg3 if arg1 & bitmask else m2_expr.ExprId( - ir.get_next_loc_key(instr), 64) + dst = arg3 if arg1 & bitmask else m2_expr.ExprLoc( + ir.get_next_loc_key(instr), + 64 + ) PC = dst ir.IRDst = dst diff --git a/miasm2/arch/arm/arch.py b/miasm2/arch/arm/arch.py index 82664476..e25e4911 100644 --- a/miasm2/arch/arm/arch.py +++ b/miasm2/arch/arm/arch.py @@ -420,6 +420,8 @@ class instruction_arm(instruction): def dstflow(self): + if self.is_subcall(): + return True return self.name in conditional_branch + unconditional_branch def dstflow2label(self, loc_db): @@ -434,6 +436,8 @@ class instruction_arm(instruction): self.args[0] = ExprLoc(loc_key, expr.size) def breakflow(self): + if self.is_subcall(): + return True if self.name in conditional_branch + unconditional_branch: return True if self.name.startswith("LDM") and PC in self.args[1].args: diff --git a/miasm2/arch/arm/ira.py b/miasm2/arch/arm/ira.py index 7b26a6e4..fd8096d7 100644 --- a/miasm2/arch/arm/ira.py +++ b/miasm2/arch/arm/ira.py @@ -1,8 +1,9 @@ #-*- coding:utf-8 -*- from miasm2.ir.analysis import ira -from miasm2.arch.arm.sem import ir_arml, ir_armtl, ir_armb, ir_armtb -from miasm2.expression.expression import ExprAff, ExprOp +from miasm2.ir.ir import IRBlock +from miasm2.arch.arm.sem import ir_arml, ir_armtl, ir_armb, ir_armtb, tab_cond +from miasm2.expression.expression import ExprAff, ExprOp, ExprLoc, ExprCond from miasm2.ir.ir import AssignBlock class ir_a_arml_base(ir_arml, ira): @@ -23,17 +24,51 @@ class ir_a_arml(ir_a_arml_base): self.ret_reg = self.arch.regs.R0 def call_effects(self, ad, instr): - return [AssignBlock([ExprAff(self.ret_reg, ExprOp('call_func_ret', ad, - self.arch.regs.R0, - self.arch.regs.R1, - self.arch.regs.R2, - self.arch.regs.R3, - )), - ExprAff(self.sp, ExprOp('call_func_stack', - ad, self.sp)), - ], - instr - )] + call_assignblk = AssignBlock( + [ + ExprAff( + self.ret_reg, + ExprOp( + 'call_func_ret', + ad, + self.arch.regs.R0, + self.arch.regs.R1, + self.arch.regs.R2, + self.arch.regs.R3, + ) + ), + ExprAff( + self.sp, + ExprOp('call_func_stack', ad, self.sp) + ), + ], + instr + ) + + + cond = instr.additional_info.cond + if cond == 14: # COND_ALWAYS: + return [call_assignblk], [] + + # Call is a conditional instruction + cond = tab_cond[cond] + + loc_next = self.get_next_loc_key(instr) + loc_next_expr = ExprLoc(loc_next, 32) + loc_do = self.loc_db.add_location() + loc_do_expr = ExprLoc(loc_do, 32) + dst_cond = ExprCond(cond, loc_do_expr, loc_next_expr) + + call_assignblks = [ + call_assignblk, + AssignBlock([ExprAff(self.IRDst, loc_next_expr)], instr), + ] + e_do = IRBlock(loc_do, call_assignblks) + assignblks_out = [ + AssignBlock([ExprAff(self.IRDst, dst_cond)], instr) + ] + return assignblks_out, [e_do] + def get_out_regs(self, _): return set([self.ret_reg, self.sp]) diff --git a/miasm2/arch/mips32/ira.py b/miasm2/arch/mips32/ira.py index 3caa8b12..def75750 100644 --- a/miasm2/arch/mips32/ira.py +++ b/miasm2/arch/mips32/ira.py @@ -37,11 +37,12 @@ class ir_a_mips32l(ir_mips32l, ira): # CALL lbl = block.get_next() new_lbl = self.gen_label() - irs = self.call_effects(pc_val, instr) + call_assignblks, extra_irblocks = self.call_effects(pc_val, instr) + ir_blocks += extra_irblocks irs.append(AssignBlock([ExprAff(self.IRDst, ExprId(lbl, size=self.pc.size))], instr)) - new_irblocks.append(IRBlock(new_lbl, irs)) + new_irblocks.append(IRBlock(new_lbl, call_assignblks)) new_irblocks.append(irb.set_dst(ExprId(new_lbl, size=self.pc.size))) return new_irblocks diff --git a/miasm2/arch/ppc/ira.py b/miasm2/arch/ppc/ira.py index a30f972d..79476e90 100644 --- a/miasm2/arch/ppc/ira.py +++ b/miasm2/arch/ppc/ira.py @@ -23,17 +23,24 @@ class ir_a_ppc32b(ir_ppc32b, ira): self.set_dead_regs(irblock) def call_effects(self, ad, instr): - return [AssignBlock([ExprAff(self.ret_reg, ExprOp('call_func_ret', ad, - self.sp, - self.arch.regs.R3, - self.arch.regs.R4, - self.arch.regs.R5, - )), - ExprAff(self.sp, ExprOp('call_func_stack', - ad, self.sp)), - ], - instr - )] + call_assignblks = AssignBlock( + [ + ExprAff( + self.ret_reg, + ExprOp( + 'call_func_ret', + ad, + self.sp, + self.arch.regs.R3, + self.arch.regs.R4, + self.arch.regs.R5, + ) + ), + ExprAff(self.sp, ExprOp('call_func_stack', ad, self.sp)), + ], + instr + ) + return [call_assignblks], [] def add_instr_to_current_state(self, instr, block, assignments, ir_blocks_all, gen_pc_updt): """ @@ -46,8 +53,12 @@ class ir_a_ppc32b(ir_ppc32b, ira): @gen_pc_updt: insert PC update effects between instructions """ if instr.is_subcall(): - call_effects = self.call_effects(instr.getdstflow(None)[0], instr) - assignments+= call_effects + call_assignblks, extra_irblocks = self.call_effects( + instr.getdstflow(None)[0], + instr + ) + assignments += call_assignblks + ir_blocks_all += extra_irblocks return True if gen_pc_updt is not False: diff --git a/miasm2/arch/x86/arch.py b/miasm2/arch/x86/arch.py index bf872667..3a0fb78e 100644 --- a/miasm2/arch/x86/arch.py +++ b/miasm2/arch/x86/arch.py @@ -256,7 +256,7 @@ cl_or_imm |= base_expr class x86_arg(m_arg): def asm_ast_to_expr(self, value, loc_db, size_hint=None, fixed_size=None): if size_hint is None: - size_hint = self.parent.v_opmode() + size_hint = self.parent.mode if fixed_size is None: fixed_size = set() if isinstance(value, AstId): diff --git a/miasm2/arch/x86/ira.py b/miasm2/arch/x86/ira.py index be10213e..a95e6c69 100644 --- a/miasm2/arch/x86/ira.py +++ b/miasm2/arch/x86/ira.py @@ -44,18 +44,25 @@ class ir_a_x86_64(ir_x86_64, ir_a_x86_16): self.ret_reg = self.arch.regs.RAX def call_effects(self, ad, instr): - return [AssignBlock([ExprAff(self.ret_reg, ExprOp('call_func_ret', ad, - self.sp, - self.arch.regs.RCX, - self.arch.regs.RDX, - self.arch.regs.R8, - self.arch.regs.R9, - )), - ExprAff(self.sp, ExprOp('call_func_stack', - ad, self.sp)), - ], - instr - )] + call_assignblk = AssignBlock( + [ + ExprAff( + self.ret_reg, + ExprOp( + 'call_func_ret', + ad, + self.sp, + self.arch.regs.RCX, + self.arch.regs.RDX, + self.arch.regs.R8, + self.arch.regs.R9, + ) + ), + ExprAff(self.sp, ExprOp('call_func_stack', ad, self.sp)), + ], + instr + ) + return [call_assignblk], [] def sizeof_char(self): return 8 diff --git a/miasm2/core/cpu.py b/miasm2/core/cpu.py index 1326d08b..686e12ba 100644 --- a/miasm2/core/cpu.py +++ b/miasm2/core/cpu.py @@ -1036,7 +1036,7 @@ class instruction(object): offset = symbols.get_location_offset(loc_key) if offset is None: raise ValueError( - 'The offset of loc_key "%s" cannot be determined' % name + 'The offset of loc_key "%s" cannot be determined' % names ) else: # Fix symbol with its offset diff --git a/miasm2/ir/analysis.py b/miasm2/ir/analysis.py index 962b9889..d49f6b4e 100644 --- a/miasm2/ir/analysis.py +++ b/miasm2/ir/analysis.py @@ -4,7 +4,7 @@ import warnings import logging from miasm2.ir.ir import IntermediateRepresentation, AssignBlock -from miasm2.expression.expression import ExprOp +from miasm2.expression.expression import ExprOp, ExprAff from miasm2.analysis.data_flow import dead_simp as new_dead_simp_imp @@ -35,15 +35,22 @@ class ira(IntermediateRepresentation): * insert dependencies to arguments (stack base, registers, ...) * add some side effects (stack clean, return value, ...) + Return a couple: + * list of assignments to add to the current irblock + * list of additional irblocks + @addr: (Expr) address of the called function @instr: native instruction which is responsible of the call """ - assignblk = AssignBlock({ - self.ret_reg: ExprOp('call_func_ret', addr, self.sp), - self.sp: ExprOp('call_func_stack', addr, self.sp)}, - instr) - return [assignblk] + call_assignblk = AssignBlock( + [ + ExprAff(self.ret_reg, ExprOp('call_func_ret', addr, self.sp)), + ExprAff(self.sp, ExprOp('call_func_stack', addr, self.sp)) + ], + instr + ) + return [call_assignblk], [] def add_instr_to_current_state(self, instr, block, assignments, ir_blocks_all, gen_pc_updt): """ @@ -62,8 +69,12 @@ class ira(IntermediateRepresentation): @gen_pc_updt: insert PC update effects between instructions """ if instr.is_subcall(): - call_effects = self.call_effects(instr.args[0], instr) - assignments+= call_effects + call_assignblks, extra_irblocks = self.call_effects( + instr.args[0], + instr + ) + assignments += call_assignblks + ir_blocks_all += extra_irblocks return True if gen_pc_updt is not False: diff --git a/test/arch/x86/unit/test_asm_x86_64.py b/test/arch/x86/unit/test_asm_x86_64.py new file mode 100644 index 00000000..4e600846 --- /dev/null +++ b/test/arch/x86/unit/test_asm_x86_64.py @@ -0,0 +1,30 @@ +from miasm2.core import asmblock +from miasm2.arch.x86 import arch +from miasm2.core import parse_asm +from miasm2.core.interval import interval + +my_mn = arch.mn_x86 + + +asmcfg, loc_db = parse_asm.parse_txt(my_mn, 64, r''' +main: + PUSH RBP + MOV RBP, RSP +loop_dec: + CMP RCX, RDX + JB loop_dec +end: + MOV RSP, RBP + POP RBP + RET + +''') + +loc_db.set_location_offset(loc_db.get_name_location("main"), 0x100001000) +dst_interval = interval([(0x100001000, 0x100002000)]) +patches = asmblock.asm_resolve_final( + my_mn, + asmcfg, + loc_db, + dst_interval +) diff --git a/test/test_all.py b/test/test_all.py index 81b6e6e5..3fb0a5b7 100755 --- a/test/test_all.py +++ b/test/test_all.py @@ -81,6 +81,7 @@ for script in ["x86/sem.py", "x86/unit/mn_seh.py", "x86/unit/mn_cpuid.py", "x86/unit/mn_div.py", + "x86/unit/test_asm_x86_64.py", "arm/arch.py", "arm/sem.py", "aarch64/unit/mn_ubfm.py", |