def make_grid(tensor, nrow=8, padding=2, pad_value=0):
    """Make a grid of images, via numpy.

    Args:
        tensor (Tensor or list): 4D mini-batch Tensor of shape (B x C x H x W)
            or a list of images all of the same size.
        nrow (int, optional): Number of images displayed in each row of the grid.
            The Final grid size is (B / nrow, nrow). Default is 8.
        padding (int, optional): amount of padding. Default is 2.
        pad_value (float, optional): Value for the padded pixels.

    """
    if not (isinstance(tensor, np.ndarray) or
            (isinstance(tensor, list) and all(isinstance(t, np.ndarray) for t in tensor))):
        raise TypeError('tensor or list of tensors expected, got {}'.format(type(tensor)))

    # if list of tensors, convert to a 4D mini-batch Tensor
    if isinstance(tensor, list):
        tensor = np.stack(tensor, 0)

    if tensor.ndim == 2:  # single image H x W
        tensor = tensor.reshape((1, tensor.shape[0], tensor.shape[1]))

    if tensor.ndim == 3:
        if tensor.shape[0] == 1:  # if single-channel, single image, convert to 3-channel
            tensor = np.concatenate((tensor, tensor, tensor), 0)
        tensor = tensor.reshape((1, tensor.shape[0], tensor.shape[1], tensor.shape[2]))

    if tensor.ndim == 4 and tensor.shape[1] == 1:  # single-channel images
        tensor = np.concatenate((tensor, tensor, tensor), 1)

    if tensor.shape[0] == 1:
        return np.squeeze(tensor)

    # make the mini-batch of images into a grid
    nmaps = tensor.shape[0]
    xmaps = min(nrow, nmaps)
    ymaps = int(math.ceil(float(nmaps) / xmaps))
    height, width = int(tensor.shape[2] + padding), int(tensor.shape[3] + padding)
    grid = np.ones((3, height * ymaps + padding, width * xmaps + padding)) * pad_value
    k = 0
    for y in range(ymaps):
        for x in range(xmaps):
            if k >= nmaps:
                break
            grid[:, y * height + padding:(y+1) * height,\
                 x * width + padding:(x+1) * width] = tensor[k]
            k = k + 1
    return grid


def save_image(tensor, filename, nrow=8, padding=2, pad_value=0):
    """Save a given Tensor into an image file.

    Args:
        tensor (Tensor or list): Image to be saved. If given a mini-batch tensor,
            saves the tensor as a grid of images by calling ``make_grid``.
        **kwargs: Other arguments are documented in ``make_grid``.
    """
    from PIL import Image
    grid = make_grid(tensor, nrow=nrow, padding=padding, pad_value=pad_value)
    im = Image.fromarray(pre_pillow_float_img_process(grid))
    im.save(filename)

def save_image ( tensor , filename , nrow = 8 , padding = 2 , pad_value = 0 ) : from PIL import Image grid = make_grid ( tensor , nrow = nrow , padding = padding , pad_value = pad_value ) im = Image . fromarray ( pre_pillow_float_img_process ( grid ) ) im . save ( filename )

Save a given Tensor into an image file .


def pythonize_arguments(arg_str):
    """
    Remove types from function arguments in cython
    """
    out_args = []
    # If there aren't any arguments return the empty string
    if arg_str is None:
        return out_str
    args = arg_str.split(',')
    for arg in args:
        components = arg.split('=')
        name_and_type=components[0].split(' ')
        # There is probably type info
        if name_and_type[-1]=='' and len(name_and_type)>1:
            name=name_and_type[-2]
        else:
            name=name_and_type[-1]
        # if there are default parameters
        if len(components)>1:
            name+='='+components[1]

        out_args.append(name)
    return ','.join(out_args)


def _set_perms(self, perms):
        """
        Sets the access permissions of the map.

        :param perms: the new permissions.
        """
        assert isinstance(perms, str) and len(perms) <= 3 and perms.strip() in ['', 'r', 'w', 'x', 'rw', 'r x', 'rx', 'rwx', 'wx', ]
        self._perms = perms

def
_set_perms
(
self
,
perms
)
:
assert
isinstance
(
perms
,
str
)
and
len
(
perms
)
<=
3
and
perms
.
strip
(
)
in
[
''
,
'r'
,
'w'
,
'x'
,
'rw'
,
'r x'
,
'rx'
,
'rwx'
,
'wx'
,
]
self
.
_perms
=
perms

Sets the access permissions of the map .


def access_ok(self, access):
        """ Check if there is enough permissions for access """
        for c in access:
            if c not in self.perms:
                return False
        return True

def access_ok ( self , access ) : for c in access : if c not in self . perms : return False return True


def _in_range(self, index):
        """ Returns True if index is in range """
        if isinstance(index, slice):
            in_range = index.start < index.stop and \
                index.start >= self.start and \
                index.stop <= self.end
        else:
            in_range = index >= self.start and \
                index <= self.end
        return in_range

def _in_range ( self , index ) : if isinstance ( index , slice ) : in_range = index . start < index . stop and index . start >= self . start and index . stop <= self . end else : in_range = index >= self . start and index <= self . end return in_range


def _get_offset(self, index):
        """
        Translates the index to the internal offsets.

        self.start   -> 0
        self.start+1 -> 1
        ...
        self.end     -> len(self)
        """
        if not self._in_range(index):
            raise IndexError('Map index out of range')
        if isinstance(index, slice):
            index = slice(index.start - self.start, index.stop - self.start)
        else:
            index -= self.start
        return index

def
_get_offset
(
self
,
index
)
:
if
not
self
.
_in_range
(
index
)
:
raise
IndexError
(
'Map index out of range'
)
if
isinstance
(
index
,
slice
)
:
index
=
slice
(
index
.
start
self
.
start
,
index
.
stop
self
.
start
)
else
:
index
-=
self
.
start
return
index

Translates the index to the internal offsets .


def mmap(self, addr, size, perms, data_init=None, name=None):
        """
        Creates a new mapping in the memory address space.

        :param addr: the starting address (took as hint). If C{addr} is C{0} the first big enough
                     chunk of memory will be selected as starting address.
        :param size: the length of the mapping.
        :param perms: the access permissions to this memory.
        :param data_init: optional data to initialize this memory.
        :param name: optional name to give to this mapping
        :return: the starting address where the memory was mapped.
        :raises error:
                   - 'Address shall be concrete' if C{addr} is not an integer number.
                   - 'Address too big' if C{addr} goes beyond the limit of the memory.
                   - 'Map already used' if the piece of memory starting in C{addr} and with length C{size} isn't free.
        :rtype: int

        """
        # If addr is NULL, the system determines where to allocate the region.
        assert addr is None or isinstance(addr, int), 'Address shall be concrete'

        self.cpu._publish('will_map_memory', addr, size, perms, None, None)

        # address is rounded down to the nearest multiple of the allocation granularity
        if addr is not None:
            assert addr < self.memory_size, 'Address too big'
            addr = self._floor(addr)

        # size value is rounded up to the next page boundary
        size = self._ceil(size)

        # If zero search for a spot
        addr = self._search(size, addr)

        # It should not be allocated
        for i in range(self._page(addr), self._page(addr + size)):
            assert i not in self._page2map, 'Map already used'

        # Create the anonymous map
        m = AnonMap(start=addr, size=size, perms=perms, data_init=data_init, name=name)

        # Okay, ready to alloc
        self._add(m)

        logger.debug('New memory map @%x size:%x', addr, size)

        self.cpu._publish('did_map_memory', addr, size, perms, None, None, addr)
        return addr

Creates a new mapping in the memory address space .


def mappings(self):
        """
        Returns a sorted list of all the mappings for this memory.

        :return: a list of mappings.
        :rtype: list
        """
        result = []
        for m in self.maps:
            if isinstance(m, AnonMap):
                result.append((m.start, m.end, m.perms, 0, ''))
            elif isinstance(m, FileMap):
                result.append((m.start, m.end, m.perms, m._offset, m._filename))
            else:
                result.append((m.start, m.end, m.perms, 0, m.name))

        return sorted(result)

def mappings ( self ) : result = [ ] for m in self . maps : if isinstance ( m , AnonMap ) : result . append ( ( m . start , m . end , m . perms , 0 , '' ) ) elif isinstance ( m , FileMap ) : result . append ( ( m . start , m . end , m . perms , m . _offset , m . _filename ) ) else : result . append ( ( m . start , m . end , m . perms , 0 , m . name ) ) return sorted ( result )

Returns a sorted list of all the mappings for this memory .


def scan_mem(self, data_to_find):
        """
        Scan for concrete bytes in all mapped memory. Successively yield addresses of all matches.

        :param bytes data_to_find: String to locate
        :return:
        """

        # TODO: for the moment we just treat symbolic bytes as bytes that don't match.
        # for our simple test cases right now, the bytes we're interested in scanning
        # for will all just be there concretely
        # TODO: Can probably do something smarter here like Boyer-Moore, but unnecessary
        # if we're looking for short strings.

        # Querying mem with an index returns [bytes]
        if isinstance(data_to_find, bytes):
            data_to_find = [bytes([c]) for c in data_to_find]

        for mapping in sorted(self.maps):
            for ptr in mapping:
                if ptr + len(data_to_find) >= mapping.end:
                    break

                candidate = mapping[ptr:ptr + len(data_to_find)]

                # TODO: treat symbolic bytes as bytes that don't match. for our simple tests right now, the
                # bytes will be there concretely
                if issymbolic(candidate[0]):
                    break

                if candidate == data_to_find:
                    yield ptr

Scan for concrete bytes in all mapped memory . Successively yield addresses of all matches .


def _reg_name(self, reg_id):
        """
        Translates a register ID from the disassembler object into the
        register name based on manticore's alias in the register file

        :param int reg_id: Register ID
        """
        if reg_id >= X86_REG_ENDING:
            logger.warning("Trying to get register name for a non-register")
            return None
        cs_reg_name = self.cpu.instruction.reg_name(reg_id)
        if cs_reg_name is None or cs_reg_name.lower() == '(invalid)':
            return None
        return self.cpu._regfile._alias(cs_reg_name.upper())

Translates a register ID from the disassembler object into the register name based on manticore s alias in the register file


def get_argument_values(self, model, prefix_args):
        """
        Extract arguments for model from the environment and return as a tuple that
        is ready to be passed to the model.

        :param callable model: Python model of the function
        :param tuple prefix_args: Parameters to pass to model before actual ones
        :return: Arguments to be passed to the model
        :rtype: tuple
        """
        spec = inspect.getfullargspec(model)

        if spec.varargs:
            logger.warning("ABI: A vararg model must be a unary function.")

        nargs = len(spec.args) - len(prefix_args)

        # If the model is a method, we need to account for `self`
        if inspect.ismethod(model):
            nargs -= 1

        def resolve_argument(arg):
            if isinstance(arg, str):
                return self._cpu.read_register(arg)
            else:
                return self._cpu.read_int(arg)

        # Create a stream of resolved arguments from argument descriptors
        descriptors = self.get_arguments()
        argument_iter = map(resolve_argument, descriptors)

        from ..models import isvariadic  # prevent circular imports

        if isvariadic(model):
            arguments = prefix_args + (argument_iter,)
        else:
            arguments = prefix_args + tuple(islice(argument_iter, nargs))

        return arguments

Extract arguments for model from the environment and return as a tuple that is ready to be passed to the model .


def write_register(self, register, value):
        """
        Dynamic interface for writing cpu registers

        :param str register: register name (as listed in `self.all_registers`)
        :param value: register value
        :type value: int or long or Expression
        """
        self._publish('will_write_register', register, value)
        value = self._regfile.write(register, value)
        self._publish('did_write_register', register, value)
        return value

