Example #1
0
    def _range_shift_uniq(self, x_min, x_max, shift, op):
        """Bounds interval for x @op @shift with
         - x of size self.size
         - @x_min <= x <= @x_max
         - operations are considered unsigned
         - shift <= self.size
        """
        assert shift <= self.size
        # Shift operations are monotonic, and overflow results in 0
        max_bound = self.mask

        if op == "<<":
            obtain_max = x_max << shift
            if obtain_max > max_bound:
                # Overflow at least on max, best-effort
                # result '0' often happen, include it
                return interval([(0, 0), ((1 << shift) - 1, max_bound)])
            else:
                return interval([(x_min << shift, obtain_max)])
        elif op == ">>":
            return interval([((x_min >> shift) & max_bound,
                              (x_max >> shift) & max_bound)])
        elif op == "a>>":
            # The Miasm2 version (Expr or ModInt) could have been used, but
            # introduce unnecessary dependencies for this module
            # Python >> is the arithmetic one
            ashr = lambda x, y: self._signed2unsigned(self._unsigned2signed(x) >> y)
            end_min, end_max = ashr(x_min, shift), ashr(x_max, shift)
            end_min, end_max = min(end_min, end_max), max(end_min, end_max)
            return interval([(end_min, end_max)])
        else:
            raise ValueError("%s is not a shifter" % op)
Example #2
0
    def __init__(self, ir_arch, bs=None):
        """Initialise a JitCore instance.
        @ir_arch: ir instance for current architecture
        @bs: bitstream
        """

        self.ir_arch = ir_arch
        self.bs = bs
        self.known_blocs = {}
        self.lbl2jitbloc = BoundedDict(self.jitted_block_max_size,
                                       delete_cb=self.jitted_block_delete_cb)
        self.lbl2bloc = {}
        self.log_mn = False
        self.log_regs = False
        self.log_newbloc = False
        self.segm_to_do = set()
        self.job_done = set()
        self.jitcount = 0
        self.addr2obj = {}
        self.addr2objref = {}
        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
                        }

        self.mdis = asmbloc.disasmEngine(ir_arch.arch, ir_arch.attrib, bs,
                                         lines_wd=self.options["jit_maxline"],
                                         symbol_pool=ir_arch.symbol_pool,
                                         follow_call=False,
                                         dontdis_retcall=False,
                                         split_dis=self.split_dis,
                                         dis_bloc_callback=self.disasm_cb)
Example #3
0
def asm_resolve_final(mnemo, blocks, symbol_pool, dst_interval=None):
    """Resolve and assemble @blocks using @symbol_pool into interval
    @dst_interval"""

    sanity_check_blocks(blocks)

    guess_blocks_size(mnemo, blocks)
    blockChains = group_constrained_blocks(symbol_pool, blocks)
    resolved_blockChains = resolve_symbol(blockChains, symbol_pool, dst_interval)

    asmbloc_final(mnemo, blocks, resolved_blockChains, symbol_pool)
    patches = {}
    output_interval = interval()

    for block in blocks:
        offset = block.label.offset
        for instr in block.lines:
            if not instr.data:
                # Empty line
                continue
            assert len(instr.data) == instr.l
            patches[offset] = instr.data
            instruction_interval = interval([(offset, offset + instr.l-1)])
            if not (instruction_interval & output_interval).empty:
                raise RuntimeError("overlapping bytes %X" % int(offset))
            instr.offset = offset
            offset += instr.l
    return patches
Example #4
0
    def __init__(self, ir_arch, bs=None):
        """Initialise a JitCore instance.
        @ir_arch: ir instance for current architecture
        @bs: bitstream
        """

        self.ir_arch = ir_arch
        self.bs = bs
        self.known_blocs = {}
        self.lbl2jitbloc = BoundedDict(self.jitted_block_max_size,
                                       delete_cb=self.jitted_block_delete_cb)
        self.lbl2bloc = {}
        self.log_mn = False
        self.log_regs = False
        self.log_newbloc = False
        self.segm_to_do = set()
        self.job_done = set()
        self.jitcount = 0
        self.addr2obj = {}
        self.addr2objref = {}
        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
                        }
