diff options
Diffstat (limited to 'miasm2/arch')
| -rw-r--r-- | miasm2/arch/aarch64/arch.py | 2 | ||||
| -rw-r--r-- | miasm2/arch/arm/arch.py | 6 | ||||
| -rw-r--r-- | miasm2/arch/arm/regs.py | 32 | ||||
| -rw-r--r-- | miasm2/arch/mips32/jit.py | 10 | ||||
| -rw-r--r-- | miasm2/arch/mips32/regs.py | 4 | ||||
| -rw-r--r-- | miasm2/arch/mips32/sem.py | 22 | ||||
| -rw-r--r-- | miasm2/arch/sh4/arch.py | 6 | ||||
| -rw-r--r-- | miasm2/arch/x86/arch.py | 107 | ||||
| -rw-r--r-- | miasm2/arch/x86/regs.py | 54 | ||||
| -rw-r--r-- | miasm2/arch/x86/sem.py | 494 |
10 files changed, 579 insertions, 158 deletions
diff --git a/miasm2/arch/aarch64/arch.py b/miasm2/arch/aarch64/arch.py index 7af1953a..2712e60a 100644 --- a/miasm2/arch/aarch64/arch.py +++ b/miasm2/arch/aarch64/arch.py @@ -219,7 +219,7 @@ simdregs_h_zero = (simd32_info.parser | def ast_id2expr(t): if not t in mn_aarch64.regs.all_regs_ids_byname: - r = m2_expr.ExprId(AsmLabel(t)) + r = m2_expr.ExprId(AsmLabel(t), 32) else: r = mn_aarch64.regs.all_regs_ids_byname[t] return r diff --git a/miasm2/arch/arm/arch.py b/miasm2/arch/arm/arch.py index c74d10a8..5e4b02f9 100644 --- a/miasm2/arch/arm/arch.py +++ b/miasm2/arch/arm/arch.py @@ -18,7 +18,7 @@ log.addHandler(console_handler) log.setLevel(logging.DEBUG) # arm regs ############## -reg_dum = ExprId('DumReg') +reg_dum = ExprId('DumReg', 32) gen_reg('PC', globals()) @@ -66,13 +66,13 @@ spsr_regs = reg_info(spsr_regs_str, spsr_regs_expr) # CP cpregs_str = ['c%d' % r for r in xrange(0x10)] -cpregs_expr = [ExprId(x) for x in cpregs_str] +cpregs_expr = [ExprId(x, 32) for x in cpregs_str] cp_regs = reg_info(cpregs_str, cpregs_expr) # P pregs_str = ['p%d' % r for r in xrange(0x10)] -pregs_expr = [ExprId(x) for x in pregs_str] +pregs_expr = [ExprId(x, 32) for x in pregs_str] p_regs = reg_info(pregs_str, pregs_expr) diff --git a/miasm2/arch/arm/regs.py b/miasm2/arch/arm/regs.py index 400c6080..8587d7c2 100644 --- a/miasm2/arch/arm/regs.py +++ b/miasm2/arch/arm/regs.py @@ -29,22 +29,22 @@ SP = regs32_expr[13] LR = regs32_expr[14] PC = regs32_expr[15] -R0_init = ExprId("R0_init") -R1_init = ExprId("R1_init") -R2_init = ExprId("R2_init") -R3_init = ExprId("R3_init") -R4_init = ExprId("R4_init") -R5_init = ExprId("R5_init") -R6_init = ExprId("R6_init") -R7_init = ExprId("R7_init") -R8_init = ExprId("R8_init") -R9_init = ExprId("R9_init") -R10_init = ExprId("R10_init") -R11_init = ExprId("R11_init") -R12_init = ExprId("R12_init") -SP_init = ExprId("SP_init") -LR_init = ExprId("LR_init") -PC_init = ExprId("PC_init") +R0_init = ExprId("R0_init", 32) +R1_init = ExprId("R1_init", 32) +R2_init = ExprId("R2_init", 32) +R3_init = ExprId("R3_init", 32) +R4_init = ExprId("R4_init", 32) +R5_init = ExprId("R5_init", 32) +R6_init = ExprId("R6_init", 32) +R7_init = ExprId("R7_init", 32) +R8_init = ExprId("R8_init", 32) +R9_init = ExprId("R9_init", 32) +R10_init = ExprId("R10_init", 32) +R11_init = ExprId("R11_init", 32) +R12_init = ExprId("R12_init", 32) +SP_init = ExprId("SP_init", 32) +LR_init = ExprId("LR_init", 32) +PC_init = ExprId("PC_init", 32) reg_zf = 'zf' diff --git a/miasm2/arch/mips32/jit.py b/miasm2/arch/mips32/jit.py index f3e54a7d..1d2ec483 100644 --- a/miasm2/arch/mips32/jit.py +++ b/miasm2/arch/mips32/jit.py @@ -35,8 +35,8 @@ class mipsCGen(CGen): def __init__(self, ir_arch): super(mipsCGen, self).__init__(ir_arch) - self.delay_slot_dst = m2_expr.ExprId("branch_dst_irdst") - self.delay_slot_set = m2_expr.ExprId("branch_dst_set") + self.delay_slot_dst = m2_expr.ExprId("branch_dst_irdst", 32) + self.delay_slot_set = m2_expr.ExprId("branch_dst_set", 32) def block2assignblks(self, block): irblocks_list = super(mipsCGen, self).block2assignblks(block) @@ -58,7 +58,7 @@ class mipsCGen(CGen): assignments[self.delay_slot_set] = m2_expr.ExprInt(1, 32) # Replace IRDst with next instruction assignments[self.ir_arch.IRDst] = m2_expr.ExprId( - self.ir_arch.get_next_instr(assignblock.instr)) + self.ir_arch.get_next_instr(assignblock.instr), 32) irs.append(AssignBlock(assignments, assignblock.instr)) irblocks[blk_idx] = IRBlock(irblock.label, irs) @@ -72,8 +72,8 @@ class mipsCGen(CGen): lbl = self.get_block_post_label(block) out = (self.CODE_RETURN_NO_EXCEPTION % (self.label_to_jitlabel(lbl), self.C_PC, - m2_expr.ExprId('branch_dst_irdst'), - m2_expr.ExprId('branch_dst_irdst'), + m2_expr.ExprId('branch_dst_irdst', 32), + m2_expr.ExprId('branch_dst_irdst', 32), self.id_to_c(m2_expr.ExprInt(lbl.offset, 32))) ).split('\n') return out diff --git a/miasm2/arch/mips32/regs.py b/miasm2/arch/mips32/regs.py index fbd55a46..afade869 100644 --- a/miasm2/arch/mips32/regs.py +++ b/miasm2/arch/mips32/regs.py @@ -12,8 +12,8 @@ gen_reg('R_HI', globals()) exception_flags = ExprId('exception_flags', 32) -PC_init = ExprId("PC_init") -PC_FETCH_init = ExprId("PC_FETCH_init") +PC_init = ExprId("PC_init", 32) +PC_FETCH_init = ExprId("PC_FETCH_init", 32) regs32_str = ["ZERO", 'AT', 'V0', 'V1'] +\ ['A%d'%i for i in xrange(4)] +\ diff --git a/miasm2/arch/mips32/sem.py b/miasm2/arch/mips32/sem.py index 645f9a4f..855cb6c8 100644 --- a/miasm2/arch/mips32/sem.py +++ b/miasm2/arch/mips32/sem.py @@ -34,7 +34,7 @@ def jal(arg1): "Jumps to the calculated address @arg1 and stores the return address in $RA" PC = arg1 ir.IRDst = arg1 - RA = ExprId(ir.get_next_break_label(instr)) + RA = ExprId(ir.get_next_break_label(instr), 32) @sbuild.parse def jalr(arg1, arg2): @@ -42,13 +42,13 @@ def jalr(arg1, arg2): address in another register @arg2""" PC = arg1 ir.IRDst = arg1 - arg2 = ExprId(ir.get_next_break_label(instr)) + arg2 = ExprId(ir.get_next_break_label(instr), 32) @sbuild.parse def bal(arg1): PC = arg1 ir.IRDst = arg1 - RA = ExprId(ir.get_next_break_label(instr)) + RA = ExprId(ir.get_next_break_label(instr), 32) @sbuild.parse def l_b(arg1): @@ -75,7 +75,7 @@ def lb(arg1, arg2): @sbuild.parse def beq(arg1, arg2, arg3): "Branches on @arg3 if the quantities of two registers @arg1, @arg2 are eq" - dst = ExprId(ir.get_next_break_label(instr)) if arg1 - arg2 else arg3 + dst = ExprId(ir.get_next_break_label(instr), 32) if arg1 - arg2 else arg3 PC = dst ir.IRDst = dst @@ -83,7 +83,7 @@ def beq(arg1, arg2, arg3): def bgez(arg1, arg2): """Branches on @arg2 if the quantities of register @arg1 is greater than or equal to zero""" - dst = ExprId(ir.get_next_break_label(instr)) if arg1.msb() else arg2 + dst = ExprId(ir.get_next_break_label(instr), 32) if arg1.msb() else arg2 PC = dst ir.IRDst = dst @@ -91,7 +91,7 @@ def bgez(arg1, arg2): def bne(arg1, arg2, arg3): """Branches on @arg3 if the quantities of two registers @arg1, @arg2 are NOT equal""" - dst = arg3 if arg1 - arg2 else ExprId(ir.get_next_break_label(instr)) + dst = arg3 if arg1 - arg2 else ExprId(ir.get_next_break_label(instr), 32) PC = dst ir.IRDst = dst @@ -229,7 +229,7 @@ def seh(arg1, arg2): @sbuild.parse def bltz(arg1, arg2): """Branches on @arg2 if the register @arg1 is less than zero""" - dst_o = arg2 if arg1.msb() else ExprId(ir.get_next_break_label(instr)) + dst_o = arg2 if arg1.msb() else ExprId(ir.get_next_break_label(instr), 32) PC = dst_o ir.IRDst = dst_o @@ -237,7 +237,7 @@ def bltz(arg1, arg2): def blez(arg1, arg2): """Branches on @arg2 if the register @arg1 is less than or equal to zero""" cond = (i1(1) if arg1 else i1(0)) | arg1.msb() - dst_o = arg2 if cond else ExprId(ir.get_next_break_label(instr)) + dst_o = arg2 if cond else ExprId(ir.get_next_break_label(instr), 32) PC = dst_o ir.IRDst = dst_o @@ -245,7 +245,7 @@ def blez(arg1, arg2): def bgtz(arg1, arg2): """Branches on @arg2 if the register @arg1 is greater than zero""" cond = (i1(1) if arg1 else i1(0)) | arg1.msb() - dst_o = ExprId(ir.get_next_break_label(instr)) if cond else arg2 + dst_o = ExprId(ir.get_next_break_label(instr), 32) if cond else arg2 PC = dst_o ir.IRDst = dst_o @@ -345,13 +345,13 @@ def c_le_d(arg1, arg2, arg3): @sbuild.parse def bc1t(arg1, arg2): - dst_o = arg2 if arg1 else ExprId(ir.get_next_break_label(instr)) + dst_o = arg2 if arg1 else ExprId(ir.get_next_break_label(instr), 32) PC = dst_o ir.IRDst = dst_o @sbuild.parse def bc1f(arg1, arg2): - dst_o = ExprId(ir.get_next_break_label(instr)) if arg1 else arg2 + dst_o = ExprId(ir.get_next_break_label(instr), 32) if arg1 else arg2 PC = dst_o ir.IRDst = dst_o diff --git a/miasm2/arch/sh4/arch.py b/miasm2/arch/sh4/arch.py index eeafd5f5..d7ae4f12 100644 --- a/miasm2/arch/sh4/arch.py +++ b/miasm2/arch/sh4/arch.py @@ -7,9 +7,9 @@ from collections import defaultdict import miasm2.arch.sh4.regs as regs_module from miasm2.arch.sh4.regs import * -jra = ExprId('jra') -jrb = ExprId('jrb') -jrc = ExprId('jrc') +jra = ExprId('jra', 32) +jrb = ExprId('jrb', 32) +jrc = ExprId('jrc', 32) # parser helper ########### diff --git a/miasm2/arch/x86/arch.py b/miasm2/arch/x86/arch.py index 13c06ae6..72ed3309 100644 --- a/miasm2/arch/x86/arch.py +++ b/miasm2/arch/x86/arch.py @@ -4306,6 +4306,10 @@ addop("pmaxuw", [bs8(0x0f), bs8(0x38), bs8(0x3e), pref_66] + addop("pmaxud", [bs8(0x0f), bs8(0x38), bs8(0x3f), pref_66] + rmmod(xmm_reg, rm_arg_xmm)) +addop("pmaxsw", [bs8(0x0f), bs8(0xee), no_xmm_pref] + + rmmod(mm_reg, rm_arg_mm_m64)) +addop("pmaxsw", [bs8(0x0f), bs8(0xee), pref_66] + + rmmod(xmm_reg, rm_arg_xmm_m128)) addop("pminub", [bs8(0x0f), bs8(0xda), no_xmm_pref] + rmmod(mm_reg, rm_arg_mm)) @@ -4339,6 +4343,11 @@ addop("pcmpgtb", [bs8(0x0f), bs8(0x64), no_xmm_pref] + addop("pcmpgtb", [bs8(0x0f), bs8(0x64), pref_66] + rmmod(xmm_reg, rm_arg_xmm)) +addop("pcmpgtw", [bs8(0x0f), bs8(0x65), no_xmm_pref] + + rmmod(mm_reg, rm_arg_mm)) +addop("pcmpgtw", [bs8(0x0f), bs8(0x65), pref_66] + + rmmod(xmm_reg, rm_arg_xmm)) + addop("pcmpgtd", [bs8(0x0f), bs8(0x66), no_xmm_pref] + rmmod(mm_reg, rm_arg_mm)) addop("pcmpgtd", [bs8(0x0f), bs8(0x66), pref_66] + @@ -4423,9 +4432,9 @@ addop("pextrq", [bs8(0x0f), bs8(0x3a), bs8(0x16), pref_66] + addop("pextrw", [bs8(0x0f), bs8(0x3a), bs8(0x15), pref_66] + rmmod(xmm_reg, rm_arg_reg_m16) + [u08], [rm_arg_reg_m16, xmm_reg, u08]) addop("pextrw", [bs8(0x0f), bs8(0xc5), no_xmm_pref] + - rmmod(mm_reg, rm_arg_reg_m16) + [u08], [rm_arg_reg_m16, mm_reg, u08]) + rmmod(rmreg, rm_arg_mm) + [u08], [rmreg, rm_arg_mm, u08]) addop("pextrw", [bs8(0x0f), bs8(0xc5), pref_66] + - rmmod(xmm_reg, rm_arg_reg_m16) + [u08], [rm_arg_reg_m16, xmm_reg, u08]) + rmmod(rmreg, rm_arg_xmm) + [u08], [rmreg, rm_arg_xmm, u08]) addop("sqrtpd", [bs8(0x0f), bs8(0x51), pref_66] + @@ -4453,6 +4462,100 @@ addop("aesdec", [bs8(0x0f), bs8(0x38), bs8(0xde), pref_66] + rmmod(xmm_reg, rm_a addop("aesenclast", [bs8(0x0f), bs8(0x38), bs8(0xdd), pref_66] + rmmod(xmm_reg, rm_arg_xmm)) addop("aesdeclast", [bs8(0x0f), bs8(0x38), bs8(0xdf), pref_66] + rmmod(xmm_reg, rm_arg_xmm)) +addop("packsswb", [bs8(0x0f), bs8(0x63), no_xmm_pref] + + rmmod(mm_reg, rm_arg_mm_m64)) +addop("packsswb", [bs8(0x0f), bs8(0x63), pref_66] + + rmmod(xmm_reg, rm_arg_xmm_m128)) +addop("packssdw", [bs8(0x0f), bs8(0x6b), no_xmm_pref] + + rmmod(mm_reg, rm_arg_mm_m64)) +addop("packssdw", [bs8(0x0f), bs8(0x6b), pref_66] + + rmmod(xmm_reg, rm_arg_xmm_m128)) + +addop("packuswb", [bs8(0x0f), bs8(0x67), no_xmm_pref] + + rmmod(mm_reg, rm_arg_mm_m64)) +addop("packuswb", [bs8(0x0f), bs8(0x67), pref_66] + + rmmod(xmm_reg, rm_arg_xmm_m128)) + +addop("pmullw", [bs8(0x0f), bs8(0xd5), no_xmm_pref] + + rmmod(mm_reg, rm_arg_mm_m64)) +addop("pmullw", [bs8(0x0f), bs8(0xd5), pref_66] + + rmmod(xmm_reg, rm_arg_xmm_m128)) +addop("pmulhuw", [bs8(0x0f), bs8(0xe4), no_xmm_pref] + + rmmod(mm_reg, rm_arg_mm_m64)) +addop("pmulhuw", [bs8(0x0f), bs8(0xe4), pref_66] + + rmmod(xmm_reg, rm_arg_xmm_m128)) +addop("pmulhw", [bs8(0x0f), bs8(0xe5), no_xmm_pref] + + rmmod(mm_reg, rm_arg_mm_m64)) +addop("pmulhw", [bs8(0x0f), bs8(0xe5), pref_66] + + rmmod(xmm_reg, rm_arg_xmm_m128)) +addop("pmuludq", [bs8(0x0f), bs8(0xf4), no_xmm_pref] + + rmmod(mm_reg, rm_arg_mm_m64)) +addop("pmuludq", [bs8(0x0f), bs8(0xf4), pref_66] + + rmmod(xmm_reg, rm_arg_xmm_m128)) + + +addop("psubusb", [bs8(0x0f), bs8(0xd8), no_xmm_pref] + + rmmod(mm_reg, rm_arg_mm_m64)) +addop("psubusb", [bs8(0x0f), bs8(0xd8), pref_66] + + rmmod(xmm_reg, rm_arg_xmm_m128)) +addop("psubusw", [bs8(0x0f), bs8(0xd9), no_xmm_pref] + + rmmod(mm_reg, rm_arg_mm_m64)) +addop("psubusw", [bs8(0x0f), bs8(0xd9), pref_66] + + rmmod(xmm_reg, rm_arg_xmm_m128)) +addop("psubsb", [bs8(0x0f), bs8(0xe8), no_xmm_pref] + + rmmod(mm_reg, rm_arg_mm_m64)) +addop("psubsb", [bs8(0x0f), bs8(0xe8), pref_66] + + rmmod(xmm_reg, rm_arg_xmm_m128)) +addop("psubsw", [bs8(0x0f), bs8(0xe9), no_xmm_pref] + + rmmod(mm_reg, rm_arg_mm_m64)) +addop("psubsw", [bs8(0x0f), bs8(0xe9), pref_66] + + rmmod(xmm_reg, rm_arg_xmm_m128)) + + +addop("paddusb", [bs8(0x0f), bs8(0xdc), no_xmm_pref] + + rmmod(mm_reg, rm_arg_mm_m64)) +addop("paddusb", [bs8(0x0f), bs8(0xdc), pref_66] + + rmmod(xmm_reg, rm_arg_xmm_m128)) +addop("paddusw", [bs8(0x0f), bs8(0xdd), no_xmm_pref] + + rmmod(mm_reg, rm_arg_mm_m64)) +addop("paddusw", [bs8(0x0f), bs8(0xdd), pref_66] + + rmmod(xmm_reg, rm_arg_xmm_m128)) +addop("paddsb", [bs8(0x0f), bs8(0xec), no_xmm_pref] + + rmmod(mm_reg, rm_arg_mm_m64)) +addop("paddsb", [bs8(0x0f), bs8(0xec), pref_66] + + rmmod(xmm_reg, rm_arg_xmm_m128)) +addop("paddsw", [bs8(0x0f), bs8(0xed), no_xmm_pref] + + rmmod(mm_reg, rm_arg_mm_m64)) +addop("paddsw", [bs8(0x0f), bs8(0xed), pref_66] + + rmmod(xmm_reg, rm_arg_xmm_m128)) + +addop("pmaddwd", [bs8(0x0f), bs8(0xf5), no_xmm_pref] + + rmmod(mm_reg, rm_arg_mm_m64)) +addop("pmaddwd", [bs8(0x0f), bs8(0xf5), pref_66] + + rmmod(xmm_reg, rm_arg_xmm_m128)) + +addop("psadbw", [bs8(0x0f), bs8(0xf6), no_xmm_pref] + + rmmod(mm_reg, rm_arg_mm_m64)) +addop("psadbw", [bs8(0x0f), bs8(0xf6), pref_66] + + rmmod(xmm_reg, rm_arg_xmm_m128)) + +addop("pavgb", [bs8(0x0f), bs8(0xe0), no_xmm_pref] + + rmmod(mm_reg, rm_arg_mm_m64)) +addop("pavgb", [bs8(0x0f), bs8(0xe0), pref_66] + + rmmod(xmm_reg, rm_arg_xmm_m128)) +addop("pavgw", [bs8(0x0f), bs8(0xe3), no_xmm_pref] + + rmmod(mm_reg, rm_arg_mm_m64)) +addop("pavgw", [bs8(0x0f), bs8(0xe3), pref_66] + + rmmod(xmm_reg, rm_arg_xmm_m128)) + +addop("maskmovq", [bs8(0x0f), bs8(0xf7), no_xmm_pref] + + rmmod(mm_reg, rm_arg_mm_reg)) +addop("maskmovdqu", [bs8(0x0f), bs8(0xf7), pref_66] + + rmmod(xmm_reg, rm_arg_xmm_reg)) + +addop("emms", [bs8(0x0f), bs8(0x77)]) + + mn_x86.bintree = factor_one_bit(mn_x86.bintree) # mn_x86.bintree = factor_fields_all(mn_x86.bintree) """ diff --git a/miasm2/arch/x86/regs.py b/miasm2/arch/x86/regs.py index cb7e0d7b..84590c75 100644 --- a/miasm2/arch/x86/regs.py +++ b/miasm2/arch/x86/regs.py @@ -251,23 +251,23 @@ reg_float_address = 'reg_float_address' reg_float_ds = 'reg_float_ds' -dr0 = ExprId(reg_dr0) -dr1 = ExprId(reg_dr1) -dr2 = ExprId(reg_dr2) -dr3 = ExprId(reg_dr3) -dr4 = ExprId(reg_dr4) -dr5 = ExprId(reg_dr5) -dr6 = ExprId(reg_dr6) -dr7 = ExprId(reg_dr7) - -cr0 = ExprId(reg_cr0) -cr1 = ExprId(reg_cr1) -cr2 = ExprId(reg_cr2) -cr3 = ExprId(reg_cr3) -cr4 = ExprId(reg_cr4) -cr5 = ExprId(reg_cr5) -cr6 = ExprId(reg_cr6) -cr7 = ExprId(reg_cr7) +dr0 = ExprId(reg_dr0, 32) +dr1 = ExprId(reg_dr1, 32) +dr2 = ExprId(reg_dr2, 32) +dr3 = ExprId(reg_dr3, 32) +dr4 = ExprId(reg_dr4, 32) +dr5 = ExprId(reg_dr5, 32) +dr6 = ExprId(reg_dr6, 32) +dr7 = ExprId(reg_dr7, 32) + +cr0 = ExprId(reg_cr0, 32) +cr1 = ExprId(reg_cr1, 32) +cr2 = ExprId(reg_cr2, 32) +cr3 = ExprId(reg_cr3, 32) +cr4 = ExprId(reg_cr4, 32) +cr5 = ExprId(reg_cr5, 32) +cr6 = ExprId(reg_cr6, 32) +cr7 = ExprId(reg_cr7, 32) mm0 = ExprId(reg_mm0, 64) mm1 = ExprId(reg_mm1, 64) @@ -330,9 +330,9 @@ float_c2 = ExprId(reg_float_c2, size=1) float_c3 = ExprId(reg_float_c3, size=1) float_stack_ptr = ExprId(reg_float_stack_ptr, size=3) float_control = ExprId(reg_float_control, 16) -float_eip = ExprId(reg_float_eip) +float_eip = ExprId(reg_float_eip, 32) float_cs = ExprId(reg_float_cs, size=16) -float_address = ExprId(reg_float_address) +float_address = ExprId(reg_float_address, 32) float_ds = ExprId(reg_float_ds, size=16) float_st0 = ExprId("float_st0", 64) @@ -352,14 +352,14 @@ float_replace = {fltregs32_expr[i]: float_list[i] for i in xrange(8)} float_replace[r_st_all.expr[0]] = float_st0 -EAX_init = ExprId('EAX_init') -EBX_init = ExprId('EBX_init') -ECX_init = ExprId('ECX_init') -EDX_init = ExprId('EDX_init') -ESI_init = ExprId('ESI_init') -EDI_init = ExprId('EDI_init') -ESP_init = ExprId('ESP_init') -EBP_init = ExprId('EBP_init') +EAX_init = ExprId('EAX_init', 32) +EBX_init = ExprId('EBX_init', 32) +ECX_init = ExprId('ECX_init', 32) +EDX_init = ExprId('EDX_init', 32) +ESI_init = ExprId('ESI_init', 32) +EDI_init = ExprId('EDI_init', 32) +ESP_init = ExprId('ESP_init', 32) +EBP_init = ExprId('EBP_init', 32) RAX_init = ExprId('RAX_init', 64) diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py index 3cbf5526..589c2eb9 100644 --- a/miasm2/arch/x86/sem.py +++ b/miasm2/arch/x86/sem.py @@ -3319,62 +3319,104 @@ def vec_op_clip(op, size): # Generic vertical operation -def vec_vertical_sem(op, elt_size, reg_size, dst, src): +def vec_vertical_sem(op, elt_size, reg_size, dst, src, apply_on_output): assert reg_size % elt_size == 0 n = reg_size / elt_size if op == '-': ops = [ - (dst[i * elt_size:(i + 1) * elt_size] - - src[i * elt_size:(i + 1) * elt_size]) for i in xrange(0, n)] + apply_on_output((dst[i * elt_size:(i + 1) * elt_size] + - src[i * elt_size:(i + 1) * elt_size])) + for i in xrange(0, n) + ] else: - ops = [m2_expr.ExprOp(op, dst[i * elt_size:(i + 1) * elt_size], - src[i * elt_size:(i + 1) * elt_size]) for i in xrange(0, n)] + ops = [ + apply_on_output(m2_expr.ExprOp(op, dst[i * elt_size:(i + 1) * elt_size], + src[i * elt_size:(i + 1) * elt_size])) + for i in xrange(0, n) + ] return m2_expr.ExprCompose(*ops) -def float_vec_vertical_sem(op, elt_size, reg_size, dst, src): +def float_vec_vertical_sem(op, elt_size, reg_size, dst, src, apply_on_output): assert reg_size % elt_size == 0 n = reg_size / elt_size x_to_int, int_to_x = {32: ('float_to_int_%d', 'int_%d_to_float'), 64: ('double_to_int_%d', 'int_%d_to_double')}[elt_size] if op == '-': - ops = [m2_expr.ExprOp(x_to_int % elt_size, - m2_expr.ExprOp(int_to_x % elt_size, dst[i * elt_size:(i + 1) * elt_size]) - - m2_expr.ExprOp( - int_to_x % elt_size, src[i * elt_size:( - i + 1) * elt_size])) for i in xrange(0, n)] + ops = [ + apply_on_output(m2_expr.ExprOp( + x_to_int % elt_size, + m2_expr.ExprOp(int_to_x % elt_size, dst[i * elt_size:(i + 1) * elt_size]) - + m2_expr.ExprOp( + int_to_x % elt_size, src[i * elt_size:( + i + 1) * elt_size]))) + for i in xrange(0, n) + ] else: - ops = [m2_expr.ExprOp(x_to_int % elt_size, - m2_expr.ExprOp(op, - m2_expr.ExprOp( - int_to_x % elt_size, dst[i * elt_size:( - i + 1) * elt_size]), - m2_expr.ExprOp( - int_to_x % elt_size, src[i * elt_size:( - i + 1) * elt_size]))) for i in xrange(0, n)] + ops = [ + apply_on_output(m2_expr.ExprOp( + x_to_int % elt_size, + m2_expr.ExprOp(op, + m2_expr.ExprOp( + int_to_x % elt_size, dst[i * elt_size:( + i + 1) * elt_size]), + m2_expr.ExprOp( + int_to_x % elt_size, src[i * elt_size:( + i + 1) * elt_size])))) + for i in xrange(0, n)] return m2_expr.ExprCompose(*ops) -def __vec_vertical_instr_gen(op, elt_size, sem): +def __vec_vertical_instr_gen(op, elt_size, sem, apply_on_output): def vec_instr(ir, instr, dst, src): e = [] if isinstance(src, m2_expr.ExprMem): src = ir.ExprMem(src.arg, dst.size) reg_size = dst.size - e.append(m2_expr.ExprAff(dst, sem(op, elt_size, reg_size, dst, src))) + e.append(m2_expr.ExprAff(dst, sem(op, elt_size, reg_size, dst, src, + apply_on_output))) return e, [] return vec_instr -def vec_vertical_instr(op, elt_size): - return __vec_vertical_instr_gen(op, elt_size, vec_vertical_sem) +def vec_vertical_instr(op, elt_size, apply_on_output=lambda x: x): + return __vec_vertical_instr_gen(op, elt_size, vec_vertical_sem, + apply_on_output) + +def float_vec_vertical_instr(op, elt_size, apply_on_output=lambda x: x): + return __vec_vertical_instr_gen(op, elt_size, float_vec_vertical_sem, + apply_on_output) -def float_vec_vertical_instr(op, elt_size): - return __vec_vertical_instr_gen(op, elt_size, float_vec_vertical_sem) + +def _keep_mul_high(expr, signed=False): + assert expr.is_op("*") and len(expr.args) == 2 + + if signed: + arg1 = expr.args[0].signExtend(expr.size * 2) + arg2 = expr.args[1].signExtend(expr.size * 2) + else: + arg1 = expr.args[0].zeroExtend(expr.size * 2) + arg2 = expr.args[1].zeroExtend(expr.size * 2) + return m2_expr.ExprOp("*", arg1, arg2)[expr.size:] + +# Op, signed => associated comparison +_min_max_func = { + ("min", False): m2_expr.expr_is_unsigned_lower, + ("min", True): m2_expr.expr_is_signed_lower, + ("max", False): m2_expr.expr_is_unsigned_greater, + ("max", True): m2_expr.expr_is_signed_greater, +} +def _min_max(expr, signed): + assert (expr.is_op("min") or expr.is_op("max")) and len(expr.args) == 2 + return m2_expr.ExprCond( + _min_max_func[(expr.op, signed)](expr.args[1], expr.args[0]), + expr.args[1], + expr.args[0], + ) # Integer arithmetic @@ -3398,6 +3440,109 @@ psubw = vec_vertical_instr('-', 16) psubd = vec_vertical_instr('-', 32) psubq = vec_vertical_instr('-', 64) +# Multiplications +# + +# SSE +pmullb = vec_vertical_instr('*', 8) +pmullw = vec_vertical_instr('*', 16) +pmulld = vec_vertical_instr('*', 32) +pmullq = vec_vertical_instr('*', 64) +pmulhub = vec_vertical_instr('*', 8, _keep_mul_high) +pmulhuw = vec_vertical_instr('*', 16, _keep_mul_high) +pmulhud = vec_vertical_instr('*', 32, _keep_mul_high) +pmulhuq = vec_vertical_instr('*', 64, _keep_mul_high) +pmulhb = vec_vertical_instr('*', 8, lambda x: _keep_mul_high(x, signed=True)) +pmulhw = vec_vertical_instr('*', 16, lambda x: _keep_mul_high(x, signed=True)) +pmulhd = vec_vertical_instr('*', 32, lambda x: _keep_mul_high(x, signed=True)) +pmulhq = vec_vertical_instr('*', 64, lambda x: _keep_mul_high(x, signed=True)) + +def pmuludq(ir, instr, dst, src): + e = [] + if dst.size == 64: + e.append(m2_expr.ExprAff( + dst, + src[:32].zeroExtend(64) * dst[:32].zeroExtend(64) + )) + elif dst.size == 128: + e.append(m2_expr.ExprAff( + dst[:64], + src[:32].zeroExtend(64) * dst[:32].zeroExtend(64) + )) + e.append(m2_expr.ExprAff( + dst[64:], + src[64:96].zeroExtend(64) * dst[64:96].zeroExtend(64) + )) + else: + raise RuntimeError("Unsupported size %d" % dst.size) + return e, [] + +# Mix +# + +# SSE +def pmaddwd(ir, instr, dst, src): + sizedst = 32 + sizesrc = 16 + out = [] + for start in xrange(0, dst.size, sizedst): + base = start + mul1 = src[base: base + sizesrc].signExtend(sizedst) * dst[base: base + sizesrc].signExtend(sizedst) + base += sizesrc + mul2 = src[base: base + sizesrc].signExtend(sizedst) * dst[base: base + sizesrc].signExtend(sizedst) + out.append(mul1 + mul2) + return [m2_expr.ExprAff(dst, m2_expr.ExprCompose(*out))], [] + + +def _absolute(expr): + """Return abs(@expr)""" + signed = expr.msb() + value_unsigned = (expr ^ expr.mask) + m2_expr.ExprInt(1, expr.size) + return m2_expr.ExprCond(signed, value_unsigned, expr) + + +def psadbw(ir, instr, dst, src): + sizedst = 16 + sizesrc = 8 + out_dst = [] + for start in xrange(0, dst.size, 64): + out = [] + for src_start in xrange(0, 64, sizesrc): + beg = start + src_start + end = beg + sizesrc + # Not clear in the doc equations, but in the text, src and dst are: + # "8 unsigned byte integers" + out.append(_absolute(dst[beg: end].zeroExtend(sizedst) - src[beg: end].zeroExtend(sizedst))) + out_dst.append(m2_expr.ExprOp("+", *out)) + out_dst.append(m2_expr.ExprInt(0, 64 - sizedst)) + + return [m2_expr.ExprAff(dst, m2_expr.ExprCompose(*out_dst))], [] + +def _average(expr): + assert expr.is_op("avg") and len(expr.args) == 2 + + arg1 = expr.args[0].zeroExtend(expr.size * 2) + arg2 = expr.args[1].zeroExtend(expr.size * 2) + one = m2_expr.ExprInt(1, arg1.size) + # avg(unsigned) = (a + b + 1) >> 1, addition beeing at least on one more bit + return ((arg1 + arg2 + one) >> one)[:expr.size] + +pavgb = vec_vertical_instr('avg', 8, _average) +pavgw = vec_vertical_instr('avg', 16, _average) + +# Comparisons +# + +# SSE +pminsw = vec_vertical_instr('min', 16, lambda x: _min_max(x, signed=True)) +pminub = vec_vertical_instr('min', 8, lambda x: _min_max(x, signed=False)) +pminuw = vec_vertical_instr('min', 16, lambda x: _min_max(x, signed=False)) +pminud = vec_vertical_instr('min', 32, lambda x: _min_max(x, signed=False)) +pmaxub = vec_vertical_instr('max', 8, lambda x: _min_max(x, signed=False)) +pmaxuw = vec_vertical_instr('max', 16, lambda x: _min_max(x, signed=False)) +pmaxud = vec_vertical_instr('max', 32, lambda x: _min_max(x, signed=False)) +pmaxsw = vec_vertical_instr('max', 16, lambda x: _min_max(x, signed=True)) + # Floating-point arithmetic # @@ -3448,12 +3593,6 @@ def por(_, instr, dst, src): return e, [] -def pminsw(_, instr, dst, src): - e = [] - e.append(m2_expr.ExprAff(dst, m2_expr.ExprCond((dst - src).msb(), dst, src))) - return e, [] - - def cvtdq2pd(_, instr, dst, src): e = [] e.append( @@ -3819,62 +3958,6 @@ def iret(ir, instr): return exprs, [] -def pmaxu(_, instr, dst, src, size): - e = [] - for i in xrange(0, dst.size, size): - op1 = dst[i:i + size] - op2 = src[i:i + size] - res = op1 - op2 - # Compote CF in @res = @op1 - @op2 - ret = (((op1 ^ op2) ^ res) ^ ((op1 ^ res) & (op1 ^ op2))).msb() - - e.append(m2_expr.ExprAff(dst[i:i + size], - m2_expr.ExprCond(ret, - src[i:i + size], - dst[i:i + size]))) - return e, [] - - -def pmaxub(ir, instr, dst, src): - return pmaxu(ir, instr, dst, src, 8) - - -def pmaxuw(ir, instr, dst, src): - return pmaxu(ir, instr, dst, src, 16) - - -def pmaxud(ir, instr, dst, src): - return pmaxu(ir, instr, dst, src, 32) - - -def pminu(_, instr, dst, src, size): - e = [] - for i in xrange(0, dst.size, size): - op1 = dst[i:i + size] - op2 = src[i:i + size] - res = op1 - op2 - # Compote CF in @res = @op1 - @op2 - ret = (((op1 ^ op2) ^ res) ^ ((op1 ^ res) & (op1 ^ op2))).msb() - - e.append(m2_expr.ExprAff(dst[i:i + size], - m2_expr.ExprCond(ret, - dst[i:i + size], - src[i:i + size]))) - return e, [] - - -def pminub(ir, instr, dst, src): - return pminu(ir, instr, dst, src, 8) - - -def pminuw(ir, instr, dst, src): - return pminu(ir, instr, dst, src, 16) - - -def pminud(ir, instr, dst, src): - return pminu(ir, instr, dst, src, 32) - - def pcmpeq(_, instr, dst, src, size): e = [] for i in xrange(0, dst.size, size): @@ -4173,6 +4256,202 @@ def palignr(ir, instr, dst, src, imm): return [m2_expr.ExprAff(dst, result)], [] +def _signed_saturation(expr, dst_size): + """Saturate the expr @expr for @dst_size bit + Signed saturation return MAX_INT / MIN_INT or value depending on the value + """ + assert expr.size > dst_size + + median = 1 << (dst_size - 1) + min_int = m2_expr.ExprInt(- median, dst_size) + max_int = m2_expr.ExprInt(median - 1, dst_size) + signed = expr.msb() + value_unsigned = (expr ^ expr.mask) + m2_expr.ExprInt(1, expr.size) + # Re-use the sign bit + value = m2_expr.ExprCompose(expr[:dst_size - 1], signed) + + # Bit hack: to avoid a double signed comparison, use mask + # ie., in unsigned, 0xXY > 0x0f iff X is not null + + # if expr >s 0 + # if expr[dst_size - 1:] > 0: # bigger than max_int + # -> max_int + # else + # -> value + # else # negative + # if expr[dst_size:-1] > 0: # smaller than min_int + # -> value + # else + # -> min_int + + return m2_expr.ExprCond( + signed, + m2_expr.ExprCond(value_unsigned[dst_size - 1:], + min_int, + value), + m2_expr.ExprCond(expr[dst_size - 1:], + max_int, + value), + ) + + +def _unsigned_saturation(expr, dst_size): + """Saturate the expr @expr for @dst_size bit + Unsigned saturation return MAX_INT or value depending on the value + """ + assert expr.size > dst_size + + zero = m2_expr.ExprInt(0, dst_size) + max_int = m2_expr.ExprInt(-1, dst_size) + value = expr[:dst_size] + signed = expr.msb() + + + # Bit hack: to avoid a double signed comparison, use mask + # ie., in unsigned, 0xXY > 0x0f iff X is not null + + return m2_expr.ExprCond( + signed, + zero, + m2_expr.ExprCond(expr[dst_size:], + max_int, + value), + ) + + + +def packsswb(ir, instr, dst, src): + out = [] + for source in [dst, src]: + for start in xrange(0, dst.size, 16): + out.append(_signed_saturation(source[start:start + 16], 8)) + return [m2_expr.ExprAff(dst, m2_expr.ExprCompose(*out))], [] + + +def packssdw(ir, instr, dst, src): + out = [] + for source in [dst, src]: + for start in xrange(0, dst.size, 32): + out.append(_signed_saturation(source[start:start + 32], 16)) + return [m2_expr.ExprAff(dst, m2_expr.ExprCompose(*out))], [] + + +def packuswb(ir, instr, dst, src): + out = [] + for source in [dst, src]: + for start in xrange(0, dst.size, 16): + out.append(_unsigned_saturation(source[start:start + 16], 8)) + return [m2_expr.ExprAff(dst, m2_expr.ExprCompose(*out))], [] + + +def _saturation_sub_unsigned(expr): + assert expr.is_op("+") and len(expr.args) == 2 and expr.args[-1].is_op("-") + + # Compute the soustraction on one more bit to be able to distinguish cases: + # 0x48 - 0xd7 in 8 bit, should saturate + arg1 = expr.args[0].zeroExtend(expr.size + 1) + arg2 = expr.args[1].args[0].zeroExtend(expr.size + 1) + return _unsigned_saturation(arg1 - arg2, expr.size) + +def _saturation_sub_signed(expr): + assert expr.is_op("+") and len(expr.args) == 2 and expr.args[-1].is_op("-") + + # Compute the substraction on two more bits, see _saturation_sub_unsigned + arg1 = expr.args[0].signExtend(expr.size + 2) + arg2 = expr.args[1].args[0].signExtend(expr.size + 2) + return _signed_saturation(arg1 - arg2, expr.size) + +def _saturation_add(expr): + assert expr.is_op("+") and len(expr.args) == 2 + + # Compute the addition on one more bit to be able to distinguish cases: + # 0x48 + 0xd7 in 8 bit, should saturate + + arg1 = expr.args[0].zeroExtend(expr.size + 1) + arg2 = expr.args[1].zeroExtend(expr.size + 1) + + # We can also use _unsigned_saturation with two additionnal bits (to + # distinguish minus and overflow case) + # The resulting expression being more complicated with an impossible case + # (signed=True), we rewrite the rule here + + return m2_expr.ExprCond((arg1 + arg2).msb(), m2_expr.ExprInt(-1, expr.size), + expr) + +def _saturation_add_signed(expr): + assert expr.is_op("+") and len(expr.args) == 2 + + # Compute the substraction on two more bits, see _saturation_add_unsigned + + arg1 = expr.args[0].signExtend(expr.size + 2) + arg2 = expr.args[1].signExtend(expr.size + 2) + + return _signed_saturation(arg1 + arg2, expr.size) + + +# Saturate SSE operations + +psubusb = vec_vertical_instr('-', 8, _saturation_sub_unsigned) +psubusw = vec_vertical_instr('-', 16, _saturation_sub_unsigned) +paddusb = vec_vertical_instr('+', 8, _saturation_add) +paddusw = vec_vertical_instr('+', 16, _saturation_add) +psubsb = vec_vertical_instr('-', 8, _saturation_sub_signed) +psubsw = vec_vertical_instr('-', 16, _saturation_sub_signed) +paddsb = vec_vertical_instr('+', 8, _saturation_add_signed) +paddsw = vec_vertical_instr('+', 16, _saturation_add_signed) + + +# Others SSE operations + +def maskmovq(ir, instr, src, mask): + lbl_next = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size) + blks = [] + + # For each possibility, check if a write is necessary + check_labels = [m2_expr.ExprId(ir.gen_label(), ir.IRDst.size) + for _ in xrange(0, mask.size, 8)] + # If the write has to be done, do it (otherwise, nothing happen) + write_labels = [m2_expr.ExprId(ir.gen_label(), ir.IRDst.size) + for _ in xrange(0, mask.size, 8)] + + # Build check blocks + for i, start in enumerate(xrange(0, mask.size, 8)): + bit = mask[start + 7: start + 8] + cur_label = check_labels[i] + next_check_label = check_labels[i + 1] if (i + 1) < len(check_labels) else lbl_next + write_label = write_labels[i] + check = m2_expr.ExprAff(ir.IRDst, + m2_expr.ExprCond(bit, + write_label, + next_check_label)) + blks.append(IRBlock(cur_label.name, [AssignBlock([check], instr)])) + + # Build write blocks + dst_addr = mRDI[instr.mode] + for i, start in enumerate(xrange(0, mask.size, 8)): + bit = mask[start + 7: start + 8] + cur_label = write_labels[i] + next_check_label = check_labels[i + 1] if (i + 1) < len(check_labels) else lbl_next + write_addr = dst_addr + m2_expr.ExprInt(i, dst_addr.size) + + # @8[DI/EDI/RDI + i] = src[byte i] + write_mem = m2_expr.ExprAff(m2_expr.ExprMem(write_addr, 8), + src[start: start + 8]) + jump = m2_expr.ExprAff(ir.IRDst, next_check_label) + blks.append(IRBlock(cur_label.name, [AssignBlock([write_mem, jump], instr)])) + + # If mask is null, bypass all + e = [m2_expr.ExprAff(ir.IRDst, m2_expr.ExprCond(mask, + check_labels[0], + lbl_next))] + return e, blks + + +def emms(ir, instr): + # Implemented as a NOP + return [], [] + + mnemo_func = {'mov': mov, 'xchg': xchg, 'movzx': movzx, @@ -4557,6 +4836,29 @@ mnemo_func = {'mov': mov, "psubd": psubd, "psubq": psubq, + # Multiplications + # SSE + "pmullb": pmullb, + "pmullw": pmullw, + "pmulld": pmulld, + "pmullq": pmullq, + "pmulhub": pmulhub, + "pmulhuw": pmulhuw, + "pmulhud": pmulhud, + "pmulhuq": pmulhuq, + "pmulhb": pmulhb, + "pmulhw": pmulhw, + "pmulhd": pmulhd, + "pmulhq": pmulhq, + "pmuludq": pmuludq, + + # Mix + # SSE + "pmaddwd": pmaddwd, + "psadbw": psadbw, + "pavgb": pavgb, + "pavgw": pavgw, + # Arithmetic (floating-point) # @@ -4614,6 +4916,7 @@ mnemo_func = {'mov': mov, "pmaxub": pmaxub, "pmaxuw": pmaxuw, "pmaxud": pmaxud, + "pmaxsw": pmaxsw, "pminub": pminub, "pminuw": pminuw, @@ -4670,8 +4973,23 @@ mnemo_func = {'mov': mov, "pmovmskb": pmovmskb, - "smsw": smsw, + "packsswb": packsswb, + "packssdw": packssdw, + "packuswb": packuswb, + + "psubusb": psubusb, + "psubusw": psubusw, + "paddusb": paddusb, + "paddusw": paddusw, + "psubsb": psubsb, + "psubsw": psubsw, + "paddsb": paddsb, + "paddsw": paddsw, + "smsw": smsw, + "maskmovq": maskmovq, + "maskmovdqu": maskmovq, + "emms": emms, } |