def write_register ( self , register , value ) : self . _publish ( 'will_write_register' , register , value ) value = self . _regfile . write ( register , value ) self . _publish ( 'did_write_register' , register , value ) return value


def read_register(self, register):
        """
        Dynamic interface for reading cpu registers

        :param str register: register name (as listed in `self.all_registers`)
        :return: register value
        :rtype: int or long or Expression
        """
        self._publish('will_read_register', register)
        value = self._regfile.read(register)
        self._publish('did_read_register', register, value)
        return value

def read_register ( self , register ) : self . _publish ( 'will_read_register' , register ) value = self . _regfile . read ( register ) self . _publish ( 'did_read_register' , register , value ) return value


def emulate_until(self, target: int):
        """
        Tells the CPU to set up a concrete unicorn emulator and use it to execute instructions
        until target is reached.

        :param target: Where Unicorn should hand control back to Manticore. Set to 0 for all instructions.
        """
        self._concrete = True
        self._break_unicorn_at = target
        if self.emu:
            self.emu._stop_at = target

def emulate_until ( self , target : int ) : self . _concrete = True self . _break_unicorn_at = target if self . emu : self . emu . _stop_at = target

Tells the CPU to set up a concrete unicorn emulator and use it to execute instructions until target is reached .


def write_int(self, where, expression, size=None, force=False):
        """
        Writes int to memory

        :param int where: address to write to
        :param expr: value to write
        :type expr: int or BitVec
        :param size: bit size of `expr`
        :param force: whether to ignore memory permissions
        """
        if size is None:
            size = self.address_bit_size
        assert size in SANE_SIZES
        self._publish('will_write_memory', where, expression, size)

        data = [Operators.CHR(Operators.EXTRACT(expression, offset, 8)) for offset in range(0, size, 8)]
        self._memory.write(where, data, force)

        self._publish('did_write_memory', where, expression, size)

def write_int ( self , where , expression , size = None , force = False ) : if size is None : size = self . address_bit_size assert size in SANE_SIZES self . _publish ( 'will_write_memory' , where , expression , size ) data = [ Operators . CHR ( Operators . EXTRACT ( expression , offset , 8 ) ) for offset in range ( 0 , size , 8 ) ] self . _memory . write ( where , data , force ) self . _publish ( 'did_write_memory' , where , expression , size )


def _raw_read(self, where: int, size=1) -> bytes:
        """
        Selects bytes from memory. Attempts to do so faster than via read_bytes.

        :param where: address to read from
        :param size: number of bytes to read
        :return: the bytes in memory
        """
        map = self.memory.map_containing(where)
        start = map._get_offset(where)
        mapType = type(map)
        if mapType is FileMap:
            end = map._get_offset(where + size)

            if end > map._mapped_size:
                logger.warning(f"Missing {end - map._mapped_size} bytes at the end of {map._filename}")

            raw_data = map._data[map._get_offset(where): min(end, map._mapped_size)]
            if len(raw_data) < end:
                raw_data += b'\x00' * (end - len(raw_data))

            data = b''
            for offset in sorted(map._overlay.keys()):
                data += raw_data[len(data):offset]
                data += map._overlay[offset]
            data += raw_data[len(data):]

        elif mapType is AnonMap:
            data = bytes(map._data[start:start + size])
        else:
            data = b''.join(self.memory[where:where + size])
        assert len(data) == size, 'Raw read resulted in wrong data read which should never happen'
        return data

Selects bytes from memory . Attempts to do so faster than via read_bytes .