Example #5
0
    def blocks_to_memrange(self, blocks):
        """Return an interval instance standing for blocks addresses
        @blocks: list of AsmBlock instances
        """

        mem_range = interval()

        for block in blocks:
            mem_range += interval([(block.ad_min, block.ad_max - 1)])

        return mem_range
Example #6
0
    def blocs2memrange(self, blocs):
        """Return an interval instance standing for blocs addresses
        @blocs: list of asm_bloc instances
        """

        mem_range = interval()

        for b in blocs:
            mem_range += interval([(b.ad_min, b.ad_max - 1)])

        return mem_range
Example #7
0
 def _range_mul(self, x_min, x_max, y_min, y_max):
     """Interval bounds for x * y, with
      - x, y of size self.size
      - @x_min <= x <= @x_max
      - @y_min <= y <= @y_max
      - operations are considered unsigned
     This is a naive version, going to TOP on overflow"""
     max_bound = self.mask
     if y_max * x_max > max_bound:
         return interval([(0, max_bound)])
     else:
         return interval([(x_min * y_min, x_max * y_max)])
Example #8
0
 def _range_minus_uniq(self, x_min, x_max):
     """Bounds interval for -x, with
      - x of size self.size
      - @x_min <= x <= @x_max
      - operations are considered unsigned
     From Hacker's Delight: Chapter 4
     """
     max_bound = self.mask
     if (x_min == 0 and x_max != 0):
         # HD returns 0, max_bound; see _range_add
         return interval([(0, 0), ((- x_max) & max_bound, max_bound)])
     else:
         return interval([((- x_max) & max_bound, (- x_min) & max_bound)])
Example #9
0
def get_blockchains_address_interval(blockChains, dst_interval):
    """Compute the interval used by the pinned @blockChains
    Check if the placed chains are in the @dst_interval"""

    allocated_interval = interval()
    for chain in blockChains:
        if not chain.pinned:
            continue
        chain_interval = interval([(chain.offset_min, chain.offset_max-1)])
        if chain_interval not in dst_interval:
            raise ValueError('Chain placed out of destination interval')
        allocated_interval += chain_interval
    return allocated_interval
Example #10
0
 def _range_mod_uniq(self, x_min, x_max, mod):
     """Interval bounds for x % @mod, with
      - x, @mod of size self.size
      - @x_min <= x <= @x_max
      - operations are considered unsigned
     """
     if (x_max - x_min) >= mod:
         return interval([(0, mod - 1)])
     x_max = x_max % mod
     x_min = x_min % mod
     if x_max < x_min:
         return interval([(0, x_max), (x_min, mod - 1)])
     else:
         return interval([(x_min, x_max)])
Example #11
0
    def mmap(self, addr, len_, prot, flags, fd, off, vmmngr):
        """Stub for 'mmap' syscall

        'mmap2' must be implemented by calling this function with off * 4096
        """
        if addr == 0:
            addr = self.mmap_current
            self.mmap_current += (len_ + 0x1000) & ~0xfff

        all_mem = vmmngr.get_all_memory()
        mapped = interval([(start, start + info["size"] - 1)
                           for start, info in all_mem.iteritems()])

        MAP_FIXED = 0x10
        if flags & MAP_FIXED:
            # Alloc missing and override
            missing = interval([(addr, addr + len_ - 1)]) - mapped
            for start, stop in missing:
                vmmngr.add_memory_page(start, PAGE_READ|PAGE_WRITE,
                                          "\x00" * (stop - start + 1),
                                          "mmap allocated")
        else:
            # Find first candidate segment nearby addr
            for start, stop in mapped:
                if stop < addr:
                    continue
                rounded = (stop + 1 + 0x1000) & ~0xfff
                if (interval([(rounded, rounded + len_)]) & mapped).empty:
                    addr = rounded
                    break
            else:
                assert (interval([(addr, addr + len_)]) & mapped).empty

            vmmngr.add_memory_page(addr, PAGE_READ|PAGE_WRITE, "\x00" * len_,
                                      "mmap allocated")


        if fd == 0xffffffff:
            if off != 0:
                raise RuntimeError("Not implemented")
            data = "\x00" * len_
        else:
            fdesc = self.file_descriptors[fd]
            cur_pos = fdesc.tell()
            fdesc.seek(off)
            data = fdesc.read(len_)
            fdesc.seek(cur_pos)

        vmmngr.set_mem(addr, data)
        return addr
