diff options
58 files changed, 1815 insertions, 2367 deletions
diff --git a/.travis.yml b/.travis.yml index c021d97f..a0bf7d06 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,12 +25,15 @@ before_script: - "git clone https://github.com/serpilliere/elfesteem elfesteem && cd elfesteem && python setup.py install && cd ..;" # install pyparsing - "pip install pyparsing" -# install z3 -- "mkdir z3 && cd z3 && wget -O z3.zip 'http://download-codeplex.sec.s-msft.com/Download/SourceControlFileDownload.ashx?ProjectName=z3&changeSetId=cee7dd39444c9060186df79c2a2c7f8845de415b'" -- "unzip -q z3.zip && rm z3.zip && python scripts/mk_make.py --prefix=$(pwd)/../ && cd build && make -j 32 && make install && cd ../.." +# install z3 with a known to working version +- "wget https://github.com/serpilliere/z3-prebuild/raw/master/z3.tgz" +- "tar xzf z3.tgz" +- "cd z3/build" +- "make install" +- "cd ../.." # install miasm - "cd ..;" - "cd miasm;" - "python setup.py build build_ext -I$(pwd)/../virtualenv/include -L$(pwd)/../virtualenv/tinycc" - "python setup.py install" -script: "cd test && python test_all.py" +script: "python -c 'import z3; x = z3.BitVec(chr(0x41), 32)' && cd test && python test_all.py" diff --git a/README.md b/README.md index 4ce234cf..09a5d44e 100644 --- a/README.md +++ b/README.md @@ -456,6 +456,9 @@ To enable code JIT, one of the following module is mandatory: * LLVM v3.2 with python-llvm, see below * LibTCC [tinycc (ONLY version 0.9.26)](http://repo.or.cz/w/tinycc.git) +'optional' Miasm can also use: +* Z3, the [Theorem Prover](https://github.com/Z3Prover/z3) + Configuration ------------- diff --git a/example/asm/shellcode.py b/example/asm/shellcode.py index 11cf9a4d..f31c88c2 100644 --- a/example/asm/shellcode.py +++ b/example/asm/shellcode.py @@ -71,7 +71,7 @@ symbol_pool.set_offset(symbol_pool.getby_name("main"), addr_main) if args.PE: symbol_pool.set_offset(symbol_pool.getby_name_create("MessageBoxA"), - pe.DirImport.get_funcvirt('MessageBoxA')) + pe.DirImport.get_funcvirt('USER32.dll', 'MessageBoxA')) # Print and graph firsts blocs before patching it for bloc in blocs: diff --git a/example/jitter/test_x86_32_seh.py b/example/jitter/test_x86_32_seh.py new file mode 100644 index 00000000..5277807d --- /dev/null +++ b/example/jitter/test_x86_32_seh.py @@ -0,0 +1,56 @@ +import os +from pdb import pm +from miasm2.analysis.sandbox import Sandbox_Win_x86_32 +from miasm2.os_dep import win_api_x86_32_seh +from miasm2.jitter.csts import * + +def deal_exception_access_violation(jitter): + jitter.pc = win_api_x86_32_seh.fake_seh_handler(jitter, win_api_x86_32_seh.EXCEPTION_ACCESS_VIOLATION) + return True + +def deal_exception_breakpoint(jitter): + jitter.pc = win_api_x86_32_seh.fake_seh_handler(jitter, win_api_x86_32_seh.EXCEPTION_BREAKPOINT) + return True + +def deal_exception_div(jitter): + jitter.pc = win_api_x86_32_seh.fake_seh_handler(jitter, win_api_x86_32_seh.EXCEPTION_INT_DIVIDE_BY_ZERO) + return True + +def deal_exception_privileged_instruction(jitter): + jitter.pc = win_api_x86_32_seh.fake_seh_handler(jitter, win_api_x86_32_seh.EXCEPTION_PRIV_INSTRUCTION) + return True + +def deal_exception_illegal_instruction(jitter): + jitter.pc = win_api_x86_32_seh.fake_seh_handler(jitter, win_api_x86_32_seh.EXCEPTION_ILLEGAL_INSTRUCTION) + return True + + +def return_from_seh(jitter): + win_api_x86_32_seh.return_from_seh(jitter) + return True + +# Insert here user defined methods + +# Parse arguments +parser = Sandbox_Win_x86_32.parser(description="PE sandboxer") +parser.add_argument("filename", help="PE Filename") +options = parser.parse_args() +options.usesegm = True +options.use_seh = True + +# Create sandbox +sb = Sandbox_Win_x86_32(options.filename, options, globals()) + +# Install Windows SEH callbacks +sb.jitter.add_exception_handler(EXCEPT_ACCESS_VIOL, deal_exception_access_violation) +sb.jitter.add_exception_handler(EXCEPT_SOFT_BP, deal_exception_breakpoint) +sb.jitter.add_exception_handler(EXCEPT_DIV_BY_ZERO, deal_exception_div) +sb.jitter.add_exception_handler(1<<17, deal_exception_privileged_instruction) +sb.jitter.add_exception_handler(EXCEPT_UNK_MNEMO, deal_exception_illegal_instruction) + +sb.jitter.add_breakpoint(win_api_x86_32_seh.return_from_exception, return_from_seh) + +# Run +sb.run() + +assert(sb.jitter.run is False) diff --git a/example/samples/x86_32_seh.S b/example/samples/x86_32_seh.S new file mode 100644 index 00000000..7bb2c3cd --- /dev/null +++ b/example/samples/x86_32_seh.S @@ -0,0 +1,76 @@ + +main: + PUSH error + PUSH DWORD PTR FS:[0x0] + MOV DWORD PTR FS:[0x0], ESP + XOR EAX, EAX + +;; Access violation +lbl_err_0: + MOV DWORD PTR [EAX], 0x0 +lbl_err_end0: + NOP + + +;; Breakpoint +lbl_err_1: + INT 0x3 +lbl_err_end1: + NOP + +;; Divide by 0 + XOR EAX, EAX +lbl_err_2: + DIV EAX +lbl_err_end2: + NOP + +;; Privileged instruction +lbl_err_3: + STI +lbl_err_end3: + NOP + +;; Unknown instruction (Bad LEA encoding) +lbl_err_4: + .byte 0x8D, 0xC0 +lbl_err_end4: + NOP + + POP DWORD PTR FS:[0x0] + ADD ESP, 4 + RET + +error: + MOV ECX, DWORD PTR [ESP+0xC] + MOV EAX, DWORD PTR [ECX+0xB8] + MOV EBX, DWORD PTR [err_num] + CMP EAX, DWORD PTR [labels_err + 4*EBX] + JZ error_address_ok + INT 0x3 +error_address_ok: + INC DWORD PTR [err_num] + MOV EAX, DWORD PTR [labels_err_end + 4*EBX] + MOV DWORD PTR [ECX+0xB8], EAX + XOR EAX, EAX + RET + + + +err_num: +.dword 0 + +labels_err: +.dword lbl_err_0 +.dword lbl_err_end1 +.dword lbl_err_2 +.dword lbl_err_3 +.dword lbl_err_4 + + +labels_err_end: +.dword lbl_err_end0 +.dword lbl_err_end1 +.dword lbl_err_end2 +.dword lbl_err_end3 +.dword lbl_err_end4 diff --git a/miasm2/analysis/machine.py b/miasm2/analysis/machine.py index f963628c..6af403ff 100644 --- a/miasm2/analysis/machine.py +++ b/miasm2/analysis/machine.py @@ -134,6 +134,7 @@ class Machine(object): self.__log_arch = log_arch self.__base_expr = arch.base_expr self.__ir = ir + self.__name = machine_name @property def dis_engine(self): @@ -171,6 +172,10 @@ class Machine(object): def base_expr(self): return self.__base_expr + @property + def name(self): + return self.__name + @classmethod def available_machine(cls): "Return a list of supported machines" diff --git a/miasm2/arch/aarch64/jit.py b/miasm2/arch/aarch64/jit.py index 44b0609f..ca8d7b39 100644 --- a/miasm2/arch/aarch64/jit.py +++ b/miasm2/arch/aarch64/jit.py @@ -11,7 +11,6 @@ hnd.setFormatter(logging.Formatter("[%(levelname)s]: %(message)s")) log.addHandler(hnd) log.setLevel(logging.CRITICAL) - class jitter_aarch64l(jitter): max_reg_arg = 8 @@ -19,7 +18,6 @@ class jitter_aarch64l(jitter): sp = asmbloc.asm_symbol_pool() jitter.__init__(self, ir_aarch64l(sp), *args, **kwargs) self.vm.set_little_endian() - self.ir_arch.jit_pc = self.ir_arch.arch.regs.PC def push_uint64_t(self, v): self.cpu.SP -= 8 @@ -70,4 +68,3 @@ class jitter_aarch64b(jitter_aarch64l): sp = asmbloc.asm_symbol_pool() jitter.__init__(self, ir_aarch64b(sp), *args, **kwargs) self.vm.set_big_endian() - self.ir_arch.jit_pc = self.ir_arch.arch.regs.PC diff --git a/miasm2/arch/aarch64/sem.py b/miasm2/arch/aarch64/sem.py index b198bc43..02a93dd2 100644 --- a/miasm2/arch/aarch64/sem.py +++ b/miasm2/arch/aarch64/sem.py @@ -793,7 +793,8 @@ class ir_aarch64l(ir): dst = self.expr_fix_regs_for_mode(dst) src = self.expr_fix_regs_for_mode(src) assignblk[dst] = src - irbloc.dst = self.expr_fix_regs_for_mode(irbloc.dst) + if irbloc.dst is not None: + irbloc.dst = self.expr_fix_regs_for_mode(irbloc.dst) def mod_pc(self, instr, instr_ir, extra_ir): "Replace PC by the instruction's offset" diff --git a/miasm2/arch/arm/arch.py b/miasm2/arch/arm/arch.py index 23935dd4..7dc5d959 100644 --- a/miasm2/arch/arm/arch.py +++ b/miasm2/arch/arm/arch.py @@ -522,7 +522,10 @@ class mn_arm(cls_mn): info.lnk = False if hasattr(self, "lnk"): info.lnk = self.lnk.value != 0 - info.cond = self.cond.value + if hasattr(self, "cond"): + info.cond = self.cond.value + else: + info.cond = None return info @classmethod @@ -1291,6 +1294,8 @@ imm4 = bs(l=4, cls=(arm_imm, m_arg)) imm12 = bs(l=12, cls=(arm_imm, m_arg)) imm16 = bs(l=16, cls=(arm_imm, m_arg)) +imm12_off = bs(l=12, fname="imm") + imm4_noarg = bs(l=4, fname="imm4") imm_4_12 = bs(l=12, cls=(arm_imm_4_12,)) @@ -1405,6 +1410,50 @@ class armt2_rot_rm(m_arg): rot_rm = bs(l=2, cls=(armt2_rot_rm,), fname="rot_rm") +class arm_mem_rn_imm(m_arg): + parser = deref + def decode(self, v): + value = self.parent.imm.value + if self.parent.rw.value == 0: + value = -value + imm = ExprInt32(value) + reg = gpregs.expr[v] + if value: + expr = ExprMem(reg + imm) + else: + expr = ExprMem(reg) + self.expr = expr + return True + + def encode(self): + self.parent.add_imm.value = 1 + self.parent.imm.value = 0 + expr = self.expr + if not isinstance(expr, ExprMem): + return False + ptr = expr.arg + if ptr in gpregs.expr: + self.value = gpregs.expr.index(ptr) + elif (isinstance(ptr, ExprOp) and + len(ptr.args) == 2 and + ptr.op == 'preinc'): + reg, imm = ptr.args + if not reg in gpregs.expr: + return False + self.value = gpregs.expr.index(reg) + if not isinstance(imm, ExprInt): + return False + value = int(imm.arg) + if value & 0x80000000: + value = -value + self.parent.add_imm.value = 0 + self.parent.imm.value = value + else: + return False + return True + +mem_rn_imm = bs(l=4, cls=(arm_mem_rn_imm,), order=1) + def armop(name, fields, args=None, alias=False): dct = {"fields": fields} dct["alias"] = alias @@ -1457,6 +1506,10 @@ bs_ctransfer_name = bs_name(l=1, name=ctransfer_name) mr_name = {'MCR': 0, 'MRC': 1} bs_mr_name = bs_name(l=1, name=mr_name) + +bs_addi = bs(l=1, fname="add_imm") +bs_rw = bs_mod_name(l=1, fname='rw', mn_mod=['W', '']) + armop("mul", [bs('000000'), bs('0'), scc, rd, bs('0000'), rs, bs('1001'), rm], [rd, rm, rs]) armop("umull", [bs('000010'), @@ -1525,6 +1578,10 @@ armop("sxth", [bs('01101011'), bs('1111'), rd, rot_rm, bs('00'), bs('0111'), rm_ armop("rev", [bs('01101011'), bs('1111'), rd, bs('1111'), bs('0011'), rm]) +armop("pld", [bs8(0xF5), bs_addi, bs_rw, bs('01'), mem_rn_imm, bs('1111'), imm12_off]) + +armop("isb", [bs8(0xF5), bs8(0x7F), bs8(0xF0), bs8(0x6F)]) + class arm_widthm1(arm_imm, m_arg): def decode(self, v): self.expr = ExprInt32(v+1) diff --git a/miasm2/arch/arm/jit.py b/miasm2/arch/arm/jit.py index a9b93f6b..70d16176 100644 --- a/miasm2/arch/arm/jit.py +++ b/miasm2/arch/arm/jit.py @@ -17,7 +17,6 @@ class jitter_arml(jitter): sp = asmbloc.asm_symbol_pool() jitter.__init__(self, ir_arml(sp), *args, **kwargs) self.vm.set_little_endian() - self.ir_arch.jit_pc = self.ir_arch.arch.regs.PC def push_uint32_t(self, v): self.cpu.SP -= 4 @@ -67,4 +66,3 @@ class jitter_armb(jitter_arml): sp = asmbloc.asm_symbol_pool() jitter.__init__(self, ir_armb(sp), *args, **kwargs) self.vm.set_big_endian() - self.ir_arch.jit_pc = self.ir_arch.arch.regs.PC diff --git a/miasm2/arch/arm/sem.py b/miasm2/arch/arm/sem.py index 6838ef66..5bd4db24 100644 --- a/miasm2/arch/arm/sem.py +++ b/miasm2/arch/arm/sem.py @@ -933,6 +933,9 @@ def rev(ir, instr, a, b): e.append(ExprAff(a, c)) return e +def pld(ir, instr, a): + return [] + COND_EQ = 0 @@ -1137,6 +1140,7 @@ mnemo_nocond = {'lsr': lsr, 'asrs': asrs, 'cbz': cbz, 'cbnz': cbnz, + 'pld': pld, } mn_cond_x = [mnemo_condm0, mnemo_condm1, diff --git a/miasm2/arch/mips32/jit.py b/miasm2/arch/mips32/jit.py index 93223896..332e8d13 100644 --- a/miasm2/arch/mips32/jit.py +++ b/miasm2/arch/mips32/jit.py @@ -1,9 +1,11 @@ +import logging + from miasm2.jitter.jitload import jitter from miasm2.core import asmbloc from miasm2.core.utils import * from miasm2.arch.mips32.sem import ir_mips32l, ir_mips32b - -import logging +from miasm2.jitter.codegen import CGen +import miasm2.expression.expression as m2_expr log = logging.getLogger('jit_mips32') hnd = logging.StreamHandler() @@ -11,13 +13,73 @@ hnd.setFormatter(logging.Formatter("[%(levelname)s]: %(message)s")) log.addHandler(hnd) log.setLevel(logging.CRITICAL) + +class mipsCGen(CGen): + CODE_INIT = CGen.CODE_INIT + r""" + unsigned int branch_dst_pc; + unsigned int branch_dst_irdst; + unsigned int branch_dst_set=0; + """ + + CODE_RETURN_NO_EXCEPTION = r""" + %s: + if (branch_dst_set) { + %s = %s; + BlockDst->address = %s; + } else { + BlockDst->address = %s; + } + return JIT_RET_NO_EXCEPTION; + """ + + 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") + + def block2assignblks(self, block): + irblocks_list = super(mipsCGen, self).block2assignblks(block) + for instr, irblocks in zip(block.lines, irblocks_list): + if not instr.breakflow(): + continue + for irblock in irblocks: + for i, assignblock in enumerate(irblock.irs): + if self.ir_arch.pc not in assignblock: + continue + # Add internal branch destination + assignblock[self.delay_slot_dst] = assignblock[ + self.ir_arch.pc] + assignblock[self.delay_slot_set] = m2_expr.ExprInt(1, 32) + # Replace IRDst with next instruction + assignblock[self.ir_arch.IRDst] = m2_expr.ExprId( + self.ir_arch.get_next_instr(instr)) + irblock.dst = m2_expr.ExprId( + self.ir_arch.get_next_instr(instr)) + return irblocks_list + + def gen_finalize(self, block): + """ + Generate the C code for the final block instruction + """ + + lbl = self.get_block_post_label(block) + out = (self.CODE_RETURN_NO_EXCEPTION % (lbl.name, + self.C_PC, + m2_expr.ExprId('branch_dst_irdst'), + m2_expr.ExprId('branch_dst_irdst'), + self.id_to_c(m2_expr.ExprInt(lbl.offset, 32))) + ).split('\n') + return out + + class jitter_mips32l(jitter): + C_Gen = mipsCGen + def __init__(self, *args, **kwargs): sp = asmbloc.asm_symbol_pool() jitter.__init__(self, ir_mips32l(sp), *args, **kwargs) self.vm.set_little_endian() - self.ir_arch.jit_pc = self.ir_arch.arch.regs.PC def push_uint32_t(self, v): self.cpu.SP -= 4 @@ -38,8 +100,8 @@ class jitter_mips32l(jitter): class jitter_mips32b(jitter_mips32l): + def __init__(self, *args, **kwargs): sp = asmbloc.asm_symbol_pool() jitter.__init__(self, ir_mips32b(sp), *args, **kwargs) self.vm.set_big_endian() - self.ir_arch.jit_pc = self.ir_arch.arch.regs.PC diff --git a/miasm2/arch/mips32/regs.py b/miasm2/arch/mips32/regs.py index 6ddcf25b..b64b40d5 100644 --- a/miasm2/arch/mips32/regs.py +++ b/miasm2/arch/mips32/regs.py @@ -11,6 +11,8 @@ gen_reg('PC_FETCH', globals()) gen_reg('R_LO', globals()) gen_reg('R_HI', globals()) +exception_flags = ExprId('exception_flags', 32) + PC_init = ExprId("PC_init") PC_FETCH_init = ExprId("PC_FETCH_init") diff --git a/miasm2/arch/msp430/jit.py b/miasm2/arch/msp430/jit.py index 5a4ff58b..95d34f96 100644 --- a/miasm2/arch/msp430/jit.py +++ b/miasm2/arch/msp430/jit.py @@ -1,6 +1,7 @@ from miasm2.jitter.jitload import jitter from miasm2.core import asmbloc from miasm2.core.utils import * +from miasm2.arch.msp430.sem import ir_msp430 import logging @@ -13,11 +14,9 @@ log.setLevel(logging.CRITICAL) class jitter_msp430(jitter): def __init__(self, *args, **kwargs): - from miasm2.arch.msp430.sem import ir_msp430 sp = asmbloc.asm_symbol_pool() jitter.__init__(self, ir_msp430(sp), *args, **kwargs) self.vm.set_little_endian() - self.ir_arch.jit_pc = self.ir_arch.arch.regs.PC def push_uint16_t(self, v): regs = self.cpu.get_gpreg() diff --git a/miasm2/arch/msp430/regs.py b/miasm2/arch/msp430/regs.py index 60638f26..1e35029f 100644 --- a/miasm2/arch/msp430/regs.py +++ b/miasm2/arch/msp430/regs.py @@ -7,6 +7,7 @@ from miasm2.core.cpu import reg_info regs16_str = ["PC", "SP", "SR"] + ["R%d" % i for i in xrange(3, 16)] regs16_expr = [ExprId(x, 16) for x in regs16_str] +exception_flags = ExprId('exception_flags', 32) gpregs = reg_info(regs16_str, regs16_expr) diff --git a/miasm2/arch/x86/arch.py b/miasm2/arch/x86/arch.py index 280090aa..ff7dc1ee 100644 --- a/miasm2/arch/x86/arch.py +++ b/miasm2/arch/x86/arch.py @@ -826,6 +826,13 @@ class mn_x86(cls_mn): self.rex_b.value = pre_dis_info['rex_b'] self.rex_x.value = pre_dis_info['rex_x'] self.rex_p.value = pre_dis_info['rex_p'] + + if hasattr(self, 'no_rex') and\ + (self.rex_r.value or self.rex_b.value or + self.rex_x.value or self.rex_p.value): + return False + + self.g1.value = pre_dis_info['g1'] self.g2.value = pre_dis_info['g2'] self.prefix = pre_dis_info['prefix'] @@ -853,6 +860,10 @@ class mn_x86(cls_mn): rex |= 0x1 if rex != 0x40 or self.rex_p.value == 1: v = chr(rex) + v + if hasattr(self, 'no_rex'): + return None + + if hasattr(self, 'prefixed'): v = self.prefixed.default + v @@ -3084,6 +3095,8 @@ pref_f3 = bs(l=0, fname="prefixed", default="\xf3") pref_66 = bs(l=0, fname="prefixed", default="\x66") no_xmm_pref = bs(l=0, fname="no_xmm_pref") +no_rex = bs(l=0, fname="no_rex") + sib_scale = bs(l=2, cls=(bs_cond_scale,), fname = "sib_scale") sib_index = bs(l=3, cls=(bs_cond_index,), fname = "sib_index") sib_base = bs(l=3, cls=(bs_cond_index,), fname = "sib_base") @@ -3723,6 +3736,7 @@ addop("outsw", [bs8(0x6f), bs_opmode16]) addop("outsd", [bs8(0x6f), bs_opmode32]) addop("outsd", [bs8(0x6f), bs_opmode64]) +addop("setalc", [bs8(0xD6)]) # addop("pause", [bs8(0xf3), bs8(0x90)]) @@ -3898,7 +3912,7 @@ addop("wrmsr", [bs8(0x0f), bs8(0x30)]) addop("xadd", [bs8(0x0f), bs("1100000"), w8] + rmmod(rmreg, rm_arg_w8), [rm_arg_w8, rmreg]) -addop("nop", [bs8(0x90)], alias=True) +addop("nop", [bs8(0x90), no_rex], alias=True) addop("xchg", [bs('10010'), d_eax, reg]) addop("xchg", [bs('1000011'), w8] + @@ -4301,10 +4315,7 @@ 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_m16) + [u08], [rm_arg_m16, xmm_reg, u08]) -#addop("pextrw", [bs8(0x0f), bs8(0x3a), bs8(0x15), no_xmm_pref] + -# rmmod(mm_reg, rm_arg_m16) + [u08], [rm_arg_m16, mm_reg, u08]) - + 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]) addop("pextrw", [bs8(0x0f), bs8(0xc5), pref_66] + diff --git a/miasm2/arch/x86/jit.py b/miasm2/arch/x86/jit.py index 5a9886c5..2e483f2a 100644 --- a/miasm2/arch/x86/jit.py +++ b/miasm2/arch/x86/jit.py @@ -4,6 +4,7 @@ from miasm2.jitter.jitload import jitter, named_arguments from miasm2.core import asmbloc from miasm2.core.utils import * from miasm2.arch.x86.sem import ir_x86_16, ir_x86_32, ir_x86_64 +from miasm2.jitter.codegen import CGen log = logging.getLogger('jit_x86') hnd = logging.StreamHandler() @@ -11,13 +12,34 @@ hnd.setFormatter(logging.Formatter("[%(levelname)s]: %(message)s")) log.addHandler(hnd) log.setLevel(logging.CRITICAL) + +class x86_32_CGen(CGen): + def __init__(self, ir_arch): + self.ir_arch = ir_arch + self.PC = self.ir_arch.arch.regs.RIP + self.init_arch_C() + + def gen_post_code(self, attrib): + out = [] + if attrib.log_regs: + out.append('dump_gpregs_32(jitcpu->cpu);') + return out + +class x86_64_CGen(x86_32_CGen): + def gen_post_code(self, attrib): + out = [] + if attrib.log_regs: + out.append('dump_gpregs_64(jitcpu->cpu);') + return out + class jitter_x86_16(jitter): + C_Gen = x86_32_CGen + def __init__(self, *args, **kwargs): sp = asmbloc.asm_symbol_pool() jitter.__init__(self, ir_x86_16(sp), *args, **kwargs) self.vm.set_little_endian() - self.ir_arch.jit_pc = self.ir_arch.arch.regs.RIP self.ir_arch.do_stk_segm = False self.orig_irbloc_fix_regs_for_mode = self.ir_arch.irbloc_fix_regs_for_mode self.ir_arch.irbloc_fix_regs_for_mode = self.ir_archbloc_fix_regs_for_mode @@ -45,11 +67,12 @@ class jitter_x86_16(jitter): class jitter_x86_32(jitter): + C_Gen = x86_32_CGen + def __init__(self, *args, **kwargs): sp = asmbloc.asm_symbol_pool() jitter.__init__(self, ir_x86_32(sp), *args, **kwargs) self.vm.set_little_endian() - self.ir_arch.jit_pc = self.ir_arch.arch.regs.RIP self.ir_arch.do_stk_segm = False self.orig_irbloc_fix_regs_for_mode = self.ir_arch.irbloc_fix_regs_for_mode @@ -81,7 +104,7 @@ class jitter_x86_32(jitter): return ret_ad, args def func_ret_stdcall(self, ret_addr, ret_value1=None, ret_value2=None): - self.cpu.EIP = ret_addr + self.pc = self.cpu.EIP = ret_addr if ret_value1 is not None: self.cpu.EAX = ret_value1 if ret_value2 is not None: @@ -105,11 +128,12 @@ class jitter_x86_32(jitter): class jitter_x86_64(jitter): + C_Gen = x86_64_CGen + def __init__(self, *args, **kwargs): sp = asmbloc.asm_symbol_pool() jitter.__init__(self, ir_x86_64(sp), *args, **kwargs) self.vm.set_little_endian() - self.ir_arch.jit_pc = self.ir_arch.arch.regs.RIP self.ir_arch.do_stk_segm = False self.orig_irbloc_fix_regs_for_mode = self.ir_arch.irbloc_fix_regs_for_mode diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py index 28e42353..cdc98fba 100644 --- a/miasm2/arch/x86/sem.py +++ b/miasm2/arch/x86/sem.py @@ -3606,19 +3606,25 @@ def ps_rl_ll(ir, instr, a, b, op, size): mask = {16: 0xF, 32: 0x1F, 64: 0x3F}[size] - test = count & m2_expr.ExprInt(((1 << a.size) - 1) ^ mask, a.size) + test = expr_simp(count & m2_expr.ExprInt(((1 << a.size) - 1) ^ mask, a.size)) e = [m2_expr.ExprAff(ir.IRDst, m2_expr.ExprCond(test, lbl_zero, lbl_do))] - e_zero = [m2_expr.ExprAff(a, m2_expr.ExprInt(0, a.size)), - m2_expr.ExprAff(ir.IRDst, lbl_next)] - - e_do = [] slices = [] for i in xrange(0, a.size, size): slices.append((m2_expr.ExprOp(op, a[i:i + size], count[:size]), i, i + size)) + + if isinstance(test, m2_expr.ExprInt): + if int(test.arg) == 0: + return [m2_expr.ExprAff(a[0:a.size], m2_expr.ExprCompose(slices))], [] + else: + return [m2_expr.ExprAff(a, m2_expr.ExprInt(0, a.size))], [] + + e_zero = [m2_expr.ExprAff(a, m2_expr.ExprInt(0, a.size)), + m2_expr.ExprAff(ir.IRDst, lbl_next)] + e_do = [] e.append(m2_expr.ExprAff(a[0:a.size], m2_expr.ExprCompose(slices))) e_do.append(m2_expr.ExprAff(ir.IRDst, lbl_next)) return e, [irbloc(lbl_do.name, [e_do]), irbloc(lbl_zero.name, [e_zero])] @@ -4484,7 +4490,6 @@ class ir_x86_16(ir): instr_ir, extra_ir = mnemo_func[ instr.name.lower()](self, instr, *args) - self.mod_pc(instr, instr_ir, extra_ir) self.mod_pc(instr, instr_ir, extra_ir) instr.additional_info.except_on_instr = False @@ -4566,7 +4571,8 @@ class ir_x86_16(ir): dst = self.expr_fix_regs_for_mode(dst, mode) src = self.expr_fix_regs_for_mode(src, mode) assignblk[dst] = src - irbloc.dst = self.expr_fix_regs_for_mode(irbloc.dst, mode) + if irbloc.dst is not None: + irbloc.dst = self.expr_fix_regs_for_mode(irbloc.dst, mode) class ir_x86_32(ir_x86_16): diff --git a/miasm2/core/bin_stream.py b/miasm2/core/bin_stream.py index 67a67de8..f8d491d2 100644 --- a/miasm2/core/bin_stream.py +++ b/miasm2/core/bin_stream.py @@ -187,7 +187,10 @@ class bin_stream_container(bin_stream): return self.bin.get(self.offset - l, self.offset) def _getbytes(self, start, l=1): - return self.bin.get(start, start + l) + try: + return self.bin.get(start, start + l) + except ValueError: + raise IOError("cannot get bytes") def __str__(self): out = self.bin.get(self.offset, self.offset + self.l) diff --git a/miasm2/expression/expression.py b/miasm2/expression/expression.py index de6746ef..c9c2627c 100644 --- a/miasm2/expression/expression.py +++ b/miasm2/expression/expression.py @@ -217,6 +217,9 @@ class Expr(object): def __neg__(self): return ExprOp('-', self) + def __pow__(self, a): + return ExprOp("**",self, a) + def __invert__(self): s = self.size return ExprOp('^', self, ExprInt(mod_size2uint[s](size2mask(s)))) diff --git a/miasm2/expression/expression_helper.py b/miasm2/expression/expression_helper.py index 44b4b5af..09feffc2 100644 --- a/miasm2/expression/expression_helper.py +++ b/miasm2/expression/expression_helper.py @@ -135,7 +135,7 @@ def merge_sliceto_slice(args): op_propag_cst = ['+', '*', '^', '&', '|', '>>', '<<', "a>>", ">>>", "<<<", - "/", "%", 'idiv', 'imod', 'umod', 'udiv'] + "/", "%", 'idiv', 'imod', 'umod', 'udiv','**'] def is_pure_int(e): diff --git a/miasm2/expression/simplifications_common.py b/miasm2/expression/simplifications_common.py index a52debe6..2d5e4e6b 100644 --- a/miasm2/expression/simplifications_common.py +++ b/miasm2/expression/simplifications_common.py @@ -30,6 +30,8 @@ def simp_cst_propagation(e_s, e): o = i1.arg + i2.arg elif op == '*': o = i1.arg * i2.arg + elif op == '**': + o =i1.arg ** i2.arg elif op == '^': o = i1.arg ^ i2.arg elif op == '&': @@ -194,7 +196,7 @@ def simp_cst_propagation(e_s, e): j += 1 i += 1 - if op in ['|', '&', '%', '/'] and len(args) == 1: + if op in ['|', '&', '%', '/', '**'] and len(args) == 1: return args[0] # A <<< A.size => A diff --git a/miasm2/expression/simplifications_cond.py b/miasm2/expression/simplifications_cond.py index c6e455b6..a5acdba6 100644 --- a/miasm2/expression/simplifications_cond.py +++ b/miasm2/expression/simplifications_cond.py @@ -197,13 +197,13 @@ def __comp_signed(arg1, arg2): """Return ExprInt1(1) if arg1 <s arg2 else ExprInt1(0) @arg1, @arg2: ExprInt""" - val1 = arg1.arg + val1 = int(arg1.arg) if val1 >> (arg1.size - 1) == 1: - val1 = - (arg1.mask.arg ^ val1 + 1) + val1 = - ((int(arg1.mask.arg) ^ val1) + 1) - val2 = arg2.arg + val2 = int(arg2.arg) if val2 >> (arg2.size - 1) == 1: - val2 = - (arg2.mask.arg ^ val2 + 1) + val2 = - ((int(arg2.mask.arg) ^ val2) + 1) return m2_expr.ExprInt1(1) if (val1 < val2) else m2_expr.ExprInt1(0) diff --git a/miasm2/ir/ir2C.py b/miasm2/ir/ir2C.py deleted file mode 100644 index ebc61e27..00000000 --- a/miasm2/ir/ir2C.py +++ /dev/null @@ -1,432 +0,0 @@ -import miasm2.expression.expression as m2_expr -from miasm2.expression.simplifications import expr_simp -from miasm2.core import asmbloc -from miasm2.ir.translators import Translator -import logging - - -log_to_c_h = logging.getLogger("ir_helper") -console_handler = logging.StreamHandler() -console_handler.setFormatter(logging.Formatter("%(levelname)-5s: %(message)s")) -log_to_c_h.addHandler(console_handler) -log_to_c_h.setLevel(logging.WARN) - -# Miasm to C translator -translator = Translator.to_language("C") - -prefetch_id = [] -prefetch_id_size = {} -for size in [8, 16, 32, 64]: - prefetch_id_size[size] = [] - for i in xrange(20): - name = 'pfmem%.2d_%d' % (size, i) - c = m2_expr.ExprId(name, size) - globals()[name] = c - prefetch_id.append(c) - prefetch_id_size[size].append(c) - -def init_arch_C(arch): - arch.id2Cid = {} - for x in arch.regs.all_regs_ids + prefetch_id: - arch.id2Cid[x] = m2_expr.ExprId('mycpu->' + str(x), x.size) - - arch.id2newCid = {} - - for x in arch.regs.all_regs_ids + prefetch_id: - arch.id2newCid[x] = m2_expr.ExprId('mycpu->%s_new' % x, x.size) - - -def patch_c_id(arch, e): - return e.replace_expr(arch.id2Cid) - - -def patch_c_new_id(arch, e): - return e.replace_expr(arch.id2newCid) - - -mask_int = 0xffffffffffffffff - - -pre_instr_test_exception = r""" -// pre instruction test exception -if (VM_exception_flag) { - %s; - return JIT_RET_EXCEPTION; -} -""" - - -code_exception_fetch_mem_at_instr = r""" -// except fetch mem at instr -if (VM_exception_flag & EXCEPT_DO_NOT_UPDATE_PC) { - %s; - return JIT_RET_EXCEPTION; -} -""" -code_exception_fetch_mem_post_instr = r""" -// except fetch mem post instr -if (VM_exception_flag) { - %s; - return JIT_RET_EXCEPTION; -} -""" - - -code_exception_fetch_mem_at_instr_noautomod = r""" -// except fetch mem at instr noauto -if ((VM_exception_flag & ~EXCEPT_CODE_AUTOMOD) & EXCEPT_DO_NOT_UPDATE_PC) { - %s; - return JIT_RET_EXCEPTION; -} -""" -code_exception_fetch_mem_post_instr_noautomod = r""" -// except post instr noauto -if (VM_exception_flag & ~EXCEPT_CODE_AUTOMOD) { - %s; - return JIT_RET_EXCEPTION; -} -""" - - -code_exception_at_instr = r""" -// except at instr -if (CPU_exception_flag && CPU_exception_flag > EXCEPT_NUM_UPDT_EIP) { - %s; - return JIT_RET_EXCEPTION; -} -""" - -code_exception_post_instr = r""" -// except post instr -if (CPU_exception_flag) { - if (CPU_exception_flag > EXCEPT_NUM_UPDT_EIP) { - %s; - } - else { - %s; - } - return JIT_RET_EXCEPTION; -} -""" - - -code_exception_at_instr_noautomod = r""" -if ((CPU_exception_flag & ~EXCEPT_CODE_AUTOMOD) && (CPU_exception_flag > EXCEPT_NUM_UPDT_EIP)) { - %s; - return JIT_RET_EXCEPTION; -} -""" - -code_exception_post_instr_noautomod = r""" -if (CPU_exception_flag & ~EXCEPT_CODE_AUTOMOD) { - if (CPU_exception_flag > EXCEPT_NUM_UPDT_EIP) { - %s; - } - else { - %s; - } - return JIT_RET_EXCEPTION; -} -""" - -goto_local_code = r""" -if (BlockDst->is_local) { - goto *local_labels[BlockDst->address]; -} -else { - return JIT_RET_NO_EXCEPTION; -} -""" - -my_size_mask = {1: 1, 2: 3, 3: 7, 7: 0x7f, - 8: 0xFF, - 16: 0xFFFF, - 32: 0xFFFFFFFF, - 64: 0xFFFFFFFFFFFFFFFFL} - -exception_flags = m2_expr.ExprId('exception_flags', 32) - - -def set_pc(ir_arch, src): - dst = ir_arch.jit_pc - if not isinstance(src, m2_expr.Expr): - src = m2_expr.ExprInt_from(dst, src) - e = m2_expr.ExprAff(dst, src.zeroExtend(dst.size)) - return e - - -def gen_resolve_int(ir_arch, e): - return 'Resolve_dst(BlockDst, 0x%X, 0)' % (e.arg) - -def gen_resolve_id_lbl(ir_arch, e): - if e.name.name.startswith("lbl_gen_"): - # TODO XXX CLEAN - return 'Resolve_dst(BlockDst, 0x%X, 1)'%(e.name.index) - else: - return 'Resolve_dst(BlockDst, 0x%X, 0)'%(e.name.offset) - -def gen_resolve_id(ir_arch, e): - return 'Resolve_dst(BlockDst, %s, 0)'%(translator.from_expr(patch_c_id(ir_arch.arch, e))) - -def gen_resolve_mem(ir_arch, e): - return 'Resolve_dst(BlockDst, %s, 0)'%(translator.from_expr(patch_c_id(ir_arch.arch, e))) - -def gen_resolve_other(ir_arch, e): - return 'Resolve_dst(BlockDst, %s, 0)'%(translator.from_expr(patch_c_id(ir_arch.arch, e))) - -def gen_resolve_dst_simple(ir_arch, e): - if isinstance(e, m2_expr.ExprInt): - return gen_resolve_int(ir_arch, e) - elif isinstance(e, m2_expr.ExprId) and isinstance(e.name, - asmbloc.asm_label): - return gen_resolve_id_lbl(ir_arch, e) - elif isinstance(e, m2_expr.ExprId): - return gen_resolve_id(ir_arch, e) - elif isinstance(e, m2_expr.ExprMem): - return gen_resolve_mem(ir_arch, e) - else: - return gen_resolve_other(ir_arch, e) - - -def gen_irdst(ir_arch, e): - out = [] - if isinstance(e, m2_expr.ExprCond): - dst_cond_c = translator.from_expr(patch_c_id(ir_arch.arch, e.cond)) - out.append("if (%s)"%dst_cond_c) - out.append(' %s;'%(gen_resolve_dst_simple(ir_arch, e.src1))) - out.append("else") - out.append(' %s;'%(gen_resolve_dst_simple(ir_arch, e.src2))) - else: - out.append('%s;'%(gen_resolve_dst_simple(ir_arch, e))) - return out - -def Expr2C(ir_arch, l, assignblk, gen_exception_code=False): - id_to_update = [] - out = ["// %s" % (l)] - out_pc = [] - - dst_dict = {} - src_mem = {} - - prefect_index = {8: 0, 16: 0, 32: 0, 64: 0} - new_expr = [] - - pc_is_dst = False - fetch_mem = False - set_exception_flags = False - for dst, src in assignblk.iteritems(): - assert not isinstance(dst, m2_expr.ExprOp) - if dst in dst_dict: - raise RuntimeError("warning: detected multi dst to same id") - new_expr.append((dst, src)) - # test exception flags - ops = m2_expr.get_expr_ops(src) - if set(['umod', 'udiv']).intersection(ops): - set_exception_flags = True - if dst == exception_flags: - set_exception_flags = True - # TODO XXX test function whose set exception_flags - - # search mem lookup for generate mem read prefetch - rs = src.get_r(mem_read=True) - for r in rs: - if (not isinstance(r, m2_expr.ExprMem)) or r in src_mem: - continue - fetch_mem = True - index = prefect_index[r.size] - prefect_index[r.size] += 1 - pfmem = prefetch_id_size[r.size][index] - src_mem[r] = pfmem - - out_mem = [] - - # first, generate mem prefetch - mem_k = src_mem.keys() - mem_k.sort() - for k in mem_k: - str_src = translator.from_expr(patch_c_id(ir_arch.arch, k)) - str_dst = translator.from_expr(patch_c_id(ir_arch.arch, src_mem[k])) - out.append('%s = %s;' % (str_dst, str_src)) - src_w_len = {} - for k, v in src_mem.items(): - src_w_len[k] = v - for dst, src in new_expr: - # reload src using prefetch - src = src.replace_expr(src_w_len) - if dst is ir_arch.IRDst: - out += gen_irdst(ir_arch, src) - continue - - - str_src = translator.from_expr(patch_c_id(ir_arch.arch, src)) - str_dst = translator.from_expr(patch_c_id(ir_arch.arch, dst)) - - - - if isinstance(dst, m2_expr.ExprId): - id_to_update.append(dst) - str_dst = patch_c_new_id(ir_arch.arch, dst) - if dst in ir_arch.arch.regs.regs_flt_expr: - # dont mask float affectation - out.append('%s = (%s);' % (str_dst, str_src)) - else: - out.append('%s = (%s)&0x%X;' % (str_dst, str_src, - my_size_mask[src.size])) - elif isinstance(dst, m2_expr.ExprMem): - fetch_mem = True - str_dst = str_dst.replace('MEM_LOOKUP', 'MEM_WRITE') - out_mem.append('%s, %s);' % (str_dst[:-1], str_src)) - - if dst == ir_arch.arch.pc[ir_arch.attrib]: - pc_is_dst = True - out_pc += ["return JIT_RET_NO_EXCEPTION;"] - - # if len(id_to_update) != len(set(id_to_update)): - # raise ValueError('Not implemented: multi dst to same id!', str([str(x) - # for x in exprs])) - out += out_mem - - if gen_exception_code: - if fetch_mem: - e = set_pc(ir_arch, l.offset & mask_int) - s1 = "%s" % translator.from_expr(patch_c_id(ir_arch.arch, e)) - s1 += ';\n Resolve_dst(BlockDst, 0x%X, 0)'%(l.offset & mask_int) - out.append(code_exception_fetch_mem_at_instr_noautomod % s1) - if set_exception_flags: - e = set_pc(ir_arch, l.offset & mask_int) - s1 = "%s" % translator.from_expr(patch_c_id(ir_arch.arch, e)) - s1 += ';\n Resolve_dst(BlockDst, 0x%X, 0)'%(l.offset & mask_int) - out.append(code_exception_at_instr_noautomod % s1) - - for i in id_to_update: - if i is ir_arch.IRDst: - continue - out.append('%s = %s;' % - (patch_c_id(ir_arch.arch, i), patch_c_new_id(ir_arch.arch, i))) - - post_instr = [] - # test stop exec #### - if gen_exception_code: - if set_exception_flags: - if pc_is_dst: - post_instr.append("if (VM_exception_flag) { " + - "/*pc = 0x%X; */return JIT_RET_EXCEPTION; }" % (l.offset)) - else: - e = set_pc(ir_arch, l.offset & mask_int) - s1 = "%s" % translator.from_expr(patch_c_id(ir_arch.arch, e)) - s1 += ';\n Resolve_dst(BlockDst, 0x%X, 0)'%(l.offset & mask_int) - e = set_pc(ir_arch, (l.offset + l.l) & mask_int) - s2 = "%s" % translator.from_expr(patch_c_id(ir_arch.arch, e)) - s2 += ';\n Resolve_dst(BlockDst, 0x%X, 0)'%((l.offset + l.l) & mask_int) - post_instr.append( - code_exception_post_instr_noautomod % (s1, s2)) - - if fetch_mem: - if l.additional_info.except_on_instr: - offset = l.offset - else: - offset = l.offset + l.l - - e = set_pc(ir_arch, offset & mask_int) - s1 = "%s" % translator.from_expr(patch_c_id(ir_arch.arch, e)) - s1 += ';\n Resolve_dst(BlockDst, 0x%X, 0)'%(offset & mask_int) - post_instr.append( - code_exception_fetch_mem_post_instr_noautomod % (s1)) - - # pc manip after all modifications - return out, post_instr, post_instr + out_pc - - -def label2offset(e): - if not isinstance(e, m2_expr.ExprId): - return e - if not isinstance(e.name, asmbloc.asm_label): - return e - return m2_expr.ExprInt_from(e, e.name.offset) - - -def expr2pyobj(arch, e): - if isinstance(e, m2_expr.ExprId): - if isinstance(e.name, asmbloc.asm_label): - src_c = 'PyString_FromStringAndSize("%s", %d)' % ( - e.name.name, len(e.name.name)) - else: - src_c = 'PyLong_FromUnsignedLongLong(%s)' % patch_c_id(arch, e) - else: - raise NotImplementedError('unknown type for e: %s' % type(e)) - return src_c - - -def ir2C(ir_arch, irbloc, lbl_done, - gen_exception_code=False, log_mn=False, log_regs=False): - out = [] - # print "TRANS" - # print irbloc - out.append(["%s:" % irbloc.label.name]) - #out.append(['printf("%s:\n");' % irbloc.label.name]) - assert len(irbloc.irs) == len(irbloc.lines) - for l, assignblk in zip(irbloc.lines, irbloc.irs): - if l.offset not in lbl_done: - e = set_pc(ir_arch, l.offset & mask_int) - s1 = "%s" % translator.from_expr(patch_c_id(ir_arch.arch, e)) - s1 += ';\n Resolve_dst(BlockDst, 0x%X, 0)'%(l.offset & mask_int) - out.append([pre_instr_test_exception % (s1)]) - lbl_done.add(l.offset) - - if log_regs: - out.append([r'dump_gpregs(jitcpu->cpu);']) - - if log_mn: - out.append(['printf("%.8X %s\\n");' % (l.offset, str(l))]) - # print l - # gen pc update - post_instr = "" - c_code, post_instr, _ = Expr2C(ir_arch, l, assignblk, gen_exception_code) - out.append(c_code + post_instr) - out.append([goto_local_code ] ) - return out - - -def irblocs2C(ir_arch, resolvers, label, irblocs, - gen_exception_code=False, log_mn=False, log_regs=False): - out = [] - - lbls = [b.label for b in irblocs] - lbls_local = [] - for l in lbls: - if l.name.startswith('lbl_gen_'): - l.index = int(l.name[8:], 16) - lbls_local.append(l) - lbl_index_min = 0 - lbls_index = [l.index for l in lbls if hasattr(l, 'index')] - lbls_local.sort(key=lambda x:x.index) - - if lbls_index: - lbl_index_min = min(lbls_index) - for l in lbls_local: - l.index -= lbl_index_min - - out.append("void* local_labels[] = {%s};"%(', '.join(["&&%s"%l.name for l in lbls_local]))) - out.append("vm_cpu_t* mycpu = (vm_cpu_t*)jitcpu->cpu;") - - - out.append("goto %s;" % label.name) - bloc_labels = [x.label for x in irblocs] - assert label in bloc_labels - - lbl_done = set([None]) - - for irbloc in irblocs: - # XXXX TEST - if irbloc.label.offset is None: - b_out = ir2C(ir_arch, irbloc, lbl_done, gen_exception_code) - else: - b_out = ir2C( - ir_arch, irbloc, lbl_done, gen_exception_code, log_mn, log_regs) - for exprs in b_out: - for l in exprs: - out.append(l) - out.append("") - - return out - diff --git a/miasm2/ir/translators/z3_ir.py b/miasm2/ir/translators/z3_ir.py index 79099520..e0460cc4 100644 --- a/miasm2/ir/translators/z3_ir.py +++ b/miasm2/ir/translators/z3_ir.py @@ -141,7 +141,7 @@ class TranslatorZ3(Translator): for subexpr, start, stop in args: sube = self.from_expr(subexpr) e = z3.Extract(stop-start-1, 0, sube) - if res: + if res != None: res = z3.Concat(e, res) else: res = e diff --git a/miasm2/jitter/JitCore.c b/miasm2/jitter/JitCore.c index a6d29a72..84f835f1 100644 --- a/miasm2/jitter/JitCore.c +++ b/miasm2/jitter/JitCore.c @@ -26,7 +26,7 @@ PyObject * JitCpu_get_vmmngr(JitCpu *self, void *closure) { if (self->pyvm) { Py_INCREF(self->pyvm); - return self->pyvm; + return (PyObject*)self->pyvm; } Py_INCREF(Py_None); return Py_None; @@ -34,7 +34,7 @@ PyObject * JitCpu_get_vmmngr(JitCpu *self, void *closure) PyObject * JitCpu_set_vmmngr(JitCpu *self, PyObject *value, void *closure) { - self->pyvm = value; + self->pyvm = (VmMngr*)value; return 0; } @@ -56,22 +56,22 @@ PyObject * JitCpu_set_jitter(JitCpu *self, PyObject *value, void *closure) uint8_t __attribute__((weak)) MEM_LOOKUP_08(JitCpu* jitcpu, uint64_t addr) { - return vm_MEM_LOOKUP_08(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr); + return vm_MEM_LOOKUP_08(&(jitcpu->pyvm->vm_mngr), addr); } uint16_t __attribute__((weak)) MEM_LOOKUP_16(JitCpu* jitcpu, uint64_t addr) { - return vm_MEM_LOOKUP_16(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr); + return vm_MEM_LOOKUP_16(&(jitcpu->pyvm->vm_mngr), addr); } uint32_t __attribute__((weak)) MEM_LOOKUP_32(JitCpu* jitcpu, uint64_t addr) { - return vm_MEM_LOOKUP_32(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr); + return vm_MEM_LOOKUP_32(&(jitcpu->pyvm->vm_mngr), addr); } uint64_t __attribute__((weak)) MEM_LOOKUP_64(JitCpu* jitcpu, uint64_t addr) { - return vm_MEM_LOOKUP_64(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr); + return vm_MEM_LOOKUP_64(&(jitcpu->pyvm->vm_mngr), addr); } void __attribute__((weak)) MEM_WRITE_08(JitCpu* jitcpu, uint64_t addr, uint8_t src) diff --git a/miasm2/jitter/JitCore.h b/miasm2/jitter/JitCore.h index bae5a417..24feb9c0 100644 --- a/miasm2/jitter/JitCore.h +++ b/miasm2/jitter/JitCore.h @@ -92,7 +92,7 @@ typedef struct { typedef struct { PyObject_HEAD - PyObject *pyvm; + VmMngr *pyvm; PyObject *jitter; void* cpu; } JitCpu; @@ -129,10 +129,9 @@ PyObject* vm_get_mem(JitCpu *self, PyObject* args); - -#define VM_exception_flag (((VmMngr*)jitcpu->pyvm)->vm_mngr.exception_flags) +#define VM_exception_flag (jitcpu->pyvm->vm_mngr.exception_flags) #define CPU_exception_flag (((vm_cpu_t*)jitcpu->cpu)->exception_flags) - +#define CPU_exception_flag_at_instr ((CPU_exception_flag) && ((CPU_exception_flag) > EXCEPT_NUM_UPDT_EIP)) #define JIT_RET_EXCEPTION 1 #define JIT_RET_NO_EXCEPTION 0 diff --git a/miasm2/jitter/Jitgcc.c b/miasm2/jitter/Jitgcc.c index 3e7225cb..8b789f70 100644 --- a/miasm2/jitter/Jitgcc.c +++ b/miasm2/jitter/Jitgcc.c @@ -35,7 +35,7 @@ PyObject* gcc_exec_bloc(PyObject* self, PyObject* args) // Get the expected jitted function address func_py = PyDict_GetItem(lbl2ptr, retaddr); if (func_py) - func = (jitted_func) PyInt_AsLong((PyObject*) func_py); + func = (jitted_func) PyLong_AsVoidPtr((PyObject*) func_py); else { if (BlockDst.is_local == 1) { fprintf(stderr, "return on local label!\n"); @@ -44,7 +44,6 @@ PyObject* gcc_exec_bloc(PyObject* self, PyObject* args) // retaddr is not jitted yet return retaddr; } - // Execute it status = func(&BlockDst, jitcpu); Py_DECREF(retaddr); diff --git a/miasm2/jitter/Jittcc.c b/miasm2/jitter/Jittcc.c index 201f9b7f..1acbd56f 100644 --- a/miasm2/jitter/Jittcc.c +++ b/miasm2/jitter/Jittcc.c @@ -154,7 +154,7 @@ PyObject* tcc_exec_bloc(PyObject* self, PyObject* args) // Get the expected jitted function address func_py = PyDict_GetItem(lbl2ptr, retaddr); if (func_py) - func = (jitted_func) PyInt_AsLong((PyObject*) func_py); + func = (jitted_func) PyLong_AsVoidPtr((PyObject*) func_py); else { if (BlockDst.is_local == 1) { fprintf(stderr, "return on local label!\n"); diff --git a/miasm2/jitter/arch/JitCore_aarch64.c b/miasm2/jitter/arch/JitCore_aarch64.c index 28661bfe..15a3c27c 100644 --- a/miasm2/jitter/arch/JitCore_aarch64.c +++ b/miasm2/jitter/arch/JitCore_aarch64.c @@ -1,11 +1,11 @@ #include <Python.h> -#include "../JitCore.h" #include "structmember.h" #include <stdint.h> #include <inttypes.h> #include "../queue.h" #include "../vm_mngr.h" #include "../vm_mngr_py.h" +#include "../JitCore.h" #include "JitCore_aarch64.h" @@ -386,7 +386,6 @@ PyObject* get_gpreg_offset_all(void) PyObject *o; get_reg_off(exception_flags); - get_reg_off(exception_flags_new); get_reg_off(X0); get_reg_off(X1); @@ -422,142 +421,12 @@ PyObject* get_gpreg_offset_all(void) get_reg_off(SP); get_reg_off(PC); - - get_reg_off(X0_new); - get_reg_off(X1_new); - get_reg_off(X2_new); - get_reg_off(X3_new); - get_reg_off(X4_new); - get_reg_off(X5_new); - get_reg_off(X6_new); - get_reg_off(X7_new); - get_reg_off(X8_new); - get_reg_off(X9_new); - get_reg_off(X10_new); - get_reg_off(X11_new); - get_reg_off(X12_new); - get_reg_off(X13_new); - get_reg_off(X14_new); - get_reg_off(X15_new); - get_reg_off(X16_new); - get_reg_off(X17_new); - get_reg_off(X18_new); - get_reg_off(X19_new); - get_reg_off(X20_new); - get_reg_off(X21_new); - get_reg_off(X22_new); - get_reg_off(X23_new); - get_reg_off(X24_new); - get_reg_off(X25_new); - get_reg_off(X26_new); - get_reg_off(X27_new); - get_reg_off(X28_new); - get_reg_off(X29_new); - get_reg_off(LR_new); - get_reg_off(SP_new); - get_reg_off(PC_new); - - - /* eflag */ get_reg_off(zf); get_reg_off(nf); get_reg_off(of); get_reg_off(cf); - get_reg_off(zf_new); - get_reg_off(nf_new); - get_reg_off(of_new); - get_reg_off(cf_new); - - - get_reg_off(pfmem08_0); - get_reg_off(pfmem08_1); - get_reg_off(pfmem08_2); - get_reg_off(pfmem08_3); - get_reg_off(pfmem08_4); - get_reg_off(pfmem08_5); - get_reg_off(pfmem08_6); - get_reg_off(pfmem08_7); - get_reg_off(pfmem08_8); - get_reg_off(pfmem08_9); - get_reg_off(pfmem08_10); - get_reg_off(pfmem08_11); - get_reg_off(pfmem08_12); - get_reg_off(pfmem08_13); - get_reg_off(pfmem08_14); - get_reg_off(pfmem08_15); - get_reg_off(pfmem08_16); - get_reg_off(pfmem08_17); - get_reg_off(pfmem08_18); - get_reg_off(pfmem08_19); - - - get_reg_off(pfmem16_0); - get_reg_off(pfmem16_1); - get_reg_off(pfmem16_2); - get_reg_off(pfmem16_3); - get_reg_off(pfmem16_4); - get_reg_off(pfmem16_5); - get_reg_off(pfmem16_6); - get_reg_off(pfmem16_7); - get_reg_off(pfmem16_8); - get_reg_off(pfmem16_9); - get_reg_off(pfmem16_10); - get_reg_off(pfmem16_11); - get_reg_off(pfmem16_12); - get_reg_off(pfmem16_13); - get_reg_off(pfmem16_14); - get_reg_off(pfmem16_15); - get_reg_off(pfmem16_16); - get_reg_off(pfmem16_17); - get_reg_off(pfmem16_18); - get_reg_off(pfmem16_19); - - - get_reg_off(pfmem32_0); - get_reg_off(pfmem32_1); - get_reg_off(pfmem32_2); - get_reg_off(pfmem32_3); - get_reg_off(pfmem32_4); - get_reg_off(pfmem32_5); - get_reg_off(pfmem32_6); - get_reg_off(pfmem32_7); - get_reg_off(pfmem32_8); - get_reg_off(pfmem32_9); - get_reg_off(pfmem32_10); - get_reg_off(pfmem32_11); - get_reg_off(pfmem32_12); - get_reg_off(pfmem32_13); - get_reg_off(pfmem32_14); - get_reg_off(pfmem32_15); - get_reg_off(pfmem32_16); - get_reg_off(pfmem32_17); - get_reg_off(pfmem32_18); - get_reg_off(pfmem32_19); - - - get_reg_off(pfmem64_0); - get_reg_off(pfmem64_1); - get_reg_off(pfmem64_2); - get_reg_off(pfmem64_3); - get_reg_off(pfmem64_4); - get_reg_off(pfmem64_5); - get_reg_off(pfmem64_6); - get_reg_off(pfmem64_7); - get_reg_off(pfmem64_8); - get_reg_off(pfmem64_9); - get_reg_off(pfmem64_10); - get_reg_off(pfmem64_11); - get_reg_off(pfmem64_12); - get_reg_off(pfmem64_13); - get_reg_off(pfmem64_14); - get_reg_off(pfmem64_15); - get_reg_off(pfmem64_16); - get_reg_off(pfmem64_17); - get_reg_off(pfmem64_18); - get_reg_off(pfmem64_19); - return dict; } diff --git a/miasm2/jitter/arch/JitCore_aarch64.h b/miasm2/jitter/arch/JitCore_aarch64.h index e1708541..2203e037 100644 --- a/miasm2/jitter/arch/JitCore_aarch64.h +++ b/miasm2/jitter/arch/JitCore_aarch64.h @@ -1,7 +1,6 @@ typedef struct { uint32_t exception_flags; - uint32_t exception_flags_new; /* gpregs */ @@ -40,141 +39,11 @@ typedef struct { uint64_t PC; - - uint64_t X0_new; - uint64_t X1_new; - uint64_t X2_new; - uint64_t X3_new; - uint64_t X4_new; - uint64_t X5_new; - uint64_t X6_new; - uint64_t X7_new; - uint64_t X8_new; - uint64_t X9_new; - uint64_t X10_new; - uint64_t X11_new; - uint64_t X12_new; - uint64_t X13_new; - uint64_t X14_new; - uint64_t X15_new; - uint64_t X16_new; - uint64_t X17_new; - uint64_t X18_new; - uint64_t X19_new; - uint64_t X20_new; - uint64_t X21_new; - uint64_t X22_new; - uint64_t X23_new; - uint64_t X24_new; - uint64_t X25_new; - uint64_t X26_new; - uint64_t X27_new; - uint64_t X28_new; - uint64_t X29_new; - uint64_t LR_new; - uint64_t SP_new; - - uint64_t PC_new; - /* eflag */ uint32_t zf; uint32_t nf; uint32_t of; uint32_t cf; - - uint32_t zf_new; - uint32_t nf_new; - uint32_t of_new; - uint32_t cf_new; - - - uint8_t pfmem08_0; - uint8_t pfmem08_1; - uint8_t pfmem08_2; - uint8_t pfmem08_3; - uint8_t pfmem08_4; - uint8_t pfmem08_5; - uint8_t pfmem08_6; - uint8_t pfmem08_7; - uint8_t pfmem08_8; - uint8_t pfmem08_9; - uint8_t pfmem08_10; - uint8_t pfmem08_11; - uint8_t pfmem08_12; - uint8_t pfmem08_13; - uint8_t pfmem08_14; - uint8_t pfmem08_15; - uint8_t pfmem08_16; - uint8_t pfmem08_17; - uint8_t pfmem08_18; - uint8_t pfmem08_19; - - - uint16_t pfmem16_0; - uint16_t pfmem16_1; - uint16_t pfmem16_2; - uint16_t pfmem16_3; - uint16_t pfmem16_4; - uint16_t pfmem16_5; - uint16_t pfmem16_6; - uint16_t pfmem16_7; - uint16_t pfmem16_8; - uint16_t pfmem16_9; - uint16_t pfmem16_10; - uint16_t pfmem16_11; - uint16_t pfmem16_12; - uint16_t pfmem16_13; - uint16_t pfmem16_14; - uint16_t pfmem16_15; - uint16_t pfmem16_16; - uint16_t pfmem16_17; - uint16_t pfmem16_18; - uint16_t pfmem16_19; - - - uint32_t pfmem32_0; - uint32_t pfmem32_1; - uint32_t pfmem32_2; - uint32_t pfmem32_3; - uint32_t pfmem32_4; - uint32_t pfmem32_5; - uint32_t pfmem32_6; - uint32_t pfmem32_7; - uint32_t pfmem32_8; - uint32_t pfmem32_9; - uint32_t pfmem32_10; - uint32_t pfmem32_11; - uint32_t pfmem32_12; - uint32_t pfmem32_13; - uint32_t pfmem32_14; - uint32_t pfmem32_15; - uint32_t pfmem32_16; - uint32_t pfmem32_17; - uint32_t pfmem32_18; - uint32_t pfmem32_19; - - - uint64_t pfmem64_0; - uint64_t pfmem64_1; - uint64_t pfmem64_2; - uint64_t pfmem64_3; - uint64_t pfmem64_4; - uint64_t pfmem64_5; - uint64_t pfmem64_6; - uint64_t pfmem64_7; - uint64_t pfmem64_8; - uint64_t pfmem64_9; - uint64_t pfmem64_10; - uint64_t pfmem64_11; - uint64_t pfmem64_12; - uint64_t pfmem64_13; - uint64_t pfmem64_14; - uint64_t pfmem64_15; - uint64_t pfmem64_16; - uint64_t pfmem64_17; - uint64_t pfmem64_18; - uint64_t pfmem64_19; - }vm_cpu_t; diff --git a/miasm2/jitter/arch/JitCore_arm.c b/miasm2/jitter/arch/JitCore_arm.c index b2550194..90e72ea4 100644 --- a/miasm2/jitter/arch/JitCore_arm.c +++ b/miasm2/jitter/arch/JitCore_arm.c @@ -1,11 +1,11 @@ #include <Python.h> -#include "../JitCore.h" #include "structmember.h" #include <stdint.h> #include <inttypes.h> #include "../queue.h" #include "../vm_mngr.h" #include "../vm_mngr_py.h" +#include "../JitCore.h" #include "JitCore_arm.h" @@ -300,8 +300,6 @@ PyObject* get_gpreg_offset_all(void) PyObject *o; get_reg_off(exception_flags); - get_reg_off(exception_flags_new); - get_reg_off(R0); get_reg_off(R1); @@ -320,122 +318,12 @@ PyObject* get_gpreg_offset_all(void) get_reg_off(LR); get_reg_off(PC); - get_reg_off(R0_new); - get_reg_off(R1_new); - get_reg_off(R2_new); - get_reg_off(R3_new); - get_reg_off(R4_new); - get_reg_off(R5_new); - get_reg_off(R6_new); - get_reg_off(R7_new); - get_reg_off(R8_new); - get_reg_off(R9_new); - get_reg_off(R10_new); - get_reg_off(R11_new); - get_reg_off(R12_new); - get_reg_off(SP_new); - get_reg_off(LR_new); - get_reg_off(PC_new); - /* eflag */ get_reg_off(zf); get_reg_off(nf); get_reg_off(of); get_reg_off(cf); - get_reg_off(zf_new); - get_reg_off(nf_new); - get_reg_off(of_new); - get_reg_off(cf_new); - - - get_reg_off(pfmem08_0); - get_reg_off(pfmem08_1); - get_reg_off(pfmem08_2); - get_reg_off(pfmem08_3); - get_reg_off(pfmem08_4); - get_reg_off(pfmem08_5); - get_reg_off(pfmem08_6); - get_reg_off(pfmem08_7); - get_reg_off(pfmem08_8); - get_reg_off(pfmem08_9); - get_reg_off(pfmem08_10); - get_reg_off(pfmem08_11); - get_reg_off(pfmem08_12); - get_reg_off(pfmem08_13); - get_reg_off(pfmem08_14); - get_reg_off(pfmem08_15); - get_reg_off(pfmem08_16); - get_reg_off(pfmem08_17); - get_reg_off(pfmem08_18); - get_reg_off(pfmem08_19); - - - get_reg_off(pfmem16_0); - get_reg_off(pfmem16_1); - get_reg_off(pfmem16_2); - get_reg_off(pfmem16_3); - get_reg_off(pfmem16_4); - get_reg_off(pfmem16_5); - get_reg_off(pfmem16_6); - get_reg_off(pfmem16_7); - get_reg_off(pfmem16_8); - get_reg_off(pfmem16_9); - get_reg_off(pfmem16_10); - get_reg_off(pfmem16_11); - get_reg_off(pfmem16_12); - get_reg_off(pfmem16_13); - get_reg_off(pfmem16_14); - get_reg_off(pfmem16_15); - get_reg_off(pfmem16_16); - get_reg_off(pfmem16_17); - get_reg_off(pfmem16_18); - get_reg_off(pfmem16_19); - - - get_reg_off(pfmem32_0); - get_reg_off(pfmem32_1); - get_reg_off(pfmem32_2); - get_reg_off(pfmem32_3); - get_reg_off(pfmem32_4); - get_reg_off(pfmem32_5); - get_reg_off(pfmem32_6); - get_reg_off(pfmem32_7); - get_reg_off(pfmem32_8); - get_reg_off(pfmem32_9); - get_reg_off(pfmem32_10); - get_reg_off(pfmem32_11); - get_reg_off(pfmem32_12); - get_reg_off(pfmem32_13); - get_reg_off(pfmem32_14); - get_reg_off(pfmem32_15); - get_reg_off(pfmem32_16); - get_reg_off(pfmem32_17); - get_reg_off(pfmem32_18); - get_reg_off(pfmem32_19); - - - get_reg_off(pfmem64_0); - get_reg_off(pfmem64_1); - get_reg_off(pfmem64_2); - get_reg_off(pfmem64_3); - get_reg_off(pfmem64_4); - get_reg_off(pfmem64_5); - get_reg_off(pfmem64_6); - get_reg_off(pfmem64_7); - get_reg_off(pfmem64_8); - get_reg_off(pfmem64_9); - get_reg_off(pfmem64_10); - get_reg_off(pfmem64_11); - get_reg_off(pfmem64_12); - get_reg_off(pfmem64_13); - get_reg_off(pfmem64_14); - get_reg_off(pfmem64_15); - get_reg_off(pfmem64_16); - get_reg_off(pfmem64_17); - get_reg_off(pfmem64_18); - get_reg_off(pfmem64_19); - return dict; } diff --git a/miasm2/jitter/arch/JitCore_arm.h b/miasm2/jitter/arch/JitCore_arm.h index dde112ef..976ff124 100644 --- a/miasm2/jitter/arch/JitCore_arm.h +++ b/miasm2/jitter/arch/JitCore_arm.h @@ -1,7 +1,6 @@ typedef struct { uint32_t exception_flags; - uint32_t exception_flags_new; /* gpregs */ uint32_t R0; @@ -21,122 +20,12 @@ typedef struct { uint32_t LR; uint32_t PC; - uint32_t R0_new; - uint32_t R1_new; - uint32_t R2_new; - uint32_t R3_new; - uint32_t R4_new; - uint32_t R5_new; - uint32_t R6_new; - uint32_t R7_new; - uint32_t R8_new; - uint32_t R9_new; - uint32_t R10_new; - uint32_t R11_new; - uint32_t R12_new; - uint32_t SP_new; - uint32_t LR_new; - uint32_t PC_new; - /* eflag */ uint32_t zf; uint32_t nf; uint32_t of; uint32_t cf; - uint32_t zf_new; - uint32_t nf_new; - uint32_t of_new; - uint32_t cf_new; - - - uint8_t pfmem08_0; - uint8_t pfmem08_1; - uint8_t pfmem08_2; - uint8_t pfmem08_3; - uint8_t pfmem08_4; - uint8_t pfmem08_5; - uint8_t pfmem08_6; - uint8_t pfmem08_7; - uint8_t pfmem08_8; - uint8_t pfmem08_9; - uint8_t pfmem08_10; - uint8_t pfmem08_11; - uint8_t pfmem08_12; - uint8_t pfmem08_13; - uint8_t pfmem08_14; - uint8_t pfmem08_15; - uint8_t pfmem08_16; - uint8_t pfmem08_17; - uint8_t pfmem08_18; - uint8_t pfmem08_19; - - - uint16_t pfmem16_0; - uint16_t pfmem16_1; - uint16_t pfmem16_2; - uint16_t pfmem16_3; - uint16_t pfmem16_4; - uint16_t pfmem16_5; - uint16_t pfmem16_6; - uint16_t pfmem16_7; - uint16_t pfmem16_8; - uint16_t pfmem16_9; - uint16_t pfmem16_10; - uint16_t pfmem16_11; - uint16_t pfmem16_12; - uint16_t pfmem16_13; - uint16_t pfmem16_14; - uint16_t pfmem16_15; - uint16_t pfmem16_16; - uint16_t pfmem16_17; - uint16_t pfmem16_18; - uint16_t pfmem16_19; - - - uint32_t pfmem32_0; - uint32_t pfmem32_1; - uint32_t pfmem32_2; - uint32_t pfmem32_3; - uint32_t pfmem32_4; - uint32_t pfmem32_5; - uint32_t pfmem32_6; - uint32_t pfmem32_7; - uint32_t pfmem32_8; - uint32_t pfmem32_9; - uint32_t pfmem32_10; - uint32_t pfmem32_11; - uint32_t pfmem32_12; - uint32_t pfmem32_13; - uint32_t pfmem32_14; - uint32_t pfmem32_15; - uint32_t pfmem32_16; - uint32_t pfmem32_17; - uint32_t pfmem32_18; - uint32_t pfmem32_19; - - - uint64_t pfmem64_0; - uint64_t pfmem64_1; - uint64_t pfmem64_2; - uint64_t pfmem64_3; - uint64_t pfmem64_4; - uint64_t pfmem64_5; - uint64_t pfmem64_6; - uint64_t pfmem64_7; - uint64_t pfmem64_8; - uint64_t pfmem64_9; - uint64_t pfmem64_10; - uint64_t pfmem64_11; - uint64_t pfmem64_12; - uint64_t pfmem64_13; - uint64_t pfmem64_14; - uint64_t pfmem64_15; - uint64_t pfmem64_16; - uint64_t pfmem64_17; - uint64_t pfmem64_18; - uint64_t pfmem64_19; - }vm_cpu_t; diff --git a/miasm2/jitter/arch/JitCore_mips32.c b/miasm2/jitter/arch/JitCore_mips32.c index c8f8fb81..fc5589ff 100644 --- a/miasm2/jitter/arch/JitCore_mips32.c +++ b/miasm2/jitter/arch/JitCore_mips32.c @@ -1,11 +1,11 @@ #include <Python.h> -#include "../JitCore.h" #include "structmember.h" #include <stdint.h> #include <inttypes.h> #include "../queue.h" #include "../vm_mngr.h" #include "../vm_mngr_py.h" +#include "../JitCore.h" #include "JitCore_mips32.h" @@ -356,7 +356,6 @@ PyObject* get_gpreg_offset_all(void) PyObject *o; get_reg_off(exception_flags); - get_reg_off(exception_flags_new); get_reg_off(ZERO); @@ -396,132 +395,6 @@ PyObject* get_gpreg_offset_all(void) get_reg_off(R_LO); get_reg_off(R_HI); - get_reg_off(ZERO_new); - get_reg_off(AT_new); - get_reg_off(V0_new); - get_reg_off(V1_new); - get_reg_off(A0_new); - get_reg_off(A1_new); - get_reg_off(A2_new); - get_reg_off(A3_new); - get_reg_off(T0_new); - get_reg_off(T1_new); - get_reg_off(T2_new); - get_reg_off(T3_new); - get_reg_off(T4_new); - get_reg_off(T5_new); - get_reg_off(T6_new); - get_reg_off(T7_new); - get_reg_off(S0_new); - get_reg_off(S1_new); - get_reg_off(S2_new); - get_reg_off(S3_new); - get_reg_off(S4_new); - get_reg_off(S5_new); - get_reg_off(S6_new); - get_reg_off(S7_new); - get_reg_off(T8_new); - get_reg_off(T9_new); - get_reg_off(K0_new); - get_reg_off(K1_new); - get_reg_off(GP_new); - get_reg_off(SP_new); - get_reg_off(FP_new); - get_reg_off(RA_new); - get_reg_off(PC_new); - get_reg_off(PC_FETCH_new); - get_reg_off(R_LO_new); - get_reg_off(R_HI_new); - - - - get_reg_off(pfmem08_0); - get_reg_off(pfmem08_1); - get_reg_off(pfmem08_2); - get_reg_off(pfmem08_3); - get_reg_off(pfmem08_4); - get_reg_off(pfmem08_5); - get_reg_off(pfmem08_6); - get_reg_off(pfmem08_7); - get_reg_off(pfmem08_8); - get_reg_off(pfmem08_9); - get_reg_off(pfmem08_10); - get_reg_off(pfmem08_11); - get_reg_off(pfmem08_12); - get_reg_off(pfmem08_13); - get_reg_off(pfmem08_14); - get_reg_off(pfmem08_15); - get_reg_off(pfmem08_16); - get_reg_off(pfmem08_17); - get_reg_off(pfmem08_18); - get_reg_off(pfmem08_19); - - - get_reg_off(pfmem16_0); - get_reg_off(pfmem16_1); - get_reg_off(pfmem16_2); - get_reg_off(pfmem16_3); - get_reg_off(pfmem16_4); - get_reg_off(pfmem16_5); - get_reg_off(pfmem16_6); - get_reg_off(pfmem16_7); - get_reg_off(pfmem16_8); - get_reg_off(pfmem16_9); - get_reg_off(pfmem16_10); - get_reg_off(pfmem16_11); - get_reg_off(pfmem16_12); - get_reg_off(pfmem16_13); - get_reg_off(pfmem16_14); - get_reg_off(pfmem16_15); - get_reg_off(pfmem16_16); - get_reg_off(pfmem16_17); - get_reg_off(pfmem16_18); - get_reg_off(pfmem16_19); - - - get_reg_off(pfmem32_0); - get_reg_off(pfmem32_1); - get_reg_off(pfmem32_2); - get_reg_off(pfmem32_3); - get_reg_off(pfmem32_4); - get_reg_off(pfmem32_5); - get_reg_off(pfmem32_6); - get_reg_off(pfmem32_7); - get_reg_off(pfmem32_8); - get_reg_off(pfmem32_9); - get_reg_off(pfmem32_10); - get_reg_off(pfmem32_11); - get_reg_off(pfmem32_12); - get_reg_off(pfmem32_13); - get_reg_off(pfmem32_14); - get_reg_off(pfmem32_15); - get_reg_off(pfmem32_16); - get_reg_off(pfmem32_17); - get_reg_off(pfmem32_18); - get_reg_off(pfmem32_19); - - - get_reg_off(pfmem64_0); - get_reg_off(pfmem64_1); - get_reg_off(pfmem64_2); - get_reg_off(pfmem64_3); - get_reg_off(pfmem64_4); - get_reg_off(pfmem64_5); - get_reg_off(pfmem64_6); - get_reg_off(pfmem64_7); - get_reg_off(pfmem64_8); - get_reg_off(pfmem64_9); - get_reg_off(pfmem64_10); - get_reg_off(pfmem64_11); - get_reg_off(pfmem64_12); - get_reg_off(pfmem64_13); - get_reg_off(pfmem64_14); - get_reg_off(pfmem64_15); - get_reg_off(pfmem64_16); - get_reg_off(pfmem64_17); - get_reg_off(pfmem64_18); - get_reg_off(pfmem64_19); - return dict; } diff --git a/miasm2/jitter/arch/JitCore_mips32.h b/miasm2/jitter/arch/JitCore_mips32.h index de98f069..55c63d3b 100644 --- a/miasm2/jitter/arch/JitCore_mips32.h +++ b/miasm2/jitter/arch/JitCore_mips32.h @@ -1,7 +1,6 @@ typedef struct { uint32_t exception_flags; - uint32_t exception_flags_new; /* gpregs */ @@ -42,132 +41,6 @@ typedef struct { uint32_t R_LO; uint32_t R_HI; - uint32_t ZERO_new; - uint32_t AT_new; - uint32_t V0_new; - uint32_t V1_new; - uint32_t A0_new; - uint32_t A1_new; - uint32_t A2_new; - uint32_t A3_new; - uint32_t T0_new; - uint32_t T1_new; - uint32_t T2_new; - uint32_t T3_new; - uint32_t T4_new; - uint32_t T5_new; - uint32_t T6_new; - uint32_t T7_new; - uint32_t S0_new; - uint32_t S1_new; - uint32_t S2_new; - uint32_t S3_new; - uint32_t S4_new; - uint32_t S5_new; - uint32_t S6_new; - uint32_t S7_new; - uint32_t T8_new; - uint32_t T9_new; - uint32_t K0_new; - uint32_t K1_new; - uint32_t GP_new; - uint32_t SP_new; - uint32_t FP_new; - uint32_t RA_new; - uint32_t PC_new; - uint32_t PC_FETCH_new; - uint32_t R_LO_new; - uint32_t R_HI_new; - - - - uint8_t pfmem08_0; - uint8_t pfmem08_1; - uint8_t pfmem08_2; - uint8_t pfmem08_3; - uint8_t pfmem08_4; - uint8_t pfmem08_5; - uint8_t pfmem08_6; - uint8_t pfmem08_7; - uint8_t pfmem08_8; - uint8_t pfmem08_9; - uint8_t pfmem08_10; - uint8_t pfmem08_11; - uint8_t pfmem08_12; - uint8_t pfmem08_13; - uint8_t pfmem08_14; - uint8_t pfmem08_15; - uint8_t pfmem08_16; - uint8_t pfmem08_17; - uint8_t pfmem08_18; - uint8_t pfmem08_19; - - - uint16_t pfmem16_0; - uint16_t pfmem16_1; - uint16_t pfmem16_2; - uint16_t pfmem16_3; - uint16_t pfmem16_4; - uint16_t pfmem16_5; - uint16_t pfmem16_6; - uint16_t pfmem16_7; - uint16_t pfmem16_8; - uint16_t pfmem16_9; - uint16_t pfmem16_10; - uint16_t pfmem16_11; - uint16_t pfmem16_12; - uint16_t pfmem16_13; - uint16_t pfmem16_14; - uint16_t pfmem16_15; - uint16_t pfmem16_16; - uint16_t pfmem16_17; - uint16_t pfmem16_18; - uint16_t pfmem16_19; - - - uint32_t pfmem32_0; - uint32_t pfmem32_1; - uint32_t pfmem32_2; - uint32_t pfmem32_3; - uint32_t pfmem32_4; - uint32_t pfmem32_5; - uint32_t pfmem32_6; - uint32_t pfmem32_7; - uint32_t pfmem32_8; - uint32_t pfmem32_9; - uint32_t pfmem32_10; - uint32_t pfmem32_11; - uint32_t pfmem32_12; - uint32_t pfmem32_13; - uint32_t pfmem32_14; - uint32_t pfmem32_15; - uint32_t pfmem32_16; - uint32_t pfmem32_17; - uint32_t pfmem32_18; - uint32_t pfmem32_19; - - - uint64_t pfmem64_0; - uint64_t pfmem64_1; - uint64_t pfmem64_2; - uint64_t pfmem64_3; - uint64_t pfmem64_4; - uint64_t pfmem64_5; - uint64_t pfmem64_6; - uint64_t pfmem64_7; - uint64_t pfmem64_8; - uint64_t pfmem64_9; - uint64_t pfmem64_10; - uint64_t pfmem64_11; - uint64_t pfmem64_12; - uint64_t pfmem64_13; - uint64_t pfmem64_14; - uint64_t pfmem64_15; - uint64_t pfmem64_16; - uint64_t pfmem64_17; - uint64_t pfmem64_18; - uint64_t pfmem64_19; - double F0; double F1; @@ -202,39 +75,6 @@ typedef struct { double F30; double F31; - double F0_new; - double F1_new; - double F2_new; - double F3_new; - double F4_new; - double F5_new; - double F6_new; - double F7_new; - double F8_new; - double F9_new; - double F10_new; - double F11_new; - double F12_new; - double F13_new; - double F14_new; - double F15_new; - double F16_new; - double F17_new; - double F18_new; - double F19_new; - double F20_new; - double F21_new; - double F22_new; - double F23_new; - double F24_new; - double F25_new; - double F26_new; - double F27_new; - double F28_new; - double F29_new; - double F30_new; - double F31_new; - uint32_t INDEX; uint32_t CPR0_1; uint32_t CPR0_2; @@ -491,266 +331,9 @@ typedef struct { uint32_t CPR0_253; uint32_t CPR0_254; uint32_t CPR0_255; - - uint32_t INDEX_new; - uint32_t CPR0_1_new; - uint32_t CPR0_2_new; - uint32_t CPR0_3_new; - uint32_t CPR0_4_new; - uint32_t CPR0_5_new; - uint32_t CPR0_6_new; - uint32_t CPR0_7_new; - uint32_t CPR0_8_new; - uint32_t CPR0_9_new; - uint32_t CPR0_10_new; - uint32_t CPR0_11_new; - uint32_t CPR0_12_new; - uint32_t CPR0_13_new; - uint32_t CPR0_14_new; - uint32_t CPR0_15_new; - uint32_t ENTRYLO0_new; - uint32_t CPR0_17_new; - uint32_t CPR0_18_new; - uint32_t CPR0_19_new; - uint32_t CPR0_20_new; - uint32_t CPR0_21_new; - uint32_t CPR0_22_new; - uint32_t CPR0_23_new; - uint32_t ENTRYLO1_new; - uint32_t CPR0_25_new; - uint32_t CPR0_26_new; - uint32_t CPR0_27_new; - uint32_t CPR0_28_new; - uint32_t CPR0_29_new; - uint32_t CPR0_30_new; - uint32_t CPR0_31_new; - uint32_t CPR0_32_new; - uint32_t CPR0_33_new; - uint32_t CPR0_34_new; - uint32_t CPR0_35_new; - uint32_t CPR0_36_new; - uint32_t CPR0_37_new; - uint32_t CPR0_38_new; - uint32_t CPR0_39_new; - uint32_t PAGEMASK_new; - uint32_t CPR0_41_new; - uint32_t CPR0_42_new; - uint32_t CPR0_43_new; - uint32_t CPR0_44_new; - uint32_t CPR0_45_new; - uint32_t CPR0_46_new; - uint32_t CPR0_47_new; - uint32_t CPR0_48_new; - uint32_t CPR0_49_new; - uint32_t CPR0_50_new; - uint32_t CPR0_51_new; - uint32_t CPR0_52_new; - uint32_t CPR0_53_new; - uint32_t CPR0_54_new; - uint32_t CPR0_55_new; - uint32_t CPR0_56_new; - uint32_t CPR0_57_new; - uint32_t CPR0_58_new; - uint32_t CPR0_59_new; - uint32_t CPR0_60_new; - uint32_t CPR0_61_new; - uint32_t CPR0_62_new; - uint32_t CPR0_63_new; - uint32_t CPR0_64_new; - uint32_t CPR0_65_new; - uint32_t CPR0_66_new; - uint32_t CPR0_67_new; - uint32_t CPR0_68_new; - uint32_t CPR0_69_new; - uint32_t CPR0_70_new; - uint32_t CPR0_71_new; - uint32_t COUNT_new; - uint32_t CPR0_73_new; - uint32_t CPR0_74_new; - uint32_t CPR0_75_new; - uint32_t CPR0_76_new; - uint32_t CPR0_77_new; - uint32_t CPR0_78_new; - uint32_t CPR0_79_new; - uint32_t ENTRYHI_new; - uint32_t CPR0_81_new; - uint32_t CPR0_82_new; - uint32_t CPR0_83_new; - uint32_t CPR0_84_new; - uint32_t CPR0_85_new; - uint32_t CPR0_86_new; - uint32_t CPR0_87_new; - uint32_t CPR0_88_new; - uint32_t CPR0_89_new; - uint32_t CPR0_90_new; - uint32_t CPR0_91_new; - uint32_t CPR0_92_new; - uint32_t CPR0_93_new; - uint32_t CPR0_94_new; - uint32_t CPR0_95_new; - uint32_t CPR0_96_new; - uint32_t CPR0_97_new; - uint32_t CPR0_98_new; - uint32_t CPR0_99_new; - uint32_t CPR0_100_new; - uint32_t CPR0_101_new; - uint32_t CPR0_102_new; - uint32_t CPR0_103_new; - uint32_t CAUSE_new; - uint32_t CPR0_105_new; - uint32_t CPR0_106_new; - uint32_t CPR0_107_new; - uint32_t CPR0_108_new; - uint32_t CPR0_109_new; - uint32_t CPR0_110_new; - uint32_t CPR0_111_new; - uint32_t EPC_new; - uint32_t CPR0_113_new; - uint32_t CPR0_114_new; - uint32_t CPR0_115_new; - uint32_t CPR0_116_new; - uint32_t CPR0_117_new; - uint32_t CPR0_118_new; - uint32_t CPR0_119_new; - uint32_t CPR0_120_new; - uint32_t CPR0_121_new; - uint32_t CPR0_122_new; - uint32_t CPR0_123_new; - uint32_t CPR0_124_new; - uint32_t CPR0_125_new; - uint32_t CPR0_126_new; - uint32_t CPR0_127_new; - uint32_t CONFIG_new; - uint32_t CPR0_129_new; - uint32_t CPR0_130_new; - uint32_t CPR0_131_new; - uint32_t CPR0_132_new; - uint32_t CPR0_133_new; - uint32_t CPR0_134_new; - uint32_t CPR0_135_new; - uint32_t CPR0_136_new; - uint32_t CPR0_137_new; - uint32_t CPR0_138_new; - uint32_t CPR0_139_new; - uint32_t CPR0_140_new; - uint32_t CPR0_141_new; - uint32_t CPR0_142_new; - uint32_t CPR0_143_new; - uint32_t CPR0_144_new; - uint32_t CPR0_145_new; - uint32_t CPR0_146_new; - uint32_t CPR0_147_new; - uint32_t CPR0_148_new; - uint32_t CPR0_149_new; - uint32_t CPR0_150_new; - uint32_t CPR0_151_new; - uint32_t WATCHHI_new; - uint32_t CPR0_153_new; - uint32_t CPR0_154_new; - uint32_t CPR0_155_new; - uint32_t CPR0_156_new; - uint32_t CPR0_157_new; - uint32_t CPR0_158_new; - uint32_t CPR0_159_new; - uint32_t CPR0_160_new; - uint32_t CPR0_161_new; - uint32_t CPR0_162_new; - uint32_t CPR0_163_new; - uint32_t CPR0_164_new; - uint32_t CPR0_165_new; - uint32_t CPR0_166_new; - uint32_t CPR0_167_new; - uint32_t CPR0_168_new; - uint32_t CPR0_169_new; - uint32_t CPR0_170_new; - uint32_t CPR0_171_new; - uint32_t CPR0_172_new; - uint32_t CPR0_173_new; - uint32_t CPR0_174_new; - uint32_t CPR0_175_new; - uint32_t CPR0_176_new; - uint32_t CPR0_177_new; - uint32_t CPR0_178_new; - uint32_t CPR0_179_new; - uint32_t CPR0_180_new; - uint32_t CPR0_181_new; - uint32_t CPR0_182_new; - uint32_t CPR0_183_new; - uint32_t CPR0_184_new; - uint32_t CPR0_185_new; - uint32_t CPR0_186_new; - uint32_t CPR0_187_new; - uint32_t CPR0_188_new; - uint32_t CPR0_189_new; - uint32_t CPR0_190_new; - uint32_t CPR0_191_new; - uint32_t CPR0_192_new; - uint32_t CPR0_193_new; - uint32_t CPR0_194_new; - uint32_t CPR0_195_new; - uint32_t CPR0_196_new; - uint32_t CPR0_197_new; - uint32_t CPR0_198_new; - uint32_t CPR0_199_new; - uint32_t CPR0_200_new; - uint32_t CPR0_201_new; - uint32_t CPR0_202_new; - uint32_t CPR0_203_new; - uint32_t CPR0_204_new; - uint32_t CPR0_205_new; - uint32_t CPR0_206_new; - uint32_t CPR0_207_new; - uint32_t CPR0_208_new; - uint32_t CPR0_209_new; - uint32_t CPR0_210_new; - uint32_t CPR0_211_new; - uint32_t CPR0_212_new; - uint32_t CPR0_213_new; - uint32_t CPR0_214_new; - uint32_t CPR0_215_new; - uint32_t CPR0_216_new; - uint32_t CPR0_217_new; - uint32_t CPR0_218_new; - uint32_t CPR0_219_new; - uint32_t CPR0_220_new; - uint32_t CPR0_221_new; - uint32_t CPR0_222_new; - uint32_t CPR0_223_new; - uint32_t CPR0_224_new; - uint32_t CPR0_225_new; - uint32_t CPR0_226_new; - uint32_t CPR0_227_new; - uint32_t CPR0_228_new; - uint32_t CPR0_229_new; - uint32_t CPR0_230_new; - uint32_t CPR0_231_new; - uint32_t CPR0_232_new; - uint32_t CPR0_233_new; - uint32_t CPR0_234_new; - uint32_t CPR0_235_new; - uint32_t CPR0_236_new; - uint32_t CPR0_237_new; - uint32_t CPR0_238_new; - uint32_t CPR0_239_new; - uint32_t CPR0_240_new; - uint32_t CPR0_241_new; - uint32_t CPR0_242_new; - uint32_t CPR0_243_new; - uint32_t CPR0_244_new; - uint32_t CPR0_245_new; - uint32_t CPR0_246_new; - uint32_t CPR0_247_new; - uint32_t CPR0_248_new; - uint32_t CPR0_249_new; - uint32_t CPR0_250_new; - uint32_t CPR0_251_new; - uint32_t CPR0_252_new; - uint32_t CPR0_253_new; - uint32_t CPR0_254_new; - uint32_t CPR0_255_new; - }vm_cpu_t; +void dump_gpregs(vm_cpu_t* vmcpu); //#define RETURN_PC return PyLong_FromUnsignedLongLong(vmcpu->PC); #define RETURN_PC return BlockDst; diff --git a/miasm2/jitter/arch/JitCore_msp430.c b/miasm2/jitter/arch/JitCore_msp430.c index 3a34248a..977b0777 100644 --- a/miasm2/jitter/arch/JitCore_msp430.c +++ b/miasm2/jitter/arch/JitCore_msp430.c @@ -1,11 +1,11 @@ #include <Python.h> -#include "../JitCore.h" #include "structmember.h" #include <stdint.h> #include <inttypes.h> #include "../queue.h" #include "../vm_mngr.h" #include "../vm_mngr_py.h" +#include "../JitCore.h" #include "JitCore_msp430.h" @@ -317,7 +317,7 @@ PyObject* get_gpreg_offset_all(void) PyObject *dict = PyDict_New(); PyObject *o; get_reg_off(exception_flags); - get_reg_off(exception_flags_new); + get_reg_off(PC); get_reg_off(SP); get_reg_off(R3); @@ -333,22 +333,7 @@ PyObject* get_gpreg_offset_all(void) get_reg_off(R13); get_reg_off(R14); get_reg_off(R15); - get_reg_off(PC_new); - get_reg_off(SP_new); - get_reg_off(SR_new); - get_reg_off(R3_new); - get_reg_off(R4_new); - get_reg_off(R5_new); - get_reg_off(R6_new); - get_reg_off(R7_new); - get_reg_off(R8_new); - get_reg_off(R9_new); - get_reg_off(R10_new); - get_reg_off(R11_new); - get_reg_off(R12_new); - get_reg_off(R13_new); - get_reg_off(R14_new); - get_reg_off(R15_new); + get_reg_off(zf); get_reg_off(nf); get_reg_off(of); @@ -359,96 +344,7 @@ PyObject* get_gpreg_offset_all(void) get_reg_off(scg0); get_reg_off(scg1); get_reg_off(res); - get_reg_off(zf_new); - get_reg_off(nf_new); - get_reg_off(of_new); - get_reg_off(cf_new); - get_reg_off(cpuoff_new); - get_reg_off(gie_new); - get_reg_off(osc_new); - get_reg_off(scg0_new); - get_reg_off(scg1_new); - get_reg_off(res_new); - get_reg_off(pfmem08_0); - get_reg_off(pfmem08_1); - get_reg_off(pfmem08_2); - get_reg_off(pfmem08_3); - get_reg_off(pfmem08_4); - get_reg_off(pfmem08_5); - get_reg_off(pfmem08_6); - get_reg_off(pfmem08_7); - get_reg_off(pfmem08_8); - get_reg_off(pfmem08_9); - get_reg_off(pfmem08_10); - get_reg_off(pfmem08_11); - get_reg_off(pfmem08_12); - get_reg_off(pfmem08_13); - get_reg_off(pfmem08_14); - get_reg_off(pfmem08_15); - get_reg_off(pfmem08_16); - get_reg_off(pfmem08_17); - get_reg_off(pfmem08_18); - get_reg_off(pfmem08_19); - get_reg_off(pfmem16_0); - get_reg_off(pfmem16_1); - get_reg_off(pfmem16_2); - get_reg_off(pfmem16_3); - get_reg_off(pfmem16_4); - get_reg_off(pfmem16_5); - get_reg_off(pfmem16_6); - get_reg_off(pfmem16_7); - get_reg_off(pfmem16_8); - get_reg_off(pfmem16_9); - get_reg_off(pfmem16_10); - get_reg_off(pfmem16_11); - get_reg_off(pfmem16_12); - get_reg_off(pfmem16_13); - get_reg_off(pfmem16_14); - get_reg_off(pfmem16_15); - get_reg_off(pfmem16_16); - get_reg_off(pfmem16_17); - get_reg_off(pfmem16_18); - get_reg_off(pfmem16_19); - get_reg_off(pfmem32_0); - get_reg_off(pfmem32_1); - get_reg_off(pfmem32_2); - get_reg_off(pfmem32_3); - get_reg_off(pfmem32_4); - get_reg_off(pfmem32_5); - get_reg_off(pfmem32_6); - get_reg_off(pfmem32_7); - get_reg_off(pfmem32_8); - get_reg_off(pfmem32_9); - get_reg_off(pfmem32_10); - get_reg_off(pfmem32_11); - get_reg_off(pfmem32_12); - get_reg_off(pfmem32_13); - get_reg_off(pfmem32_14); - get_reg_off(pfmem32_15); - get_reg_off(pfmem32_16); - get_reg_off(pfmem32_17); - get_reg_off(pfmem32_18); - get_reg_off(pfmem32_19); - get_reg_off(pfmem64_0); - get_reg_off(pfmem64_1); - get_reg_off(pfmem64_2); - get_reg_off(pfmem64_3); - get_reg_off(pfmem64_4); - get_reg_off(pfmem64_5); - get_reg_off(pfmem64_6); - get_reg_off(pfmem64_7); - get_reg_off(pfmem64_8); - get_reg_off(pfmem64_9); - get_reg_off(pfmem64_10); - get_reg_off(pfmem64_11); - get_reg_off(pfmem64_12); - get_reg_off(pfmem64_13); - get_reg_off(pfmem64_14); - get_reg_off(pfmem64_15); - get_reg_off(pfmem64_16); - get_reg_off(pfmem64_17); - get_reg_off(pfmem64_18); - get_reg_off(pfmem64_19); + return dict; } diff --git a/miasm2/jitter/arch/JitCore_msp430.h b/miasm2/jitter/arch/JitCore_msp430.h index 179554ad..03b0bb25 100644 --- a/miasm2/jitter/arch/JitCore_msp430.h +++ b/miasm2/jitter/arch/JitCore_msp430.h @@ -1,7 +1,6 @@ typedef struct { uint32_t exception_flags; - uint32_t exception_flags_new; /* gpregs */ uint32_t PC; @@ -20,23 +19,6 @@ typedef struct { uint32_t R14; uint32_t R15; - uint32_t PC_new; - uint32_t SP_new; - uint32_t SR_new; - uint32_t R3_new; - uint32_t R4_new; - uint32_t R5_new; - uint32_t R6_new; - uint32_t R7_new; - uint32_t R8_new; - uint32_t R9_new; - uint32_t R10_new; - uint32_t R11_new; - uint32_t R12_new; - uint32_t R13_new; - uint32_t R14_new; - uint32_t R15_new; - /* eflag */ uint32_t zf; uint32_t nf; @@ -50,108 +32,6 @@ typedef struct { uint32_t scg1; uint32_t res; - - uint32_t zf_new; - uint32_t nf_new; - uint32_t of_new; - uint32_t cf_new; - - uint32_t cpuoff_new; - uint32_t gie_new; - uint32_t osc_new; - uint32_t scg0_new; - uint32_t scg1_new; - uint32_t res_new; - - - uint8_t pfmem08_0; - uint8_t pfmem08_1; - uint8_t pfmem08_2; - uint8_t pfmem08_3; - uint8_t pfmem08_4; - uint8_t pfmem08_5; - uint8_t pfmem08_6; - uint8_t pfmem08_7; - uint8_t pfmem08_8; - uint8_t pfmem08_9; - uint8_t pfmem08_10; - uint8_t pfmem08_11; - uint8_t pfmem08_12; - uint8_t pfmem08_13; - uint8_t pfmem08_14; - uint8_t pfmem08_15; - uint8_t pfmem08_16; - uint8_t pfmem08_17; - uint8_t pfmem08_18; - uint8_t pfmem08_19; - - - uint16_t pfmem16_0; - uint16_t pfmem16_1; - uint16_t pfmem16_2; - uint16_t pfmem16_3; - uint16_t pfmem16_4; - uint16_t pfmem16_5; - uint16_t pfmem16_6; - uint16_t pfmem16_7; - uint16_t pfmem16_8; - uint16_t pfmem16_9; - uint16_t pfmem16_10; - uint16_t pfmem16_11; - uint16_t pfmem16_12; - uint16_t pfmem16_13; - uint16_t pfmem16_14; - uint16_t pfmem16_15; - uint16_t pfmem16_16; - uint16_t pfmem16_17; - uint16_t pfmem16_18; - uint16_t pfmem16_19; - - - uint32_t pfmem32_0; - uint32_t pfmem32_1; - uint32_t pfmem32_2; - uint32_t pfmem32_3; - uint32_t pfmem32_4; - uint32_t pfmem32_5; - uint32_t pfmem32_6; - uint32_t pfmem32_7; - uint32_t pfmem32_8; - uint32_t pfmem32_9; - uint32_t pfmem32_10; - uint32_t pfmem32_11; - uint32_t pfmem32_12; - uint32_t pfmem32_13; - uint32_t pfmem32_14; - uint32_t pfmem32_15; - uint32_t pfmem32_16; - uint32_t pfmem32_17; - uint32_t pfmem32_18; - uint32_t pfmem32_19; - - - uint64_t pfmem64_0; - uint64_t pfmem64_1; - uint64_t pfmem64_2; - uint64_t pfmem64_3; - uint64_t pfmem64_4; - uint64_t pfmem64_5; - uint64_t pfmem64_6; - uint64_t pfmem64_7; - uint64_t pfmem64_8; - uint64_t pfmem64_9; - uint64_t pfmem64_10; - uint64_t pfmem64_11; - uint64_t pfmem64_12; - uint64_t pfmem64_13; - uint64_t pfmem64_14; - uint64_t pfmem64_15; - uint64_t pfmem64_16; - uint64_t pfmem64_17; - uint64_t pfmem64_18; - uint64_t pfmem64_19; - - }vm_cpu_t; //#define RETURN_PC return PyLong_FromUnsignedLongLong(vmcpu->PC); diff --git a/miasm2/jitter/arch/JitCore_x86.c b/miasm2/jitter/arch/JitCore_x86.c index b406e755..0b788071 100644 --- a/miasm2/jitter/arch/JitCore_x86.c +++ b/miasm2/jitter/arch/JitCore_x86.c @@ -1,11 +1,11 @@ #include <Python.h> -#include "../JitCore.h" #include "structmember.h" #include <stdint.h> #include <inttypes.h> #include "../queue.h" #include "../vm_mngr.h" #include "../vm_mngr_py.h" +#include "../JitCore.h" #include "JitCore_x86.h" @@ -176,17 +176,46 @@ PyObject * cpu_init_regs(JitCpu* self) } -void dump_gpregs(vm_cpu_t* vmcpu) +void dump_gpregs_32(vm_cpu_t* vmcpu) +{ + + printf("EAX %.8"PRIX32" EBX %.8"PRIX32" ECX %.8"PRIX32" EDX %.8"PRIX32" ", + (uint32_t)(vmcpu->RAX & 0xFFFFFFFF), + (uint32_t)(vmcpu->RBX & 0xFFFFFFFF), + (uint32_t)(vmcpu->RCX & 0xFFFFFFFF), + (uint32_t)(vmcpu->RDX & 0xFFFFFFFF)); + printf("ESI %.8"PRIX32" EDI %.8"PRIX32" ESP %.8"PRIX32" EBP %.8"PRIX32" ", + (uint32_t)(vmcpu->RSI & 0xFFFFFFFF), + (uint32_t)(vmcpu->RDI & 0xFFFFFFFF), + (uint32_t)(vmcpu->RSP & 0xFFFFFFFF), + (uint32_t)(vmcpu->RBP & 0xFFFFFFFF)); + printf("EIP %.8"PRIX32" ", + (uint32_t)(vmcpu->RIP & 0xFFFFFFFF)); + printf("zf %.1"PRIX32" nf %.1"PRIX32" of %.1"PRIX32" cf %.1"PRIX32"\n", + (uint32_t)(vmcpu->zf & 0x1), + (uint32_t)(vmcpu->nf & 0x1), + (uint32_t)(vmcpu->of & 0x1), + (uint32_t)(vmcpu->cf & 0x1)); + +} + +void dump_gpregs_64(vm_cpu_t* vmcpu) { - printf("RAX %.16"PRIX64" RBX %.16"PRIX64" RCX %.16"PRIX64" RDX %.16"PRIX64"\n", + printf("RAX %.16"PRIX64" RBX %.16"PRIX64" RCX %.16"PRIX64" RDX %.16"PRIX64" ", vmcpu->RAX, vmcpu->RBX, vmcpu->RCX, vmcpu->RDX); - printf("RSI %.16"PRIX64" RDI %.16"PRIX64" RSP %.16"PRIX64" RBP %.16"PRIX64"\n", + printf("RSI %.16"PRIX64" RDI %.16"PRIX64" RSP %.16"PRIX64" RBP %.16"PRIX64" ", vmcpu->RSI, vmcpu->RDI, vmcpu->RSP, vmcpu->RBP); - printf("zf %.16"PRIX64" nf %.16"PRIX64" of %.16"PRIX64" cf %.16"PRIX64"\n", - vmcpu->zf, vmcpu->nf, vmcpu->of, vmcpu->cf); printf("RIP %.16"PRIX64"\n", vmcpu->RIP); + printf("R8 %.16"PRIX64" R9 %.16"PRIX64" R10 %.16"PRIX64" R11 %.16"PRIX64" ", + vmcpu->R8, vmcpu->R9, vmcpu->R10, vmcpu->R11); + printf("R12 %.16"PRIX64" R13 %.16"PRIX64" R14 %.16"PRIX64" R15 %.16"PRIX64" ", + vmcpu->R12, vmcpu->R13, vmcpu->R14, vmcpu->R15); + + + printf("zf %.1"PRIX64" nf %.1"PRIX64" of %.1"PRIX64" cf %.1"PRIX64"\n", + vmcpu->zf, vmcpu->nf, vmcpu->of, vmcpu->cf); } @@ -195,7 +224,7 @@ PyObject * cpu_dump_gpregs(JitCpu* self, PyObject* args) vm_cpu_t* vmcpu; vmcpu = self->cpu; - dump_gpregs(vmcpu); + dump_gpregs_64(vmcpu); Py_INCREF(Py_None); return Py_None; } @@ -293,42 +322,24 @@ IMOD(16) IMOD(32) IMOD(64) - - - -void check_automod(JitCpu* jitcpu, uint64_t addr, uint64_t size) -{ - PyObject *result; - - if (!(((VmMngr*)jitcpu->pyvm)->vm_mngr.exception_flags & EXCEPT_CODE_AUTOMOD)) - return; - result = PyObject_CallMethod(jitcpu->jitter, "automod_cb", "LL", addr, size); - Py_DECREF(result); - -} - void MEM_WRITE_08(JitCpu* jitcpu, uint64_t addr, uint8_t src) { vm_MEM_WRITE_08(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src); - check_automod(jitcpu, addr, 8); } void MEM_WRITE_16(JitCpu* jitcpu, uint64_t addr, uint16_t src) { vm_MEM_WRITE_16(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src); - check_automod(jitcpu, addr, 16); } void MEM_WRITE_32(JitCpu* jitcpu, uint64_t addr, uint32_t src) { vm_MEM_WRITE_32(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src); - check_automod(jitcpu, addr, 32); } void MEM_WRITE_64(JitCpu* jitcpu, uint64_t addr, uint64_t src) { vm_MEM_WRITE_64(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src); - check_automod(jitcpu, addr, 64); } @@ -358,7 +369,6 @@ PyObject* vm_set_mem(JitCpu *self, PyObject* args) ret = vm_write_mem(&(((VmMngr*)self->pyvm)->vm_mngr), addr, buffer, size); if (ret < 0) RAISE(PyExc_TypeError,"arg must be str"); - check_automod(self, addr, size*8); Py_INCREF(Py_None); return Py_None; @@ -518,7 +528,6 @@ PyObject* get_gpreg_offset_all(void) PyObject *o; get_reg_off(exception_flags); - get_reg_off(exception_flags_new); get_reg_off(RAX); get_reg_off(RBX); @@ -537,23 +546,6 @@ PyObject* get_gpreg_offset_all(void) get_reg_off(R14); get_reg_off(R15); get_reg_off(RIP); - get_reg_off(RAX_new); - get_reg_off(RBX_new); - get_reg_off(RCX_new); - get_reg_off(RDX_new); - get_reg_off(RSI_new); - get_reg_off(RDI_new); - get_reg_off(RSP_new); - get_reg_off(RBP_new); - get_reg_off(R8_new); - get_reg_off(R9_new); - get_reg_off(R10_new); - get_reg_off(R11_new); - get_reg_off(R12_new); - get_reg_off(R13_new); - get_reg_off(R14_new); - get_reg_off(R15_new); - get_reg_off(RIP_new); get_reg_off(zf); get_reg_off(nf); get_reg_off(pf); @@ -561,13 +553,6 @@ PyObject* get_gpreg_offset_all(void) get_reg_off(cf); get_reg_off(af); get_reg_off(df); - get_reg_off(zf_new); - get_reg_off(nf_new); - get_reg_off(pf_new); - get_reg_off(of_new); - get_reg_off(cf_new); - get_reg_off(af_new); - get_reg_off(df_new); get_reg_off(tf); get_reg_off(i_f); get_reg_off(iopl_f); @@ -578,16 +563,6 @@ PyObject* get_gpreg_offset_all(void) get_reg_off(vif); get_reg_off(vip); get_reg_off(i_d); - get_reg_off(tf_new); - get_reg_off(i_f_new); - get_reg_off(iopl_f_new); - get_reg_off(nt_new); - get_reg_off(rf_new); - get_reg_off(vm_new); - get_reg_off(ac_new); - get_reg_off(vif_new); - get_reg_off(vip_new); - get_reg_off(i_d_new); get_reg_off(my_tick); get_reg_off(cond); @@ -599,14 +574,6 @@ PyObject* get_gpreg_offset_all(void) get_reg_off(float_st5); get_reg_off(float_st6); get_reg_off(float_st7); - get_reg_off(float_st0_new); - get_reg_off(float_st1_new); - get_reg_off(float_st2_new); - get_reg_off(float_st3_new); - get_reg_off(float_st4_new); - get_reg_off(float_st5_new); - get_reg_off(float_st6_new); - get_reg_off(float_st7_new); get_reg_off(ES); get_reg_off(CS); @@ -614,93 +581,6 @@ PyObject* get_gpreg_offset_all(void) get_reg_off(DS); get_reg_off(FS); get_reg_off(GS); - get_reg_off(ES_new); - get_reg_off(CS_new); - get_reg_off(SS_new); - get_reg_off(DS_new); - get_reg_off(FS_new); - get_reg_off(GS_new); - - get_reg_off(pfmem08_0); - get_reg_off(pfmem08_1); - get_reg_off(pfmem08_2); - get_reg_off(pfmem08_3); - get_reg_off(pfmem08_4); - get_reg_off(pfmem08_5); - get_reg_off(pfmem08_6); - get_reg_off(pfmem08_7); - get_reg_off(pfmem08_8); - get_reg_off(pfmem08_9); - get_reg_off(pfmem08_10); - get_reg_off(pfmem08_11); - get_reg_off(pfmem08_12); - get_reg_off(pfmem08_13); - get_reg_off(pfmem08_14); - get_reg_off(pfmem08_15); - get_reg_off(pfmem08_16); - get_reg_off(pfmem08_17); - get_reg_off(pfmem08_18); - get_reg_off(pfmem08_19); - get_reg_off(pfmem16_0); - get_reg_off(pfmem16_1); - get_reg_off(pfmem16_2); - get_reg_off(pfmem16_3); - get_reg_off(pfmem16_4); - get_reg_off(pfmem16_5); - get_reg_off(pfmem16_6); - get_reg_off(pfmem16_7); - get_reg_off(pfmem16_8); - get_reg_off(pfmem16_9); - get_reg_off(pfmem16_10); - get_reg_off(pfmem16_11); - get_reg_off(pfmem16_12); - get_reg_off(pfmem16_13); - get_reg_off(pfmem16_14); - get_reg_off(pfmem16_15); - get_reg_off(pfmem16_16); - get_reg_off(pfmem16_17); - get_reg_off(pfmem16_18); - get_reg_off(pfmem16_19); - get_reg_off(pfmem32_0); - get_reg_off(pfmem32_1); - get_reg_off(pfmem32_2); - get_reg_off(pfmem32_3); - get_reg_off(pfmem32_4); - get_reg_off(pfmem32_5); - get_reg_off(pfmem32_6); - get_reg_off(pfmem32_7); - get_reg_off(pfmem32_8); - get_reg_off(pfmem32_9); - get_reg_off(pfmem32_10); - get_reg_off(pfmem32_11); - get_reg_off(pfmem32_12); - get_reg_off(pfmem32_13); - get_reg_off(pfmem32_14); - get_reg_off(pfmem32_15); - get_reg_off(pfmem32_16); - get_reg_off(pfmem32_17); - get_reg_off(pfmem32_18); - get_reg_off(pfmem32_19); - get_reg_off(pfmem64_0); - get_reg_off(pfmem64_1); - get_reg_off(pfmem64_2); - get_reg_off(pfmem64_3); - get_reg_off(pfmem64_4); - get_reg_off(pfmem64_5); - get_reg_off(pfmem64_6); - get_reg_off(pfmem64_7); - get_reg_off(pfmem64_8); - get_reg_off(pfmem64_9); - get_reg_off(pfmem64_10); - get_reg_off(pfmem64_11); - get_reg_off(pfmem64_12); - get_reg_off(pfmem64_13); - get_reg_off(pfmem64_14); - get_reg_off(pfmem64_15); - get_reg_off(pfmem64_16); - get_reg_off(pfmem64_17); - get_reg_off(pfmem64_18); - get_reg_off(pfmem64_19); get_reg_off(MM0); get_reg_off(MM1); @@ -710,19 +590,9 @@ PyObject* get_gpreg_offset_all(void) get_reg_off(MM5); get_reg_off(MM6); get_reg_off(MM7); - get_reg_off(MM0_new); - get_reg_off(MM1_new); - get_reg_off(MM2_new); - get_reg_off(MM3_new); - get_reg_off(MM4_new); - get_reg_off(MM5_new); - get_reg_off(MM6_new); - get_reg_off(MM7_new); get_reg_off(tsc1); get_reg_off(tsc2); - get_reg_off(tsc1_new); - get_reg_off(tsc2_new); return dict; } diff --git a/miasm2/jitter/arch/JitCore_x86.h b/miasm2/jitter/arch/JitCore_x86.h index ac794d8e..d4282640 100644 --- a/miasm2/jitter/arch/JitCore_x86.h +++ b/miasm2/jitter/arch/JitCore_x86.h @@ -1,9 +1,7 @@ typedef struct { uint32_t exception_flags; - uint32_t exception_flags_new; uint32_t interrupt_num; - uint32_t interrupt_num_new; /* gpregs */ @@ -26,25 +24,6 @@ typedef struct { uint64_t RIP; - uint64_t RAX_new; - uint64_t RBX_new; - uint64_t RCX_new; - uint64_t RDX_new; - uint64_t RSI_new; - uint64_t RDI_new; - uint64_t RSP_new; - uint64_t RBP_new; - uint64_t R8_new; - uint64_t R9_new; - uint64_t R10_new; - uint64_t R11_new; - uint64_t R12_new; - uint64_t R13_new; - uint64_t R14_new; - uint64_t R15_new; - - uint64_t RIP_new; - /* eflag */ uint64_t zf; uint64_t nf; @@ -54,14 +33,6 @@ typedef struct { uint64_t af; uint64_t df; - uint64_t zf_new; - uint64_t nf_new; - uint64_t pf_new; - uint64_t of_new; - uint64_t cf_new; - uint64_t af_new; - uint64_t df_new; - uint64_t tf; uint64_t i_f; uint64_t iopl_f; @@ -73,17 +44,6 @@ typedef struct { uint64_t vip; uint64_t i_d; - uint64_t tf_new; - uint64_t i_f_new; - uint64_t iopl_f_new; - uint64_t nt_new; - uint64_t rf_new; - uint64_t vm_new; - uint64_t ac_new; - uint64_t vif_new; - uint64_t vip_new; - uint64_t i_d_new; - uint64_t my_tick; uint64_t cond; @@ -97,47 +57,25 @@ typedef struct { double float_st6; double float_st7; - double float_st0_new; - double float_st1_new; - double float_st2_new; - double float_st3_new; - double float_st4_new; - double float_st5_new; - double float_st6_new; - double float_st7_new; - unsigned int float_c0; unsigned int float_c1; unsigned int float_c2; unsigned int float_c3; - unsigned int float_c0_new; - unsigned int float_c1_new; - unsigned int float_c2_new; - unsigned int float_c3_new; unsigned int float_stack_ptr; - unsigned int float_stack_ptr_new; unsigned int reg_float_control; - unsigned int reg_float_control_new; unsigned int reg_float_eip; - unsigned int reg_float_eip_new; unsigned int reg_float_cs; - unsigned int reg_float_cs_new; unsigned int reg_float_address; - unsigned int reg_float_address_new; unsigned int reg_float_ds; - unsigned int reg_float_ds_new; uint64_t tsc1; uint64_t tsc2; - uint64_t tsc1_new; - uint64_t tsc2_new; - uint64_t ES; uint64_t CS; @@ -146,108 +84,8 @@ typedef struct { uint64_t FS; uint64_t GS; - uint64_t ES_new; - uint64_t CS_new; - uint64_t SS_new; - uint64_t DS_new; - uint64_t FS_new; - uint64_t GS_new; - unsigned int cr0; - unsigned int cr0_new; - unsigned int cr3; - unsigned int cr3_new; - - - - uint8_t pfmem08_0; - uint8_t pfmem08_1; - uint8_t pfmem08_2; - uint8_t pfmem08_3; - uint8_t pfmem08_4; - uint8_t pfmem08_5; - uint8_t pfmem08_6; - uint8_t pfmem08_7; - uint8_t pfmem08_8; - uint8_t pfmem08_9; - uint8_t pfmem08_10; - uint8_t pfmem08_11; - uint8_t pfmem08_12; - uint8_t pfmem08_13; - uint8_t pfmem08_14; - uint8_t pfmem08_15; - uint8_t pfmem08_16; - uint8_t pfmem08_17; - uint8_t pfmem08_18; - uint8_t pfmem08_19; - - - uint16_t pfmem16_0; - uint16_t pfmem16_1; - uint16_t pfmem16_2; - uint16_t pfmem16_3; - uint16_t pfmem16_4; - uint16_t pfmem16_5; - uint16_t pfmem16_6; - uint16_t pfmem16_7; - uint16_t pfmem16_8; - uint16_t pfmem16_9; - uint16_t pfmem16_10; - uint16_t pfmem16_11; - uint16_t pfmem16_12; - uint16_t pfmem16_13; - uint16_t pfmem16_14; - uint16_t pfmem16_15; - uint16_t pfmem16_16; - uint16_t pfmem16_17; - uint16_t pfmem16_18; - uint16_t pfmem16_19; - - - uint32_t pfmem32_0; - uint32_t pfmem32_1; - uint32_t pfmem32_2; - uint32_t pfmem32_3; - uint32_t pfmem32_4; - uint32_t pfmem32_5; - uint32_t pfmem32_6; - uint32_t pfmem32_7; - uint32_t pfmem32_8; - uint32_t pfmem32_9; - uint32_t pfmem32_10; - uint32_t pfmem32_11; - uint32_t pfmem32_12; - uint32_t pfmem32_13; - uint32_t pfmem32_14; - uint32_t pfmem32_15; - uint32_t pfmem32_16; - uint32_t pfmem32_17; - uint32_t pfmem32_18; - uint32_t pfmem32_19; - - - uint64_t pfmem64_0; - uint64_t pfmem64_1; - uint64_t pfmem64_2; - uint64_t pfmem64_3; - uint64_t pfmem64_4; - uint64_t pfmem64_5; - uint64_t pfmem64_6; - uint64_t pfmem64_7; - uint64_t pfmem64_8; - uint64_t pfmem64_9; - uint64_t pfmem64_10; - uint64_t pfmem64_11; - uint64_t pfmem64_12; - uint64_t pfmem64_13; - uint64_t pfmem64_14; - uint64_t pfmem64_15; - uint64_t pfmem64_16; - uint64_t pfmem64_17; - uint64_t pfmem64_18; - uint64_t pfmem64_19; - uint64_t MM0; uint64_t MM1; @@ -258,15 +96,6 @@ typedef struct { uint64_t MM6; uint64_t MM7; - uint64_t MM0_new; - uint64_t MM1_new; - uint64_t MM2_new; - uint64_t MM3_new; - uint64_t MM4_new; - uint64_t MM5_new; - uint64_t MM6_new; - uint64_t MM7_new; - uint32_t segm_base[0x10000]; }vm_cpu_t; @@ -274,7 +103,8 @@ typedef struct { -void dump_gpregs(vm_cpu_t* vmcpu); +void dump_gpregs_32(vm_cpu_t* vmcpu); +void dump_gpregs_64(vm_cpu_t* vmcpu); uint64_t segm2addr(JitCpu* jitcpu, uint64_t segm, uint64_t addr); diff --git a/miasm2/jitter/codegen.py b/miasm2/jitter/codegen.py new file mode 100644 index 00000000..7630a2ef --- /dev/null +++ b/miasm2/jitter/codegen.py @@ -0,0 +1,578 @@ +import miasm2.expression.expression as m2_expr +from miasm2.ir.ir import irbloc +from miasm2.ir.translators import Translator +from miasm2.core.asmbloc import expr_is_label, asm_block_bad, asm_label + +# Miasm to C translator +translator = Translator.to_language("C") + +SIZE_TO_MASK = {x: 2**x - 1 for x in (1, 2, 3, 7, 8, 16, 32, 64)} + +MASK_INT = 0xffffffffffffffff + + +class Attributes(object): + + """ + Store an irblock attributes + """ + + def __init__(self, log_mn=False, log_regs=False): + self.mem_read = False + self.mem_write = False + self.set_exception = False + self.op_set_exception = False + self.log_mn = log_mn + self.log_regs = log_regs + self.instr = None + + +class CGen(object): + + IMPLICIT_EXCEPTION_OP = set(['umod', 'udiv']) + + """ + Translate native assembly block to C + """ + + CODE_EXCEPTION_MEM_AT_INSTR = r""" + // except fetch mem at instr noauto + if ((VM_exception_flag & ~EXCEPT_CODE_AUTOMOD) & EXCEPT_DO_NOT_UPDATE_PC) { + %s = %s; + BlockDst->address = %s; + return JIT_RET_EXCEPTION; + } + """ + + CODE_EXCEPTION_MEM_POST_INSTR = r""" + // except fetch mem post instr + if (VM_exception_flag) { + %s = %s; + BlockDst->address = %s; + return JIT_RET_EXCEPTION; + } + """ + + CODE_EXCEPTION_AT_INSTR = r""" + if (CPU_exception_flag_at_instr) { + %s = %s; + BlockDst->address = %s; + return JIT_RET_EXCEPTION; + } + """ + + CODE_EXCEPTION_POST_INSTR = r""" + if (CPU_exception_flag) { + %s = %s; + BlockDst->address = %s; + return JIT_RET_EXCEPTION; + } + """ + + CODE_RETURN_EXCEPTION = r""" + return JIT_RET_EXCEPTION; + """ + + CODE_RETURN_NO_EXCEPTION = r""" + %s: + %s = %s; + BlockDst->address = %s; + return JIT_RET_NO_EXCEPTION; + """ + + CODE_CPU_EXCEPTION_POST_INSTR = r""" + if (CPU_exception_flag) { + %s = %s; + BlockDst->address = DST_value; + return JIT_RET_EXCEPTION; + } + """ + + CODE_VM_EXCEPTION_POST_INSTR = r""" + check_memory_breakpoint(&(jitcpu->pyvm->vm_mngr)); + check_invalid_code_blocs(&(jitcpu->pyvm->vm_mngr)); + if (VM_exception_flag) { + %s = %s; + BlockDst->address = DST_value; + return JIT_RET_EXCEPTION; + } + """ + + CODE_INIT = r""" + int DST_case; + unsigned long long DST_value; + vm_cpu_t* mycpu = (vm_cpu_t*)jitcpu->cpu; + + goto %s; + """ + + CODE_BAD_BLOCK = r""" + // Unknown mnemonic + CPU_exception_flag = EXCEPT_UNK_MNEMO; + """ + CODE_RETURN_EXCEPTION + + def __init__(self, ir_arch): + self.ir_arch = ir_arch + self.PC = self.ir_arch.pc + self.init_arch_C() + + def init_arch_C(self): + self.id_to_c_id = {} + for reg in self.ir_arch.arch.regs.all_regs_ids: + self.id_to_c_id[reg] = m2_expr.ExprId('mycpu->%s' % reg, reg.size) + + self.C_PC = self.id_to_c(self.PC) + + def dst_to_c(self, src): + if not isinstance(src, m2_expr.Expr): + src = m2_expr.ExprInt(src, self.PC.size) + return self.id_to_c(src) + + def patch_c_id(self, expr): + return expr.replace_expr(self.id_to_c_id) + + def id_to_c(self, expr): + return translator.from_expr(self.patch_c_id(expr)) + + def get_post_instr_label(self, offset): + return self.ir_arch.symbol_pool.getby_name_create("lbl_gen_post_instr_%.8X" % (offset)) + + def add_label_index(self, dst2index, lbl): + dst2index[lbl] = len(dst2index) + + def assignblk_to_irbloc(self, instr, assignblk): + """ + Ensure IRDst is always set in the head @assignblk of the @instr + @assignblk: Assignblk instance + @instr: an instruction instance + """ + if self.ir_arch.IRDst not in assignblk: + assignblk[self.ir_arch.IRDst] = m2_expr.ExprInt( + instr.offset + instr.l, + self.ir_arch.IRDst.size) + + return irbloc(self.ir_arch.get_instr_label(instr), [assignblk]) + + def block2assignblks(self, block): + irblocks_list = [] + for instr in block.lines: + assignblk_head, assignblks_extra = self.ir_arch.instr2ir(instr) + # Keep result in ordered list as first element is the assignblk head + # The remainings order is not really important + irblock_head = self.assignblk_to_irbloc(instr, assignblk_head) + irblocks = [irblock_head] + assignblks_extra + + for irblock in irblocks: + assert irblock.dst is not None + irblocks_list.append(irblocks) + return irblocks_list + + def gen_mem_prefetch(self, assignblk, mems_to_prefetch): + out = [] + for expr, prefetcher in sorted(mems_to_prefetch.iteritems()): + str_src = self.id_to_c(expr) + str_dst = self.id_to_c(prefetcher) + out.append('%s = %s;' % (str_dst, str_src)) + assignblk.C_prefetch = out + return out + + def add_local_var(self, dst_var, dst_index, expr): + size = expr.size + if size < 8: + size = 8 + if size not in dst_index: + raise RuntimeError("Unsupported operand size %s", size) + var_num = dst_index[size] + dst = m2_expr.ExprId("var_%.2d_%.2d" % (size, var_num), size) + dst_index[size] += 1 + dst_var[expr] = dst + return dst + + def gen_assignments(self, assignblk, prefetchers): + out_var = [] + out_main = [] + out_mem = [] + out_updt = [] + + dst_index = {8: 0, 16: 0, 32: 0, 64: 0} + dst_var = {} + + for var in prefetchers.itervalues(): + out_var.append("uint%d_t %s;" % (var.size, var)) + + for dst, src in sorted(assignblk.iteritems()): + src = src.replace_expr(prefetchers) + if dst is self.ir_arch.IRDst: + pass + elif isinstance(dst, m2_expr.ExprId): + new_dst = self.add_local_var(dst_var, dst_index, dst) + if dst in self.ir_arch.arch.regs.regs_flt_expr: + # Dont mask float affectation + out_main.append( + '%s = (%s);' % (self.id_to_c(new_dst), self.id_to_c(src))) + else: + out_main.append( + '%s = (%s)&0x%X;' % (self.id_to_c(new_dst), + self.id_to_c(src), + SIZE_TO_MASK[src.size])) + elif isinstance(dst, m2_expr.ExprMem): + ptr = dst.arg.replace_expr(prefetchers) + new_dst = m2_expr.ExprMem(ptr, dst.size) + str_dst = self.id_to_c(new_dst).replace('MEM_LOOKUP', 'MEM_WRITE') + out_mem.append('%s, %s);' % (str_dst[:-1], self.id_to_c(src))) + else: + raise ValueError("Unknown dst") + + for dst, new_dst in dst_var.iteritems(): + if dst is self.ir_arch.IRDst: + continue + out_updt.append('%s = %s;' % (self.id_to_c(dst), self.id_to_c(new_dst))) + out_var.append("uint%d_t %s;" % (new_dst.size, new_dst)) + + assignblk.C_var = out_var + assignblk.C_main = out_main + assignblk.C_mem = out_mem + assignblk.C_updt = out_updt + + def gen_c_assignblk(self, assignblk): + mem_read, mem_write = False, False + + mem_index = {8: 0, 16: 0, 32: 0, 64: 0} + mem_var = {} + prefetch_index = {8: 0, 16: 0, 32: 0, 64: 0} + + # Prefetch memory read + for expr in assignblk.get_r(mem_read=True): + if not isinstance(expr, m2_expr.ExprMem): + continue + mem_read = True + var_num = mem_index[expr.size] + mem_index[expr.size] += 1 + var = m2_expr.ExprId( + "prefetch_%.2d_%.2d" % (expr.size, var_num), expr.size) + mem_var[expr] = var + + # Check if assignblk can write mem + mem_write = any(isinstance(expr, m2_expr.ExprMem) + for expr in assignblk.get_w()) + + assignblk.mem_write = mem_write + assignblk.mem_read = mem_read + + # Generate memory prefetch + return mem_var + + def gen_check_memory_exception(self, address): + dst = self.dst_to_c(address) + return (self.CODE_EXCEPTION_MEM_AT_INSTR % (self.C_PC, dst, dst)).split('\n') + + def gen_check_memory_exception_post(self, address): + dst = self.dst_to_c(address) + return (self.CODE_EXCEPTION_MEM_POST_INSTR % (self.C_PC, dst, dst)).split('\n') + + def gen_check_cpu_exception(self, address): + dst = self.dst_to_c(address) + return (self.CODE_EXCEPTION_AT_INSTR % (self.C_PC, dst, dst)).split('\n') + + def gen_check_cpu_exception_post(self, address): + dst = self.dst_to_c(address) + return (self.CODE_EXCEPTION_POST_INSTR % (self.C_PC, dst, dst)).split('\n') + + def traverse_expr_dst(self, expr, dst2index): + """ + Generate the index of the destination label for the @expr + @dst2index: dictionnary to link label to its index + """ + + if isinstance(expr, m2_expr.ExprCond): + cond = self.id_to_c(expr.cond) + src1, src1b = self.traverse_expr_dst(expr.src1, dst2index) + src2, src2b = self.traverse_expr_dst(expr.src2, dst2index) + return ("((%s)?(%s):(%s))" % (cond, src1, src2), + "((%s)?(%s):(%s))" % (cond, src1b, src2b)) + elif isinstance(expr, m2_expr.ExprInt): + offset = int(expr.arg) + self.add_label_index(dst2index, offset) + return ("%s" % dst2index[offset], + hex(offset)) + elif expr_is_label(expr): + label = expr.name + if label.offset != None: + offset = label.offset + self.add_label_index(dst2index, offset) + return ("%s" % dst2index[offset], + hex(offset)) + else: + self.add_label_index(dst2index, label) + return ("%s" % dst2index[label], + "0") + + elif (isinstance(expr, m2_expr.ExprId) or + isinstance(expr, m2_expr.ExprMem) or + isinstance(expr, m2_expr.ExprSlice)): + dst2index[expr] = -1 + return ("-1", + self.id_to_c(expr)) + else: + raise RuntimeError("Unsupported IRDst type %s" % expr) + + def gen_assignblk_dst(self, dst): + dst2index = {} + (ret, retb) = self.traverse_expr_dst(dst, dst2index) + ret = "DST_case = %s;" % ret + retb = "DST_value = %s;" % retb + return ['// %s' % dst2index, + '%s' % ret, + '%s' % retb], dst2index + + def gen_post_instr_checks(self, attrib, dst): + out = [] + dst = self.dst_to_c(dst) + if attrib.mem_read | attrib.mem_write: + out += (self.CODE_VM_EXCEPTION_POST_INSTR % (self.C_PC, dst)).split('\n') + if attrib.set_exception or attrib.op_set_exception: + out += (self.CODE_CPU_EXCEPTION_POST_INSTR % (self.C_PC, dst)).split('\n') + + if attrib.mem_read | attrib.mem_write: + out.append("reset_memory_access(&(jitcpu->pyvm->vm_mngr));") + + return out + + def gen_pre_code(self, attrib): + out = [] + + if attrib.log_mn: + out.append('printf("%.8X %s\\n");' % (attrib.instr.offset, + attrib.instr)) + return out + + def gen_post_code(self, attrib): + out = [] + if attrib.log_regs: + out.append('dump_gpregs(jitcpu->cpu);') + return out + + def gen_goto_code(self, attrib, instr_offsets, dst): + out = [] + if isinstance(dst, asm_label): + out.append('goto %s;' % dst.name) + elif dst in instr_offsets: + lbl = self.ir_arch.symbol_pool.getby_offset_create(dst) + out += self.gen_post_code(attrib) + out += self.gen_post_instr_checks(attrib, dst) + out.append('goto %s;' % lbl.name) + else: + out += self.gen_post_code(attrib) + out.append('BlockDst->address = DST_value;') + out += self.gen_post_instr_checks(attrib, dst) + out.append('\t\treturn JIT_RET_NO_EXCEPTION;') + return out + + def gen_dst_goto(self, attrib, instr_offsets, dst2index): + """ + Generate code for possible @dst2index. + + @attrib: an Attributs instance + @instr_offsets: list of instructions offsets + @dst2index: link from dstination to index + """ + + if not dst2index: + return [] + out = [] + out.append('switch(DST_case) {') + for dst, index in sorted(dst2index.iteritems(), key=lambda lblindex: lblindex[1]): + out.append('\tcase %d:' % index) + out += self.gen_goto_code(attrib, instr_offsets, dst) + out.append('\t\tbreak;') + out.append('};') + return out + + def gen_c_code(self, assignblk, c_dst): + """ + Generate the C code for @assignblk. + @assignblk: an Assignblk instance + @c_dst: irdst C code + """ + out = [] + out.append("{") + out.append("// var") + out += assignblk.C_var + out.append("// Prefetch") + out += assignblk.C_prefetch + out.append("// Dst") + out += c_dst + out.append("// Main") + out += assignblk.C_main + + out.append("// Check op/mem exceptions") + + # Check memory access if assignblk has memory read + if assignblk.C_prefetch: + out += self.gen_check_memory_exception(assignblk.instr_addr) + + # Check if operator raised exception flags + if assignblk.op_set_exception: + out += self.gen_check_cpu_exception(assignblk.instr_addr) + + out.append("// Mem updt") + out += assignblk.C_mem + + out.append("// Check exception Mem write") + # Check memory write exceptions + if assignblk.mem_write: + out += self.gen_check_memory_exception(assignblk.instr_addr) + + out.append("// Updt") + out += assignblk.C_updt + + out.append("// Checks exception") + + # Check post assignblk exception flags + if assignblk.set_exception: + out += self.gen_check_cpu_exception(assignblk.instr_addr) + + out.append("}") + + return out + + def is_exception_operator(self, operator): + """Return True if the @op operator can raise a runtime exception""" + + return any(operator.startswith(except_op) + for except_op in self.IMPLICIT_EXCEPTION_OP) + + def get_caracteristics(self, irblock): + """ + Get the carateristics of each assignblk in the @irblock + @irblock: an irbloc instance + """ + + for assignblk in irblock.irs: + assignblk.mem_read, assignblk.mem_write = False, False + assignblk.op_set_exception = False + # Check explicit exception raising + assignblk.set_exception = self.ir_arch.arch.regs.exception_flags in assignblk + + element_read = assignblk.get_r(mem_read=True) + # Check implicit exception raising + assignblk.op_set_exception = any(self.is_exception_operator(operator) + for elem in assignblk.values() + for operator in m2_expr.get_expr_ops(elem)) + # Check mem read + assignblk.mem_read = any(isinstance(expr, m2_expr.ExprMem) + for expr in element_read) + # Check mem write + assignblk.mem_write = any(isinstance(dst, m2_expr.ExprMem) + for dst in assignblk) + + def get_attributes(self, instr, irblocks, log_mn=False, log_regs=False): + """ + Get the carateristics of each @irblocks. Returns the corresponding + attributes object. + @irblock: a list of irbloc instance + @log_mn: generate code to log instructions + @log_regs: generate code to log registers states + """ + + attrib = Attributes(log_mn, log_regs) + + for irblock in irblocks: + for assignblk in irblock.irs: + self.get_caracteristics(irblock) + attrib.mem_read |= assignblk.mem_read + attrib.mem_write |= assignblk.mem_write + attrib.set_exception |= assignblk.set_exception + attrib.op_set_exception |= assignblk.op_set_exception + attrib.instr = instr + return attrib + + def gen_bad_block(self): + """ + Generate the C code for a bad_block instance + """ + return self.CODE_BAD_BLOCK.split("\n") + + def get_block_post_label(self, block): + last_instr = block.lines[-1] + offset = last_instr.offset + last_instr.l + return self.ir_arch.symbol_pool.getby_offset_create(offset) + + def gen_init(self, block): + """ + Generate the init C code for a @block + @block: an asm_bloc instance + """ + + instr_offsets = [line.offset for line in block.lines] + instr_offsets.append(self.get_block_post_label(block).offset) + lbl_start = self.ir_arch.symbol_pool.getby_offset_create(instr_offsets[0]) + return (self.CODE_INIT % lbl_start.name).split("\n"), instr_offsets + + def gen_irblock(self, attrib, instr_offsets, instr, irblock): + """ + Generate the C code for an @irblock + @instr: the current instruction to translate + @irblock: an irbloc instance + @attrib: an Attributs instance + """ + + out = [] + dst2index = None + for index, assignblk in enumerate(irblock.irs): + if index == irblock.dst_linenb: + c_dst, dst2index = self.gen_assignblk_dst(irblock.dst) + else: + c_dst = [] + assignblk.instr_addr = instr.offset + prefetchers = self.gen_c_assignblk(assignblk) + self.gen_mem_prefetch(assignblk, prefetchers) + self.gen_assignments(assignblk, prefetchers) + + out += self.gen_c_code(assignblk, c_dst) + + if dst2index: + out.append("// Set irdst") + # Gen goto on irdst set + out += self.gen_dst_goto(attrib, instr_offsets, dst2index) + + return out + + def gen_finalize(self, block): + """ + Generate the C code for the final block instruction + """ + + lbl = self.get_block_post_label(block) + dst = self.dst_to_c(lbl.offset) + code = self.CODE_RETURN_NO_EXCEPTION % (lbl.name, self.C_PC, dst, dst) + return code.split('\n') + + def gen_c(self, block, log_mn=False, log_regs=False): + """ + Generate the C code for the @block and return it as a list of lines + @log_mn: log mnemonics + @log_regs: log registers + """ + + if isinstance(block, asm_block_bad): + return self.gen_bad_block() + irblocks_list = self.block2assignblks(block) + + out, instr_offsets = self.gen_init(block) + + for instr, irblocks in zip(block.lines, irblocks_list): + attrib = self.get_attributes(instr, irblocks, log_mn, log_regs) + + for index, irblock in enumerate(irblocks): + self.ir_arch.irbloc_fix_regs_for_mode( + irblock, self.ir_arch.attrib) + + out.append("%-40s // %.16X %s" % + (str(irblock.label.name) + ":", instr.offset, instr)) + if index == 0: + out += self.gen_pre_code(attrib) + out += self.gen_irblock(attrib, instr_offsets, instr, irblock) + + out += self.gen_finalize(block) + return ['\t' + line for line in out] diff --git a/miasm2/jitter/csts.py b/miasm2/jitter/csts.py index b71e9463..7af2435f 100644 --- a/miasm2/jitter/csts.py +++ b/miasm2/jitter/csts.py @@ -13,6 +13,9 @@ EXCEPT_BREAKPOINT_INTERN = (1 << 10) EXCEPT_ACCESS_VIOL = ((1 << 14) | EXCEPT_DO_NOT_UPDATE_PC) EXCEPT_DIV_BY_ZERO = ((1 << 16) | EXCEPT_DO_NOT_UPDATE_PC) EXCEPT_PRIV_INSN = ((1 << 17) | EXCEPT_DO_NOT_UPDATE_PC) +EXCEPT_ILLEGAL_INSN = ((1 << 18) | EXCEPT_DO_NOT_UPDATE_PC) +EXCEPT_UNK_MNEMO = ((1 << 19) | EXCEPT_DO_NOT_UPDATE_PC) + # VM Mngr constants PAGE_READ = 1 diff --git a/miasm2/jitter/emulatedsymbexec.py b/miasm2/jitter/emulatedsymbexec.py index f7c48227..d72de771 100644 --- a/miasm2/jitter/emulatedsymbexec.py +++ b/miasm2/jitter/emulatedsymbexec.py @@ -5,13 +5,14 @@ from miasm2.ir.symbexec import symbexec class EmulatedSymbExec(symbexec): """Symbolic exec instance linked with a jitter""" - def __init__(self, cpu, *args, **kwargs): + def __init__(self, cpu, vm, *args, **kwargs): """Instanciate an EmulatedSymbExec, associated to CPU @cpu and bind memory accesses. @cpu: JitCpu instance """ super(EmulatedSymbExec, self).__init__(*args, **kwargs) self.cpu = cpu + self.vm = vm self.func_read = self._func_read self.func_write = self._func_write @@ -28,6 +29,7 @@ class EmulatedSymbExec(symbexec): addr = expr_mem.arg.arg.arg size = expr_mem.size / 8 value = self.cpu.get_mem(addr, size) + self.vm.add_mem_read(addr, size) return m2_expr.ExprInt(int(value[::-1].encode("hex"), 16), expr_mem.size) @@ -53,6 +55,7 @@ class EmulatedSymbExec(symbexec): # Write in VmMngr context self.cpu.set_mem(addr, content) + self.vm.add_mem_write(addr, len(content)) # Interaction symbexec <-> jitter def update_cpu_from_engine(self): diff --git a/miasm2/jitter/jitcore.py b/miasm2/jitter/jitcore.py index 74c438a7..04bd707a 100644 --- a/miasm2/jitter/jitcore.py +++ b/miasm2/jitter/jitcore.py @@ -51,8 +51,6 @@ class JitCore(object): self.blocs_mem_interval = interval() self.disasm_cb = None self.split_dis = set() - self.addr_mod = interval() - self.options = {"jit_maxline": 50 # Maximum number of line jitted } @@ -95,6 +93,11 @@ class JitCore(object): if cur_bloc.lines: cur_bloc.ad_min = cur_bloc.lines[0].offset cur_bloc.ad_max = cur_bloc.lines[-1].offset + cur_bloc.lines[-1].l + else: + # 1 byte block for unknown mnemonic + cur_bloc.ad_min = cur_bloc.label.offset + cur_bloc.ad_max = cur_bloc.label.offset+1 + def add_bloc_to_mem_interval(self, vm, bloc): "Update vm to include bloc addresses in its memory range" @@ -142,16 +145,13 @@ class JitCore(object): cur_bloc = self.mdis.dis_bloc(addr) except IOError: # vm_exception_flag is set - cur_bloc = asmbloc.asm_bloc(label) + label = self.ir_arch.symbol_pool.getby_offset_create(addr) + cur_bloc = asmbloc.asm_block_bad(label) # Logging if self.log_newbloc: print cur_bloc - # Check for empty blocks - if not cur_bloc.lines: - raise ValueError("Cannot JIT a block without any assembly line") - # Update label -> bloc self.lbl2bloc[cur_bloc.label] = cur_bloc @@ -259,15 +259,21 @@ class JitCore(object): return modified_blocs - def updt_automod_code(self, vm): - """Remove code jitted in range self.addr_mod + def updt_automod_code_range(self, vm, mem_range): + """Remove jitted code in range @mem_range @vm: VmMngr instance + @mem_range: list of start/stop addresses """ - for addr_start, addr_stop in self.addr_mod: - self.del_bloc_in_range(addr_start, addr_stop + 1) + for addr_start, addr_stop in mem_range: + self.del_bloc_in_range(addr_start, addr_stop) self.__updt_jitcode_mem_range(vm) - self.addr_mod = interval() + vm.reset_memory_access() - def automod_cb(self, addr=0, size=0): - self.addr_mod += interval([(addr, addr + size / 8 - 1)]) - return None + def updt_automod_code(self, vm): + """Remove jitted code updated by memory write + @vm: VmMngr instance + """ + mem_range = [] + for addr_start, addr_stop in vm.get_memory_write(): + mem_range.append((addr_start, addr_stop)) + self.updt_automod_code_range(vm, mem_range) diff --git a/miasm2/jitter/jitcore_gcc.py b/miasm2/jitter/jitcore_gcc.py index db0b7880..7f72d8e7 100644 --- a/miasm2/jitter/jitcore_gcc.py +++ b/miasm2/jitter/jitcore_gcc.py @@ -4,11 +4,11 @@ import os import tempfile import ctypes +import _ctypes from distutils.sysconfig import get_python_inc from subprocess import check_call from hashlib import md5 -from miasm2.ir.ir2C import irblocs2C from miasm2.jitter import jitcore, Jitgcc from miasm2.core.utils import keydefaultdict @@ -79,7 +79,11 @@ class JitCore_Gcc(jitcore.JitCore): self.include_files = None def deleteCB(self, offset): - pass + """Free the state associated to @offset and delete it + @offset: gcc state offset + """ + _ctypes.dlclose(self.gcc_states[offset]._handle) + del self.gcc_states[offset] def load(self): lib_dir = os.path.dirname(os.path.realpath(__file__)) @@ -92,6 +96,13 @@ class JitCore_Gcc(jitcore.JitCore): self.include_files = include_files self.libs = libs + def init_codegen(self, codegen): + """ + Get the code generator @codegen + @codegen: an CGen instance + """ + self.codegen = codegen + def label2fname(self, label): """ Generate function name from @label @@ -105,9 +116,10 @@ class JitCore_Gcc(jitcore.JitCore): func = getattr(lib, f_name) addr = ctypes.cast(func, ctypes.c_void_p).value self.lbl2jitbloc[label.offset] = addr - self.gcc_states[label.offset] = None + self.gcc_states[label.offset] = lib + - def gen_c_code(self, label, irblocks): + def gen_c_code(self, label, block): """ Return the C code corresponding to the @irblocks @label: asm_label of the block to jit @@ -115,10 +127,7 @@ class JitCore_Gcc(jitcore.JitCore): """ f_name = self.label2fname(label) f_declaration = 'int %s(block_id * BlockDst, JitCpu* jitcpu)' % f_name - out = irblocs2C(self.ir_arch, self.resolver, label, irblocks, - gen_exception_code=True, - log_mn=self.log_mn, - log_regs=self.log_regs) + out = self.codegen.gen_c(block, log_mn=self.log_mn, log_regs=self.log_regs) out = [f_declaration + '{'] + out + ['}\n'] c_code = out @@ -136,8 +145,7 @@ class JitCore_Gcc(jitcore.JitCore): fname_out = os.path.join(self.tempdir, "%s.so" % block_hash) if not os.access(fname_out, os.R_OK | os.X_OK): - irblocks = self.ir_arch.add_bloc(block, gen_pc_updt=True) - func_code = self.gen_c_code(block.label, irblocks) + func_code = self.gen_c_code(block.label, block) # Create unique C file fdesc, fname_in = tempfile.mkstemp(suffix=".c") diff --git a/miasm2/jitter/jitcore_python.py b/miasm2/jitter/jitcore_python.py index e1e62816..ae72b307 100644 --- a/miasm2/jitter/jitcore_python.py +++ b/miasm2/jitter/jitcore_python.py @@ -17,10 +17,14 @@ class JitCore_Python(jitcore.JitCore): super(JitCore_Python, self).__init__(ir_arch, bs) self.ir_arch = ir_arch - # CPU (None for now) will be set by the "jitted" Python function - self.symbexec = EmulatedSymbExec(None, self.ir_arch, {}) + # CPU & VM (None for now) will be set by the "jitted" Python function + self.symbexec = EmulatedSymbExec(None, None, self.ir_arch, {}) self.symbexec.enable_emulated_simplifications() + def set_cpu_vm(self, cpu, vm): + self.symbexec.cpu = cpu + self.symbexec.vm = vm + def load(self): "Preload symbols according to current architecture" self.symbexec.reset_regs() @@ -45,7 +49,6 @@ class JitCore_Python(jitcore.JitCore): # Get exec engine exec_engine = self.symbexec - exec_engine.cpu = cpu # For each irbloc inside irblocs while True: @@ -66,12 +69,19 @@ class JitCore_Python(jitcore.JitCore): # For each new instruction (in assembly) if line.offset not in offsets_jitted: + # Test exceptions + vmmngr.check_invalid_code_blocs() + vmmngr.check_memory_breakpoint() + if vmmngr.get_exception(): + exec_engine.update_cpu_from_engine() + return line.offset + offsets_jitted.add(line.offset) # Log registers values if self.log_regs: exec_engine.update_cpu_from_engine() - cpu.dump_gpregs() + exec_engine.cpu.dump_gpregs() # Log instruction if self.log_mn: @@ -90,6 +100,9 @@ class JitCore_Python(jitcore.JitCore): exec_engine.update_cpu_from_engine() return line.offset + vmmngr.check_invalid_code_blocs() + vmmngr.check_memory_breakpoint() + # Get next bloc address ad = expr_simp(exec_engine.eval_expr(self.ir_arch.IRDst)) diff --git a/miasm2/jitter/jitcore_tcc.py b/miasm2/jitter/jitcore_tcc.py index 151fab7d..d3e90f85 100644 --- a/miasm2/jitter/jitcore_tcc.py +++ b/miasm2/jitter/jitcore_tcc.py @@ -7,7 +7,6 @@ from subprocess import Popen, PIPE from hashlib import md5 import tempfile -from miasm2.ir.ir2C import irblocs2C from miasm2.jitter import jitcore, Jittcc @@ -141,6 +140,13 @@ class JitCore_Tcc(jitcore.JitCore): include_files = ";".join(include_files) Jittcc.tcc_set_emul_lib_path(include_files, libs) + def init_codegen(self, codegen): + """ + Get the code generator @codegen + @codegen: an CGen instance + """ + self.codegen = codegen + def __del__(self): for tcc_state in self.tcc_states.values(): Jittcc.tcc_end(tcc_state) @@ -164,7 +170,7 @@ class JitCore_Tcc(jitcore.JitCore): self.lbl2jitbloc[label.offset] = mcode self.tcc_states[label.offset] = tcc_state - def gen_c_code(self, label, irblocks): + def gen_c_code(self, label, block): """ Return the C code corresponding to the @irblocks @label: asm_label of the block to jit @@ -172,10 +178,7 @@ class JitCore_Tcc(jitcore.JitCore): """ f_name = self.label2fname(label) f_declaration = 'int %s(block_id * BlockDst, JitCpu* jitcpu)' % f_name - out = irblocs2C(self.ir_arch, self.resolver, label, irblocks, - gen_exception_code=True, - log_mn=self.log_mn, - log_regs=self.log_regs) + out = self.codegen.gen_c(block, log_mn=self.log_mn, log_regs=self.log_regs) out = [f_declaration + '{'] + out + ['}\n'] c_code = out @@ -194,9 +197,7 @@ class JitCore_Tcc(jitcore.JitCore): if os.access(fname_out, os.R_OK): func_code = open(fname_out).read() else: - irblocks = self.ir_arch.add_bloc(block, gen_pc_updt=True) - block.irblocs = irblocks - func_code = self.gen_c_code(block.label, irblocks) + func_code = self.gen_c_code(block.label, block) # Create unique C file fdesc, fname_tmp = tempfile.mkstemp(suffix=".c") diff --git a/miasm2/jitter/jitload.py b/miasm2/jitter/jitload.py index cc92b0cf..d8393230 100644 --- a/miasm2/jitter/jitload.py +++ b/miasm2/jitter/jitload.py @@ -2,14 +2,14 @@ import logging from functools import wraps -from collections import Sequence, namedtuple +from collections import Sequence, namedtuple, Iterator from miasm2.jitter.csts import * from miasm2.core.utils import * from miasm2.core.bin_stream import bin_stream_vm -from miasm2.ir.ir2C import init_arch_C from miasm2.core.interval import interval from miasm2.jitter.emulatedsymbexec import EmulatedSymbExec +from miasm2.jitter.codegen import CGen hnd = logging.StreamHandler() hnd.setFormatter(logging.Formatter("[%(levelname)s]: %(message)s")) @@ -161,11 +161,14 @@ class jitter: "Main class for JIT handling" + C_Gen = CGen + def __init__(self, ir_arch, jit_type="tcc"): """Init an instance of jitter. @ir_arch: ir instance for this architecture @jit_type: JiT backend to use. Available options are: - "tcc" + - "gcc" - "llvm" - "python" """ @@ -194,9 +197,8 @@ class jitter: self.cpu = jcore.JitCpu() self.ir_arch = ir_arch self.bs = bin_stream_vm(self.vm) - init_arch_C(self.arch) - self.symbexec = EmulatedSymbExec(self.cpu, self.ir_arch, {}) + self.symbexec = EmulatedSymbExec(self.cpu, self.vm, self.ir_arch, {}) self.symbexec.reset_regs() try: @@ -214,6 +216,10 @@ class jitter: raise RuntimeError('Unsupported jitter: %s' % jit_type) self.jit = JitCore(self.ir_arch, self.bs) + if jit_type in ['tcc', 'gcc']: + self.jit.init_codegen(self.C_Gen(self.ir_arch)) + elif jit_type == "python": + self.jit.set_cpu_vm(self.cpu, self.vm) self.cpu.init_regs() self.vm.init_memory_page_pool() @@ -261,8 +267,7 @@ class jitter: self.breakpoints_handler.add_callback(addr, callback) self.jit.add_disassembly_splits(addr) # De-jit previously jitted blocks - self.jit.addr_mod = interval([(addr, addr)]) - self.jit.updt_automod_code(self.vm) + self.jit.updt_automod_code_range(self.vm, [(addr, addr)]) def set_breakpoint(self, addr, *args): """Set callbacks associated with addr. @@ -309,6 +314,17 @@ class jitter: old_pc = self.pc for res in self.breakpoints_handler.call_callbacks(self.pc, self): if res is not True: + if isinstance(res, collections.Iterator): + # If the breakpoint is a generator, yield it step by step + for tmp in res: + yield tmp + else: + yield res + + # Check exceptions (raised by breakpoints) + exception_flag = self.get_exception() + for res in self.exceptions_handler(exception_flag, self): + if res is not True: yield res # If a callback changed pc, re call every callback @@ -321,7 +337,7 @@ class jitter: # Run the bloc at PC self.pc = self.runbloc(self.pc) - # Check exceptions + # Check exceptions (raised by the execution of the block) exception_flag = self.get_exception() for res in self.exceptions_handler(exception_flag, self): if res is not True: diff --git a/miasm2/jitter/loader/pe.py b/miasm2/jitter/loader/pe.py index bb6740af..e8dacb55 100644 --- a/miasm2/jitter/loader/pe.py +++ b/miasm2/jitter/loader/pe.py @@ -98,6 +98,12 @@ def get_export_name_addr_list(e): # hex(e.rva2virt(addr.rva)))) out.append( (o.ordinal + e.DirExport.expdesc.base, e.rva2virt(addr.rva))) + + for i, s in enumerate(e.DirExport.f_address): + if not s.rva: + continue + out.append((i + e.DirExport.expdesc.base, e.rva2virt(s.rva))) + return out @@ -396,6 +402,7 @@ class libimp_pe(libimp): c_name = canon_libname_libfunc( name_inv[libad], imp_ord_or_name) self.fad2cname[ad] = c_name + log.debug("Add func %s %s", hex(ad), c_name) self.fad2info[ad] = libad, imp_ord_or_name def gen_new_lib(self, target_pe, filter_import=lambda peobj, ad: True, **kwargs): diff --git a/miasm2/jitter/vm_mngr.c b/miasm2/jitter/vm_mngr.c index f5c83b8b..df8326d9 100644 --- a/miasm2/jitter/vm_mngr.c +++ b/miasm2/jitter/vm_mngr.c @@ -76,7 +76,38 @@ const uint8_t parity_table[256] = { 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, }; -//#define DEBUG_MIASM_AUTOMOD_CODE +// #define DEBUG_MIASM_AUTOMOD_CODE + +void memory_access_list_init(struct memory_access_list * access) +{ + access->array = NULL; + access->allocated = 0; + access->num = 0; +} + +void memory_access_list_reset(struct memory_access_list * access) +{ + if (access->array) { + free(access->array); + access->array = NULL; + } + access->allocated = 0; + access->num = 0; +} + +void memory_access_list_add(struct memory_access_list * access, uint64_t start, uint64_t stop) +{ + if (access->num >= access->allocated) { + if (access->allocated == 0) + access->allocated = 1; + else + access->allocated *= 2; + access->array = realloc(access->array, access->allocated * sizeof(struct memory_access)); + } + access->array[access->num].start = start; + access->array[access->num].stop = stop; + access->num += 1; +} @@ -119,9 +150,6 @@ inline int midpoint(int imin, int imax) int find_page_node(struct memory_page_node * array, uint64_t key, int imin, int imax) { - if (imax < 1) - return -1; - imax--; // continue searching while [imin,imax] is not empty while (imin <= imax) { // calculate the midpoint for roughly equal partition @@ -149,7 +177,7 @@ struct memory_page_node * get_memory_page_from_address(vm_mngr_t* vm_mngr, uint6 i = find_page_node(vm_mngr->memory_pages_array, ad, 0, - vm_mngr->memory_pages_number); + vm_mngr->memory_pages_number - 1); if (i >= 0) { mpn = &vm_mngr->memory_pages_array[i]; if ((mpn->ad <= ad) && (ad < mpn->ad + mpn->size)) @@ -226,7 +254,7 @@ static uint64_t memory_page_read(vm_mngr_t* vm_mngr, unsigned int my_size, uint6 if (!mpn) return 0; addr = &((unsigned char*)mpn->ad_hp)[ad - mpn->ad]; - ret |= (*((unsigned char*)addr)&0xFF)<<(index); + ret |= ((uint64_t)(*((unsigned char*)addr)&0xFF))<<(index); index +=8; new_size -= 8; ad ++; @@ -396,29 +424,123 @@ void dump_code_bloc(vm_mngr_t* vm_mngr) } -void check_write_code_bloc(vm_mngr_t* vm_mngr, uint64_t my_size, uint64_t addr) +void add_range_to_list(struct memory_access_list * access, uint64_t addr1, uint64_t addr2) +{ + if (access->num > 0) { + /* Check match on upper bound */ + if (access->array[access->num-1].stop == addr1) { + access->array[access->num-1].stop = addr2; + return; + } + + /* Check match on lower bound */ + if (access->array[0].start == addr2) { + access->array[0].start = addr1; + return; + } + } + + /* No merge, add to the list */ + memory_access_list_add(access, addr1, addr2); +} + + +void add_mem_read(vm_mngr_t* vm_mngr, uint64_t addr, uint64_t size) { + add_range_to_list(&(vm_mngr->memory_r), addr, addr + size); +} + +void add_mem_write(vm_mngr_t* vm_mngr, uint64_t addr, uint64_t size) +{ + add_range_to_list(&(vm_mngr->memory_w), addr, addr + size); +} + +void check_invalid_code_blocs(vm_mngr_t* vm_mngr) +{ + int i; struct code_bloc_node * cbp; + for (i=0;i<vm_mngr->memory_w.num; i++) { + if (vm_mngr->exception_flags & EXCEPT_CODE_AUTOMOD) + break; + if (vm_mngr->memory_w.array[i].stop <= vm_mngr->code_bloc_pool_ad_min || + vm_mngr->memory_w.array[i].start >=vm_mngr->code_bloc_pool_ad_max) + continue; - if (!(addr + my_size/8 <= vm_mngr->code_bloc_pool_ad_min || - addr >=vm_mngr->code_bloc_pool_ad_max)){ LIST_FOREACH(cbp, &vm_mngr->code_bloc_pool, next){ - if ((cbp->ad_start < addr + my_size/8) && - (addr < cbp->ad_stop)){ + if ((cbp->ad_start < vm_mngr->memory_w.array[i].stop) && + (vm_mngr->memory_w.array[i].start < cbp->ad_stop)){ #ifdef DEBUG_MIASM_AUTOMOD_CODE fprintf(stderr, "**********************************\n"); - fprintf(stderr, "self modifying code %"PRIX64" %.8X\n", - addr, my_size); + fprintf(stderr, "self modifying code %"PRIX64" %"PRIX64"\n", + vm_mngr->memory_w.array[i].start, + vm_mngr->memory_w.array[i].stop); fprintf(stderr, "**********************************\n"); #endif vm_mngr->exception_flags |= EXCEPT_CODE_AUTOMOD; - break; } } } } + +void check_memory_breakpoint(vm_mngr_t* vm_mngr) +{ + int i; + struct memory_breakpoint_info * memory_bp; + + /* Check memory breakpoints */ + LIST_FOREACH(memory_bp, &vm_mngr->memory_breakpoint_pool, next) { + if (vm_mngr->exception_flags & EXCEPT_BREAKPOINT_INTERN) + break; + if (memory_bp->access & BREAKPOINT_READ) { + for (i=0;i<vm_mngr->memory_r.num; i++) { + if ((memory_bp->ad < vm_mngr->memory_r.array[i].stop) && + (vm_mngr->memory_r.array[i].start < memory_bp->ad + memory_bp->size)) { + vm_mngr->exception_flags |= EXCEPT_BREAKPOINT_INTERN; + break; + } + } + } + if (memory_bp->access & BREAKPOINT_WRITE) { + for (i=0;i<vm_mngr->memory_w.num; i++) { + if ((memory_bp->ad < vm_mngr->memory_w.array[i].stop) && + (vm_mngr->memory_w.array[i].start < memory_bp->ad + memory_bp->size)) { + vm_mngr->exception_flags |= EXCEPT_BREAKPOINT_INTERN; + break; + } + } + } + } +} + + +PyObject* get_memory_pylist(vm_mngr_t* vm_mngr, struct memory_access_list* memory_list) +{ + int i; + PyObject *pylist; + PyObject *range; + pylist = PyList_New(memory_list->num); + for (i=0;i<memory_list->num;i++) { + range = PyTuple_New(2); + PyTuple_SetItem(range, 0, PyLong_FromUnsignedLongLong((uint64_t)memory_list->array[i].start)); + PyTuple_SetItem(range, 1, PyLong_FromUnsignedLongLong((uint64_t)memory_list->array[i].stop)); + PyList_SetItem(pylist, i, range); + } + return pylist; + +} + +PyObject* get_memory_read(vm_mngr_t* vm_mngr) +{ + return get_memory_pylist(vm_mngr, &vm_mngr->memory_r); +} + +PyObject* get_memory_write(vm_mngr_t* vm_mngr) +{ + return get_memory_pylist(vm_mngr, &vm_mngr->memory_w); +} + PyObject* addr2BlocObj(vm_mngr_t* vm_mngr, uint64_t addr) { PyObject* pyaddr; @@ -438,49 +560,53 @@ PyObject* addr2BlocObj(vm_mngr_t* vm_mngr, uint64_t addr) void vm_MEM_WRITE_08(vm_mngr_t* vm_mngr, uint64_t addr, unsigned char src) { - check_write_code_bloc(vm_mngr, 8, addr); + add_mem_write(vm_mngr, addr, 1); memory_page_write(vm_mngr, 8, addr, src); } void vm_MEM_WRITE_16(vm_mngr_t* vm_mngr, uint64_t addr, unsigned short src) { - check_write_code_bloc(vm_mngr, 16, addr); + add_mem_write(vm_mngr, addr, 2); memory_page_write(vm_mngr, 16, addr, src); } void vm_MEM_WRITE_32(vm_mngr_t* vm_mngr, uint64_t addr, unsigned int src) { - check_write_code_bloc(vm_mngr, 32, addr); + add_mem_write(vm_mngr, addr, 4); memory_page_write(vm_mngr, 32, addr, src); } void vm_MEM_WRITE_64(vm_mngr_t* vm_mngr, uint64_t addr, uint64_t src) { - check_write_code_bloc(vm_mngr, 64, addr); + add_mem_write(vm_mngr, addr, 8); memory_page_write(vm_mngr, 64, addr, src); } unsigned char vm_MEM_LOOKUP_08(vm_mngr_t* vm_mngr, uint64_t addr) { - unsigned char ret; - ret = memory_page_read(vm_mngr, 8, addr); - return ret; + unsigned char ret; + add_mem_read(vm_mngr, addr, 1); + ret = memory_page_read(vm_mngr, 8, addr); + return ret; } unsigned short vm_MEM_LOOKUP_16(vm_mngr_t* vm_mngr, uint64_t addr) { - unsigned short ret; - ret = memory_page_read(vm_mngr, 16, addr); - return ret; + unsigned short ret; + add_mem_read(vm_mngr, addr, 2); + ret = memory_page_read(vm_mngr, 16, addr); + return ret; } unsigned int vm_MEM_LOOKUP_32(vm_mngr_t* vm_mngr, uint64_t addr) { - unsigned int ret; - ret = memory_page_read(vm_mngr, 32, addr); - return ret; + unsigned int ret; + add_mem_read(vm_mngr, addr, 4); + ret = memory_page_read(vm_mngr, 32, addr); + return ret; } uint64_t vm_MEM_LOOKUP_64(vm_mngr_t* vm_mngr, uint64_t addr) { - uint64_t ret; - ret = memory_page_read(vm_mngr, 64, addr); - return ret; + uint64_t ret; + add_mem_read(vm_mngr, addr, 8); + ret = memory_page_read(vm_mngr, 64, addr); + return ret; } @@ -521,8 +647,6 @@ int vm_write_mem(vm_mngr_t* vm_mngr, uint64_t addr, char *buffer, uint64_t size) uint64_t len; struct memory_page_node * mpn; - check_write_code_bloc(vm_mngr, size * 8, addr); - /* write is multiple page wide */ while (size){ mpn = get_memory_page_from_address(vm_mngr, addr, 1); @@ -1393,6 +1517,11 @@ void init_code_bloc_pool(vm_mngr_t* vm_mngr) LIST_INIT(&vm_mngr->code_bloc_pool); vm_mngr->code_bloc_pool_ad_min = 0xffffffff; vm_mngr->code_bloc_pool_ad_max = 0; + + memory_access_list_init(&(vm_mngr->memory_r)); + memory_access_list_init(&(vm_mngr->memory_w)); + + } void init_memory_breakpoint(vm_mngr_t* vm_mngr) @@ -1403,6 +1532,13 @@ void init_memory_breakpoint(vm_mngr_t* vm_mngr) void reset_memory_page_pool(vm_mngr_t* vm_mngr) { + struct memory_page_node * mpn; + int i; + for (i=0;i<vm_mngr->memory_pages_number; i++) { + mpn = &vm_mngr->memory_pages_array[i]; + free(mpn->ad_hp); + free(mpn->name); + } free(vm_mngr->memory_pages_array); vm_mngr->memory_pages_array = NULL; vm_mngr->memory_pages_number = 0; @@ -1423,6 +1559,11 @@ void reset_code_bloc_pool(vm_mngr_t* vm_mngr) vm_mngr->code_bloc_pool_ad_max = 0; } +void reset_memory_access(vm_mngr_t* vm_mngr) +{ + memory_access_list_reset(&(vm_mngr->memory_r)); + memory_access_list_reset(&(vm_mngr->memory_w)); +} void reset_memory_breakpoint(vm_mngr_t* vm_mngr) { @@ -1436,6 +1577,8 @@ void reset_memory_breakpoint(vm_mngr_t* vm_mngr) } + + /* We don't use dichotomy here for the insertion */ int is_mpn_in_tab(vm_mngr_t* vm_mngr, struct memory_page_node* mpn_a) { diff --git a/miasm2/jitter/vm_mngr.h b/miasm2/jitter/vm_mngr.h index 76b1c0dd..13ec065a 100644 --- a/miasm2/jitter/vm_mngr.h +++ b/miasm2/jitter/vm_mngr.h @@ -73,7 +73,16 @@ struct memory_page_node { char* name; }; +struct memory_access { + uint64_t start; + uint64_t stop; +}; +struct memory_access_list { + struct memory_access *array; + uint64_t allocated; + uint64_t num; +}; typedef struct { int sex; @@ -90,6 +99,14 @@ typedef struct { uint64_t exception_flags; uint64_t exception_flags_new; PyObject *addr2obj; + + + struct memory_access_list memory_r; + struct memory_access_list memory_w; + + + int write_num; + }vm_mngr_t; @@ -205,6 +222,7 @@ unsigned int umul16_hi(unsigned short a, unsigned short b); uint64_t rot_left(uint64_t size, uint64_t a, uint64_t b); uint64_t rot_right(uint64_t size, uint64_t a, uint64_t b); unsigned int rcl_rez_op(unsigned int size, unsigned int a, unsigned int b, unsigned int cf); +unsigned int rcr_rez_op(unsigned int size, unsigned int a, unsigned int b, unsigned int cf); #define UDIV(sizeA) \ @@ -259,6 +277,11 @@ unsigned int rcl_rez_op(unsigned int size, unsigned int a, unsigned int b, unsig } +void memory_access_list_init(struct memory_access_list * access); +void memory_access_list_reset(struct memory_access_list * access); +void memory_access_list_add(struct memory_access_list * access, uint64_t start, uint64_t stop); + + void hexdump(char* m, unsigned int l); struct code_bloc_node * create_code_bloc_node(uint64_t ad_start, uint64_t ad_stop); @@ -280,7 +303,13 @@ void remove_memory_breakpoint(vm_mngr_t* vm_mngr, uint64_t ad, unsigned int acce void add_memory_page(vm_mngr_t* vm_mngr, struct memory_page_node* mpn); -void check_write_code_bloc(vm_mngr_t* vm_mngr, uint64_t my_size, uint64_t addr); +void add_mem_read(vm_mngr_t* vm_mngr, uint64_t addr, uint64_t size); +void add_mem_write(vm_mngr_t* vm_mngr, uint64_t addr, uint64_t size); +void check_invalid_code_blocs(vm_mngr_t* vm_mngr); +void check_memory_breakpoint(vm_mngr_t* vm_mngr); +void reset_memory_access(vm_mngr_t* vm_mngr); +PyObject* get_memory_read(vm_mngr_t* vm_mngr); +PyObject* get_memory_write(vm_mngr_t* vm_mngr); char* dump(vm_mngr_t* vm_mngr); diff --git a/miasm2/jitter/vm_mngr_py.c b/miasm2/jitter/vm_mngr_py.c index 215517ee..5aece270 100644 --- a/miasm2/jitter/vm_mngr_py.c +++ b/miasm2/jitter/vm_mngr_py.c @@ -186,7 +186,8 @@ PyObject* vm_set_mem(VmMngr* self, PyObject* args) if (ret < 0) RAISE(PyExc_TypeError, "Error in set_mem"); - check_write_code_bloc(&self->vm_mngr, size*8, addr); + add_mem_write(&self->vm_mngr, addr, size); + check_invalid_code_blocs(&self->vm_mngr); Py_INCREF(Py_None); return Py_None; @@ -320,6 +321,63 @@ PyObject* vm_reset_memory_breakpoint(VmMngr* self, PyObject* args) } +PyObject* vm_reset_memory_access(VmMngr* self, PyObject* args) +{ + reset_memory_access(&self->vm_mngr); + Py_INCREF(Py_None); + return Py_None; +} + +PyObject* py_add_mem_read(VmMngr* self, PyObject* args) +{ + PyObject *py_addr; + PyObject *py_size; + uint64_t addr; + uint64_t size; + + if (!PyArg_ParseTuple(args, "OO", &py_addr, &py_size)) + return NULL; + + PyGetInt(py_addr, addr); + PyGetInt(py_size, size); + add_mem_read(&self->vm_mngr, addr, size); + Py_INCREF(Py_None); + return Py_None; + +} + +PyObject* py_add_mem_write(VmMngr* self, PyObject* args) +{ + PyObject *py_addr; + PyObject *py_size; + uint64_t addr; + uint64_t size; + + if (!PyArg_ParseTuple(args, "OO", &py_addr, &py_size)) + return NULL; + + PyGetInt(py_addr, addr); + PyGetInt(py_size, size); + add_mem_write(&self->vm_mngr, addr, size); + Py_INCREF(Py_None); + return Py_None; + +} + +PyObject* vm_check_invalid_code_blocs(VmMngr* self, PyObject* args) +{ + check_invalid_code_blocs(&self->vm_mngr); + Py_INCREF(Py_None); + return Py_None; +} + +PyObject* vm_check_memory_breakpoint(VmMngr* self, PyObject* args) +{ + check_memory_breakpoint(&self->vm_mngr); + Py_INCREF(Py_None); + return Py_None; +} + PyObject *vm_dump(PyObject* self) { char* buf_final; @@ -460,6 +518,23 @@ PyObject* vm_is_mapped(VmMngr* self, PyObject* args) return PyLong_FromUnsignedLongLong((uint64_t)ret); } +PyObject* vm_get_memory_read(VmMngr* self, PyObject* args) +{ + PyObject* result; + result = get_memory_read(&self->vm_mngr); + Py_INCREF(result); + return result; +} + +PyObject* vm_get_memory_write(VmMngr* self, PyObject* args) +{ + PyObject* result; + result = get_memory_write(&self->vm_mngr); + Py_INCREF(result); + return result; +} + + static PyObject * vm_set_big_endian(VmMngr *self, PyObject *value, void *closure) @@ -557,11 +632,24 @@ static PyMethodDef VmMngr_methods[] = { "X"}, {"get_exception",(PyCFunction)vm_get_exception, METH_VARARGS, "X"}, - {"set_big_endian",(PyCFunction)vm_set_big_endian, METH_VARARGS, "X"}, {"set_little_endian",(PyCFunction)vm_set_little_endian, METH_VARARGS, "X"}, + {"get_memory_read",(PyCFunction)vm_get_memory_read, METH_VARARGS, + "X"}, + {"get_memory_write",(PyCFunction)vm_get_memory_write, METH_VARARGS, + "X"}, + {"reset_memory_access",(PyCFunction)vm_reset_memory_access, METH_VARARGS, + "X"}, + {"add_mem_read",(PyCFunction)py_add_mem_read, METH_VARARGS, + "X"}, + {"add_mem_write",(PyCFunction)py_add_mem_write, METH_VARARGS, + "X"}, + {"check_invalid_code_blocs",(PyCFunction)vm_check_invalid_code_blocs, METH_VARARGS, + "X"}, + {"check_memory_breakpoint",(PyCFunction)vm_check_memory_breakpoint, METH_VARARGS, + "X"}, {NULL} /* Sentinel */ }; diff --git a/miasm2/os_dep/win_32_structs.py b/miasm2/os_dep/win_32_structs.py new file mode 100644 index 00000000..993fc79c --- /dev/null +++ b/miasm2/os_dep/win_32_structs.py @@ -0,0 +1,198 @@ +from miasm2.core.types import MemStruct, Num, Ptr, Str, \ + Array, RawStruct, Union, \ + BitField, Self, Void, Bits, \ + set_allocator, MemUnion, Struct + + +class UnicodeString(MemStruct): + fields = [ + ("length", Num("H")), + ("maxlength", Num("H")), + ("data", Ptr("<I", Str("utf16"))), + ] + + +class ListEntry(MemStruct): + fields = [ + ("flink", Ptr("<I", Void())), + ("blink", Ptr("<I", Void())), + ] + + +class LdrDataEntry(MemStruct): + + """ + +0x000 InLoadOrderLinks : _LIST_ENTRY + +0x008 InMemoryOrderLinks : _LIST_ENTRY + +0x010 InInitializationOrderLinks : _LIST_ENTRY + +0x018 DllBase : Ptr32 Void + +0x01c EntryPoint : Ptr32 Void + +0x020 SizeOfImage : Uint4B + +0x024 FullDllName : _UNICODE_STRING + +0x02c BaseDllName : _UNICODE_STRING + +0x034 Flags : Uint4B + +0x038 LoadCount : Uint2B + +0x03a TlsIndex : Uint2B + +0x03c HashLinks : _LIST_ENTRY + +0x03c SectionPointer : Ptr32 Void + +0x040 CheckSum : Uint4B + +0x044 TimeDateStamp : Uint4B + +0x044 LoadedImports : Ptr32 Void + +0x048 EntryPointActivationContext : Ptr32 Void + +0x04c PatchInformation : Ptr32 Void + """ + + fields = [ + ("InLoadOrderLinks", ListEntry), + ("InMemoryOrderLinks", ListEntry), + ("InInitializationOrderLinks", ListEntry), + ("DllBase", Ptr("<I", Void())), + ("EntryPoint", Ptr("<I", Void())), + ("SizeOfImage", Num("<I")), + ("FullDllName", UnicodeString), + ("BaseDllName", UnicodeString), + ("Flags", Array(Num("B"), 4)), + ("LoadCount", Num("H")), + ("TlsIndex", Num("H")), + ("union1", Union([ + ("HashLinks", Ptr("<I", Void())), + ("SectionPointer", Ptr("<I", Void())), + ])), + ("CheckSum", Num("<I")), + ("union2", Union([ + ("TimeDateStamp", Num("<I")), + ("LoadedImports", Ptr("<I", Void())), + ])), + ("EntryPointActivationContext", Ptr("<I", Void())), + ("PatchInformation", Ptr("<I", Void())), + + ] + + +class PEB_LDR_DATA(MemStruct): + + """ + +0x000 Length : Uint4B + +0x004 Initialized : UChar + +0x008 SsHandle : Ptr32 Void + +0x00c InLoadOrderModuleList : _LIST_ENTRY + +0x014 InMemoryOrderModuleList : _LIST_ENTRY + +0x01C InInitializationOrderModuleList : _LIST_ENTRY + """ + + fields = [ + ("Length", Num("<I")), + ("Initialized", Num("<I")), + ("SsHandle", Ptr("<I", Void())), + ("InLoadOrderModuleList", ListEntry), + ("InMemoryOrderModuleList", ListEntry), + ("InInitializationOrderModuleList", ListEntry) + ] + + +class PEB(MemStruct): + + """ + +0x000 InheritedAddressSpace : UChar + +0x001 ReadImageFileExecOptions : UChar + +0x002 BeingDebugged : UChar + +0x003 SpareBool : UChar + +0x004 Mutant : Ptr32 Void + +0x008 ImageBaseAddress : Ptr32 Void + +0x00c Ldr : Ptr32 _PEB_LDR_DATA + +0x010 processparameter + """ + + fields = [ + ("InheritedAddressSpace", Num("B")), + ("ReadImageFileExecOptions", Num("B")), + ("BeingDebugged", Num("B")), + ("SpareBool", Num("B")), + ("Mutant", Ptr("<I", Void())), + ("ImageBaseAddress", Num("<I")), + ("Ldr", Ptr("<I", PEB_LDR_DATA)), + ] + + +class NT_TIB(MemStruct): + + """ + +00 struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList + +04 void *StackBase + +08 void *StackLimit + +0c void *SubSystemTib + +10 void *FiberData + +10 uint32 Version + +14 void *ArbitraryUserPointer + +18 struct _NT_TIB *Self + """ + + fields = [ + ("ExceptionList", Ptr("<I", Void())), + ("StackBase", Ptr("<I", Void())), + ("StackLimit", Ptr("<I", Void())), + ("SubSystemTib", Ptr("<I", Void())), + (None, Union([ + ("FiberData", Ptr("<I", Void())), + ("Version", Num("<I")) + ])), + ("ArbitraryUserPointer", Ptr("<I", Void())), + ("Self", Ptr("<I", Self())), + ] + + +class TEB(MemStruct): + + """ + +0x000 NtTib : _NT_TIB + +0x01c EnvironmentPointer : Ptr32 Void + +0x020 ClientId : _CLIENT_ID + +0x028 ActiveRpcHandle : Ptr32 Void + +0x02c ThreadLocalStoragePointer : Ptr32 Void + +0x030 ProcessEnvironmentBlock : Ptr32 _PEB + +0x034 LastErrorValue : Uint4B + ... + """ + + fields = [ + ("NtTib", NT_TIB), + ("EnvironmentPointer", Ptr("<I", Void())), + ("ClientId", Array(Num("B"), 0x8)), + ("ActiveRpcHandle", Ptr("<I", Void())), + ("ThreadLocalStoragePointer", Ptr("<I", Void())), + ("ProcessEnvironmentBlock", Ptr("<I", PEB)), + ("LastErrorValue", Num("<I")), + ] + + +class ContextException(MemStruct): + fields = [ + ("ContectFlags", Num("<I")), + ("dr0", Num("<I")), + ("dr1", Num("<I")), + ("dr2", Num("<I")), + ("dr3", Num("<I")), + ("dr4", Num("<I")), + ("dr5", Num("<I")), + + ("Float", Array(Num("B"), 112)), + + ("gs", Num("<I")), + ("fs", Num("<I")), + ("es", Num("<I")), + ("ds", Num("<I")), + + ("edi", Num("<I")), + ("esi", Num("<I")), + ("ebx", Num("<I")), + ("edx", Num("<I")), + ("ecx", Num("<I")), + ("eax", Num("<I")), + ("ebp", Num("<I")), + ("eip", Num("<I")), + + ("cs", Num("<I")), + ("eflags", Num("<I")), + ("esp", Num("<I")), + ("ss", Num("<I")), + ] diff --git a/miasm2/os_dep/win_api_x86_32.py b/miasm2/os_dep/win_api_x86_32.py index a6041b15..029af8b5 100644 --- a/miasm2/os_dep/win_api_x86_32.py +++ b/miasm2/os_dep/win_api_x86_32.py @@ -383,10 +383,10 @@ def user32_FindWindowA(jitter): ret_ad, args = jitter.func_args_stdcall(["pclassname", "pwindowname"]) if args.pclassname: classname = jitter.get_str_ansi(args.pclassname) - log.info("classname %s", classname) + log.info("FindWindowA classname %s", classname) if args.pwindowname: windowname = jitter.get_str_ansi(args.pwindowname) - log.info("windowname %s", windowname) + log.info("FindWindowA windowname %s", windowname) jitter.func_ret_stdcall(ret_ad, 0) @@ -526,7 +526,7 @@ def kernel32_CreateFile(jitter, funcname, get_str): return fname = get_str(jitter, args.lpfilename) - log.debug('fname %s', fname) + log.info('CreateFile fname %s', fname) ret = 0xffffffff log.debug("%r %r", fname.lower(), winobjs.module_path.lower()) @@ -617,7 +617,7 @@ def kernel32_CreateFile(jitter, funcname, get_str): # h = open(sb_fname, 'rb+') # ret = winobjs.handle_pool.add(sb_fname, h) - log.debug('ret %x', ret) + log.debug('CreateFile ret %x', ret) jitter.func_ret_stdcall(ret_ad, ret) @@ -752,7 +752,7 @@ def kernel32_VirtualAlloc(jitter): alloc_addr, access_dict[args.flprotect], "\x00" * args.dwsize, "Alloc in %s ret 0x%X" % (whoami(), ret_ad)) - log.debug('Memory addr: %x', alloc_addr) + log.info('VirtualAlloc addr: 0x%x', alloc_addr) jitter.func_ret_stdcall(ret_ad, alloc_addr) @@ -814,7 +814,7 @@ def kernel32_CreateMutex(jitter, funcname, get_str): if args.lpname: name = get_str(jitter, args.lpname) - log.debug(name) + log.info("CreateMutex %r", name) else: name = None if args.initowner: @@ -890,10 +890,8 @@ def kernel32_LoadLibraryA(jitter): ret_ad, args = jitter.func_args_stdcall(["dllname"]) libname = get_str_ansi(jitter, args.dllname, 0x100) - log.info(libname) - ret = winobjs.runtime_dll.lib_get_add_base(libname) - log.info("ret %x", ret) + log.info("Loading %r ret 0x%x", libname, ret) jitter.func_ret_stdcall(ret_ad, ret) @@ -903,10 +901,8 @@ def kernel32_LoadLibraryExA(jitter): if args.hfile != 0: raise NotImplementedError("Untested case") libname = get_str_ansi(jitter, args.dllname, 0x100) - log.info(libname) - ret = winobjs.runtime_dll.lib_get_add_base(libname) - log.info("ret %x", ret) + log.info("Loading %r ret 0x%x", libname, ret) jitter.func_ret_stdcall(ret_ad, ret) @@ -919,12 +915,11 @@ def kernel32_GetProcAddress(jitter): fname = get_str_ansi(jitter, fname, 0x100) if not fname: fname = None - log.info(fname) if fname is not None: ad = winobjs.runtime_dll.lib_get_add_func(args.libbase, fname) else: ad = 0 - ad = winobjs.runtime_dll.lib_get_add_func(args.libbase, fname) + log.info("GetProcAddress %r %r ret 0x%x", args.libbase, fname, ad) jitter.add_breakpoint(ad, jitter.handle_lib) jitter.func_ret_stdcall(ret_ad, ad) @@ -933,10 +928,8 @@ def kernel32_LoadLibraryW(jitter): ret_ad, args = jitter.func_args_stdcall(["dllname"]) libname = get_str_unic(jitter, args.dllname, 0x100) - log.info(libname) - ret = winobjs.runtime_dll.lib_get_add_base(libname) - log.info("ret %x", ret) + log.info("Loading %r ret 0x%x", libname, ret) jitter.func_ret_stdcall(ret_ad, ret) @@ -945,15 +938,15 @@ def kernel32_GetModuleHandle(jitter, funcname, get_str): if args.dllname: libname = get_str(jitter, args.dllname) - log.info(libname) if libname: ret = winobjs.runtime_dll.lib_get_add_base(libname) else: log.warning('unknown module!') ret = 0 + log.info("GetModuleHandle %r ret 0x%x", libname, ret) else: ret = winobjs.current_pe.NThdr.ImageBase - log.debug("default img base %x", ret) + log.info("GetModuleHandle default ret 0x%x", ret) jitter.func_ret_stdcall(ret_ad, ret) @@ -1030,7 +1023,7 @@ def kernel32_GetCommandLineW(jitter): def shell32_CommandLineToArgvW(jitter): ret_ad, args = jitter.func_args_stdcall(["pcmd", "pnumargs"]) cmd = get_str_unic(jitter, args.pcmd) - log.debug(cmd) + log.info("CommandLineToArgv %r", cmd) tks = cmd.split(' ') addr = winobjs.heap.alloc(jitter, len(cmd) * 2 + 4 * len(tks)) addr_ret = winobjs.heap.alloc(jitter, 4 * (len(tks) + 1)) @@ -1525,7 +1518,7 @@ def my_GetEnvironmentVariable(jitter, funcname, get_str, set_str, mylen): s = get_str(jitter, args.lpname) if get_str == get_str_unic: s = s - log.debug('variable %r', s) + log.info('GetEnvironmentVariable %r', s) if s in winobjs.env_variables: v = set_str(winobjs.env_variables[s]) else: @@ -2018,9 +2011,9 @@ def advapi32_RegSetValue(jitter, funcname, get_str): "valuetype", "pvalue", "vlen"]) if args.psubkey: - log.debug("Subkey %s", get_str(jitter, args.psubkey)) + log.info("Subkey %s", get_str(jitter, args.psubkey)) if args.pvalue: - log.debug("Value %s", get_str(jitter, args.pvalue)) + log.info("Value %s", get_str(jitter, args.pvalue)) jitter.func_ret_stdcall(ret_ad, 0) @@ -2224,7 +2217,7 @@ def kernel32_MapViewOfFile(jitter): data = fd.read(args.length) if args.length else fd.read() length = len(data) - log.debug('mapp total: %x', len(data)) + log.debug('MapViewOfFile len: %x', len(data)) access_dict = { 0x0: 0, 0x1: 0, @@ -2271,6 +2264,8 @@ def kernel32_GetDriveType(jitter, funcname, get_str): p = get_str(jitter, args.pathname) p = p.upper() + log.debug('Drive: %r', p) + ret = 0 if p[0] == "C": ret = 3 @@ -2375,10 +2370,10 @@ def kernel32_SetFilePointer(jitter): # data = None if args.hwnd in winobjs.files_hwnd: - winobjs.files_hwnd[winobjs.module_cur_hwnd].seek(args.distance) + winobjs.files_hwnd[winobjs.module_cur_hwnd].seek(args.distance, args.movemethod) elif args.hwnd in winobjs.handle_pool: wh = winobjs.handle_pool[args.hwnd] - data = wh.info.seek(args.distance) + wh.info.seek(args.distance, args.movemethod) else: raise ValueError('unknown filename') jitter.func_ret_stdcall(ret_ad, args.distance) @@ -2403,10 +2398,10 @@ def kernel32_SetFilePointerEx(jitter): # data = None if args.hwnd in winobjs.files_hwnd: - winobjs.files_hwnd[winobjs.module_cur_hwnd].seek(distance) + winobjs.files_hwnd[winobjs.module_cur_hwnd].seek(distance, args.movemethod) elif args.hwnd in winobjs.handle_pool: wh = winobjs.handle_pool[args.hwnd] - # data = wh.info.seek(distance) + wh.info.seek(distance, args.movemethod) else: raise ValueError('unknown filename') jitter.func_ret_stdcall(ret_ad, 1) @@ -2733,8 +2728,7 @@ def msvcrt_myfopen(jitter, func): fname = func(jitter, args.pfname) rw = func(jitter, args.pmode) - log.debug(fname) - log.debug(rw) + log.info("fopen %r, %r", fname, rw) if rw in ['r', 'rb', 'wb+']: sb_fname = windows_to_sbpath(fname) diff --git a/miasm2/os_dep/win_api_x86_32_seh.py b/miasm2/os_dep/win_api_x86_32_seh.py index 6bf491bf..da8df7d7 100644 --- a/miasm2/os_dep/win_api_x86_32_seh.py +++ b/miasm2/os_dep/win_api_x86_32_seh.py @@ -28,6 +28,8 @@ from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE from miasm2.core.utils import pck32, upck32 import miasm2.arch.x86.regs as x86_regs +from miasm2.os_dep.win_32_structs import LdrDataEntry, ListEntry, \ + TEB, NT_TIB, PEB, PEB_LDR_DATA, ContextException # Constants Windows EXCEPTION_BREAKPOINT = 0x80000003 @@ -46,6 +48,7 @@ log.setLevel(logging.INFO) FS_0_AD = 0x7ff70000 PEB_AD = 0x7ffdf000 LDR_AD = 0x340000 +DEFAULT_SEH = 0x7ffff000 MAX_MODULES = 0x40 @@ -67,7 +70,6 @@ InLoadOrderModuleList_offset = 0x1ee0 + \ InLoadOrderModuleList_address = LDR_AD + \ InLoadOrderModuleList_offset -default_seh = PEB_AD + 0x20000 process_environment_address = 0x10000 process_parameters_address = 0x200000 @@ -86,56 +88,50 @@ def build_teb(jitter, teb_address): """ Build TEB informations using following structure: - +0x000 NtTib : _NT_TIB - +0x01c EnvironmentPointer : Ptr32 Void - +0x020 ClientId : _CLIENT_ID - +0x028 ActiveRpcHandle : Ptr32 Void - +0x02c ThreadLocalStoragePointer : Ptr32 Void - +0x030 ProcessEnvironmentBlock : Ptr32 _PEB - +0x034 LastErrorValue : Uint4B - ... @jitter: jitter instance @teb_address: the TEB address """ - o = "" - o += pck32(default_seh) - o += (0x18 - len(o)) * "\x00" - o += pck32(tib_address) - - o += (0x30 - len(o)) * "\x00" - o += pck32(peb_address) - o += pck32(0x11223344) - - jitter.vm.add_memory_page(teb_address, PAGE_READ | PAGE_WRITE, o, "TEB") - + # Only allocate space for ExceptionList/ProcessEnvironmentBlock/Self + jitter.vm.add_memory_page(teb_address, PAGE_READ | PAGE_WRITE, + "\x00" * NT_TIB.get_offset("StackBase"), + "TEB.NtTib.ExceptionList") + jitter.vm.add_memory_page(teb_address + NT_TIB.get_offset("Self"), + PAGE_READ | PAGE_WRITE, + "\x00" * (NT_TIB.sizeof() - NT_TIB.get_offset("Self")), + "TEB.NtTib.Self") + jitter.vm.add_memory_page(teb_address + TEB.get_offset("ProcessEnvironmentBlock"), + PAGE_READ | PAGE_WRITE, + "\x00" * (TEB.get_offset("LastErrorValue") - + TEB.get_offset("ProcessEnvironmentBlock")), + "TEB.ProcessEnvironmentBlock") + Teb = TEB(jitter.vm, teb_address) + Teb.NtTib.ExceptionList = DEFAULT_SEH + Teb.NtTib.Self = teb_address + Teb.ProcessEnvironmentBlock = peb_address def build_peb(jitter, peb_address): """ Build PEB informations using following structure: - +0x000 InheritedAddressSpace : UChar - +0x001 ReadImageFileExecOptions : UChar - +0x002 BeingDebugged : UChar - +0x003 SpareBool : UChar - +0x004 Mutant : Ptr32 Void - +0x008 ImageBaseAddress : Ptr32 Void - +0x00c Ldr : Ptr32 _PEB_LDR_DATA - +0x010 processparameter - @jitter: jitter instance @peb_address: the PEB address """ - offset = peb_address + 8 - o = "" if main_pe: - o += pck32(main_pe.NThdr.ImageBase) + offset, length = peb_address + 8, 4 else: - offset += 4 - o += pck32(peb_ldr_data_address) - o += pck32(process_parameters_address) - jitter.vm.add_memory_page(offset, PAGE_READ | PAGE_WRITE, o, "PEB") + offset, length = peb_address + 0xC, 0 + length += 4 + + jitter.vm.add_memory_page(offset, PAGE_READ | PAGE_WRITE, + "\x00" * length, + "PEB") + + Peb = PEB(jitter.vm, peb_address) + if main_pe: + Peb.ImageBaseAddress = main_pe.NThdr.ImageBase + Peb.Ldr = peb_ldr_data_address def build_ldr_data(jitter, modules_info): @@ -156,8 +152,42 @@ def build_ldr_data(jitter, modules_info): """ # ldr offset pad - offset = peb_ldr_data_address + 0xC + offset = 0xC + addr = LDR_AD + peb_ldr_data_offset + ldrdata = PEB_LDR_DATA(jitter.vm, addr) + + main_pe = modules_info.name2module.get(main_pe_name, None) + ntdll_pe = modules_info.name2module.get("ntdll.dll", None) + + size = 0 + if main_pe: + size += ListEntry.sizeof() * 2 + main_addr_entry = modules_info.module2entry[main_pe] + if ntdll_pe: + size += ListEntry.sizeof() + ntdll_addr_entry = modules_info.module2entry[ntdll_pe] + + jitter.vm.add_memory_page(addr + offset, PAGE_READ | PAGE_WRITE, + "\x00" * size, + "Loader struct") # (ldrdata.get_size() - offset)) + + if main_pe: + ldrdata.InLoadOrderModuleList.flink = main_addr_entry + ldrdata.InLoadOrderModuleList.blink = 0 + + ldrdata.InMemoryOrderModuleList.flink = main_addr_entry + \ + LdrDataEntry.get_type().get_offset("InMemoryOrderLinks") + ldrdata.InMemoryOrderModuleList.blink = 0 + + if ntdll_pe: + ldrdata.InInitializationOrderModuleList.flink = ntdll_addr_entry + \ + LdrDataEntry.get_type().get_offset("InInitializationOrderLinks") + ldrdata.InInitializationOrderModuleList.blink = 0 + + # data += pck32(ntdll_addr_entry + 0x10) + pck32(0) # XXX TODO fix blink + + """ # get main pe info main_pe = modules_info.name2module.get(main_pe_name, None) if not main_pe: @@ -167,18 +197,20 @@ def build_ldr_data(jitter, modules_info): main_addr_entry = modules_info.module2entry[main_pe] log.info('Ldr %x', main_addr_entry) data = pck32(main_addr_entry) + pck32(0) - data += pck32(main_addr_entry + 0x8) + pck32(0) # XXX TODO fix prev + data += pck32(main_addr_entry + 0x8) + pck32(0) # XXX TODO fix blink ntdll_pe = modules_info.name2module.get("ntdll.dll", None) if not ntdll_pe: log.warn('No ntdll, ldr data will be unconsistant') else: ntdll_addr_entry = modules_info.module2entry[ntdll_pe] - data += pck32(ntdll_addr_entry + 0x10) + pck32(0) # XXX TODO fix prev + data += pck32(ntdll_addr_entry + 0x10) + pck32(0) # XXX TODO fix blink if data: - jitter.vm.add_memory_page(offset, PAGE_READ | PAGE_WRITE, data, + jitter.vm.add_memory_page(offset, PAGE_READ | PAGE_WRITE, + data, "Loader struct") + """ # Add dummy dll base jitter.vm.add_memory_page(peb_ldr_data_address + 0x24, @@ -216,26 +248,6 @@ def create_modules_chain(jitter, name2module): """ Create the modules entries. Those modules are not linked in this function. - kd> dt nt!_LDR_DATA_TABLE_ENTRY - +0x000 InLoadOrderLinks : _LIST_ENTRY - +0x008 InMemoryOrderLinks : _LIST_ENTRY - +0x010 InInitializationOrderLinks : _LIST_ENTRY - +0x018 DllBase : Ptr32 Void - +0x01c EntryPoint : Ptr32 Void - +0x020 SizeOfImage : Uint4B - +0x024 FullDllName : _UNICODE_STRING - +0x02c BaseDllName : _UNICODE_STRING - +0x034 Flags : Uint4B - +0x038 LoadCount : Uint2B - +0x03a TlsIndex : Uint2B - +0x03c HashLinks : _LIST_ENTRY - +0x03c SectionPointer : Ptr32 Void - +0x040 CheckSum : Uint4B - +0x044 TimeDateStamp : Uint4B - +0x044 LoadedImports : Ptr32 Void - +0x048 EntryPointActivationContext : Ptr32 Void - +0x04c PatchInformation : Ptr32 Void - @jitter: jitter instance @name2module: dict containing association between name and its pe instance """ @@ -259,36 +271,30 @@ def create_modules_chain(jitter, name2module): modules_info.add(bname_str, pe_obj, addr) - m_o = "" - m_o += pck32(0) - m_o += pck32(0) - m_o += pck32(0) - m_o += pck32(0) - m_o += pck32(0) - m_o += pck32(0) - m_o += pck32(pe_obj.NThdr.ImageBase) - m_o += pck32(pe_obj.rva2virt(pe_obj.Opthdr.AddressOfEntryPoint)) - m_o += pck32(pe_obj.NThdr.sizeofimage) - m_o += struct.pack('HH', len(bname), len(bname) + 2) - m_o += pck32(addr + offset_path) - m_o += struct.pack('HH', len(bname), len(bname) + 2) - m_o += pck32(addr + offset_name) - jitter.vm.add_memory_page(addr, PAGE_READ | PAGE_WRITE, m_o, + # Allocate a partial LdrDataEntry (0-Flags) + jitter.vm.add_memory_page(addr, PAGE_READ | PAGE_WRITE, + "\x00" * LdrDataEntry.get_offset("Flags"), "Module info %r" % bname_str) - m_o = "" - m_o += bname - m_o += "\x00" * 3 - jitter.vm.add_memory_page( - addr + offset_name, PAGE_READ | PAGE_WRITE, m_o, - "Module name %r" % bname_str) + LdrEntry = LdrDataEntry(jitter.vm, addr) - m_o = "" - m_o += "\x00".join(bpath) + "\x00" - m_o += "\x00" * 3 - jitter.vm.add_memory_page( - addr + offset_path, PAGE_READ | PAGE_WRITE, m_o, - "Module path %r" % bname_str) + LdrEntry.DllBase = pe_obj.NThdr.ImageBase + LdrEntry.EntryPoint = pe_obj.Opthdr.AddressOfEntryPoint + LdrEntry.SizeOfImage = pe_obj.NThdr.sizeofimage + LdrEntry.FullDllName.length = len(bname) + LdrEntry.FullDllName.maxlength = len(bname) + 2 + LdrEntry.FullDllName.data = addr + offset_path + LdrEntry.BaseDllName.length = len(bname) + LdrEntry.BaseDllName.maxlength = len(bname) + 2 + LdrEntry.BaseDllName.data = addr + offset_name + + jitter.vm.add_memory_page(addr + offset_name, PAGE_READ | PAGE_WRITE, + bname + "\x00" * 3, + "Module name %r" % bname_str) + + jitter.vm.add_memory_page(addr + offset_path, PAGE_READ | PAGE_WRITE, + "\x00".join(bpath) + "\x00" + "\x00" * 3, + "Module path %r" % bname_str) return modules_info @@ -443,100 +449,94 @@ def init_seh(jitter): add_process_env(jitter) add_process_parameters(jitter) - jitter.vm.add_memory_page(default_seh, PAGE_READ | PAGE_WRITE, pck32( - 0xffffffff) + pck32(0x41414141) + pck32(0x42424242), - "Default seh handler") - - -# http://www.codeproject.com/KB/system/inject2exe.aspx#RestorethefirstRegistersContext5_1 -def regs2ctxt(jitter): +def regs2ctxt(jitter, context_address): """ Build x86_32 cpu context for exception handling @jitter: jitload instance """ - ctxt = [] + ctxt = ContextException(jitter.vm, context_address) + ctxt.memset("\x00") # ContextFlags - ctxt += [pck32(0x0)] + # XXX + # DRX - ctxt += [pck32(0x0)] * 6 + ctxt.dr0 = 0 + ctxt.dr1 = 0 + ctxt.dr2 = 0 + ctxt.dr3 = 0 + ctxt.dr4 = 0 + ctxt.dr5 = 0 + # Float context - ctxt += ['\x00' * 112] + # XXX + # Segment selectors - ctxt += [pck32(reg) for reg in (jitter.cpu.GS, jitter.cpu.FS, - jitter.cpu.ES, jitter.cpu.DS)] + ctxt.gs = jitter.cpu.GS + ctxt.fs = jitter.cpu.FS + ctxt.es = jitter.cpu.ES + ctxt.ds = jitter.cpu.DS + # Gpregs - ctxt += [pck32(reg) for reg in (jitter.cpu.EDI, jitter.cpu.ESI, - jitter.cpu.EBX, jitter.cpu.EDX, - jitter.cpu.ECX, jitter.cpu.EAX, - jitter.cpu.EBP, jitter.cpu.EIP)] + ctxt.edi = jitter.cpu.EDI + ctxt.esi = jitter.cpu.ESI + ctxt.ebx = jitter.cpu.EBX + ctxt.edx = jitter.cpu.EDX + ctxt.ecx = jitter.cpu.ECX + ctxt.eax = jitter.cpu.EAX + ctxt.ebp = jitter.cpu.EBP + ctxt.eip = jitter.cpu.EIP + # CS - ctxt += [pck32(jitter.cpu.CS)] + ctxt.cs = jitter.cpu.CS + # Eflags # XXX TODO real eflag - ctxt += [pck32(0x0)] + # ESP - ctxt += [pck32(jitter.cpu.ESP)] + ctxt.esp = jitter.cpu.ESP + # SS - ctxt += [pck32(jitter.cpu.SS)] - return "".join(ctxt) + ctxt.ss = jitter.cpu.SS -def ctxt2regs(ctxt, jitter): +def ctxt2regs(jitter, ctxt_ptr): """ Restore x86_32 registers from an exception context @ctxt: the serialized context @jitter: jitload instance """ - ctxt = ctxt[:] - # ContextFlags - ctxt = ctxt[4:] - # DRX XXX TODO - ctxt = ctxt[4 * 6:] - # Float context XXX TODO - ctxt = ctxt[112:] - # gs - jitter.cpu.GS = upck32(ctxt[:4]) - ctxt = ctxt[4:] - # fs - jitter.cpu.FS = upck32(ctxt[:4]) - ctxt = ctxt[4:] - # es - jitter.cpu.ES = upck32(ctxt[:4]) - ctxt = ctxt[4:] - # ds - jitter.cpu.DS = upck32(ctxt[:4]) - ctxt = ctxt[4:] + ctxt = ContextException(jitter.vm, ctxt_ptr) + + # Selectors + jitter.cpu.GS = ctxt.gs + jitter.cpu.FS = ctxt.fs + jitter.cpu.ES = ctxt.es + jitter.cpu.DS = ctxt.ds # Gpregs - jitter.cpu.EDI = upck32(ctxt[:4]) - ctxt = ctxt[4:] - jitter.cpu.ESI = upck32(ctxt[:4]) - ctxt = ctxt[4:] - jitter.cpu.EBX = upck32(ctxt[:4]) - ctxt = ctxt[4:] - jitter.cpu.EDX = upck32(ctxt[:4]) - ctxt = ctxt[4:] - jitter.cpu.ECX = upck32(ctxt[:4]) - ctxt = ctxt[4:] - jitter.cpu.EAX = upck32(ctxt[:4]) - ctxt = ctxt[4:] - jitter.cpu.EBP = upck32(ctxt[:4]) - ctxt = ctxt[4:] - jitter.cpu.EIP = upck32(ctxt[:4]) - ctxt = ctxt[4:] + jitter.cpu.EDI = ctxt.edi + jitter.cpu.ESI = ctxt.esi + jitter.cpu.EBX = ctxt.ebx + jitter.cpu.EDX = ctxt.edx + jitter.cpu.ECX = ctxt.ecx + jitter.cpu.EAX = ctxt.eax + jitter.cpu.EBP = ctxt.ebp + jitter.cpu.EIP = ctxt.eip # CS - jitter.cpu.CS = upck32(ctxt[:4]) - ctxt = ctxt[4:] - # Eflag XXX TODO - ctxt = ctxt[4:] + jitter.cpu.CS = ctxt.cs + + # Eflag + # XXX TODO + # ESP - jitter.cpu.ESP = upck32(ctxt[:4]) - ctxt = ctxt[4:] + jitter.cpu.ESP = ctxt.esp + # SS + jitter.cpu.SS = ctxt.ss def fake_seh_handler(jitter, except_code): @@ -551,11 +551,15 @@ def fake_seh_handler(jitter, except_code): log.warning('Exception at %x %r', jitter.cpu.EIP, seh_count) seh_count += 1 - # Help lambda - p = lambda s: struct.pack('I', s) + # Get space on stack for exception handling + new_ESP = jitter.cpu.ESP - 0x3c8 + exception_base_address = new_ESP + exception_record_address = exception_base_address + 0xe8 + context_address = exception_base_address + 0xfc + fake_seh_address = exception_base_address + 0x14 - # Forge a CONTEXT - ctxt = regs2ctxt(jitter) + # Save a CONTEXT + regs2ctxt(jitter, context_address) # Get current seh (fs:[0]) seh_ptr = upck32(jitter.vm.get_mem(tib_address, 4)) @@ -564,19 +568,10 @@ def fake_seh_handler(jitter, except_code): old_seh, eh, safe_place = struct.unpack( 'III', jitter.vm.get_mem(seh_ptr, 0xc)) - # Get space on stack for exception handling - jitter.cpu.ESP -= 0x3c8 - exception_base_address = jitter.cpu.ESP - exception_record_address = exception_base_address + 0xe8 - context_address = exception_base_address + 0xfc - fake_seh_address = exception_base_address + 0x14 - log.info('seh_ptr %x { old_seh %x eh %x safe_place %x} ctx_addr %x', seh_ptr, old_seh, eh, safe_place, context_address) - # Write context - jitter.vm.set_mem(context_address, ctxt) - + jitter.cpu.ESP = new_ESP # Write exception_record """ @@ -634,10 +629,12 @@ def dump_seh(jitter): if loop > MAX_SEH: log.warn("Too many seh, quit") return + if not jitter.vm.is_mapped(cur_seh_ptr, 8): + break prev_seh, eh = struct.unpack('II', jitter.vm.get_mem(cur_seh_ptr, 8)) log.info('\t' * indent + 'seh_ptr: %x { prev_seh: %x eh %x }', cur_seh_ptr, prev_seh, eh) - if prev_seh in [0xFFFFFFFF, 0]: + if prev_seh == 0: break cur_seh_ptr = prev_seh indent += 1 @@ -683,8 +680,8 @@ def return_from_seh(jitter): log.info('Seh continues Context: %x', ctxt_ptr) # Get registers changes - ctxt_str = jitter.vm.get_mem(ctxt_ptr, 0x2cc) - ctxt2regs(ctxt_str, jitter) + # ctxt_str = jitter.vm.get_mem(ctxt_ptr, 0x2cc) + ctxt2regs(jitter, ctxt_ptr) jitter.pc = jitter.cpu.EIP log.info('Context::Eip: %x', jitter.pc) diff --git a/test/arch/arm/arch.py b/test/arch/arm/arch.py index 2ffbd3b1..a00fe3d6 100644 --- a/test/arch/arm/arch.py +++ b/test/arch/arm/arch.py @@ -245,6 +245,11 @@ reg_tests_arm = [ ("XXXXXXXX REV R0, R2", "320FBFE6"), + ('XXXXXXXX PLD [R1]', + '00F0D1F5'), + ('XXXXXXXX PLD [R1, 0x1C]', + '1CF0D1F5'), + ] ts = time.time() diff --git a/test/arch/x86/arch.py b/test/arch/x86/arch.py index 9a7f3d8a..80a8563d 100644 --- a/test/arch/x86/arch.py +++ b/test/arch/x86/arch.py @@ -72,6 +72,8 @@ reg_tests = [ (m64, "XXXXXXXX CPUID", "0fa2"), + (m32, "XXXXXXXX SETALC", + "D6"), (m32, "XXXXXXXX PMINSW MM0, QWORD PTR [EAX]", "0fea00"), @@ -2224,6 +2226,9 @@ reg_tests = [ (m32, "00000000 NOP", "90"), + (m64, "00000000 XCHG RAX, R8", + "4990"), + (m32, "00000000 XCHG BYTE PTR [EAX], AL", "8600"), @@ -2882,6 +2887,9 @@ reg_tests = [ (m64, "00000000 PEXTRQ QWORD PTR [RDX], XMM2, 0x5", "66480F3A161205"), + (m64, "00000000 PEXTRW RCX, XMM14, 0x5", + "664C0F3A15F105"), + (m32, "00000000 UNPCKHPS XMM2, XMMWORD PTR [EDX]", "0f1512"), diff --git a/test/expression/simplifications.py b/test/expression/simplifications.py index acef0904..99cc7c35 100644 --- a/test/expression/simplifications.py +++ b/test/expression/simplifications.py @@ -144,6 +144,8 @@ to_test = [(ExprInt32(1) - ExprInt32(1), ExprInt32(0)), ExprOp('*', a, b, c, ExprInt32(0x12))), (ExprOp('*', -a, -b, -c, ExprInt32(0x12)), - ExprOp('*', a, b, c, ExprInt32(0x12))), + (ExprOp('**', ExprInt32(2), ExprInt32(8)), ExprInt32(0x100)), + (ExprInt32(2)**ExprInt32(8), ExprInt32(256)), (a | ExprInt32(0xffffffff), ExprInt32(0xffffffff)), (ExprCond(a, ExprInt32(1), ExprInt32(2)) * ExprInt32(4), @@ -349,6 +351,12 @@ to_test = [ (ExprOp_equal(ExprInt32(12), ExprInt32(-12)), ExprInt1(0)), (ExprCond(a - b, ExprInt1(0), ExprInt1(1)), ExprOp_equal(a, b)), (ExprCond(a + b, ExprInt1(0), ExprInt1(1)), ExprOp_equal(a, -b)), + (ExprOp_inf_signed(ExprInt32(-2), ExprInt32(3)), ExprInt1(1)), + (ExprOp_inf_signed(ExprInt32(3), ExprInt32(-3)), ExprInt1(0)), + (ExprOp_inf_signed(ExprInt32(2), ExprInt32(3)), ExprInt1(1)), + (ExprOp_inf_signed(ExprInt32(-3), ExprInt32(-2)), ExprInt1(1)), + (ExprOp_inf_signed(ExprInt32(0), ExprInt32(2)), ExprInt1(1)), + (ExprOp_inf_signed(ExprInt32(-3), ExprInt32(0)), ExprInt1(1)), ] expr_simp_cond = ExpressionSimplifier() diff --git a/test/test_all.py b/test/test_all.py index 35f081de..c9401552 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -232,8 +232,7 @@ for script in ["modint.py", ]: testset += RegressionTest([script], base_dir="expression") ## IR -for script in ["ir2C.py", - "symbexec.py", +for script in ["symbexec.py", ]: testset += RegressionTest([script], base_dir="ir") testset += RegressionTest(["analysis.py"], base_dir="ir", @@ -399,6 +398,8 @@ test_mips32l = ExampleShellcode(["mips32l", "mips32.S", "mips32_sc_l.bin"]) test_x86_64 = ExampleShellcode(["x86_64", "x86_64.S", "demo_x86_64.bin", "--PE"]) test_x86_32_if_reg = ExampleShellcode(['x86_32', 'x86_32_if_reg.S', "x86_32_if_reg.bin"]) +test_x86_32_seh = ExampleShellcode(["x86_32", "x86_32_seh.S", "x86_32_seh.bin", + "--PE"]) testset += test_armb testset += test_arml @@ -413,6 +414,7 @@ testset += test_mips32b testset += test_mips32l testset += test_x86_64 testset += test_x86_32_if_reg +testset += test_x86_32_seh class ExampleDisassembler(Example): """Disassembler examples specificities: @@ -554,6 +556,14 @@ class ExampleJitter(Example): jitter_engines = ["tcc", "llvm", "python", "gcc"] +class ExampleJitterNoPython(ExampleJitter): + """Jitter examples specificities: + - script path begins with "jitter/" + Run jitting script without python support + """ + jitter_engines = ["tcc", "llvm", "gcc"] + + for jitter in ExampleJitter.jitter_engines: # Take 5 min on a Core i5 tags = {"python": [TAGS["long"]], @@ -588,6 +598,13 @@ for script, dep in [(["x86_32.py", Example.get_sample("x86_32_sc.bin")], []), testset += ExampleJitter(script + ["--jitter", jitter], depends=dep, tags=tags) + +for jitter in ExampleJitterNoPython.jitter_engines: + tags = [TAGS[jitter]] if jitter in TAGS else [] + testset += ExampleJitterNoPython(["test_x86_32_seh.py", Example.get_sample("x86_32_seh.bin")] + ["--jitter", jitter], + depends=[test_x86_32_seh], + tags=tags) + testset += ExampleJitter(["example_types.py"]) |