def read_int(self, where, size=None, force=False):
        """
        Reads int from memory

        :param int where: address to read from
        :param size: number of bits to read
        :return: the value read
        :rtype: int or BitVec
        :param force: whether to ignore memory permissions
        """
        if size is None:
            size = self.address_bit_size
        assert size in SANE_SIZES
        self._publish('will_read_memory', where, size)

        data = self._memory.read(where, size // 8, force)
        assert (8 * len(data)) == size
        value = Operators.CONCAT(size, *map(Operators.ORD, reversed(data)))

        self._publish('did_read_memory', where, value, size)
        return value

def read_int ( self , where , size = None , force = False ) : if size is None : size = self . address_bit_size assert size in SANE_SIZES self . _publish ( 'will_read_memory' , where , size ) data = self . _memory . read ( where , size // 8 , force ) assert ( 8 * len ( data ) ) == size value = Operators . CONCAT ( size , * map ( Operators . ORD , reversed ( data ) ) ) self . _publish ( 'did_read_memory' , where , value , size ) return value


def read_bytes(self, where, size, force=False):
        """
        Read from memory.

        :param int where: address to read data from
        :param int size: number of bytes
        :param force: whether to ignore memory permissions
        :return: data
        :rtype: list[int or Expression]
        """
        result = []
        for i in range(size):
            result.append(Operators.CHR(self.read_int(where + i, 8, force)))
        return result

def read_bytes ( self , where , size , force = False ) : result = [ ] for i in range ( size ) : result . append ( Operators . CHR ( self . read_int ( where + i , 8 , force ) ) ) return result


def read_string(self, where, max_length=None, force=False):
        """
        Read a NUL-terminated concrete buffer from memory. Stops reading at first symbolic byte.

        :param int where: Address to read string from
        :param int max_length:
            The size in bytes to cap the string at, or None [default] for no
            limit.
        :param force: whether to ignore memory permissions
        :return: string read
        :rtype: str
        """
        s = io.BytesIO()
        while True:
            c = self.read_int(where, 8, force)

            if issymbolic(c) or c == 0:
                break

            if max_length is not None:
                if max_length == 0:
                    break
                max_length = max_length - 1
            s.write(Operators.CHR(c))
            where += 1
        return s.getvalue().decode()

def read_string ( self , where , max_length = None , force = False ) : s = io . BytesIO ( ) while True : c = self . read_int ( where , 8 , force ) if issymbolic ( c ) or c == 0 : break if max_length is not None : if max_length == 0 : break max_length = max_length - 1 s . write ( Operators . CHR ( c ) ) where += 1 return s . getvalue ( ) . decode ( )

Read a NUL - terminated concrete buffer from memory . Stops reading at first symbolic byte .


def push_bytes(self, data, force=False):
        """
        Write `data` to the stack and decrement the stack pointer accordingly.

        :param str data: Data to write
        :param force: whether to ignore memory permissions
        """
        self.STACK -= len(data)
        self.write_bytes(self.STACK, data, force)
        return self.STACK

def push_bytes ( self , data , force = False ) : self . STACK -= len ( data ) self . write_bytes ( self . STACK , data , force ) return self . STACK

Write data to the stack and decrement the stack pointer accordingly .


def pop_bytes(self, nbytes, force=False):
        """
        Read `nbytes` from the stack, increment the stack pointer, and return
        data.

        :param int nbytes: How many bytes to read
        :param force: whether to ignore memory permissions
        :return: Data read from the stack
        """
        data = self.read_bytes(self.STACK, nbytes, force=force)
        self.STACK += nbytes
        return data

def pop_bytes ( self , nbytes , force = False ) : data = self . read_bytes ( self . STACK , nbytes , force = force ) self . STACK += nbytes return data

Read nbytes from the stack increment the stack pointer and return data .


def push_int(self, value, force=False):
        """
        Decrement the stack pointer and write `value` to the stack.

        :param int value: The value to write
        :param force: whether to ignore memory permissions
        :return: New stack pointer
        """
        self.STACK -= self.address_bit_size // 8
        self.write_int(self.STACK, value, force=force)
        return self.STACK

def push_int ( self , value , force = False ) : self . STACK -= self . address_bit_size // 8 self . write_int ( self . STACK , value , force = force ) return self . STACK

Decrement the stack pointer and write value to the stack .


def pop_int(self, force=False):
        """
        Read a value from the stack and increment the stack pointer.

        :param force: whether to ignore memory permissions
        :return: Value read
        """
        value = self.read_int(self.STACK, force=force)
        self.STACK += self.address_bit_size // 8
        return value

def pop_int ( self , force = False ) : value = self . read_int ( self . STACK , force = force ) self . STACK += self . address_bit_size // 8 return value

Read a value from the stack and increment the stack pointer .


def decode_instruction(self, pc):
        """
        This will decode an instruction from memory pointed by `pc`

        :param int pc: address of the instruction
        """
        # No dynamic code!!! #TODO!
        # Check if instruction was already decoded
        if pc in self._instruction_cache:
            return self._instruction_cache[pc]

        text = b''

        # Read Instruction from memory
        for address in range(pc, pc + self.max_instr_width):
            # This reads a byte from memory ignoring permissions
            # and concretize it if symbolic
            if not self.memory.access_ok(address, 'x'):
                break

            c = self.memory[address]

            if issymbolic(c):
                # In case of fully symbolic memory, eagerly get a valid ptr
                if isinstance(self.memory, LazySMemory):
                    try:
                        vals = visitors.simplify_array_select(c)
                        c = bytes([vals[0]])
                    except visitors.ArraySelectSimplifier.ExpressionNotSimple:
                        c = struct.pack('B', solver.get_value(self.memory.constraints, c))
                elif isinstance(c, Constant):
                    c = bytes([c.value])
                else:
                    logger.error('Concretize executable memory %r %r', c, text)
                    raise ConcretizeMemory(self.memory,
                                           address=pc,
                                           size=8 * self.max_instr_width,
                                           policy='INSTRUCTION')
            text += c

        # Pad potentially incomplete instruction with zeroes
        code = text.ljust(self.max_instr_width, b'\x00')

        try:
            # decode the instruction from code
            insn = self.disasm.disassemble_instruction(code, pc)
        except StopIteration as e:
            raise DecodeException(pc, code)

        # Check that the decoded instruction is contained in executable memory
        if not self.memory.access_ok(slice(pc, pc + insn.size), 'x'):
            logger.info("Trying to execute instructions from non-executable memory")
            raise InvalidMemoryAccess(pc, 'x')

        insn.operands = self._wrap_operands(insn.operands)
        self._instruction_cache[pc] = insn
        return insn

This will decode an instruction from memory pointed by pc


def execute(self):
        """
        Decode, and execute one instruction pointed by register PC
        """
        if issymbolic(self.PC):
            raise ConcretizeRegister(self, 'PC', policy='ALL')

        if not self.memory.access_ok(self.PC, 'x'):
            raise InvalidMemoryAccess(self.PC, 'x')

        self._publish('will_decode_instruction', self.PC)

        insn = self.decode_instruction(self.PC)
        self._last_pc = self.PC

        self._publish('will_execute_instruction', self.PC, insn)

        # FIXME (theo) why just return here?
        if insn.address != self.PC:
            return

        name = self.canonicalize_instruction_name(insn)

        if logger.level == logging.DEBUG:
            logger.debug(self.render_instruction(insn))
            for l in self.render_registers():
                register_logger.debug(l)

        try:
            if self._concrete and 'SYSCALL' in name:
                self.emu.sync_unicorn_to_manticore()
            if self._concrete and 'SYSCALL' not in name:
                self.emulate(insn)
                if self.PC == self._break_unicorn_at:
                    logger.debug("Switching from Unicorn to Manticore")
                    self._break_unicorn_at = None
                    self._concrete = False
            else:
                implementation = getattr(self, name, None)

                if implementation is not None:
                    implementation(*insn.operands)

                else:
                    text_bytes = ' '.join('%02x' % x for x in insn.bytes)
                    logger.warning("Unimplemented instruction: 0x%016x:\t%s\t%s\t%s",
                                   insn.address, text_bytes, insn.mnemonic, insn.op_str)
                    self.backup_emulate(insn)
        except (Interruption, Syscall) as e:
            e.on_handled = lambda: self._publish_instruction_as_executed(insn)
            raise e
        else:
            self._publish_instruction_as_executed(insn)

Decode and execute one instruction pointed by register PC


def _publish_instruction_as_executed(self, insn):
        """
        Notify listeners that an instruction has been executed.
        """
        self._icount += 1
        self._publish('did_execute_instruction', self._last_pc, self.PC, insn)

def _publish_instruction_as_executed ( self , insn ) : self . _icount += 1 self . _publish ( 'did_execute_instruction' , self . _last_pc , self . PC , insn )

Notify listeners that an instruction has been executed .


def concrete_emulate(self, insn):
        """
        Start executing in Unicorn from this point until we hit a syscall or reach break_unicorn_at

        :param capstone.CsInsn insn: The instruction object to emulate
        """

        if not self.emu:
            self.emu = ConcreteUnicornEmulator(self)
            self.emu._stop_at = self._break_unicorn_at
        try:
            self.emu.emulate(insn)
        except unicorn.UcError as e:
            if e.errno == unicorn.UC_ERR_INSN_INVALID:
                text_bytes = ' '.join('%02x' % x for x in insn.bytes)
                logger.error("Unimplemented instruction: 0x%016x:\t%s\t%s\t%s",
                             insn.address, text_bytes, insn.mnemonic, insn.op_str)
            raise InstructionEmulationError(str(e))


def backup_emulate(self, insn):
        """
        If we could not handle emulating an instruction, use Unicorn to emulate
        it.

        :param capstone.CsInsn instruction: The instruction object to emulate
        """

        if not hasattr(self, 'backup_emu'):
            self.backup_emu = UnicornEmulator(self)
        try:
            self.backup_emu.emulate(insn)
        except unicorn.UcError as e:
            if e.errno == unicorn.UC_ERR_INSN_INVALID:
                text_bytes = ' '.join('%02x' % x for x in insn.bytes)
                logger.error("Unimplemented instruction: 0x%016x:\t%s\t%s\t%s",
                             insn.address, text_bytes, insn.mnemonic, insn.op_str)
            raise InstructionEmulationError(str(e))
        finally:
            # We have been seeing occasional Unicorn issues with it not clearing
            # the backing unicorn instance. Saw fewer issues with the following
            # line present.
            del self.backup_emu

If we could not handle emulating an instruction use Unicorn to emulate it .


def visualize(self):
        """
        Given a Manticore workspace, or trace file, highlight the basic blocks.
        """
        if os.path.isfile(self.workspace):
            t = threading.Thread(target=self.highlight_from_file,
                                 args=(self.workspace,))
        elif os.path.isdir(self.workspace):
            t = threading.Thread(target=self.highlight_from_dir,
                                 args=(self.workspace,))
        t.start()

def visualize ( self ) : if os . path . isfile ( self . workspace ) : t = threading . Thread ( target = self . highlight_from_file , args = ( self . workspace , ) ) elif os . path . isdir ( self . workspace ) : t = threading . Thread ( target = self . highlight_from_dir , args = ( self . workspace , ) ) t . start ( )

Given a Manticore workspace or trace file highlight the basic blocks .


def push(cpu, value, size):
        """
        Writes a value in the stack.

        :param value: the value to put in the stack.
        :param size: the size of the value.
        """
        assert size in (8, 16, cpu.address_bit_size)
        cpu.STACK = cpu.STACK - size // 8
        base, _, _ = cpu.get_descriptor(cpu.read_register('SS'))
        address = cpu.STACK + base
        cpu.write_int(address, value, size)

def push ( cpu , value , size ) : assert size in ( 8 , 16 , cpu . address_bit_size ) cpu . STACK = cpu . STACK - size // 8 base , _ , _ = cpu . get_descriptor ( cpu . read_register ( 'SS' ) ) address = cpu . STACK + base cpu . write_int ( address , value , size )


def pop(cpu, size):
        """
        Gets a value from the stack.

        :rtype: int
        :param size: the size of the value to consume from the stack.
        :return: the value from the stack.
        """
        assert size in (16, cpu.address_bit_size)
        base, _, _ = cpu.get_descriptor(cpu.SS)
        address = cpu.STACK + base
        value = cpu.read_int(address, size)
        cpu.STACK = cpu.STACK + size // 8
        return value

def pop ( cpu , size ) : assert size in ( 16 , cpu . address_bit_size ) base , _ , _ = cpu . get_descriptor ( cpu . SS ) address = cpu . STACK + base value = cpu . read_int ( address , size ) cpu . STACK = cpu . STACK + size // 8 return value


def invalidate_cache(cpu, address, size):
        """ remove decoded instruction from instruction cache """
        cache = cpu.instruction_cache
        for offset in range(size):
            if address + offset in cache:
                del cache[address + offset]

def invalidate_cache ( cpu , address , size ) : cache = cpu . instruction_cache for offset in range ( size ) : if address + offset in cache : del cache [ address + offset ]


def CPUID(cpu):
        """
        CPUID instruction.

        The ID flag (bit 21) in the EFLAGS register indicates support for the
        CPUID instruction.  If a software procedure can set and clear this
        flag, the processor executing the procedure supports the CPUID
        instruction. This instruction operates the same in non-64-bit modes and
        64-bit mode.  CPUID returns processor identification and feature
        information in the EAX, EBX, ECX, and EDX registers.

        The instruction's output is dependent on the contents of the EAX
        register upon execution.

        :param cpu: current CPU.
        """
        # FIXME Choose conservative values and consider returning some default when eax not here
        conf = {0x0: (0x0000000d, 0x756e6547, 0x6c65746e, 0x49656e69),
                0x1: (0x000306c3, 0x05100800, 0x7ffafbff, 0xbfebfbff),
                0x2: (0x76035a01, 0x00f0b5ff, 0x00000000, 0x00c10000),
                0x4: {0x0: (0x1c004121, 0x01c0003f, 0x0000003f, 0x00000000),
                      0x1: (0x1c004122, 0x01c0003f, 0x0000003f, 0x00000000),
                      0x2: (0x1c004143, 0x01c0003f, 0x000001ff, 0x00000000),
                      0x3: (0x1c03c163, 0x03c0003f, 0x00000fff, 0x00000006)},
                0x7: (0x00000000, 0x00000000, 0x00000000, 0x00000000),
                0x8: (0x00000000, 0x00000000, 0x00000000, 0x00000000),
                0xb: {0x0: (0x00000001, 0x00000002, 0x00000100, 0x00000005),
                      0x1: (0x00000004, 0x00000004, 0x00000201, 0x00000003)},
                0xd: {0x0: (0x00000000, 0x00000000, 0x00000000, 0x00000000),
                      0x1: (0x00000000, 0x00000000, 0x00000000, 0x00000000)},
                }

        if cpu.EAX not in conf:
            logger.warning('CPUID with EAX=%x not implemented @ %x', cpu.EAX, cpu.PC)
            cpu.EAX, cpu.EBX, cpu.ECX, cpu.EDX = 0, 0, 0, 0
            return

        if isinstance(conf[cpu.EAX], tuple):
            cpu.EAX, cpu.EBX, cpu.ECX, cpu.EDX = conf[cpu.EAX]
            return

        if cpu.ECX not in conf[cpu.EAX]:
            logger.warning('CPUID with EAX=%x ECX=%x not implemented', cpu.EAX, cpu.ECX)
            cpu.EAX, cpu.EBX, cpu.ECX, cpu.EDX = 0, 0, 0, 0
            return

        cpu.EAX, cpu.EBX, cpu.ECX, cpu.EDX = conf[cpu.EAX][cpu.ECX]


def AND(cpu, dest, src):
        """
        Logical AND.

        Performs a bitwise AND operation on the destination (first) and source
        (second) operands and stores the result in the destination operand location.
        Each bit of the result is set to 1 if both corresponding bits of the first and
        second operands are 1; otherwise, it is set to 0.

        The OF and CF flags are cleared; the SF, ZF, and PF flags are set according to the result::

            DEST  =  DEST AND SRC;

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        # XXX bypass a capstone bug that incorrectly extends and computes operands sizes
        # the bug has been fixed since capstone 4.0.alpha2 (commit de8dd26)
        if src.size == 64 and src.type == 'immediate' and dest.size == 64:
            arg1 = Operators.SEXTEND(src.read(), 32, 64)
        else:
            arg1 = src.read()
        res = dest.write(dest.read() & arg1)
        # Defined Flags: szp
        cpu._calculate_logic_flags(dest.size, res)


def TEST(cpu, src1, src2):
        """
        Logical compare.

        Computes the bit-wise logical AND of first operand (source 1 operand)
        and the second operand (source 2 operand) and sets the SF, ZF, and PF
        status flags according to the result. The result is then discarded::

            TEMP  =  SRC1 AND SRC2;
            SF  =  MSB(TEMP);
            IF TEMP  =  0
            THEN ZF  =  1;
            ELSE ZF  =  0;
            FI:
            PF  =  BitwiseXNOR(TEMP[0:7]);
            CF  =  0;
            OF  =  0;
            (*AF is Undefined*)

        :param cpu: current CPU.
        :param src1: first operand.
        :param src2: second operand.
        """
        # Defined Flags: szp
        temp = src1.read() & src2.read()
        cpu.SF = (temp & (1 << (src1.size - 1))) != 0
        cpu.ZF = temp == 0
        cpu.PF = cpu._calculate_parity_flag(temp)
        cpu.CF = False
        cpu.OF = False

def
TEST
(
cpu
,
src1
,
src2
)
:
# Defined Flags: szp
temp
=
src1
.
read
(
)
&
src2
.
read
(
)
cpu
.
SF
=
(
temp
&
(
1
<<
(
src1
.
size
1
)
)
)
!=
0
cpu
.
ZF
=
temp
==
0
cpu
.
PF
=
cpu
.
_calculate_parity_flag
(
temp
)
cpu
.
CF
=
False
cpu
.
OF
=
False


def OR(cpu, dest, src):
        """
        Logical inclusive OR.

        Performs a bitwise inclusive OR operation between the destination (first)
        and source (second) operands and stores the result in the destination operand location.

        Each bit of the result of the OR instruction is set to 0 if both corresponding
        bits of the first and second operands are 0; otherwise, each bit is set
        to 1.

        The OF and CF flags are cleared; the SF, ZF, and PF flags are set according to the result::

            DEST  =  DEST OR SRC;

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        res = dest.write(dest.read() | src.read())
        # Defined Flags: szp
        cpu._calculate_logic_flags(dest.size, res)

def
OR
(
cpu
,
dest
,
src
)
:
res
=
dest
.
write
(
dest
.
read
(
)
|
src
.
read
(
)
)
# Defined Flags: szp
cpu
.
_calculate_logic_flags
(
dest
.
size
,
res
)


def AAA(cpu):
        """
        ASCII adjust after addition.

        Adjusts the sum of two unpacked BCD values to create an unpacked BCD
        result. The AL register is the implied source and destination operand
        for this instruction. The AAA instruction is only useful when it follows
        an ADD instruction that adds (binary addition) two unpacked BCD values
        and stores a byte result in the AL register. The AAA instruction then
        adjusts the contents of the AL register to contain the correct 1-digit
        unpacked BCD result.
        If the addition produces a decimal carry, the AH register is incremented
        by 1, and the CF and AF flags are set. If there was no decimal carry,
        the CF and AF flags are cleared and the AH register is unchanged. In either
        case, bits 4 through 7 of the AL register are cleared to 0.

        This instruction executes as described in compatibility mode and legacy mode.
        It is not valid in 64-bit mode.
        ::
                IF ((AL AND 0FH) > 9) Operators.OR(AF  =  1)
                THEN
                    AL  =  (AL + 6);
                    AH  =  AH + 1;
                    AF  =  1;
                    CF  =  1;
                ELSE
                    AF  =  0;
                    CF  =  0;
                FI;
                AL  =  AL AND 0FH;
        :param cpu: current CPU.
        """
        cpu.AF = Operators.OR(cpu.AL & 0x0F > 9, cpu.AF)
        cpu.CF = cpu.AF
        cpu.AH = Operators.ITEBV(8, cpu.AF, cpu.AH + 1, cpu.AH)
        cpu.AL = Operators.ITEBV(8, cpu.AF, cpu.AL + 6, cpu.AL)
        """
        if (cpu.AL & 0x0F > 9) or cpu.AF == 1:
            cpu.AL = cpu.AL + 6
            cpu.AH = cpu.AH + 1
            cpu.AF = True
            cpu.CF = True
        else:
            cpu.AF = False
            cpu.CF = False
        """
        cpu.AL = cpu.AL & 0x0f


def AAD(cpu, imm=None):
        """
        ASCII adjust AX before division.

        Adjusts two unpacked BCD digits (the least-significant digit in the
        AL register and the most-significant digit in the AH register) so that
        a division operation performed on the result will yield a correct unpacked
        BCD value. The AAD instruction is only useful when it precedes a DIV instruction
        that divides (binary division) the adjusted value in the AX register by
        an unpacked BCD value.
        The AAD instruction sets the value in the AL register to (AL + (10 * AH)), and then
        clears the AH register to 00H. The value in the AX register is then equal to the binary
        equivalent of the original unpacked two-digit (base 10) number in registers AH and AL.

        The SF, ZF, and PF flags are set according to the resulting binary value in the AL register.

        This instruction executes as described in compatibility mode and legacy mode.
        It is not valid in 64-bit mode.::

                tempAL  =  AL;
                tempAH  =  AH;
                AL  =  (tempAL + (tempAH * 10)) AND FFH;
                AH  =  0

        :param cpu: current CPU.
        """
        if imm is None:
            imm = 10
        else:
            imm = imm.read()

        cpu.AL += cpu.AH * imm
        cpu.AH = 0

        # Defined flags: ...sz.p.
        cpu._calculate_logic_flags(8, cpu.AL)

def
AAD
(
cpu
,
imm
=
)
:
if
imm
is
:
imm
=
10
else
:
imm
=
imm
.
read
(
)
cpu
.
AL
+=
cpu
.
AH
*
imm
cpu
.
AH
=
0
# Defined flags: ...sz.p.
cpu
.
_calculate_logic_flags
(
8
,
cpu
.
AL
)


def AAM(cpu, imm=None):
        """
        ASCII adjust AX after multiply.

        Adjusts the result of the multiplication of two unpacked BCD values
        to create a pair of unpacked (base 10) BCD values. The AX register is
        the implied source and destination operand for this instruction. The AAM
        instruction is only useful when it follows a MUL instruction that multiplies
        (binary multiplication) two unpacked BCD values and stores a word result
        in the AX register. The AAM instruction then adjusts the contents of the
        AX register to contain the correct 2-digit unpacked (base 10) BCD result.

        The SF, ZF, and PF flags are set according to the resulting binary value in the AL register.

        This instruction executes as described in compatibility mode and legacy mode.
        It is not valid in 64-bit mode.::

                tempAL  =  AL;
                AH  =  tempAL / 10;
                AL  =  tempAL MOD 10;

        :param cpu: current CPU.
        """
        if imm is None:
            imm = 10
        else:
            imm = imm.read()

        cpu.AH = Operators.UDIV(cpu.AL, imm)
        cpu.AL = Operators.UREM(cpu.AL, imm)

        # Defined flags: ...sz.p.
        cpu._calculate_logic_flags(8, cpu.AL)

def
AAM
(
cpu
,
imm
=
)
:
if
imm
is
:
imm
=
10
else
:
imm
=
imm
.
read
(
)
cpu
.
AH
=
Operators
.
UDIV
(
cpu
.
AL
,
imm
)
cpu
.
AL
=
Operators
.
UREM
(
cpu
.
AL
,
imm
)
# Defined flags: ...sz.p.
cpu
.
_calculate_logic_flags
(
8
,
cpu
.
AL
)


def AAS(cpu):
        """
        ASCII Adjust AL after subtraction.

        Adjusts the result of the subtraction of two unpacked BCD values to  create a unpacked
        BCD result. The AL register is the implied source and destination operand for this instruction.
        The AAS instruction is only useful when it follows a SUB instruction that subtracts
        (binary subtraction) one unpacked BCD value from another and stores a byte result in the AL
        register. The AAA instruction then adjusts the contents of the AL register to contain the
        correct 1-digit unpacked BCD result. If the subtraction produced a decimal carry, the AH register
        is decremented by 1, and the CF and AF flags are set. If no decimal carry occurred, the CF and AF
        flags are cleared, and the AH register is unchanged. In either case, the AL register is left with
        its top nibble set to 0.

        The AF and CF flags are set to 1 if there is a decimal borrow; otherwise, they are cleared to 0.

        This instruction executes as described in compatibility mode and legacy mode.
        It is not valid in 64-bit mode.::

                IF ((AL AND 0FH) > 9) Operators.OR(AF  =  1)
                THEN
                    AX  =  AX - 6;
                    AH  =  AH - 1;
                    AF  =  1;
                    CF  =  1;
                ELSE
                    CF  =  0;
                    AF  =  0;
                FI;
                AL  =  AL AND 0FH;

        :param cpu: current CPU.
        """
        if (cpu.AL & 0x0F > 9) or cpu.AF == 1:
            cpu.AX = cpu.AX - 6
            cpu.AH = cpu.AH - 1
            cpu.AF = True
            cpu.CF = True
        else:
            cpu.AF = False
            cpu.CF = False
        cpu.AL = cpu.AL & 0x0f

def AAS ( cpu ) : if ( cpu . AL & 0x0F > 9 ) or cpu . AF == 1 : cpu . AX = cpu . AX - 6 cpu . AH = cpu . AH - 1 cpu . AF = True cpu . CF = True else : cpu . AF = False cpu . CF = False cpu . AL = cpu . AL & 0x0f


def ADC(cpu, dest, src):
        """
        Adds with carry.

        Adds the destination operand (first operand), the source operand (second operand),
        and the carry (CF) flag and stores the result in the destination operand. The state
        of the CF flag represents a carry from a previous addition. When an immediate value
        is used as an operand, it is sign-extended to the length of the destination operand
        format. The ADC instruction does not distinguish between signed or unsigned operands.
        Instead, the processor evaluates the result for both data types and sets the OF and CF
        flags to indicate a carry in the signed or unsigned result, respectively. The SF flag
        indicates the sign of the signed result. The ADC instruction is usually executed as
        part of a multibyte or multiword addition in which an ADD instruction is followed by an
        ADC instruction::

                DEST  =  DEST + SRC + CF;

        The OF, SF, ZF, AF, CF, and PF flags are set according to the result.

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        cpu._ADD(dest, src, carry=True)

def ADC ( cpu , dest , src ) : cpu . _ADD ( dest , src , carry = True )


def CMP(cpu, src1, src2):
        """
        Compares two operands.

        Compares the first source operand with the second source operand and sets the status flags
        in the EFLAGS register according to the results. The comparison is performed by subtracting
        the second operand from the first operand and then setting the status flags in the same manner
        as the SUB instruction. When an immediate value is used as an operand, it is sign-extended to
        the length of the first operand::

                temp  =  SRC1 - SignExtend(SRC2);
                ModifyStatusFlags; (* Modify status flags in the same manner as the SUB instruction*)

        The CF, OF, SF, ZF, AF, and PF flags are set according to the result.

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        arg0 = src1.read()
        arg1 = Operators.SEXTEND(src2.read(), src2.size, src1.size)

        # Affected Flags o..szapc
        cpu._calculate_CMP_flags(src1.size, arg0 - arg1, arg0, arg1)

def
CMP
(
cpu
,
src1
,
src2
)
:
arg0
=
src1
.
read
(
)
arg1
=
Operators
.
SEXTEND
(
src2
.
read
(
)
,
src2
.
size
,
src1
.
size
)
# Affected Flags o..szapc
cpu
.
_calculate_CMP_flags
(
src1
.
size
,
arg0
arg1
,
arg0
,
arg1
)


def CMPXCHG(cpu, dest, src):
        """
        Compares and exchanges.

        Compares the value in the AL, AX, EAX or RAX register (depending on the
        size of the operand) with the first operand (destination operand). If
        the two values are equal, the second operand (source operand) is loaded
        into the destination operand. Otherwise, the destination operand is
        loaded into the AL, AX, EAX or RAX register.

        The ZF flag is set if the values in the destination operand and
        register AL, AX, or EAX are equal; otherwise it is cleared. The CF, PF,
        AF, SF, and OF flags are set according to the results of the comparison
        operation::

        (* accumulator  =  AL, AX, EAX or RAX,  depending on whether *)
        (* a byte, word, a doubleword or a 64bit comparison is being performed*)
        IF accumulator  ==  DEST
        THEN
            ZF  =  1
            DEST  =  SRC
        ELSE
            ZF  =  0
            accumulator  =  DEST
        FI;

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        size = dest.size
        reg_name = {8: 'AL', 16: 'AX', 32: 'EAX', 64: 'RAX'}[size]
        accumulator = cpu.read_register(reg_name)
        sval = src.read()
        dval = dest.read()

        cpu.write_register(reg_name, dval)
        dest.write(Operators.ITEBV(size, accumulator == dval, sval, dval))

        # Affected Flags o..szapc
        cpu._calculate_CMP_flags(size, accumulator - dval, accumulator, dval)

def
CMPXCHG
(
cpu
,
dest
,
src
)
:
size
=
dest
.
size
reg_name
=
{
8
:
'AL'
,
16
:
'AX'
,
32
:
'EAX'
,
64
:
'RAX'
}
[
size
]
accumulator
=
cpu
.
read_register
(
reg_name
)
sval
=
src
.
read
(
)
dval
=
dest
.
read
(
)
cpu
.
write_register
(
reg_name
,
dval
)
dest
.
write
(
Operators
.
ITEBV
(
size
,
accumulator
==
dval
,
sval
,
dval
)
)
# Affected Flags o..szapc
cpu
.
_calculate_CMP_flags
(
size
,
accumulator
dval
,
accumulator
,
dval
)


def CMPXCHG8B(cpu, dest):
        """
        Compares and exchanges bytes.

        Compares the 64-bit value in EDX:EAX (or 128-bit value in RDX:RAX if
        operand size is 128 bits) with the operand (destination operand). If
        the values are equal, the 64-bit value in ECX:EBX (or 128-bit value in
        RCX:RBX) is stored in the destination operand.  Otherwise, the value in
        the destination operand is loaded into EDX:EAX (or RDX:RAX)::

                IF (64-Bit Mode and OperandSize = 64)
                THEN
                    IF (RDX:RAX = DEST)
                    THEN
                        ZF = 1;
                        DEST = RCX:RBX;
                    ELSE
                        ZF = 0;
                        RDX:RAX = DEST;
                    FI
                ELSE
                    IF (EDX:EAX = DEST)
                    THEN
                        ZF = 1;
                        DEST = ECX:EBX;
                    ELSE
                        ZF = 0;
                        EDX:EAX = DEST;
                    FI;
                FI;

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        size = dest.size
        cmp_reg_name_l = {64: 'EAX', 128: 'RAX'}[size]
        cmp_reg_name_h = {64: 'EDX', 128: 'RDX'}[size]
        src_reg_name_l = {64: 'EBX', 128: 'RBX'}[size]
        src_reg_name_h = {64: 'ECX', 128: 'RCX'}[size]

        # EDX:EAX or RDX:RAX
        cmph = cpu.read_register(cmp_reg_name_h)
        cmpl = cpu.read_register(cmp_reg_name_l)

        srch = cpu.read_register(src_reg_name_h)
        srcl = cpu.read_register(src_reg_name_l)

        cmp0 = Operators.CONCAT(size, cmph, cmpl)
        src0 = Operators.CONCAT(size, srch, srcl)
        arg_dest = dest.read()
        cpu.ZF = arg_dest == cmp0

        dest.write(
            Operators.ITEBV(size, cpu.ZF,
                            Operators.CONCAT(size, srch, srcl),
                            arg_dest)
        )
        cpu.write_register(cmp_reg_name_l, Operators.ITEBV(size // 2, cpu.ZF, cmpl,
                                                           Operators.EXTRACT(arg_dest, 0, size // 2)))
        cpu.write_register(cmp_reg_name_h, Operators.ITEBV(size // 2, cpu.ZF, cmph,
                                                           Operators.EXTRACT(arg_dest, size // 2, size // 2)))

def
CMPXCHG8B
(
cpu
,
dest
)
:
size
=
dest
.
size
cmp_reg_name_l
=
{
64
:
'EAX'
,
128
:
'RAX'
}
[
size
]
cmp_reg_name_h
=
{
64
:
'EDX'
,
128
:
'RDX'
}
[
size
]
src_reg_name_l
=
{
64
:
'EBX'
,
128
:
'RBX'
}
[
size
]
src_reg_name_h
=
{
64
:
'ECX'
,
128
:
'RCX'
}
[
size
]
# EDX:EAX or RDX:RAX
cmph
=
cpu
.
read_register
(
cmp_reg_name_h
)
cmpl
=
cpu
.
read_register
(
cmp_reg_name_l
)
srch
=
cpu
.
read_register
(
src_reg_name_h
)
srcl
=
cpu
.
read_register
(
src_reg_name_l
)
cmp0
=
Operators
.
CONCAT
(
size
,
cmph
,
cmpl
)
src0
=
Operators
.
CONCAT
(
size
,
srch
,
srcl
)
arg_dest
=
dest
.
read
(
)
cpu
.
ZF
=
arg_dest
==
cmp0
dest
.
write
(
Operators
.
ITEBV
(
size
,
cpu
.
ZF
,
Operators
.
CONCAT
(
size
,
srch
,
srcl
)
,
arg_dest
)
)
cpu
.
write_register
(
cmp_reg_name_l
,
Operators
.
ITEBV
(
size
//
2
,
cpu
.
ZF
,
cmpl
,
Operators
.
EXTRACT
(
arg_dest
,
0
,
size
//
2
)
)
)
cpu
.
write_register
(
cmp_reg_name_h
,
Operators
.
ITEBV
(
size
//
2
,
cpu
.
ZF
,
cmph
,
Operators
.
EXTRACT
(
arg_dest
,
size
//
2
,
size
//
2
)
)
)


def DAA(cpu):
        """
        Decimal adjusts AL after addition.

        Adjusts the sum of two packed BCD values to create a packed BCD result. The AL register
        is the implied source and destination operand. If a decimal carry is detected, the CF
        and AF flags are set accordingly.
        The CF and AF flags are set if the adjustment of the value results in a decimal carry in
        either digit of the result. The SF, ZF, and PF flags are set according to the result.

        This instruction is not valid in 64-bit mode.::

                IF (((AL AND 0FH) > 9) or AF  =  1)
                THEN
                    AL  =  AL + 6;
                    CF  =  CF OR CarryFromLastAddition; (* CF OR carry from AL  =  AL + 6 *)
                    AF  =  1;
                ELSE
                    AF  =  0;
                FI;
                IF ((AL AND F0H) > 90H) or CF  =  1)
                THEN
                    AL  =  AL + 60H;
                    CF  =  1;
                ELSE
                    CF  =  0;
                FI;

        :param cpu: current CPU.
        """

        cpu.AF = Operators.OR((cpu.AL & 0x0f) > 9, cpu.AF)
        oldAL = cpu.AL
        cpu.AL = Operators.ITEBV(8, cpu.AF, cpu.AL + 6, cpu.AL)
        cpu.CF = Operators.ITE(cpu.AF, Operators.OR(cpu.CF, cpu.AL < oldAL), cpu.CF)

        cpu.CF = Operators.OR((cpu.AL & 0xf0) > 0x90, cpu.CF)
        cpu.AL = Operators.ITEBV(8, cpu.CF, cpu.AL + 0x60, cpu.AL)
        """
        #old not-symbolic aware version...
        if ((cpu.AL & 0x0f) > 9) or cpu.AF:
            oldAL = cpu.AL
            cpu.AL =  cpu.AL + 6
            cpu.CF = Operators.OR(cpu.CF, cpu.AL < oldAL)
            cpu.AF  =  True
        else:
            cpu.AF  =  False

        if ((cpu.AL & 0xf0) > 0x90) or cpu.CF:
            cpu.AL  = cpu.AL + 0x60
            cpu.CF  =  True
        else:
            cpu.CF  =  False
        """

        cpu.ZF = cpu.AL == 0
        cpu.SF = (cpu.AL & 0x80) != 0
        cpu.PF = cpu._calculate_parity_flag(cpu.AL)


def DAS(cpu):
        """
        Decimal adjusts AL after subtraction.

        Adjusts the result of the subtraction of two packed BCD values to create a packed BCD result.
        The AL register is the implied source and destination operand. If a decimal borrow is detected,
        the CF and AF flags are set accordingly. This instruction is not valid in 64-bit mode.

        The SF, ZF, and PF flags are set according to the result.::

                IF (AL AND 0FH) > 9 OR AF  =  1
                THEN
                    AL  =  AL - 6;
                    CF  =  CF OR BorrowFromLastSubtraction; (* CF OR borrow from AL  =  AL - 6 *)
                    AF  =  1;
                ELSE
                    AF  =  0;
                FI;
                IF ((AL > 99H) or OLD_CF  =  1)
                THEN
                    AL  =  AL - 60H;
                    CF  =  1;

        :param cpu: current CPU.
        """
        oldAL = cpu.AL
        oldCF = cpu.CF

        cpu.AF = Operators.OR((cpu.AL & 0x0f) > 9, cpu.AF)
        cpu.AL = Operators.ITEBV(8, cpu.AF, cpu.AL - 6, cpu.AL)
        cpu.CF = Operators.ITE(cpu.AF, Operators.OR(oldCF, cpu.AL > oldAL), cpu.CF)

        cpu.CF = Operators.ITE(Operators.OR(oldAL > 0x99, oldCF), True, cpu.CF)
        cpu.AL = Operators.ITEBV(8, Operators.OR(oldAL > 0x99, oldCF), cpu.AL - 0x60, cpu.AL)
        #
        """
        if (cpu.AL & 0x0f) > 9 or cpu.AF:
            cpu.AL = cpu.AL - 6;
            cpu.CF = Operators.OR(oldCF, cpu.AL > oldAL)
            cpu.AF = True
        else:
            cpu.AF  =  False

        if ((oldAL > 0x99) or oldCF):
            cpu.AL = cpu.AL - 0x60
            cpu.CF = True
        """
        cpu.ZF = cpu.AL == 0
        cpu.SF = (cpu.AL & 0x80) != 0
        cpu.PF = cpu._calculate_parity_flag(cpu.AL)


def DIV(cpu, src):
        """
        Unsigned divide.

        Divides (unsigned) the value in the AX register, DX:AX register pair,
        or EDX:EAX or RDX:RAX register pair (dividend) by the source operand
        (divisor) and stores the result in the AX (AH:AL), DX:AX, EDX:EAX or
        RDX:RAX registers. The source operand can be a general-purpose register
        or a memory location. The action of this instruction depends of the
        operand size (dividend/divisor). Division using 64-bit operand is
        available only in 64-bit mode. Non-integral results are truncated
        (chopped) towards 0. The reminder is always less than the divisor in
        magnitude. Overflow is indicated with the #DE (divide error) exception
        rather than with the CF flag::

            IF SRC  =  0
                THEN #DE; FI;(* divide error *)
            IF OperandSize  =  8 (* word/byte operation *)
                THEN
                    temp  =  AX / SRC;
                    IF temp > FFH
                        THEN #DE; (* divide error *) ;
                        ELSE
                            AL  =  temp;
                            AH  =  AX MOD SRC;
                    FI;
                ELSE IF OperandSize  =  16 (* doubleword/word operation *)
                    THEN
                        temp  =  DX:AX / SRC;
                        IF temp > FFFFH
                            THEN #DE; (* divide error *) ;
                        ELSE
                            AX  =  temp;
                            DX  =  DX:AX MOD SRC;
                        FI;
                    FI;
                ELSE If OperandSize = 32 (* quadword/doubleword operation *)
                    THEN
                        temp  =  EDX:EAX / SRC;
                        IF temp > FFFFFFFFH
                            THEN #DE; (* divide error *) ;
                        ELSE
                            EAX  =  temp;
                            EDX  =  EDX:EAX MOD SRC;
                        FI;
                    FI;
                ELSE IF OperandSize = 64 (*Doublequadword/quadword operation*)
                    THEN
                        temp = RDX:RAX / SRC;
                        IF temp > FFFFFFFFFFFFFFFFH
                            THEN #DE; (* Divide error *)
                        ELSE
                            RAX = temp;
                            RDX = RDX:RAX MOD SRC;
                        FI;
                    FI;
            FI;

        :param cpu: current CPU.
        :param src: source operand.
        """
        size = src.size
        reg_name_h = {8: 'DL', 16: 'DX', 32: 'EDX', 64: 'RDX'}[size]
        reg_name_l = {8: 'AL', 16: 'AX', 32: 'EAX', 64: 'RAX'}[size]

        dividend = Operators.CONCAT(size * 2,
                                    cpu.read_register(reg_name_h),
                                    cpu.read_register(reg_name_l))
        divisor = Operators.ZEXTEND(src.read(), size * 2)

        # TODO make symbol friendly
        if isinstance(divisor, int) and divisor == 0:
            raise DivideByZeroError()
        quotient = Operators.UDIV(dividend, divisor)

        MASK = (1 << size) - 1

        # TODO make symbol friendly
        if isinstance(quotient, int) and quotient > MASK:
            raise DivideByZeroError()
        remainder = Operators.UREM(dividend, divisor)

        cpu.write_register(reg_name_l, Operators.EXTRACT(quotient, 0, size))
        cpu.write_register(reg_name_h, Operators.EXTRACT(remainder, 0, size))

def
DIV
(
cpu
,
src
)
:
size
=
src
.
size
reg_name_h
=
{
8
:
'DL'
,
16
:
'DX'
,
32
:
'EDX'
,
64
:
'RDX'
}
[
size
]
reg_name_l
=
{
8
:
'AL'
,
16
:
'AX'
,
32
:
'EAX'
,
64
:
'RAX'
}
[
size
]
dividend
=
Operators
.
CONCAT
(
size
*
2
,
cpu
.
read_register
(
reg_name_h
)
,
cpu
.
read_register
(
reg_name_l
)
)
divisor
=
Operators
.
ZEXTEND
(
src
.
read
(
)
,
size
*
2
)
# TODO make symbol friendly
if
isinstance
(
divisor
,
int
)
and
divisor
==
0
:
raise
DivideByZeroError
(
)
quotient
=
Operators
.
UDIV
(
dividend
,
divisor
)
MASK
=
(
1
<<
size
)
1
# TODO make symbol friendly
if
isinstance
(
quotient
,
int
)
and
quotient
>
MASK
:
raise
DivideByZeroError
(
)
remainder
=
Operators
.
UREM
(
dividend
,
divisor
)
cpu
.
write_register
(
reg_name_l
,
Operators
.
EXTRACT
(
quotient
,
0
,
size
)
)
cpu
.
write_register
(
reg_name_h
,
Operators
.
EXTRACT
(
remainder
,
0
,
size
)
)


def IDIV(cpu, src):
        """
        Signed divide.

        Divides (signed) the value in the AL, AX, or EAX register by the source
        operand and stores the result in the AX, DX:AX, or EDX:EAX registers.
        The source operand can be a general-purpose register or a memory
        location. The action of this instruction depends on the operand size.::

        IF SRC  =  0
        THEN #DE; (* divide error *)
        FI;
        IF OpernadSize  =  8 (* word/byte operation *)
        THEN
            temp  =  AX / SRC; (* signed division *)
            IF (temp > 7FH) Operators.OR(temp < 80H)
            (* if a positive result is greater than 7FH or a negative result is
            less than 80H *)
            THEN #DE; (* divide error *) ;
            ELSE
                AL  =  temp;
                AH  =  AX SignedModulus SRC;
            FI;
        ELSE
            IF OpernadSize  =  16 (* doubleword/word operation *)
            THEN
                temp  =  DX:AX / SRC; (* signed division *)
                IF (temp > 7FFFH) Operators.OR(temp < 8000H)
                (* if a positive result is greater than 7FFFH *)
                (* or a negative result is less than 8000H *)
                THEN #DE; (* divide error *) ;
                ELSE
                    AX  =  temp;
                    DX  =  DX:AX SignedModulus SRC;
                FI;
            ELSE (* quadword/doubleword operation *)
                temp  =  EDX:EAX / SRC; (* signed division *)
                IF (temp > 7FFFFFFFH) Operators.OR(temp < 80000000H)
                (* if a positive result is greater than 7FFFFFFFH *)
                (* or a negative result is less than 80000000H *)
                THEN #DE; (* divide error *) ;
                ELSE
                    EAX  =  temp;
                    EDX  =  EDX:EAX SignedModulus SRC;
                FI;
            FI;
        FI;

        :param cpu: current CPU.
        :param src: source operand.
        """

        reg_name_h = {8: 'AH', 16: 'DX', 32: 'EDX', 64: 'RDX'}[src.size]
        reg_name_l = {8: 'AL', 16: 'AX', 32: 'EAX', 64: 'RAX'}[src.size]

        dividend = Operators.CONCAT(src.size * 2,
                                    cpu.read_register(reg_name_h),
                                    cpu.read_register(reg_name_l))

        divisor = src.read()
        if isinstance(divisor, int) and divisor == 0:
            raise DivideByZeroError()

        dst_size = src.size * 2

        divisor = Operators.SEXTEND(divisor, src.size, dst_size)
        mask = (1 << dst_size) - 1
        sign_mask = 1 << (dst_size - 1)

        dividend_sign = (dividend & sign_mask) != 0
        divisor_sign = (divisor & sign_mask) != 0

        if isinstance(divisor, int):
            if divisor_sign:
                divisor = ((~divisor) + 1) & mask
                divisor = -divisor

        if isinstance(dividend, int):
            if dividend_sign:
                dividend = ((~dividend) + 1) & mask
                dividend = -dividend

        quotient = Operators.SDIV(dividend, divisor)
        if (isinstance(dividend, int) and
                isinstance(dividend, int)):
            # handle the concrete case
            remainder = dividend - (quotient * divisor)
        else:
            # symbolic case -- optimize via SREM
            remainder = Operators.SREM(dividend, divisor)

        cpu.write_register(reg_name_l, Operators.EXTRACT(quotient, 0, src.size))
        cpu.write_register(reg_name_h, Operators.EXTRACT(remainder, 0, src.size))

def
IDIV
(
cpu
,
src
)
:
reg_name_h
=
{
8
:
'AH'
,
16
:
'DX'
,
32
:
'EDX'
,
64
:
'RDX'
}
[
src
.
size
]
reg_name_l
=
{
8
:
'AL'
,
16
:
'AX'
,
32
:
'EAX'
,
64
:
'RAX'
}
[
src
.
size
]
dividend
=
Operators
.
CONCAT
(
src
.
size
*
2
,
cpu
.
read_register
(
reg_name_h
)
,
cpu
.
read_register
(
reg_name_l
)
)
divisor
=
src
.
read
(
)
if
isinstance
(
divisor
,
int
)
and
divisor
==
0
:
raise
DivideByZeroError
(
)
dst_size
=
src
.
size
*
2
divisor
=
Operators
.
SEXTEND
(
divisor
,
src
.
size
,
dst_size
)
mask
=
(
1
<<
dst_size
)
1
sign_mask
=
1
<<
(
dst_size
1
)
dividend_sign
=
(
dividend
&
sign_mask
)
!=
0
divisor_sign
=
(
divisor
&
sign_mask
)
!=
0
if
isinstance
(
divisor
,
int
)
:
if
divisor_sign
:
divisor
=
(
(
~
divisor
)
+
1
)
&
mask
divisor
=
divisor
if
isinstance
(
dividend
,
int
)
:
if
dividend_sign
:
dividend
=
(
(
~
dividend
)
+
1
)
&
mask
dividend
=
dividend
quotient
=
Operators
.
SDIV
(
dividend
,
divisor
)
if
(
isinstance
(
dividend
,
int
)
and
isinstance
(
dividend
,
int
)
)
:
# handle the concrete case
remainder
=
dividend
(
quotient
*
divisor
)
else
:
# symbolic case -- optimize via SREM
remainder
=
Operators
.
SREM
(
dividend
,
divisor
)
cpu
.
write_register
(
reg_name_l
,
Operators
.
EXTRACT
(
quotient
,
0
,
src
.
size
)
)
cpu
.
write_register
(
reg_name_h
,
Operators
.
EXTRACT
(
remainder
,
0
,
src
.
size
)
)


def IMUL(cpu, *operands):
        """
        Signed multiply.

        Performs a signed multiplication of two operands. This instruction has
        three forms, depending on the number of operands.
            - One-operand form. This form is identical to that used by the MUL
            instruction. Here, the source operand (in a general-purpose
            register or memory location) is multiplied by the value in the AL,
            AX, or EAX register (depending on the operand size) and the product
            is stored in the AX, DX:AX, or EDX:EAX registers, respectively.
            - Two-operand form. With this form the destination operand (the
            first operand) is multiplied by the source operand (second
            operand). The destination operand is a general-purpose register and
            the source operand is an immediate value, a general-purpose
            register, or a memory location. The product is then stored in the
            destination operand location.
            - Three-operand form. This form requires a destination operand (the
            first operand) and two source operands (the second and the third
            operands). Here, the first source operand (which can be a
            general-purpose register or a memory location) is multiplied by the
            second source operand (an immediate value). The product is then
            stored in the destination operand (a general-purpose register).

        When an immediate value is used as an operand, it is sign-extended to
        the length of the destination operand format. The CF and OF flags are
        set when significant bits are carried into the upper half of the
        result. The CF and OF flags are cleared when the result fits exactly in
        the lower half of the result. The three forms of the IMUL instruction
        are similar in that the length of the product is calculated to twice
        the length of the operands. With the one-operand form, the product is
        stored exactly in the destination. With the two- and three- operand
        forms, however, result is truncated to the length of the destination
        before it is stored in the destination register. Because of this
        truncation, the CF or OF flag should be tested to ensure that no
        significant bits are lost. The two- and three-operand forms may also be
        used with unsigned operands because the lower half of the product is
        the same regardless if the operands are signed or unsigned. The CF and
        OF flags, however, cannot be used to determine if the upper half of the
        result is non-zero::

        IF (NumberOfOperands == 1)
        THEN
            IF (OperandSize == 8)
            THEN
                AX = AL * SRC (* Signed multiplication *)
                IF AL == AX
                THEN
                    CF = 0; OF = 0;
                ELSE
                    CF = 1; OF = 1;
                FI;
            ELSE
                IF OperandSize == 16
                THEN
                    DX:AX = AX * SRC (* Signed multiplication *)
                    IF sign_extend_to_32 (AX) == DX:AX
                    THEN
                        CF = 0; OF = 0;
                    ELSE
                        CF = 1; OF = 1;
                    FI;
                ELSE
                    IF OperandSize == 32
                    THEN
                        EDX:EAX = EAX * SRC (* Signed multiplication *)
                        IF EAX == EDX:EAX
                        THEN
                            CF = 0; OF = 0;
                        ELSE
                            CF = 1; OF = 1;
                        FI;
                    ELSE (* OperandSize = 64 *)
                        RDX:RAX = RAX * SRC (* Signed multiplication *)
                        IF RAX == RDX:RAX
                        THEN
                            CF = 0; OF = 0;
                        ELSE
                           CF = 1; OF = 1;
                        FI;
                    FI;
                FI;
        ELSE
            IF (NumberOfOperands = 2)
            THEN
                temp = DEST * SRC (* Signed multiplication; temp is double DEST size *)
                DEST = DEST * SRC (* Signed multiplication *)
                IF temp != DEST
                THEN
                    CF = 1; OF = 1;
                ELSE
                    CF = 0; OF = 0;
                FI;
            ELSE (* NumberOfOperands = 3 *)
                DEST = SRC1 * SRC2 (* Signed multiplication *)
                temp = SRC1 * SRC2 (* Signed multiplication; temp is double SRC1 size *)
                IF temp != DEST
                THEN
                    CF = 1; OF = 1;
                ELSE
                    CF = 0; OF = 0;
                FI;
            FI;
        FI;

        :param cpu: current CPU.
        :param operands: variable list of operands.
        """
        dest = operands[0]
        OperandSize = dest.size
        reg_name_h = {8: 'AH', 16: 'DX', 32: 'EDX', 64: 'RDX'}[OperandSize]
        reg_name_l = {8: 'AL', 16: 'AX', 32: 'EAX', 64: 'RAX'}[OperandSize]

        arg0 = dest.read()
        arg1 = None
        arg2 = None
        res = None
        if len(operands) == 1:
            arg1 = cpu.read_register(reg_name_l)
            temp = (Operators.SEXTEND(arg0, OperandSize, OperandSize * 2) *
                    Operators.SEXTEND(arg1, OperandSize, OperandSize * 2))
            temp = temp & ((1 << (OperandSize * 2)) - 1)
            cpu.write_register(reg_name_l,
                               Operators.EXTRACT(temp, 0, OperandSize))
            cpu.write_register(reg_name_h,
                               Operators.EXTRACT(temp, OperandSize, OperandSize))
            res = Operators.EXTRACT(temp, 0, OperandSize)
        elif len(operands) == 2:
            arg1 = operands[1].read()
            arg1 = Operators.SEXTEND(arg1, OperandSize, OperandSize * 2)
            temp = Operators.SEXTEND(arg0, OperandSize, OperandSize * 2) * arg1
            temp = temp & ((1 << (OperandSize * 2)) - 1)
            res = dest.write(Operators.EXTRACT(temp, 0, OperandSize))
        else:
            arg1 = operands[1].read()
            arg2 = operands[2].read()
            temp = (Operators.SEXTEND(arg1, OperandSize, OperandSize * 2) *
                    Operators.SEXTEND(arg2, operands[2].size, OperandSize * 2))
            temp = temp & ((1 << (OperandSize * 2)) - 1)
            res = dest.write(Operators.EXTRACT(temp, 0, OperandSize))

        cpu.CF = (Operators.SEXTEND(res, OperandSize, OperandSize * 2) != temp)
        cpu.OF = cpu.CF

def IMUL ( cpu , * operands ) : dest = operands [ 0 ] OperandSize = dest . size reg_name_h = { 8 : 'AH' , 16 : 'DX' , 32 : 'EDX' , 64 : 'RDX' } [ OperandSize ] reg_name_l = { 8 : 'AL' , 16 : 'AX' , 32 : 'EAX' , 64 : 'RAX' } [ OperandSize ] arg0 = dest . read ( ) arg1 = None arg2 = None res = None if len ( operands ) == 1 : arg1 = cpu . read_register ( reg_name_l ) temp = ( Operators . SEXTEND ( arg0 , OperandSize , OperandSize * 2 ) * Operators . SEXTEND ( arg1 , OperandSize , OperandSize * 2 ) ) temp = temp & ( ( 1 << ( OperandSize * 2 ) ) - 1 ) cpu . write_register ( reg_name_l , Operators . EXTRACT ( temp , 0 , OperandSize ) ) cpu . write_register ( reg_name_h , Operators . EXTRACT ( temp , OperandSize , OperandSize ) ) res = Operators . EXTRACT ( temp , 0 , OperandSize ) elif len ( operands ) == 2 : arg1 = operands [ 1 ] . read ( ) arg1 = Operators . SEXTEND ( arg1 , OperandSize , OperandSize * 2 ) temp = Operators . SEXTEND ( arg0 , OperandSize , OperandSize * 2 ) * arg1 temp = temp & ( ( 1 << ( OperandSize * 2 ) ) - 1 ) res = dest . write ( Operators . EXTRACT ( temp , 0 , OperandSize ) ) else : arg1 = operands [ 1 ] . read ( ) arg2 = operands [ 2 ] . read ( ) temp = ( Operators . SEXTEND ( arg1 , OperandSize , OperandSize * 2 ) * Operators . SEXTEND ( arg2 , operands [ 2 ] . size , OperandSize * 2 ) ) temp = temp & ( ( 1 << ( OperandSize * 2 ) ) - 1 ) res = dest . write ( Operators . EXTRACT ( temp , 0 , OperandSize ) ) cpu . CF = ( Operators . SEXTEND ( res , OperandSize , OperandSize * 2 ) != temp ) cpu . OF = cpu . CF


def INC(cpu, dest):
        """
        Increments by 1.

        Adds 1 to the destination operand, while preserving the state of the
        CF flag. The destination operand can be a register or a memory location.
        This instruction allows a loop counter to be updated without disturbing
        the CF flag. (Use a ADD instruction with an immediate operand of 1 to
        perform an increment operation that does updates the CF flag.)::

                DEST  =  DEST +1;

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        arg0 = dest.read()
        res = dest.write(arg0 + 1)
        res &= (1 << dest.size) - 1
        SIGN_MASK = 1 << (dest.size - 1)
        cpu.AF = ((arg0 ^ 1) ^ res) & 0x10 != 0
        cpu.ZF = res == 0
        cpu.SF = (res & SIGN_MASK) != 0
        cpu.OF = res == SIGN_MASK
        cpu.PF = cpu._calculate_parity_flag(res)

def INC ( cpu , dest ) : arg0 = dest . read ( ) res = dest . write ( arg0 + 1 ) res &= ( 1 << dest . size ) - 1 SIGN_MASK = 1 << ( dest . size - 1 ) cpu . AF = ( ( arg0 ^ 1 ) ^ res ) & 0x10 != 0 cpu . ZF = res == 0 cpu . SF = ( res & SIGN_MASK ) != 0 cpu . OF = res == SIGN_MASK cpu . PF = cpu . _calculate_parity_flag ( res )


def MUL(cpu, src):
        """
        Unsigned multiply.

        Performs an unsigned multiplication of the first operand (destination
        operand) and the second operand (source operand) and stores the result
        in the destination operand. The destination operand is an implied operand
        located in register AL, AX or EAX (depending on the size of the operand);
        the source operand is located in a general-purpose register or a memory location.

        The result is stored in register AX, register pair DX:AX, or register
        pair EDX:EAX (depending on the operand size), with the high-order bits
        of the product contained in register AH, DX, or EDX, respectively. If
        the high-order bits of the product are 0, the CF and OF flags are cleared;
        otherwise, the flags are set::

                IF byte operation
                THEN
                    AX  =  AL * SRC
                ELSE (* word or doubleword operation *)
                    IF OperandSize  =  16
                    THEN
                        DX:AX  =  AX * SRC
                    ELSE (* OperandSize  =  32 *)
                        EDX:EAX  =  EAX * SRC
                    FI;
                FI;

        :param cpu: current CPU.
        :param src: source operand.
        """
        size = src.size
        reg_name_low, reg_name_high = {8: ('AL', 'AH'),
                                       16: ('AX', 'DX'),
                                       32: ('EAX', 'EDX'),
                                       64: ('RAX', 'RDX')}[size]
        res = (Operators.ZEXTEND(cpu.read_register(reg_name_low), 256) *
               Operators.ZEXTEND(src.read(), 256))
        cpu.write_register(reg_name_low, Operators.EXTRACT(res, 0, size))
        cpu.write_register(reg_name_high, Operators.EXTRACT(res, size, size))
        cpu.OF = Operators.EXTRACT(res, size, size) != 0
        cpu.CF = cpu.OF

def MUL ( cpu , src ) : size = src . size reg_name_low , reg_name_high = { 8 : ( 'AL' , 'AH' ) , 16 : ( 'AX' , 'DX' ) , 32 : ( 'EAX' , 'EDX' ) , 64 : ( 'RAX' , 'RDX' ) } [ size ] res = ( Operators . ZEXTEND ( cpu . read_register ( reg_name_low ) , 256 ) * Operators . ZEXTEND ( src . read ( ) , 256 ) ) cpu . write_register ( reg_name_low , Operators . EXTRACT ( res , 0 , size ) ) cpu . write_register ( reg_name_high , Operators . EXTRACT ( res , size , size ) ) cpu . OF = Operators . EXTRACT ( res , size , size ) != 0 cpu . CF = cpu . OF


def NEG(cpu, dest):
        """
        Two's complement negation.

        Replaces the value of operand (the destination operand) with its two's complement.
        (This operation is equivalent to subtracting the operand from 0.) The destination operand is
        located in a general-purpose register or a memory location::

                IF DEST  =  0
                THEN CF  =  0
                ELSE CF  =  1;
                FI;
                DEST  =  - (DEST)

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        source = dest.read()
        res = dest.write(-source)
        cpu._calculate_logic_flags(dest.size, res)
        cpu.CF = source != 0
        cpu.AF = (res & 0x0f) != 0x00

def NEG ( cpu , dest ) : source = dest . read ( ) res = dest . write ( - source ) cpu . _calculate_logic_flags ( dest . size , res ) cpu . CF = source != 0 cpu . AF = ( res & 0x0f ) != 0x00


def SBB(cpu, dest, src):
        """
        Integer subtraction with borrow.

        Adds the source operand (second operand) and the carry (CF) flag, and
        subtracts the result from the destination operand (first operand). The
        result of the subtraction is stored in the destination operand. The
        destination operand can be a register or a memory location; the source
        operand can be an immediate, a register, or a memory location.
        (However, two memory operands cannot be used in one instruction.) The
        state of the CF flag represents a borrow from a previous subtraction.
        When an immediate value is used as an operand, it is sign-extended to
        the length of the destination operand format.
        The SBB instruction does not distinguish between signed or unsigned
        operands. Instead, the processor evaluates the result for both data
        types and sets the OF and CF flags to indicate a borrow in the signed
        or unsigned result, respectively. The SF flag indicates the sign of the
        signed result.  The SBB instruction is usually executed as part of a
        multibyte or multiword subtraction in which a SUB instruction is
        followed by a SBB instruction::

                DEST  =  DEST - (SRC + CF);

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        cpu._SUB(dest, src, carry=True)

def SBB ( cpu , dest , src ) : cpu . _SUB ( dest , src , carry = True )


def XADD(cpu, dest, src):
        """
        Exchanges and adds.

        Exchanges the first operand (destination operand) with the second operand
        (source operand), then loads the sum of the two values into the destination
        operand. The destination operand can be a register or a memory location;
        the source operand is a register.
        This instruction can be used with a LOCK prefix::

                TEMP  =  SRC + DEST
                SRC  =  DEST
                DEST  =  TEMP

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        MASK = (1 << dest.size) - 1
        SIGN_MASK = 1 << (dest.size - 1)

        arg0 = dest.read()
        arg1 = src.read()
        temp = (arg1 + arg0) & MASK
        src.write(arg0)
        dest.write(temp)

        # Affected flags: oszapc
        tempCF = Operators.OR(Operators.ULT(temp, arg0), Operators.ULT(temp, arg1))
        cpu.CF = tempCF
        cpu.AF = ((arg0 ^ arg1) ^ temp) & 0x10 != 0
        cpu.ZF = temp == 0
        cpu.SF = (temp & SIGN_MASK) != 0
        cpu.OF = (((arg0 ^ arg1 ^ SIGN_MASK) & (temp ^ arg1)) & SIGN_MASK) != 0
        cpu.PF = cpu._calculate_parity_flag(temp)

def
XADD
(
cpu
,
dest
,
src
)
:
MASK
=
(
1
<<
dest
.
size
)
1
SIGN_MASK
=
1
<<
(
dest
.
size
1
)
arg0
=
dest
.
read
(
)
arg1
=
src
.
read
(
)
temp
=
(
arg1
+
arg0
)
&
MASK
src
.
write
(
arg0
)
dest
.
write
(
temp
)
# Affected flags: oszapc
tempCF
=
Operators
.
OR
(
Operators
.
ULT
(
temp
,
arg0
)
,
Operators
.
ULT
(
temp
,
arg1
)
)
cpu
.
CF
=
tempCF
cpu
.
AF
=
(
(
arg0
^
arg1
)
^
temp
)
&
0x10
!=
0
cpu
.
ZF
=
temp
==
0
cpu
.
SF
=
(
temp
&
SIGN_MASK
)
!=
0
cpu
.
OF
=
(
(
(
arg0
^
arg1
^
SIGN_MASK
)
&
(
temp
^
arg1
)
)
&
SIGN_MASK
)
!=
0
cpu
.
PF
=
cpu
.
_calculate_parity_flag
(
temp
)


def BSWAP(cpu, dest):
        """
        Byte swap.

        Reverses the byte order of a 32-bit (destination) register: bits 0 through
        7 are swapped with bits 24 through 31, and bits 8 through 15 are swapped
        with bits 16 through 23. This instruction is provided for converting little-endian
        values to big-endian format and vice versa.
        To swap bytes in a word value (16-bit register), use the XCHG instruction.
        When the BSWAP instruction references a 16-bit register, the result is
        undefined::

            TEMP  =  DEST
            DEST[7..0]  =  TEMP[31..24]
            DEST[15..8]  =  TEMP[23..16]
            DEST[23..16]  =  TEMP[15..8]
            DEST[31..24]  =  TEMP[7..0]

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        parts = []
        arg0 = dest.read()
        for i in range(0, dest.size, 8):
            parts.append(Operators.EXTRACT(arg0, i, 8))

        dest.write(Operators.CONCAT(8 * len(parts), *parts))

def BSWAP ( cpu , dest ) : parts = [ ] arg0 = dest . read ( ) for i in range ( 0 , dest . size , 8 ) : parts . append ( Operators . EXTRACT ( arg0 , i , 8 ) ) dest . write ( Operators . CONCAT ( 8 * len ( parts ) , * parts ) )


def CMOVG(cpu, dest, src):
        """
        Conditional move - Greater.

        Tests the status flags in the EFLAGS register and moves the source operand
        (second operand) to the destination operand (first operand) if the given
        test condition is true.

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        dest.write(Operators.ITEBV(dest.size, Operators.AND(cpu.ZF == 0, cpu.SF == cpu.OF), src.read(), dest.read()))

def CMOVG ( cpu , dest , src ) : dest . write ( Operators . ITEBV ( dest . size , Operators . AND ( cpu . ZF == 0 , cpu . SF == cpu . OF ) , src . read ( ) , dest . read ( ) ) )


def CMOVO(cpu, dest, src):
        """
        Conditional move - Overflow.

        Tests the status flags in the EFLAGS register and moves the source operand
        (second operand) to the destination operand (first operand) if the given
        test condition is true.

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        dest.write(Operators.ITEBV(dest.size, cpu.OF, src.read(), dest.read()))

def CMOVO ( cpu , dest , src ) : dest . write ( Operators . ITEBV ( dest . size , cpu . OF , src . read ( ) , dest . read ( ) ) )


def CMOVNO(cpu, dest, src):
        """
        Conditional move - Not overflow.

        Tests the status flags in the EFLAGS register and moves the source operand
        (second operand) to the destination operand (first operand) if the given
        test condition is true.

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        dest.write(Operators.ITEBV(dest.size, cpu.OF == False, src.read(), dest.read()))

def CMOVNO ( cpu , dest , src ) : dest . write ( Operators . ITEBV ( dest . size , cpu . OF == False , src . read ( ) , dest . read ( ) ) )


def LAHF(cpu):
        """
        Loads status flags into AH register.

        Moves the low byte of the EFLAGS register (which includes status flags
        SF, ZF, AF, PF, and CF) to the AH register. Reserved bits 1, 3, and 5
        of the EFLAGS register are set in the AH register::

                AH  =  EFLAGS(SF:ZF:0:AF:0:PF:1:CF);

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        used_regs = (cpu.SF, cpu.ZF, cpu.AF, cpu.PF, cpu.CF)
        is_expression = any(issymbolic(x) for x in used_regs)

        def make_flag(val, offset):
            if is_expression:
                return Operators.ITEBV(8, val,
                                       BitVecConstant(8, 1 << offset),
                                       BitVecConstant(8, 0))
            else:
                return val << offset

        cpu.AH = (make_flag(cpu.SF, 7) |
                  make_flag(cpu.ZF, 6) |
                  make_flag(0, 5) |
                  make_flag(cpu.AF, 4) |
                  make_flag(0, 3) |
                  make_flag(cpu.PF, 2) |
                  make_flag(1, 1) |
                  make_flag(cpu.CF, 0))

def LAHF ( cpu ) : used_regs = ( cpu . SF , cpu . ZF , cpu . AF , cpu . PF , cpu . CF ) is_expression = any ( issymbolic ( x ) for x in used_regs ) def make_flag ( val , offset ) : if is_expression : return Operators . ITEBV ( 8 , val , BitVecConstant ( 8 , 1 << offset ) , BitVecConstant ( 8 , 0 ) ) else : return val << offset cpu . AH = ( make_flag ( cpu . SF , 7 ) | make_flag ( cpu . ZF , 6 ) | make_flag ( 0 , 5 ) | make_flag ( cpu . AF , 4 ) | make_flag ( 0 , 3 ) | make_flag ( cpu . PF , 2 ) | make_flag ( 1 , 1 ) | make_flag ( cpu . CF , 0 ) )


def LEA(cpu, dest, src):
        """
        Loads effective address.

        Computes the effective address of the second operand (the source operand) and stores it in the first operand
        (destination operand). The source operand is a memory address (offset part) specified with one of the processors
        addressing modes; the destination operand is a general-purpose register. The address-size and operand-size
        attributes affect the action performed by this instruction. The operand-size
        attribute of the instruction is determined by the chosen register; the address-size attribute is determined by the
        attribute of the code segment.

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        dest.write(Operators.EXTRACT(src.address(), 0, dest.size))

def LEA ( cpu , dest , src ) : dest . write ( Operators . EXTRACT ( src . address ( ) , 0 , dest . size ) )


def MOVBE(cpu, dest, src):
        """
        Moves data after swapping bytes.

        Performs a byte swap operation on the data copied from the second operand (source operand) and store the result
        in the first operand (destination operand). The source operand can be a general-purpose register, or memory location; the destination register can be a general-purpose register, or a memory location; however, both operands can
        not be registers, and only one operand can be a memory location. Both operands must be the same size, which can
        be a word, a doubleword or quadword.
        The MOVBE instruction is provided for swapping the bytes on a read from memory or on a write to memory; thus
        providing support for converting little-endian values to big-endian format and vice versa.
        In 64-bit mode, the instruction's default operation size is 32 bits. Use of the REX.R prefix permits access to additional registers (R8-R15). Use of the REX.W prefix promotes operation to 64 bits::

                TEMP = SRC
                IF ( OperandSize = 16)
                THEN
                    DEST[7:0] = TEMP[15:8];
                    DEST[15:8] = TEMP[7:0];
                ELSE IF ( OperandSize = 32)
                    DEST[7:0] = TEMP[31:24];
                    DEST[15:8] = TEMP[23:16];
                    DEST[23:16] = TEMP[15:8];
                    DEST[31:23] = TEMP[7:0];
                ELSE IF ( OperandSize = 64)
                    DEST[7:0] = TEMP[63:56];
                    DEST[15:8] = TEMP[55:48];
                    DEST[23:16] = TEMP[47:40];
                    DEST[31:24] = TEMP[39:32];
                    DEST[39:32] = TEMP[31:24];
                    DEST[47:40] = TEMP[23:16];
                    DEST[55:48] = TEMP[15:8];
                    DEST[63:56] = TEMP[7:0];
                FI;

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        size = dest.size
        arg0 = dest.read()
        temp = 0
        for pos in range(0, size, 8):
            temp = (temp << 8) | (arg0 & 0xff)
            arg0 = arg0 >> 8
        dest.write(arg0)

def MOVBE ( cpu , dest , src ) : size = dest . size arg0 = dest . read ( ) temp = 0 for pos in range ( 0 , size , 8 ) : temp = ( temp << 8 ) | ( arg0 & 0xff ) arg0 = arg0 >> 8 dest . write ( arg0 )


def SAHF(cpu):
        """
        Stores AH into flags.

        Loads the SF, ZF, AF, PF, and CF flags of the EFLAGS register with values
        from the corresponding bits in the AH register (bits 7, 6, 4, 2, and 0,
        respectively). Bits 1, 3, and 5 of register AH are ignored; the corresponding
        reserved bits (1, 3, and 5) in the EFLAGS register remain as shown below::

                EFLAGS(SF:ZF:0:AF:0:PF:1:CF)  =  AH;

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """

        eflags_size = 32
        val = cpu.AH & 0xD5 | 0x02

        cpu.EFLAGS = Operators.ZEXTEND(val, eflags_size)

def SAHF ( cpu ) : eflags_size = 32 val = cpu . AH & 0xD5 | 0x02 cpu . EFLAGS = Operators . ZEXTEND ( val , eflags_size )


def SETA(cpu, dest):
        """
        Sets byte if above.

        Sets the destination operand to 0 or 1 depending on the settings of the status flags (CF, SF, OF, ZF, and PF, 1, 0) in the
        EFLAGS register. The destination operand points to a byte register or a byte in memory. The condition code suffix
        (cc, 1, 0) indicates the condition being tested for::
                IF condition
                THEN
                    DEST = 1;
                ELSE
                    DEST = 0;
                FI;

        :param cpu: current CPU.
        :param dest: destination operand.
         """
        dest.write(Operators.ITEBV(dest.size, Operators.OR(cpu.CF, cpu.ZF) == False, 1, 0))

def SETA ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , Operators . OR ( cpu . CF , cpu . ZF ) == False , 1 , 0 ) )


def SETB(cpu, dest):
        """
        Sets byte if below.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, cpu.CF, 1, 0))

def SETB ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , cpu . CF , 1 , 0 ) )


def SETBE(cpu, dest):
        """
        Sets byte if below or equal.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, Operators.OR(cpu.CF, cpu.ZF), 1, 0))

def SETBE ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , Operators . OR ( cpu . CF , cpu . ZF ) , 1 , 0 ) )


def SETC(cpu, dest):
        """
        Sets if carry.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, cpu.CF, 1, 0))

def SETC ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , cpu . CF , 1 , 0 ) )