Example #12
0
 def _interval_shift(self, operation, shifter):
     """Apply the shifting operation @operation with a shifting
     ModularIntervals @shifter on the current instance"""
     # Work on a copy of shifter intervals
     shifter = interval(shifter.intervals)
     if (shifter.hull()[1] >= self.size):
         shifter += interval([(self.size, self.size)])
     shifter &= interval([(0, self.size)])
     ret = interval()
     for shift_range in shifter:
         for shift in xrange(shift_range[0], shift_range[1] + 1):
             for x_min, x_max in self.intervals:
                 ret += self._range_shift_uniq(x_min, x_max, shift, operation)
     return self.__class__(self.size, ret)
Example #13
0
def retrieve_stack_accesses(ir_arch_a, ssa):
    """
    Walk the ssa graph and find stack based variables.
    Return a dictionnary linking stack base address to its size/name
    @ir_arch_a: ira instance
    @ssa: SSADiGraph instance
    """
    stack_vars = set()
    for block in ssa.graph.blocks.itervalues():
        for assignblk in block:
            for dst, src in assignblk.iteritems():
                stack_vars.update(get_stack_accesses(ir_arch_a, dst))
                stack_vars.update(get_stack_accesses(ir_arch_a, src))
    stack_vars = filter(lambda expr: check_expr_below_stack(ir_arch_a, expr), stack_vars)

    base_to_var = {}
    for var in stack_vars:
        base_to_var.setdefault(var.ptr, set()).add(var)


    base_to_interval = {}
    for addr, vars in base_to_var.iteritems():
        var_interval = interval()
        for var in vars:
            offset = expr_simp(addr - ir_arch_a.sp)
            if not offset.is_int():
                # skip non linear stack offset
                continue

            start = int(offset)
            stop = int(expr_simp(offset + ExprInt(var.size / 8, offset.size)))
            mem = interval([(start, stop-1)])
            var_interval += mem
        base_to_interval[addr] = var_interval
    if not base_to_interval:
        return {}
    # Check if not intervals overlap
    _, tmp = base_to_interval.popitem()
    while base_to_interval:
        addr, mem = base_to_interval.popitem()
        assert (tmp & mem).empty
        tmp += mem

    base_to_info = {}
    for addr, vars in base_to_var.iteritems():
        name = "var_%d" % (len(base_to_info))
        size = max([var.size for var in vars])
        base_to_info[addr] = size, name
    return base_to_info
Example #14
0
def vm_load_elf(vm, fdata, **kargs):
    """
    Very dirty elf loader
    TODO XXX: implement real loader
    """
    #log.setLevel(logging.DEBUG)
    e = elf_init.ELF(fdata, **kargs)
    i = interval()
    all_data = {}
    for p in e.ph.phlist:
        if p.ph.type != 1:
            continue
        log.debug('0x%x 0x%x 0x%x 0x%x', p.ph.vaddr, p.ph.memsz, p.ph.offset,
                  p.ph.filesz)
        data_o = e._content[p.ph.offset:p.ph.offset + p.ph.filesz]
        addr_o = p.ph.vaddr
        a_addr = addr_o & ~0xFFF
        b_addr = addr_o + max(p.ph.memsz, p.ph.filesz)
        b_addr = (b_addr + 0xFFF) & ~0xFFF
        all_data[addr_o] = data_o
        # -2: Trick to avoid merging 2 consecutive pages
        i += [(a_addr, b_addr-2)]
    for a, b in i.intervals:
        #print hex(a), hex(b)
        vm.add_memory_page(a, PAGE_READ | PAGE_WRITE, "\x00"*(b+2-a))

    #vm.dump_memory_page_pool()

    for r_vaddr, data in all_data.items():
        vm.set_mem(r_vaddr, data)
    return e