def SETE(cpu, dest):
        """
        Sets byte if equal.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, cpu.ZF, 1, 0))

def SETE ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , cpu . ZF , 1 , 0 ) )


def SETGE(cpu, dest):
        """
        Sets byte if greater or equal.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, cpu.SF == cpu.OF, 1, 0))

def SETGE ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , cpu . SF == cpu . OF , 1 , 0 ) )


def SETNAE(cpu, dest):
        """
        Sets byte if not above or equal.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, cpu.CF, 1, 0))

def SETNAE ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , cpu . CF , 1 , 0 ) )


def SETNB(cpu, dest):
        """
        Sets byte if not below.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, cpu.CF == False, 1, 0))

def SETNB ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , cpu . CF == False , 1 , 0 ) )


def SETNBE(cpu, dest):
        """
        Sets byte if not below or equal.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, Operators.AND(cpu.CF == False, cpu.ZF == False), 1, 0))

def SETNBE ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , Operators . AND ( cpu . CF == False , cpu . ZF == False ) , 1 , 0 ) )


def SETNG(cpu, dest):
        """
        Sets byte if not greater.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, Operators.OR(cpu.ZF, cpu.SF != cpu.OF), 1, 0))

def SETNG ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , Operators . OR ( cpu . ZF , cpu . SF != cpu . OF ) , 1 , 0 ) )


def SETNLE(cpu, dest):
        """
        Sets byte if not less or equal.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, Operators.AND(cpu.ZF == False, cpu.SF == cpu.OF), 1, 0))

def SETNLE ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , Operators . AND ( cpu . ZF == False , cpu . SF == cpu . OF ) , 1 , 0 ) )


def SETNO(cpu, dest):
        """
        Sets byte if not overflow.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, cpu.OF == False, 1, 0))

def SETNO ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , cpu . OF == False , 1 , 0 ) )


def SETNS(cpu, dest):
        """
        Sets byte if not sign.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, cpu.SF == False, 1, 0))

def SETNS ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , cpu . SF == False , 1 , 0 ) )


def SETNZ(cpu, dest):
        """
        Sets byte if not zero.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, cpu.ZF == False, 1, 0))

def SETNZ ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , cpu . ZF == False , 1 , 0 ) )


def SETO(cpu, dest):
        """
        Sets byte if overflow.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, cpu.OF, 1, 0))

def SETO ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , cpu . OF , 1 , 0 ) )


def SETP(cpu, dest):
        """
        Sets byte if parity.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, cpu.PF, 1, 0))

def SETP ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , cpu . PF , 1 , 0 ) )


def SETPE(cpu, dest):
        """
        Sets byte if parity even.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, cpu.PF, 1, 0))

def SETPE ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , cpu . PF , 1 , 0 ) )


def SETPO(cpu, dest):
        """
        Sets byte if parity odd.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, cpu.PF == False, 1, 0))

def SETPO ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , cpu . PF == False , 1 , 0 ) )


def SETS(cpu, dest):
        """
        Sets byte if sign.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, cpu.SF, 1, 0))

def SETS ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , cpu . SF , 1 , 0 ) )


def SETZ(cpu, dest):
        """
        Sets byte if zero.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, cpu.ZF, 1, 0))

def SETZ ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , cpu . ZF , 1 , 0 ) )