Example #15
0
    def __init__(self, ir_arch, bin_stream):
        """Initialise a JitCore instance.
        @ir_arch: ir instance for current architecture
        @bin_stream: bin_stream instance
        """
        # Arch related
        self.ir_arch = ir_arch
        self.ircfg = self.ir_arch.new_ircfg()
        self.arch_name = "%s%s" % (self.ir_arch.arch.name, self.ir_arch.attrib)

        # Structures for block tracking
        self.offset_to_jitted_func = BoundedDict(self.jitted_block_max_size,
                                       delete_cb=self.jitted_block_delete_cb)
        self.loc_key_to_block = {}
        self.blocks_mem_interval = interval()

        # Logging & options
        self.log_mn = False
        self.log_regs = False
        self.log_newbloc = False
        self.options = {"jit_maxline": 50,  # Maximum number of line jitted
                        "max_exec_per_call": 0 # 0 means no limit
                        }

        # Disassembly Engine
        self.split_dis = set()
        self.mdis = disasmEngine(
            ir_arch.arch, ir_arch.attrib, bin_stream,
            lines_wd=self.options["jit_maxline"],
            loc_db=ir_arch.loc_db,
            follow_call=False,
            dontdis_retcall=False,
            split_dis=self.split_dis,
        )
Example #16
0
    def add_block_to_mem_interval(self, vm, block):
        "Update vm to include block addresses in its memory range"
        self.blocks_mem_interval += interval([(block.ad_min, block.ad_max - 1)])

        vm.reset_code_bloc_pool()
        for a, b in self.blocks_mem_interval:
            vm.add_code_bloc(a, b + 1)
Example #17
0
 def updt_automod_code(self, vm):
     """Remove code jitted in range self.addr_mod
     @vm: VmMngr instance
     """
     for addr_start, addr_stop in self.addr_mod:
         self.del_bloc_in_range(addr_start, addr_stop + 1)
     self.__updt_jitcode_mem_range(vm)
     self.addr_mod = interval()
Example #18
0
def resolve_symbol(blockChains, symbol_pool, dst_interval=None):
    """Place @blockChains in the @dst_interval"""

    log_asmbloc.info('resolve_symbol')
    if dst_interval is None:
        dst_interval = interval([(0, 0xFFFFFFFFFFFFFFFF)])

    forbidden_interval = interval(
        [(-1, 0xFFFFFFFFFFFFFFFF + 1)]) - dst_interval
    allocated_interval = get_blockchains_address_interval(blockChains,
                                                          dst_interval)
    log_asmbloc.debug('allocated interval: %s', allocated_interval)

    pinned_chains = [chain for chain in blockChains if chain.pinned]

    # Add wedge in forbidden intervals
    for start, stop in forbidden_interval.intervals:
        wedge = BlockChainWedge(
            symbol_pool, offset=start, size=stop + 1 - start)
        pinned_chains.append(wedge)

    # Try to place bigger blockChains first
    pinned_chains.sort(key=lambda x: x.offset_min)
    blockChains.sort(key=lambda x: -x.max_size)

    fixed_chains = list(pinned_chains)

    log_asmbloc.debug("place chains")
    for chain in blockChains:
        if chain.pinned:
            continue
        fixed = False
        for i in xrange(1, len(fixed_chains)):
            prev_chain = fixed_chains[i - 1]
            next_chain = fixed_chains[i]

            if prev_chain.offset_max + chain.max_size < next_chain.offset_min:
                new_chains = prev_chain.merge(chain)
                fixed_chains[i - 1:i] = new_chains
                fixed = True
                break
        if not fixed:
            raise RuntimeError('Cannot find enough space to place blocks')

    return [chain for chain in fixed_chains if isinstance(chain, BlockChain)]
Example #19
0
    def brk(self, addr, vmmngr):
        """Stub for 'brk' syscall"""
        if addr == 0:
            addr = self.brk_current
        else:
            all_mem = vmmngr.get_all_memory()
            mapped = interval([(start, start + info["size"] - 1)
                               for start, info in all_mem.iteritems()])

            # Alloc missing and override
            missing = interval([(self.brk_current, addr)]) - mapped
            for start, stop in missing:
                vmmngr.add_memory_page(start, PAGE_READ|PAGE_WRITE,
                                       "\x00" * (stop - start + 1),
                                       "BRK")

            self.brk_current = addr
        return addr
Example #20
0
 def ret_func(self, target):
     if isinstance(target, (int, long)):
         target = ModularIntervals(self.size, interval([(target, target)]))
     if not isinstance(target, ModularIntervals):
         raise TypeError("Unsupported operation with %s" % target.__class__)
     if target.size != self.size:
         raise TypeError("Size are not the same: %s vs %s" % (self.size,
                                                              target.size))
     return func(self, target)
Example #21
0
 def _range_and(self, x_min, x_max, y_min, y_max):
     """Interval bounds for x & y, with
      - x, y of size @size
      - @x_min <= x <= @x_max
      - @y_min <= y <= @y_max
      - operations are considered unsigned
     From Hacker's Delight: Chapter 4
     """
     return interval([(self._range_and_min(x_min, x_max, y_min, y_max),
                       self._range_and_max(x_min, x_max, y_min, y_max))])
Example #22
0
 def add_breakpoint(self, addr, callback):
     """Add a callback associated with addr.
     @addr: breakpoint address
     @callback: function with definition (jitter instance)
     """
     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)
Example #23
0
File: elf.py Project: commial/miasm
def vm_load_elf(vm, fdata, name="", base_addr=0, loc_db=None, apply_reloc=False,
                **kargs):
    """
    Very dirty elf loader
    TODO XXX: implement real loader
    """
    elf = elf_init.ELF(fdata, **kargs)
    i = interval()
    all_data = {}

    for p in elf.ph.phlist:
        if p.ph.type != elf_csts.PT_LOAD:
            continue
        log.debug(
            '0x%x 0x%x 0x%x 0x%x 0x%x', p.ph.vaddr, p.ph.memsz, p.ph.offset,
                  p.ph.filesz, p.ph.type)
        data_o = elf._content[p.ph.offset:p.ph.offset + p.ph.filesz]
        addr_o = p.ph.vaddr + base_addr
        a_addr = addr_o & ~0xFFF
        b_addr = addr_o + max(p.ph.memsz, p.ph.filesz)
        b_addr = (b_addr + 0xFFF) & ~0xFFF
        all_data[addr_o] = data_o
        # -2: Trick to avoid merging 2 consecutive pages
        i += [(a_addr, b_addr - 2)]
    for a, b in i.intervals:
        vm.add_memory_page(a, PAGE_READ | PAGE_WRITE, "\x00" * (b + 2 - a),
                           repr(name))

    for r_vaddr, data in all_data.items():
        vm.set_mem(r_vaddr, data)

    if loc_db is not None:
        fill_loc_db_with_symbols(elf, loc_db, base_addr)

    if apply_reloc:
        arch = guess_arch(elf)
        sections = []
        for section in elf.sh:
            if not hasattr(section, 'reltab'):
                continue
            if isinstance(section, elf_init.RelATable):
                pass
            elif isinstance(section, elf_init.RelTable):
                if arch == "x86_64":
                    log.warning("REL section should not happen in x86_64")
            else:
                raise RuntimeError("Unknown relocation section type: %r" % section)
            sections.append(section)
        for section in sections:
            if arch in ["x86_64", "x86_32"]:
                apply_reloc_x86(elf, vm, section, base_addr, loc_db)
            else:
                log.debug("Unsupported relocation for arch %r" % arch)

    return elf
Example #24
0
 def _range_add(self, x_min, x_max, y_min, y_max):
     """Bounds interval for x + y, with
      - x, y of size 'self.size'
      - @x_min <= x <= @x_max
      - @y_min <= y <= @y_max
      - operations are considered unsigned
     From Hacker's Delight: Chapter 4
     """
     max_bound = self.mask
     if (x_min + y_min <= max_bound and
         x_max + y_max >= max_bound + 1):
         # HD returns 0, max_bound; but this is because it cannot handle multiple
         # interval.
         # x_max + y_max can only overflow once, so returns
         # [result_min, overflow] U [0, overflow_rest]
         return interval([(x_min + y_min, max_bound),
                          (0, (x_max + y_max) & max_bound)])
     else:
         return interval([((x_min + y_min) & max_bound,
                           (x_max + y_max) & max_bound)])
Example #25
0
    def __init__(self, size, intervals=None):
        """Instanciate a ModularIntervals of size @size
        @size: maximum size of elements
        @intervals: (optional) interval instance, or any type  supported by
                    interval initialisation; element of the current instance
        """
        # Create or cast @intervals argument
        if intervals is None:
            intervals = interval()
        if not isinstance(intervals, interval):
            intervals = interval(intervals)
        self.intervals = intervals
        self.size = size

        # Sanity check
        start, end = intervals.hull()
        if start is not None:
            assert start >= 0
        if end is not None:
            assert end <= self.mask
Example #26
0
def gen_all_intervals(size):
    """Return every possible interval for element of @size bit
    -> 2**(2**size) (number of partition)
    """
    nb_elements = 1 << size
    for bvec in xrange(1 << nb_elements):
        # Bit vector: if bit i is on, i is in the interval
        to_ret = interval()
        for i in xrange(nb_elements):
            if bvec & i == i:
                to_ret += [(i, i)]
        yield to_ret
Example #27
0
    def step(self):
        "Step in jit"

        self.myjit.jit.set_options(jit_maxline=1)
        self.myjit.jit.addr_mod = interval([(self.myjit.pc, self.myjit.pc)])
        self.myjit.jit.updt_automod_code(self.myjit.vm)

        res = self.myjit.continue_run(step=True)
        self.handle_exception(res)

        self.myjit.jit.set_options(jit_maxline=50)
        self.on_step()

        return res
Example #28
0
    def substract_mems(self, arg1, arg2):
        """
        Return the remaining memory areas of @arg1 - @arg2
        @arg1, @arg2: ExprMem
        """

        ptr_diff = self.expr_simp(arg2.arg - arg1.arg)
        ptr_diff = int(int32(ptr_diff.arg))

        zone1 = interval([(0, arg1.size/8-1)])
        zone2 = interval([(ptr_diff, ptr_diff + arg2.size/8-1)])
        zones = zone1 - zone2

        out = []
        for start, stop in zones:
            ptr = arg1.arg + m2_expr.ExprInt(start, arg1.arg.size)
            ptr = self.expr_simp(ptr)
            value = self.expr_simp(self.symbols[arg1][start*8:(stop+1)*8])
            mem = m2_expr.ExprMem(ptr, (stop - start + 1)*8)
            assert mem.size == value.size
            out.append((mem, value))

        return out
Example #29
0
    def _interval_rotate(self, operation, shifter):
        """Apply the rotate operation @operation with a shifting
        ModularIntervals @shifter on the current instance"""
        # Consider only rotation without repetition, and enumerate
        # -> apply a '% size' on shifter
        shifter %= self.size
        ret = interval()
        for shift_range in shifter:
            for shift in xrange(shift_range[0], shift_range[1] + 1):
                for x_min, x_max in self.intervals:
                    ret += self._range_rotate_uniq(x_min, x_max, shift,
                                                   operation)

        return self.__class__(self.size, ret)
Example #30
0
 def _range_xor(self, x_min, x_max, y_min, y_max):
     """Interval bounds for x ^ y, with
      - x, y of size self.size
      - @x_min <= x <= @x_max
      - @y_min <= y <= @y_max
      - operations are considered unsigned
     From Hacker's Delight: Chapter 4
     """
     not_size = lambda x: x ^ self.mask
     min_xor = self._range_and_min(x_min, x_max, not_size(y_max), not_size(y_min)) | self._range_and_min(not_size(x_max), not_size(x_min), y_min, y_max)
     max_xor = self._range_or_max(0,
                                  self._range_and_max(x_min, x_max, not_size(y_max), not_size(y_min)),
                                  0,
                                  self._range_and_max(not_size(x_max), not_size(x_min), y_min, y_max))
     return interval([(min_xor, max_xor)])
Example #31
0
 def _range_xor(self, x_min, x_max, y_min, y_max):
     """Interval bounds for x ^ y, with
      - x, y of size self.size
      - @x_min <= x <= @x_max
      - @y_min <= y <= @y_max
      - operations are considered unsigned
     From Hacker's Delight: Chapter 4
     """
     not_size = lambda x: x ^ self.mask
     min_xor = self._range_and_min(x_min, x_max, not_size(y_max),
                                   not_size(y_min)) | self._range_and_min(
                                       not_size(x_max), not_size(x_min),
                                       y_min, y_max)
     max_xor = self._range_or_max(
         0,
         self._range_and_max(x_min, x_max, not_size(y_max),
                             not_size(y_min)), 0,
         self._range_and_max(not_size(x_max), not_size(x_min), y_min,
                             y_max))
     return interval([(min_xor, max_xor)])
Example #32
0
    def __init__(self, ir_arch, bin_stream):
        """Initialise a JitCore instance.
        @ir_arch: ir instance for current architecture
        @bin_stream: bin_stream instance
        """
        # Arch related
        self.ir_arch = ir_arch
        self.ircfg = self.ir_arch.new_ircfg()
        self.arch_name = "%s%s" % (self.ir_arch.arch.name, self.ir_arch.attrib)

        # Structures for block tracking
        self.offset_to_jitted_func = BoundedDict(
            self.jitted_block_max_size, delete_cb=self.jitted_block_delete_cb)
        self.loc_key_to_block = {}
        self.blocks_mem_interval = interval()

        # Logging & options
        self.log_mn = False
        self.log_regs = False
        self.log_newbloc = False
        self.options = {
            "jit_maxline": 50,  # Maximum number of line jitted
            "max_exec_per_call": 0  # 0 means no limit
        }

        # Disassembly Engine
        self.split_dis = set()
        self.mdis = disasmEngine(
            ir_arch.arch,
            ir_arch.attrib,
            bin_stream,
            lines_wd=self.options["jit_maxline"],
            loc_db=ir_arch.loc_db,
            follow_call=False,
            dontdis_retcall=False,
            split_dis=self.split_dis,
        )
Example #33
0
    def __init__(self, ir_arch, bs=None):
        """Initialise a JitCore instance.
        @ir_arch: ir instance for current architecture
        @bs: bitstream
        """

        self.ir_arch = ir_arch
        self.arch_name = "%s%s" % (self.ir_arch.arch.name, self.ir_arch.attrib)
        self.bs = bs
        self.known_blocs = {}
        self.loc_key_to_jit_block = BoundedDict(
            self.jitted_block_max_size, delete_cb=self.jitted_block_delete_cb)
        self.lbl2bloc = {}
        self.log_mn = False
        self.log_regs = False
        self.log_newbloc = False
        self.segm_to_do = set()
        self.jitcount = 0
        self.addr2obj = {}
        self.addr2objref = {}
        self.blocs_mem_interval = interval()
        self.disasm_cb = None
        self.split_dis = set()
        self.options = {
            "jit_maxline": 50,  # Maximum number of line jitted
            "max_exec_per_call": 0  # 0 means no limit
        }

        self.mdis = disasmEngine(ir_arch.arch,
                                 ir_arch.attrib,
                                 bs,
                                 lines_wd=self.options["jit_maxline"],
                                 symbol_pool=ir_arch.symbol_pool,
                                 follow_call=False,
                                 dontdis_retcall=False,
                                 split_dis=self.split_dis,
                                 dis_block_callback=self.disasm_cb)
Example #34
0
    try:
        addrs.append(int(addr, 0))
    except ValueError:
        # Second chance, try with symbol
        addrs.append(mdis.symbol_pool.getby_name(addr).offset)

if len(addrs) == 0 and default_addr is not None:
    addrs.append(default_addr)
for ad in addrs:
    todo += [(mdis, None, ad)]

done = set()
all_funcs = set()
all_funcs_blocks = {}

done_interval = interval()
finish = False

# Main disasm loop
while not finish and todo:
    while not finish and todo:
        mdis, caller, ad = todo.pop(0)
        if ad in done:
            continue
        done.add(ad)
        allblocks = mdis.dis_multibloc(ad)

        log.info('func ok %.16x (%d)' % (ad, len(all_funcs)))

        all_funcs.add(ad)
        all_funcs_blocks[ad] = allblocks
Example #35
0
 def ret_func(self, target):
     ret = interval()
     for left_i, right_i in product(self.intervals, target.intervals):
         ret += func(self, left_i[0], left_i[1], right_i[0], right_i[1])
     return self.__class__(self.size, ret)
Example #36
0
 def automod_cb(self, addr=0, size=0):
     self.addr_mod += interval([(addr, addr + size / 8 - 1)])
     return None
Example #37
0
 def ret_func(self, *args):
     ret = interval()
     for x_min, x_max in self.intervals:
         ret += func(self, x_min, x_max, *args)
     return self.__class__(self.size, ret)
Example #38
0
 def clear_jitted_blocks(self):
     "Reset all jitted blocks"
     self.offset_to_jitted_func.clear()
     self.loc_key_to_block.clear()
     self.blocks_mem_interval = interval()
Example #39
0
from miasm2.core import asmblock
from miasm2.arch.x86 import arch
from miasm2.core import parse_asm
from miasm2.core.interval import interval

my_mn = arch.mn_x86

asmcfg, loc_db = parse_asm.parse_txt(
    my_mn, 64, r'''
main:
  PUSH   RBP
  MOV    RBP, RSP
loop_dec:
  CMP    RCX, RDX
  JB    loop_dec
end:
  MOV    RSP, RBP
  POP    RBP
  RET

''')

loc_db.set_location_offset(loc_db.get_name_location("main"), 0x100001000)
dst_interval = interval([(0x100001000, 0x100002000)])
patches = asmblock.asm_resolve_final(my_mn, asmcfg, loc_db, dst_interval)
Example #40
0
 def clear_jitted_blocks(self):
     "Reset all jitted blocks"
     self.loc_key_to_jit_block.clear()
     self.lbl2bloc.clear()
     self.blocs_mem_interval = interval()
Example #41
0
    pe = pe_init.PE(wsize=size)
    s_text = pe.SHList.add_section(name="text", addr=0x1000, rawsize=0x1000)
    s_iat = pe.SHList.add_section(name="iat", rawsize=0x100)
    new_dll = [({
        "name": "USER32.dll",
        "firstthunk": s_iat.addr
    }, ["MessageBoxA"])]
    pe.DirImport.add_dlldesc(new_dll)
    s_myimp = pe.SHList.add_section(name="myimp", rawsize=len(pe.DirImport))
    pe.DirImport.set_rva(s_myimp.addr)
    pe.Opthdr.AddressOfEntryPoint = s_text.addr

    addr_main = pe.rva2virt(s_text.addr)
    virt = pe.virt
    output = pe
    dst_interval = interval([(pe.rva2virt(s_text.addr),
                              pe.rva2virt(s_text.addr + s_text.size))])
else:
    st = StrPatchwork()

    addr_main = 0
    virt = st
    output = st

# Get and parse the source code
with open(args.source) as fstream:
    source = fstream.read()

blocks, symbol_pool = parse_asm.parse_txt(machine.mn, attrib, source)

# Fix shellcode addrs
symbol_pool.set_offset(symbol_pool.getby_name("main"), addr_main)