def LEAVE(cpu):
        """
        High level procedure exit.

        Releases the stack frame set up by an earlier ENTER instruction. The
        LEAVE instruction copies the frame pointer (in the EBP register) into
        the stack pointer register (ESP), which releases the stack space allocated
        to the stack frame. The old frame pointer (the frame pointer for the calling
        procedure that was saved by the ENTER instruction) is then popped from
        the stack into the EBP register, restoring the calling procedure's stack
        frame.
        A RET instruction is commonly executed following a LEAVE instruction
        to return program control to the calling procedure::

                IF Stackaddress_bit_size  =  32
                THEN
                    ESP  =  EBP;
                ELSE (* Stackaddress_bit_size  =  16*)
                    SP  =  BP;
                FI;
                IF OperandSize  =  32
                THEN
                    EBP  =  Pop();
                ELSE (* OperandSize  =  16*)
                    BP  =  Pop();
                FI;

        :param cpu: current CPU.
        """
        cpu.STACK = cpu.FRAME
        cpu.FRAME = cpu.pop(cpu.address_bit_size)

def LEAVE ( cpu ) : cpu . STACK = cpu . FRAME cpu . FRAME = cpu . pop ( cpu . address_bit_size )


def PUSH(cpu, src):
        """
        Pushes a value onto the stack.

        Decrements the stack pointer and then stores the source operand on the top of the stack.

        :param cpu: current CPU.
        :param src: source operand.
        """
        # http://stackoverflow.com/questions/11291151/how-push-imm-encodes
        size = src.size
        v = src.read()
        if size != 64 and size != cpu.address_bit_size // 2:
            v = Operators.SEXTEND(v, size, cpu.address_bit_size)
            size = cpu.address_bit_size
        cpu.push(v, size)


def CALL(cpu, op0):
        """
        Procedure call.

        Saves procedure linking information on the stack and branches to the called procedure specified using the target
        operand. The target operand specifies the address of the first instruction in the called procedure. The operand can
        be an immediate value, a general-purpose register, or a memory location.

        :param cpu: current CPU.
        :param op0: target operand.
        """
        # TODO FIX 64Bit FIX segment
        proc = op0.read()
        cpu.push(cpu.PC, cpu.address_bit_size)
        cpu.PC = proc

def
CALL
(
cpu
,
op0
)
:
# TODO FIX 64Bit FIX segment
proc
=
op0
.
read
(
)
cpu
.
push
(
cpu
.
PC
,
cpu
.
address_bit_size
)
cpu
.
PC
=
proc


def RET(cpu, *operands):
        """
        Returns from procedure.

        Transfers program control to a return address located on the top of
        the stack. The address is usually placed on the stack by a CALL instruction,
        and the return is made to the instruction that follows the CALL instruction.
        The optional source operand specifies the number of stack bytes to be
        released after the return address is popped; the default is none.

        :param cpu: current CPU.
        :param operands: variable operands list.
        """
        # TODO FIX 64Bit FIX segment
        N = 0
        if len(operands) > 0:
            N = operands[0].read()
        cpu.PC = cpu.pop(cpu.address_bit_size)
        cpu.STACK += N

def
RET
(
cpu
,
*
operands
)
:
# TODO FIX 64Bit FIX segment
N
=
0
if
len
(
operands
)
>
0
:
N
=
operands
[
0
]
.
read
(
)
cpu
.
PC
=
cpu
.
pop
(
cpu
.
address_bit_size
)
cpu
.
STACK
+=
N


def JA(cpu, target):
        """
        Jumps short if above.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, Operators.AND(cpu.CF == False, cpu.ZF == False), target.read(), cpu.PC)

def JA ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , Operators . AND ( cpu . CF == False , cpu . ZF == False ) , target . read ( ) , cpu . PC )


def JB(cpu, target):
        """
        Jumps short if below.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, cpu.CF == True, target.read(), cpu.PC)

def JB ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , cpu . CF == True , target . read ( ) , cpu . PC )


def JBE(cpu, target):
        """
        Jumps short if below or equal.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, Operators.OR(cpu.CF, cpu.ZF), target.read(), cpu.PC)

def JBE ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , Operators . OR ( cpu . CF , cpu . ZF ) , target . read ( ) , cpu . PC )


def JC(cpu, target):
        """
        Jumps short if carry.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, cpu.CF, target.read(), cpu.PC)

def JC ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , cpu . CF , target . read ( ) , cpu . PC )


def JCXZ(cpu, target):
        """
        Jumps short if CX register is 0.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, cpu.CX == 0, target.read(), cpu.PC)

def JCXZ ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , cpu . CX == 0 , target . read ( ) , cpu . PC )


def JECXZ(cpu, target):
        """
        Jumps short if ECX register is 0.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, cpu.ECX == 0, target.read(), cpu.PC)

def JECXZ ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , cpu . ECX == 0 , target . read ( ) , cpu . PC )


def JRCXZ(cpu, target):
        """
        Jumps short if RCX register is 0.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, cpu.RCX == 0, target.read(), cpu.PC)

def JRCXZ ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , cpu . RCX == 0 , target . read ( ) , cpu . PC )


def JG(cpu, target):
        """
        Jumps short if greater.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, Operators.AND(cpu.ZF == False, cpu.SF == cpu.OF), target.read(), cpu.PC)

def JG ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , Operators . AND ( cpu . ZF == False , cpu . SF == cpu . OF ) , target . read ( ) , cpu . PC )


def JGE(cpu, target):
        """
        Jumps short if greater or equal.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, (cpu.SF == cpu.OF), target.read(), cpu.PC)

def JGE ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , ( cpu . SF == cpu . OF ) , target . read ( ) , cpu . PC )


def JNB(cpu, target):
        """
        Jumps short if not below.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, cpu.CF == False, target.read(), cpu.PC)

def JNB ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , cpu . CF == False , target . read ( ) , cpu . PC )


def JNE(cpu, target):
        """
        Jumps short if not equal.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, False == cpu.ZF, target.read(), cpu.PC)

def JNE ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , False == cpu . ZF , target . read ( ) , cpu . PC )


def JNG(cpu, target):
        """
        Jumps short if not greater.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, Operators.OR(cpu.ZF, cpu.SF != cpu.OF), target.read(), cpu.PC)

def JNG ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , Operators . OR ( cpu . ZF , cpu . SF != cpu . OF ) , target . read ( ) , cpu . PC )


def JNO(cpu, target):
        """
        Jumps short if not overflow.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, False == cpu.OF, target.read(), cpu.PC)

def JNO ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , False == cpu . OF , target . read ( ) , cpu . PC )


def JNP(cpu, target):
        """
        Jumps short if not parity.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, False == cpu.PF, target.read(), cpu.PC)

def JNP ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , False == cpu . PF , target . read ( ) , cpu . PC )


def JNS(cpu, target):
        """
        Jumps short if not sign.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, False == cpu.SF, target.read(), cpu.PC)

def JNS ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , False == cpu . SF , target . read ( ) , cpu . PC )


def JO(cpu, target):
        """
        Jumps short if overflow.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, cpu.OF, target.read(), cpu.PC)

def JO ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , cpu . OF , target . read ( ) , cpu . PC )


def JP(cpu, target):
        """
        Jumps short if parity.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, cpu.PF, target.read(), cpu.PC)

def JP ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , cpu . PF , target . read ( ) , cpu . PC )


def JS(cpu, target):
        """
        Jumps short if sign.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, cpu.SF, target.read(), cpu.PC)

def JS ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , cpu . SF , target . read ( ) , cpu . PC )


def JZ(cpu, target):
        """
        Jumps short if zero.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, cpu.ZF, target.read(), cpu.PC)

def JZ ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , cpu . ZF , target . read ( ) , cpu . PC )


def LJMP(cpu, cs_selector, target):
        """
        We are just going to ignore the CS selector for now.
        """
        logger.info("LJMP: Jumping to: %r:%r", cs_selector.read(), target.read())
        cpu.CS = cs_selector.read()
        cpu.PC = target.read()

def
LJMP
(
cpu
,
cs_selector
,
target
)
:
logger
.
info
(
"LJMP: Jumping to: %r:%r"
,
cs_selector
.
read
(
)
,
target
.
read
(
)
)
cpu
.
CS
=
cs_selector
.
read
(
)
cpu
.
PC
=
target
.
read
(
)

We are just going to ignore the CS selector for now .


def LOOP(cpu, dest):
        """
        Loops according to ECX counter.

        Performs a loop operation using the ECX or CX register as a counter.
        Each time the LOOP instruction is executed, the count register is decremented,
        then checked for 0. If the count is 0, the loop is terminated and program
        execution continues with the instruction following the LOOP instruction.
        If the count is not zero, a near jump is performed to the destination
        (target) operand, which is presumably the instruction at the beginning
        of the loop. If the address-size attribute is 32 bits, the ECX register
        is used as the count register; otherwise the CX register is used::

                IF address_bit_size  =  32
                THEN
                    Count is ECX;
                ELSE (* address_bit_size  =  16 *)
                    Count is CX;
                FI;
                Count  =  Count - 1;

                IF (Count  0)  =  1
                THEN
                    EIP  =  EIP + SignExtend(DEST);
                    IF OperandSize  =  16
                    THEN
                        EIP  =  EIP AND 0000FFFFH;
                    FI;
                ELSE
                    Terminate loop and continue program execution at EIP;
                FI;

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        counter_name = {16: 'CX', 32: 'ECX', 64: 'RCX'}[cpu.address_bit_size]
        counter = cpu.write_register(counter_name, cpu.read_register(counter_name) - 1)
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, counter == 0, (cpu.PC + dest.read()) & ((1 << dest.size) - 1), cpu.PC + cpu.instruction.size)

def LOOP ( cpu , dest ) : counter_name = { 16 : 'CX' , 32 : 'ECX' , 64 : 'RCX' } [ cpu . address_bit_size ] counter = cpu . write_register ( counter_name , cpu . read_register ( counter_name ) - 1 ) cpu . PC = Operators . ITEBV ( cpu . address_bit_size , counter == 0 , ( cpu . PC + dest . read ( ) ) & ( ( 1 << dest . size ) - 1 ) , cpu . PC + cpu . instruction . size )


def LOOPNZ(cpu, target):
        """
        Loops if ECX counter is nonzero.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        counter_name = {16: 'CX', 32: 'ECX', 64: 'RCX'}[cpu.address_bit_size]
        counter = cpu.write_register(counter_name, cpu.read_register(counter_name) - 1)
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, counter != 0, (cpu.PC + target.read()) & ((1 << target.size) - 1), cpu.PC + cpu.instruction.size)

def LOOPNZ ( cpu , target ) : counter_name = { 16 : 'CX' , 32 : 'ECX' , 64 : 'RCX' } [ cpu . address_bit_size ] counter = cpu . write_register ( counter_name , cpu . read_register ( counter_name ) - 1 ) cpu . PC = Operators . ITEBV ( cpu . address_bit_size , counter != 0 , ( cpu . PC + target . read ( ) ) & ( ( 1 << target . size ) - 1 ) , cpu . PC + cpu . instruction . size )


def RCL(cpu, dest, src):
        """
        Rotates through carry left.

        Shifts (rotates) the bits of the first operand (destination operand) the number of bit positions specified in the
        second operand (count operand) and stores the result in the destination operand. The destination operand can be
        a register or a memory location; the count operand is an unsigned integer that can be an immediate or a value in
        the CL register. In legacy and compatibility mode, the processor restricts the count to a number between 0 and 31
        by masking all the bits in the count operand except the 5 least-significant bits.

        The RCL instruction shifts the CF flag into the least-significant bit and shifts the most-significant bit into the CF flag.

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: count operand.
        """
        OperandSize = dest.size
        count = src.read()
        countMask = {8: 0x1f,
                     16: 0x1f,
                     32: 0x1f,
                     64: 0x3f}[OperandSize]
        tempCount = Operators.ZEXTEND((count & countMask) % (src.size + 1), OperandSize)

        value = dest.read()

        if isinstance(tempCount, int) and tempCount == 0:
            # this is a no-op
            new_val = value
            dest.write(new_val)
        else:
            carry = Operators.ITEBV(OperandSize, cpu.CF, 1, 0)
            right = value >> (OperandSize - tempCount)
            new_val = (value << tempCount) | (carry << (tempCount - 1)) | (right >> 1)
            dest.write(new_val)

            def sf(v, size):
                return (v & (1 << (size - 1))) != 0
            cpu.CF = sf(value << (tempCount - 1), OperandSize)
            cpu.OF = Operators.ITE(tempCount == 1,
                                   sf(new_val, OperandSize) != cpu.CF,
                                   cpu.OF)

def
RCL
(
cpu
,
dest
,
src
)
:
OperandSize
=
dest
.
size
count
=
src
.
read
(
)
countMask
=
{
8
:
0x1f
,
16
:
0x1f
,
32
:
0x1f
,
64
:
0x3f
}
[
OperandSize
]
tempCount
=
Operators
.
ZEXTEND
(
(
count
&
countMask
)
%
(
src
.
size
+
1
)
,
OperandSize
)
value
=
dest
.
read
(
)
if
isinstance
(
tempCount
,
int
)
and
tempCount
==
0
:
# this is a no-op
new_val
=
value
dest
.
write
(
new_val
)
else
:
carry
=
Operators
.
ITEBV
(
OperandSize
,
cpu
.
CF
,
1
,
0
)
right
=
value
>>
(
OperandSize
tempCount
)
new_val
=
(
value
<<
tempCount
)
|
(
carry
<<
(
tempCount
1
)
)
|
(
right
>>
1
)
dest
.
write
(
new_val
)
def
sf
(
v
,
size
)
:
return
(
v
&
(
1
<<
(
size
1
)
)
)
!=
0
cpu
.
CF
=
sf
(
value
<<
(
tempCount
1
)
,
OperandSize
)
cpu
.
OF
=
Operators
.
ITE
(
tempCount
==
1
,
sf
(
new_val
,
OperandSize
)
!=
cpu
.
CF
,
cpu
.
OF
)


def SAR(cpu, dest, src):
        """
        Shift arithmetic right.

        The shift arithmetic right (SAR) and shift logical right (SHR) instructions shift the bits of the destination operand to
        the right (toward less significant bit locations). For each shift count, the least significant bit of the destination
        operand is shifted into the CF flag, and the most significant bit is either set or cleared depending on the instruction
        type. The SHR instruction clears the most significant bit. the SAR instruction sets or clears the most significant bit
        to correspond to the sign (most significant bit) of the original value in the destination operand. In effect, the SAR
        instruction fills the empty bit position's shifted value with the sign of the unshifted value

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        OperandSize = dest.size
        countMask = {8: 0x1f,
                     16: 0x1f,
                     32: 0x1f,
                     64: 0x3f}[OperandSize]

        count = src.read() & countMask
        value = dest.read()

        res = Operators.SAR(OperandSize, value, Operators.ZEXTEND(count, OperandSize))
        dest.write(res)

        SIGN_MASK = (1 << (OperandSize - 1))

        # We can't use this one as the 'true' expression gets eagerly calculated even on count == 0		 +        cpu.CF = Operators.ITE(count!=0, ((value >> Operators.ZEXTEND(count-1, OperandSize)) & 1) !=0, cpu.CF)
        # cpu.CF = Operators.ITE(count!=0, ((value >> Operators.ZEXTEND(count-1, OperandSize)) & 1) !=0, cpu.CF)

        if issymbolic(count):
            # We can't use this one as the EXTRACT op needs the offset arguments to be concrete
            #    cpu.CF = Operators.ITE(count!=0, Operands.EXTRACT(value,count-1,1) !=0, cpu.CF)
            cpu.CF = Operators.ITE(Operators.AND(count != 0, count <= OperandSize), ((value >> Operators.ZEXTEND(count - 1, OperandSize)) & 1) != 0, cpu.CF)
        else:
            if count != 0:
                if count > OperandSize:
                    count = OperandSize
                cpu.CF = Operators.EXTRACT(value, count - 1, 1) != 0

        # on count == 0 AF is unaffected, for count > 0, AF is undefined.
        # in either case, do not touch AF
        cpu.ZF = Operators.ITE(count != 0, res == 0, cpu.ZF)
        cpu.SF = Operators.ITE(count != 0, (res & SIGN_MASK) != 0, cpu.SF)
        cpu.OF = Operators.ITE(count == 1, False, cpu.OF)
        cpu.PF = Operators.ITE(count != 0, cpu._calculate_parity_flag(res), cpu.PF)


def SHR(cpu, dest, src):
        """
        Shift logical right.

        The shift arithmetic right (SAR) and shift logical right (SHR)
        instructions shift the bits of the destination operand to the right
        (toward less significant bit locations). For each shift count, the
        least significant bit of the destination operand is shifted into the CF
        flag, and the most significant bit is either set or cleared depending
        on the instruction type. The SHR instruction clears the most
        significant bit.

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: count operand.
        """
        OperandSize = dest.size
        count = Operators.ZEXTEND(src.read() & (OperandSize - 1), OperandSize)
        value = dest.read()

        res = dest.write(value >> count)  # UNSIGNED Operators.UDIV2 !! TODO Check

        MASK = (1 << OperandSize) - 1
        SIGN_MASK = 1 << (OperandSize - 1)

        if issymbolic(count):
            cpu.CF = Operators.ITE(count != 0,
                                   ((value >> Operators.ZEXTEND(count - 1, OperandSize)) & 1) != 0,
                                   cpu.CF)
        else:
            if count != 0:
                cpu.CF = Operators.EXTRACT(value, count - 1, 1) != 0

        cpu.ZF = Operators.ITE(count != 0, res == 0, cpu.ZF)
        cpu.SF = Operators.ITE(count != 0, (res & SIGN_MASK) != 0, cpu.SF)
        # OF is only defined for count == 1, but in practice (unit tests from real cpu) it's calculated for count != 0
        cpu.OF = Operators.ITE(count != 0, ((value >> (OperandSize - 1)) & 0x1) == 1, cpu.OF)
        cpu.PF = Operators.ITE(count != 0, cpu._calculate_parity_flag(res), cpu.PF)


def SHLD(cpu, dest, src, count):
        """
        Double precision shift right.

        Shifts the first operand (destination operand) to the left the number of bits specified by the third operand
        (count operand). The second operand (source operand) provides bits to shift in from the right (starting with
        the least significant bit of the destination operand).

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        :param count: count operand
        """
        OperandSize = dest.size
        tempCount = Operators.ZEXTEND(count.read(), OperandSize) & (OperandSize - 1)
        arg0 = dest.read()
        arg1 = src.read()

        MASK = ((1 << OperandSize) - 1)
        t0 = (arg0 << tempCount)
        t1 = arg1 >> (OperandSize - tempCount)
        res = Operators.ITEBV(OperandSize, tempCount == 0, arg0, t0 | t1)
        res = res & MASK
        dest.write(res)
        if isinstance(tempCount, int) and tempCount == 0:
            pass
        else:
            SIGN_MASK = 1 << (OperandSize - 1)
            lastbit = 0 != ((arg0 << (tempCount - 1)) & SIGN_MASK)

            cpu._set_shiftd_flags(OperandSize, arg0, res, lastbit, tempCount)

def SHLD ( cpu , dest , src , count ) : OperandSize = dest . size tempCount = Operators . ZEXTEND ( count . read ( ) , OperandSize ) & ( OperandSize - 1 ) arg0 = dest . read ( ) arg1 = src . read ( ) MASK = ( ( 1 << OperandSize ) - 1 ) t0 = ( arg0 << tempCount ) t1 = arg1 >> ( OperandSize - tempCount ) res = Operators . ITEBV ( OperandSize , tempCount == 0 , arg0 , t0 | t1 ) res = res & MASK dest . write ( res ) if isinstance ( tempCount , int ) and tempCount == 0 : pass else : SIGN_MASK = 1 << ( OperandSize - 1 ) lastbit = 0 != ( ( arg0 << ( tempCount - 1 ) ) & SIGN_MASK ) cpu . _set_shiftd_flags ( OperandSize , arg0 , res , lastbit , tempCount )


def BSF(cpu, dest, src):
        """
        Bit scan forward.

        Searches the source operand (second operand) for the least significant
        set bit (1 bit). If a least significant 1 bit is found, its bit index
        is stored in the destination operand (first operand). The source operand
        can be a register or a memory location; the destination operand is a register.
        The bit index is an unsigned offset from bit 0 of the source operand.
        If the contents source operand are 0, the contents of the destination
        operand is undefined::

                    IF SRC  =  0
                    THEN
                        ZF  =  1;
                        DEST is undefined;
                    ELSE
                        ZF  =  0;
                        temp  =  0;
                        WHILE Bit(SRC, temp)  =  0
                        DO
                            temp  =  temp + 1;
                            DEST  =  temp;
                        OD;
                    FI;

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        value = src.read()
        flag = Operators.EXTRACT(value, 0, 1) == 1
        res = 0
        for pos in range(1, src.size):
            res = Operators.ITEBV(dest.size, flag, res, pos)
            flag = Operators.OR(flag, Operators.EXTRACT(value, pos, 1) == 1)

        cpu.ZF = value == 0
        dest.write(Operators.ITEBV(dest.size, cpu.ZF, dest.read(), res))

def BSF ( cpu , dest , src ) : value = src . read ( ) flag = Operators . EXTRACT ( value , 0 , 1 ) == 1 res = 0 for pos in range ( 1 , src . size ) : res = Operators . ITEBV ( dest . size , flag , res , pos ) flag = Operators . OR ( flag , Operators . EXTRACT ( value , pos , 1 ) == 1 ) cpu . ZF = value == 0 dest . write ( Operators . ITEBV ( dest . size , cpu . ZF , dest . read ( ) , res ) )


def BSR(cpu, dest, src):
        """
        Bit scan reverse.

        Searches the source operand (second operand) for the most significant
        set bit (1 bit). If a most significant 1 bit is found, its bit index is
        stored in the destination operand (first operand). The source operand
        can be a register or a memory location; the destination operand is a register.
        The bit index is an unsigned offset from bit 0 of the source operand.
        If the contents source operand are 0, the contents of the destination
        operand is undefined::

                IF SRC  =  0
                THEN
                    ZF  =  1;
                    DEST is undefined;
                ELSE
                    ZF  =  0;
                    temp  =  OperandSize - 1;
                    WHILE Bit(SRC, temp)  =  0
                    DO
                        temp  =  temp - 1;
                        DEST  =  temp;
                    OD;
                FI;

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        value = src.read()
        flag = Operators.EXTRACT(value, src.size - 1, 1) == 1
        res = 0

        for pos in reversed(range(0, src.size)):
            res = Operators.ITEBV(dest.size, flag, res, pos)
            flag = Operators.OR(flag, (Operators.EXTRACT(value, pos, 1) == 1))

        cpu.PF = cpu._calculate_parity_flag(res)
        cpu.ZF = value == 0
        dest.write(Operators.ITEBV(dest.size, cpu.ZF, dest.read(), res))

def BSR ( cpu , dest , src ) : value = src . read ( ) flag = Operators . EXTRACT ( value , src . size - 1 , 1 ) == 1 res = 0 for pos in reversed ( range ( 0 , src . size ) ) : res = Operators . ITEBV ( dest . size , flag , res , pos ) flag = Operators . OR ( flag , ( Operators . EXTRACT ( value , pos , 1 ) == 1 ) ) cpu . PF = cpu . _calculate_parity_flag ( res ) cpu . ZF = value == 0 dest . write ( Operators . ITEBV ( dest . size , cpu . ZF , dest . read ( ) , res ) )


def BT(cpu, dest, src):
        """
        Bit Test.

        Selects the bit in a bit string (specified with the first operand, called the bit base) at the
        bit-position designated by the bit offset (specified by the second operand) and stores the value
        of the bit in the CF flag. The bit base operand can be a register or a memory location; the bit
        offset operand can be a register or an immediate value:
            - If the bit base operand specifies a register, the instruction takes the modulo 16, 32, or 64
              of the bit offset operand (modulo size depends on the mode and register size; 64-bit operands
              are available only in 64-bit mode).
            - If the bit base operand specifies a memory location, the operand represents the address of the
              byte in memory that contains the bit base (bit 0 of the specified byte) of the bit string. The
              range of the bit position that can be referenced by the offset operand depends on the operand size.

        :param cpu: current CPU.
        :param dest: bit base.
        :param src: bit offset.
        """
        if dest.type == 'register':
            cpu.CF = ((dest.read() >> (src.read() % dest.size)) & 1) != 0
        elif dest.type == 'memory':
            addr, pos = cpu._getMemoryBit(dest, src)
            base, size, ty = cpu.get_descriptor(cpu.DS)
            value = cpu.read_int(addr + base, 8)
            cpu.CF = Operators.EXTRACT(value, pos, 1) == 1
        else:
            raise NotImplementedError(f"Unknown operand for BT: {dest.type}")

def
BT
(
cpu
,
dest
,
src
)
:
if
dest
.
type
==
'register'
:
cpu
.
CF
=
(
(
dest
.
read
(
)
>>
(
src
.
read
(
)
%
dest
.
size
)
)
&
1
)
!=
0
elif
dest
.
type
==
'memory'
:
addr
,
pos
=
cpu
.
_getMemoryBit
(
dest
,
src
)
base
,
size
,
ty
=
cpu
.
get_descriptor
(
cpu
.
DS
)
value
=
cpu
.
read_int
(
addr
+
base
,
8
)
cpu
.
CF
=
Operators
.
EXTRACT
(
value
,
pos
,
1
)
==
1
else
:
raise
NotImplementedError
(
f"Unknown operand for BT: {dest.type}"
)


def BTC(cpu, dest, src):
        """
        Bit test and complement.

        Selects the bit in a bit string (specified with the first operand, called
        the bit base) at the bit-position designated by the bit offset operand
        (second operand), stores the value of the bit in the CF flag, and complements
        the selected bit in the bit string.

        :param cpu: current CPU.
        :param dest: bit base operand.
        :param src: bit offset operand.
        """
        if dest.type == 'register':
            value = dest.read()
            pos = src.read() % dest.size
            cpu.CF = value & (1 << pos) == 1 << pos
            dest.write(value ^ (1 << pos))
        elif dest.type == 'memory':
            addr, pos = cpu._getMemoryBit(dest, src)
            base, size, ty = cpu.get_descriptor(cpu.DS)
            addr += base
            value = cpu.read_int(addr, 8)
            cpu.CF = value & (1 << pos) == 1 << pos
            value = value ^ (1 << pos)
            cpu.write_int(addr, value, 8)
        else:
            raise NotImplementedError(f"Unknown operand for BTC: {dest.type}")

def
BTC
(
cpu
,
dest
,
src
)
:
if
dest
.
type
==
'register'
:
value
=
dest
.
read
(
)
pos
=
src
.
read
(
)
%
dest
.
size
cpu
.
CF
=
value
&
(
1
<<
pos
)
==
1
<<
pos
dest
.
write
(
value
^
(
1
<<
pos
)
)
elif
dest
.
type
==
'memory'
:
addr
,
pos
=
cpu
.
_getMemoryBit
(
dest
,
src
)
base
,
size
,
ty
=
cpu
.
get_descriptor
(
cpu
.
DS
)
addr
+=
base
value
=
cpu
.
read_int
(
addr
,
8
)
cpu
.
CF
=
value
&
(
1
<<
pos
)
==
1
<<
pos
value
=
value
^
(
1
<<
pos
)
cpu
.
write_int
(
addr
,
value
,
8
)
else
:
raise
NotImplementedError
(
f"Unknown operand for BTC: {dest.type}"
)


def CMPS(cpu, dest, src):
        """
        Compares string operands.

        Compares the byte, word, double word or quad specified with the first source
        operand with the byte, word, double or quad word specified with the second
        source operand and sets the status flags in the EFLAGS register according
        to the results. Both the source operands are located in memory::

                temp  = SRC1 - SRC2;
                SetStatusFlags(temp);
                IF (byte comparison)
                THEN IF DF  =  0
                    THEN
                        (E)SI  =  (E)SI + 1;
                        (E)DI  =  (E)DI + 1;
                    ELSE
                        (E)SI  =  (E)SI - 1;
                        (E)DI  =  (E)DI - 1;
                    FI;
                ELSE IF (word comparison)
                    THEN IF DF  =  0
                        (E)SI  =  (E)SI + 2;
                        (E)DI  =  (E)DI + 2;
                    ELSE
                        (E)SI  =  (E)SI - 2;
                        (E)DI  =  (E)DI - 2;
                    FI;
                ELSE (* doubleword comparison*)
                    THEN IF DF  =  0
                        (E)SI  =  (E)SI + 4;
                        (E)DI  =  (E)DI + 4;
                    ELSE
                        (E)SI  =  (E)SI - 4;
                        (E)DI  =  (E)DI - 4;
                    FI;
                FI;

        :param cpu: current CPU.
        :param dest: first source operand.
        :param src: second source operand.
        """
        src_reg = {8: 'SI', 32: 'ESI', 64: 'RSI'}[cpu.address_bit_size]
        dest_reg = {8: 'DI', 32: 'EDI', 64: 'RDI'}[cpu.address_bit_size]

        base, _, ty = cpu.get_descriptor(cpu.DS)

        src_addr = cpu.read_register(src_reg) + base
        dest_addr = cpu.read_register(dest_reg) + base
        size = dest.size

        # Compare
        arg1 = cpu.read_int(dest_addr, size)
        arg0 = cpu.read_int(src_addr, size)
        res = (arg0 - arg1) & ((1 << size) - 1)

        cpu._calculate_CMP_flags(size, res, arg0, arg1)

        #Advance EDI/ESI pointers
        increment = Operators.ITEBV(cpu.address_bit_size, cpu.DF, -size // 8, size // 8)
        cpu.write_register(src_reg, cpu.read_register(src_reg) + increment)
        cpu.write_register(dest_reg, cpu.read_register(dest_reg) + increment)

def
CMPS
(
cpu
,
dest
,
src
)
:
src_reg
=
{
8
:
'SI'
,
32
:
'ESI'
,
64
:
'RSI'
}
[
cpu
.
address_bit_size
]
dest_reg
=
{
8
:
'DI'
,
32
:
'EDI'
,
64
:
'RDI'
}
[
cpu
.
address_bit_size
]
base
,
_
,
ty
=
cpu
.
get_descriptor
(
cpu
.
DS
)
src_addr
=
cpu
.
read_register
(
src_reg
)
+
base
dest_addr
=
cpu
.
read_register
(
dest_reg
)
+
base
size
=
dest
.
size
# Compare
arg1
=
cpu
.
read_int
(
dest_addr
,
size
)
arg0
=
cpu
.
read_int
(
src_addr
,
size
)
res
=
(
arg0
arg1
)
&
(
(
1
<<
size
)
1
)
cpu
.
_calculate_CMP_flags
(
size
,
res
,
arg0
,
arg1
)
#Advance EDI/ESI pointers
increment
=
Operators
.
ITEBV
(
cpu
.
address_bit_size
,
cpu
.
DF
,
size
//
8
,
size
//
8
)
cpu
.
write_register
(
src_reg
,
cpu
.
read_register
(
src_reg
)
+
increment
)
cpu
.
write_register
(
dest_reg
,
cpu
.
read_register
(
dest_reg
)
+
increment
)


def LODS(cpu, dest, src):
        """
        Loads string.

        Loads a byte, word, or doubleword from the source operand into the AL, AX, or EAX register, respectively. The
        source operand is a memory location, the address of which is read from the DS:ESI or the DS:SI registers
        (depending on the address-size attribute of the instruction, 32 or 16, respectively). The DS segment may be over-
        ridden with a segment override prefix.
        After the byte, word, or doubleword is transferred from the memory location into the AL, AX, or EAX register, the
        (E)SI register is incremented or decremented automatically according to the setting of the DF flag in the EFLAGS
        register. (If the DF flag is 0, the (E)SI register is incremented; if the DF flag is 1, the ESI register is decremented.)
        The (E)SI register is incremented or decremented by 1 for byte operations, by 2 for word operations, or by 4 for
        doubleword operations.

        :param cpu: current CPU.
        :param dest: source operand.
        """
        src_reg = {8: 'SI', 32: 'ESI', 64: 'RSI'}[cpu.address_bit_size]
        base, _, ty = cpu.get_descriptor(cpu.DS)

        src_addr = cpu.read_register(src_reg) + base
        size = dest.size

        arg0 = cpu.read_int(src_addr, size)
        dest.write(arg0)

        increment = Operators.ITEBV(cpu.address_bit_size, cpu.DF, -size // 8, size // 8)
        cpu.write_register(src_reg, cpu.read_register(src_reg) + increment)

def LODS ( cpu , dest , src ) : src_reg = { 8 : 'SI' , 32 : 'ESI' , 64 : 'RSI' } [ cpu . address_bit_size ] base , _ , ty = cpu . get_descriptor ( cpu . DS ) src_addr = cpu . read_register ( src_reg ) + base size = dest . size arg0 = cpu . read_int ( src_addr , size ) dest . write ( arg0 ) increment = Operators . ITEBV ( cpu . address_bit_size , cpu . DF , - size // 8 , size // 8 ) cpu . write_register ( src_reg , cpu . read_register ( src_reg ) + increment )


def MOVS(cpu, dest, src):
        """
        Moves data from string to string.

        Moves the byte, word, or doubleword specified with the second operand (source operand) to the location specified
        with the first operand (destination operand). Both the source and destination operands are located in memory. The
        address of the source operand is read from the DS:ESI or the DS:SI registers (depending on the address-size
        attribute of the instruction, 32 or 16, respectively). The address of the destination operand is read from the ES:EDI
        or the ES:DI registers (again depending on the address-size attribute of the instruction). The DS segment may be
        overridden with a segment override prefix, but the ES segment cannot be overridden.

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        base, size, ty = cpu.get_descriptor(cpu.DS)
        src_addr = src.address() + base
        dest_addr = dest.address() + base

        src_reg = src.mem.base
        dest_reg = dest.mem.base
        size = dest.size

        # Copy the data
        dest.write(src.read())

        #Advance EDI/ESI pointers
        increment = Operators.ITEBV(cpu.address_bit_size, cpu.DF, -size // 8, size // 8)
        cpu.write_register(src_reg, cpu.read_register(src_reg) + increment)
        cpu.write_register(dest_reg, cpu.read_register(dest_reg) + increment)

def
MOVS
(
cpu
,
dest
,
src
)
:
base
,
size
,
ty
=
cpu
.
get_descriptor
(
cpu
.
DS
)
src_addr
=
src
.
address
(
)
+
base
dest_addr
=
dest
.
address
(
)
+
base
src_reg
=
src
.
mem
.
base
dest_reg
=
dest
.
mem
.
base
size
=
dest
.
size
# Copy the data
dest
.
write
(
src
.
read
(
)
)
#Advance EDI/ESI pointers
increment
=
Operators
.
ITEBV
(
cpu
.
address_bit_size
,
cpu
.
DF
,
size
//
8
,
size
//
8
)
cpu
.
write_register
(
src_reg
,
cpu
.
read_register
(
src_reg
)
+
increment
)
cpu
.
write_register
(
dest_reg
,
cpu
.
read_register
(
dest_reg
)
+
increment
)


def SCAS(cpu, dest, src):
        """
        Scans String.

        Compares the byte, word, or double word specified with the memory operand
        with the value in the AL, AX, EAX, or RAX register, and sets the status flags
        according to the results. The memory operand address is read from either
        the ES:RDI, ES:EDI or the ES:DI registers (depending on the address-size
        attribute of the instruction, 32 or 16, respectively)::

                IF (byte comparison)
                THEN
                    temp  =  AL - SRC;
                    SetStatusFlags(temp);
                    THEN IF DF  =  0
                        THEN (E)DI  =  (E)DI + 1;
                        ELSE (E)DI  =  (E)DI - 1;
                        FI;
                    ELSE IF (word comparison)
                        THEN
                            temp  =  AX - SRC;
                            SetStatusFlags(temp)
                            THEN IF DF  =  0
                                THEN (E)DI  =  (E)DI + 2;
                                ELSE (E)DI  =  (E)DI - 2;
                                FI;
                     ELSE (* doubleword comparison *)
                           temp  =  EAX - SRC;
                           SetStatusFlags(temp)
                           THEN IF DF  =  0
                                THEN
                                    (E)DI  =  (E)DI + 4;
                                ELSE
                                    (E)DI  =  (E)DI - 4;
                                FI;
                           FI;
                     FI;

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        dest_reg = dest.reg
        mem_reg = src.mem.base  # , src.type, src.read()
        size = dest.size
        arg0 = dest.read()
        arg1 = src.read()
        res = arg0 - arg1
        cpu._calculate_CMP_flags(size, res, arg0, arg1)

        increment = Operators.ITEBV(cpu.address_bit_size, cpu.DF, -size // 8, size // 8)
        cpu.write_register(mem_reg, cpu.read_register(mem_reg) + increment)

def
SCAS
(
cpu
,
dest
,
src
)
:
dest_reg
=
dest
.
reg
mem_reg
=
src
.
mem
.
base
# , src.type, src.read()
size
=
dest
.
size
arg0
=
dest
.
read
(
)
arg1
=
src
.
read
(
)
res
=
arg0
arg1
cpu
.
_calculate_CMP_flags
(
size
,
res
,
arg0
,
arg1
)
increment
=
Operators
.
ITEBV
(
cpu
.
address_bit_size
,
cpu
.
DF
,
size
//
8
,
size
//
8
)
cpu
.
write_register
(
mem_reg
,
cpu
.
read_register
(
mem_reg
)
+
increment
)


def STOS(cpu, dest, src):
        """
        Stores String.

        Stores a byte, word, or doubleword from the AL, AX, or EAX register,
        respectively, into the destination operand. The destination operand is
        a memory location, the address of which is read from either the ES:EDI
        or the ES:DI registers (depending on the address-size attribute of the
        instruction, 32 or 16, respectively). The ES segment cannot be overridden
        with a segment override prefix.

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        size = src.size
        dest.write(src.read())
        dest_reg = dest.mem.base
        increment = Operators.ITEBV({'RDI': 64, 'EDI': 32, 'DI': 16}[dest_reg], cpu.DF, -size // 8, size // 8)
        cpu.write_register(dest_reg, cpu.read_register(dest_reg) + increment)

def STOS ( cpu , dest , src ) : size = src . size dest . write ( src . read ( ) ) dest_reg = dest . mem . base increment = Operators . ITEBV ( { 'RDI' : 64 , 'EDI' : 32 , 'DI' : 16 } [ dest_reg ] , cpu . DF , - size // 8 , size // 8 ) cpu . write_register ( dest_reg , cpu . read_register ( dest_reg ) + increment )


def SARX(cpu, dest, src, count):
        """
        The shift arithmetic right.

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: count operand.
        """
        OperandSize = dest.size
        count = count.read()
        countMask = {8: 0x1f,
                     16: 0x1f,
                     32: 0x1f,
                     64: 0x3f}[OperandSize]
        tempCount = count & countMask
        tempDest = value = src.read()

        sign = value & (1 << (OperandSize - 1))
        while tempCount != 0:
            cpu.CF = (value & 0x1) != 0  # LSB
            value = (value >> 1) | sign
            tempCount = tempCount - 1
        res = dest.write(value)

def
SARX
(
cpu
,
dest
,
src
,
count
)
:
OperandSize
=
dest
.
size
count
=
count
.
read
(
)
countMask
=
{
8
:
0x1f
,
16
:
0x1f
,
32
:
0x1f
,
64
:
0x3f
}
[
OperandSize
]
tempCount
=
count
&
countMask
tempDest
=
value
=
src
.
read
(
)
sign
=
value
&
(
1
<<
(
OperandSize
1
)
)
while
tempCount
!=
0
:
cpu
.
CF
=
(
value
&
0x1
)
!=
0
# LSB
value
=
(
value
>>
1
)
|
sign
tempCount
=
tempCount
1
res
=
dest
.
write
(
value
)


def PSHUFW(cpu, op0, op1, op3):
        """
        Packed shuffle words.

        Copies doublewords from source operand (second operand) and inserts them in the destination operand
        (first operand) at locations selected with the order operand (third operand).

        :param cpu: current CPU.
        :param op0: destination operand.
        :param op1: source operand.
        :param op3: order operand.
         """
        size = op0.size
        arg0 = op0.read()
        arg1 = op1.read()
        arg3 = Operators.ZEXTEND(op3.read(), size)
        assert size == 64
        arg0 |= ((arg1 >> ((arg3 >> 0) & 3 * 16)) & 0xffff)
        arg0 |= ((arg1 >> ((arg3 >> 2) & 3 * 16)) & 0xffff) << 16
        arg0 |= ((arg1 >> ((arg3 >> 4) & 3 * 16)) & 0xffff) << 32
        arg0 |= ((arg1 >> ((arg3 >> 6) & 3 * 16)) & 0xffff) << 48
        op0.write(arg0)


def PSHUFD(cpu, op0, op1, op3):
        """
        Packed shuffle doublewords.

        Copies doublewords from source operand (second operand) and inserts them in the destination operand
        (first operand) at locations selected with the order operand (third operand).

        :param cpu: current CPU.
        :param op0: destination operand.
        :param op1: source operand.
        :param op3: order operand.
         """
        size = op0.size
        arg0 = op0.read()
        arg1 = op1.read()
        order = Operators.ZEXTEND(op3.read(), size)

        arg0 = arg0 & 0xffffffffffffffffffffffffffffffff00000000000000000000000000000000
        arg0 |= ((arg1 >> (((order >> 0) & 3) * 32)) & 0xffffffff)
        arg0 |= ((arg1 >> (((order >> 2) & 3) * 32)) & 0xffffffff) << 32
        arg0 |= ((arg1 >> (((order >> 4) & 3) * 32)) & 0xffffffff) << 64
        arg0 |= ((arg1 >> (((order >> 6) & 3) * 32)) & 0xffffffff) << 96

        op0.write(arg0)


def PMOVMSKB(cpu, op0, op1):
        """
        Moves byte mask to general-purpose register.

        Creates an 8-bit mask made up of the most significant bit of each byte of the source operand
        (second operand) and stores the result in the low byte or word of the destination operand
        (first operand). The source operand is an MMX(TM) technology or an XXM register; the destination
        operand is a general-purpose register.

        :param cpu: current CPU.
        :param op0: destination operand.
        :param op1: source operand.
        """
        arg0 = op0.read()
        arg1 = op1.read()

        res = 0
        for i in reversed(range(7, op1.size, 8)):
            res = (res << 1) | ((arg1 >> i) & 1)
        op0.write(Operators.EXTRACT(res, 0, op0.size))

def PMOVMSKB ( cpu , op0 , op1 ) : arg0 = op0 . read ( ) arg1 = op1 . read ( ) res = 0 for i in reversed ( range ( 7 , op1 . size , 8 ) ) : res = ( res << 1 ) | ( ( arg1 >> i ) & 1 ) op0 . write ( Operators . EXTRACT ( res , 0 , op0 . size ) )

Moves byte mask to general - purpose register .


def PSRLDQ(cpu, dest, src):
        """
        Packed shift right logical double quadword.

        Shifts the destination operand (first operand) to the right by the number
        of bytes specified in the count operand (second operand). The empty high-order
        bytes are cleared (set to all 0s). If the value specified by the count
        operand is greater than 15, the destination operand is set to all 0s.
        The destination operand is an XMM register. The count operand is an 8-bit
        immediate::

            TEMP  =  SRC;
            if (TEMP > 15) TEMP  =  16;
            DEST  =  DEST >> (temp * 8);

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: count operand.
        """
        # TODO(yan): Verify the correctness of truncating SRC like this ( tests
        # use '-1' as the value
        temp = Operators.EXTRACT(src.read(), 0, 8)
        temp = Operators.ITEBV(src.size, temp > 15, 16, temp)
        dest.write(dest.read() >> (temp * 8))

Packed shift right logical double quadword .


def MOVZX(cpu, op0, op1):
        """
        Moves with zero-extend.

        Copies the contents of the source operand (register or memory location) to the destination
        operand (register) and zero extends the value to 16 or 32 bits. The size of the converted value
        depends on the operand-size attribute::

                OP0  =  ZeroExtend(OP1);

        :param cpu: current CPU.
        :param op0: destination operand.
        :param op1: source operand.
        """
        op0.write(Operators.ZEXTEND(op1.read(), op0.size))

def MOVZX ( cpu , op0 , op1 ) : op0 . write ( Operators . ZEXTEND ( op1 . read ( ) , op0 . size ) )


def MOVSX(cpu, op0, op1):
        """
        Moves with sign-extension.

        Copies the contents of the source operand (register or memory location) to the destination
        operand (register) and sign extends the value to 16::

                OP0  =  SignExtend(OP1);

        :param cpu: current CPU.
        :param op0: destination operand.
        :param op1: source operand.
        """
        op0.write(Operators.SEXTEND(op1.read(), op1.size, op0.size))

def MOVSX ( cpu , op0 , op1 ) : op0 . write ( Operators . SEXTEND ( op1 . read ( ) , op1 . size , op0 . size ) )


def CWDE(cpu):
        """
        Converts word to doubleword.

        ::
            DX = sign-extend of AX.

        :param cpu: current CPU.
        """
        bit = Operators.EXTRACT(cpu.AX, 15, 1)
        cpu.EAX = Operators.SEXTEND(cpu.AX, 16, 32)
        cpu.EDX = Operators.SEXTEND(bit, 1, 32)

def CWDE ( cpu ) : bit = Operators . EXTRACT ( cpu . AX , 15 , 1 ) cpu . EAX = Operators . SEXTEND ( cpu . AX , 16 , 32 ) cpu . EDX = Operators . SEXTEND ( bit , 1 , 32 )


def RDTSC(cpu):
        """
        Reads time-stamp counter.

        Loads the current value of the processor's time-stamp counter into the
        EDX:EAX registers.  The time-stamp counter is contained in a 64-bit
        MSR. The high-order 32 bits of the MSR are loaded into the EDX
        register, and the low-order 32 bits are loaded into the EAX register.
        The processor increments the time-stamp counter MSR every clock cycle
        and resets it to 0 whenever the processor is reset.

        :param cpu: current CPU.
        """
        val = cpu.icount
        cpu.RAX = val & 0xffffffff
        cpu.RDX = (val >> 32) & 0xffffffff

def RDTSC ( cpu ) : val = cpu . icount cpu . RAX = val & 0xffffffff cpu . RDX = ( val >> 32 ) & 0xffffffff


def MOVLPD(cpu, dest, src):
        """
        Moves low packed double-precision floating-point value.

        Moves a double-precision floating-point value from the source operand (second operand) and the
        destination operand (first operand). The source and destination operands can be an XMM register
        or a 64-bit memory location. This instruction allows double-precision floating-point values to be moved
        to and from the low quadword of an XMM register and memory. It cannot be used for register to register
        or memory to memory moves. When the destination operand is an XMM register, the high quadword of the
        register remains unchanged.

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        value = src.read()
        if src.size == 64 and dest.size == 128:
            value = (dest.read() & 0xffffffffffffffff0000000000000000) | Operators.ZEXTEND(value, 128)
        dest.write(value)

def MOVLPD ( cpu , dest , src ) : value = src . read ( ) if src . size == 64 and dest . size == 128 : value = ( dest . read ( ) & 0xffffffffffffffff0000000000000000 ) | Operators . ZEXTEND ( value , 128 ) dest . write ( value )

Moves low packed double - precision floating - point value .


def MOVHPD(cpu, dest, src):
        """
        Moves high packed double-precision floating-point value.

        Moves a double-precision floating-point value from the source operand (second operand) and the
        destination operand (first operand). The source and destination operands can be an XMM register
        or a 64-bit memory location. This instruction allows double-precision floating-point values to be moved
        to and from the high quadword of an XMM register and memory. It cannot be used for register to
        register or memory to memory moves. When the destination operand is an XMM register, the low quadword
        of the register remains unchanged.

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        if src.size == 128:
            assert dest.size == 64
            dest.write(Operators.EXTRACT(src.read(), 64, 64))
        else:
            assert src.size == 64 and dest.size == 128
            value = Operators.EXTRACT(dest.read(), 0, 64)  # low part
            dest.write(Operators.CONCAT(128, src.read(), value))

def
MOVHPD
(
cpu
,
dest
,
src
)
:
if
src
.
size
==
128
:
assert
dest
.
size
==
64
dest
.
write
(
Operators
.
EXTRACT
(
src
.
read
(
)
,
64
,
64
)
)
else
:
assert
src
.
size
==
64
and
dest
.
size
==
128
value
=
Operators
.
EXTRACT
(
dest
.
read
(
)
,
0
,
64
)
# low part
dest
.
write
(
Operators
.
CONCAT
(
128
,
src
.
read
(
)
,
value
)
)

Moves high packed double - precision floating - point value .


def PSUBB(cpu, dest, src):
        """
        Packed subtract.

        Performs a SIMD subtract of the packed integers of the source operand (second operand) from the packed
        integers of the destination operand (first operand), and stores the packed integer results in the
        destination operand. The source operand can be an MMX(TM) technology register or a 64-bit memory location,
        or it can be an XMM register or a 128-bit memory location. The destination operand can be an MMX or an XMM
        register.
        The PSUBB instruction subtracts packed byte integers. When an individual result is too large or too small
        to be represented in a byte, the result is wrapped around and the low 8 bits are written to the
        destination element.

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        result = []
        value_a = dest.read()
        value_b = src.read()
        for i in reversed(range(0, dest.size, 8)):
            a = Operators.EXTRACT(value_a, i, 8)
            b = Operators.EXTRACT(value_b, i, 8)
            result.append((a - b) & 0xff)
        dest.write(Operators.CONCAT(8 * len(result), *result))

def PSUBB ( cpu , dest , src ) : result = [ ] value_a = dest . read ( ) value_b = src . read ( ) for i in reversed ( range ( 0 , dest . size , 8 ) ) : a = Operators . EXTRACT ( value_a , i , 8 ) b = Operators . EXTRACT ( value_b , i , 8 ) result . append ( ( a - b ) & 0xff ) dest . write ( Operators . CONCAT ( 8 * len ( result ) , * result ) )


def MOVQ(cpu, dest, src):
        """
        Move quadword.

        Copies a quadword from the source operand (second operand) to the destination operand (first operand).
        The source and destination operands can be MMX(TM) technology registers, XMM registers, or 64-bit memory
        locations. This instruction can be used to move a between two MMX registers or between an MMX register
        and a 64-bit memory location, or to move data between two XMM registers or between an XMM register and
        a 64-bit memory location. The instruction cannot be used to transfer data between memory locations.
        When the source operand is an XMM register, the low quadword is moved; when the destination operand is
        an XMM register, the quadword is stored to the low quadword of the register, and the high quadword is
        cleared to all 0s::

            MOVQ instruction when operating on MMX registers and memory locations:

            DEST  =  SRC;

            MOVQ instruction when source and destination operands are XMM registers:

            DEST[63-0]  =  SRC[63-0];

            MOVQ instruction when source operand is XMM register and destination operand is memory location:

            DEST  =  SRC[63-0];

            MOVQ instruction when source operand is memory location and destination operand is XMM register:

            DEST[63-0]  =  SRC;
            DEST[127-64]  =  0000000000000000H;

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        # mmx to mmx or mmx to mem
        if dest.size == src.size and dest.size == 64:
            dest.write(src.read())
        # two xmm regs
        elif dest.size == src.size and dest.size == 128:
            src_lo = Operators.EXTRACT(src.read(), 0, 64)
            dest.write(Operators.ZEXTEND(src_lo, 128))
        # mem to xmm
        elif dest.size == 128 and src.size == 64:
            dest.write(Operators.ZEXTEND(src.read(), dest.size))
        # xmm to mem
        elif dest.size == 64 and src.size == 128:
            dest.write(Operators.EXTRACT(src.read(), 0, dest.size))
        else:
            msg = 'Invalid size in MOVQ'
            logger.error(msg)
            raise Exception(msg)

def
MOVQ
(
cpu
,
dest
,
src
)
:
# mmx to mmx or mmx to mem
if
dest
.
size
==
src
.
size
and
dest
.
size
==
64
:
dest
.
write
(
src
.
read
(
)
)
# two xmm regs
elif
dest
.
size
==
src
.
size
and
dest
.
size
==
128
:
src_lo
=
Operators
.
EXTRACT
(
src
.
read
(
)
,
0
,
64
)
dest
.
write
(
Operators
.
ZEXTEND
(
src_lo
,
128
)
)
# mem to xmm
elif
dest
.
size
==
128
and
src
.
size
==
64
:
dest
.
write
(
Operators
.
ZEXTEND
(
src
.
read
(
)
,
dest
.
size
)
)
# xmm to mem
elif
dest
.
size
==
64
and
src
.
size
==
128
:
dest
.
write
(
Operators
.
EXTRACT
(
src
.
read
(
)
,
0
,
dest
.
size
)
)
else
:
msg
=
'Invalid size in MOVQ'
logger
.
error
(
msg
)
raise
Exception
(
msg
)


def MOVSD(cpu, dest, src):
        """
        Move Scalar Double-Precision Floating-Point Value

        Moves a scalar double-precision floating-point value from the source
        operand (second operand) to the destination operand (first operand).
        The source and destination operands can be XMM registers or 64-bit memory
        locations. This instruction can be used to move a double-precision
        floating-point value to and from the low quadword of an XMM register and
        a 64-bit memory location, or to move a double-precision floating-point
        value between the low quadwords of two XMM registers. The instruction
        cannot be used to transfer data between memory locations.
        When the source and destination operands are XMM registers, the high
        quadword of the destination operand remains unchanged. When the source
        operand is a memory location and destination operand is an XMM registers,
        the high quadword of the destination operand is cleared to all 0s.

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        assert dest.type != 'memory' or src.type != 'memory'
        value = Operators.EXTRACT(src.read(), 0, 64)
        if dest.size > src.size:
            value = Operators.ZEXTEND(value, dest.size)
        dest.write(value)

def MOVSD ( cpu , dest , src ) : assert dest . type != 'memory' or src . type != 'memory' value = Operators . EXTRACT ( src . read ( ) , 0 , 64 ) if dest . size > src . size : value = Operators . ZEXTEND ( value , dest . size ) dest . write ( value )

Move Scalar Double - Precision Floating - Point Value


def MOVSS(cpu, dest, src):
        """
        Moves a scalar single-precision floating-point value

        Moves a scalar single-precision floating-point value from the source operand (second operand)
        to the destination operand (first operand). The source and destination operands can be XMM
        registers or 32-bit memory locations. This instruction can be used to move a single-precision
        floating-point value to and from the low doubleword of an XMM register and a 32-bit memory
        location, or to move a single-precision floating-point value between the low doublewords of
        two XMM registers. The instruction cannot be used to transfer data between memory locations.
        When the source and destination operands are XMM registers, the three high-order doublewords of the
        destination operand remain unchanged. When the source operand is a memory location and destination
        operand is an XMM registers, the three high-order doublewords of the destination operand are cleared to all 0s.

        //MOVSS instruction when source and destination operands are XMM registers:
        if(IsXMM(Source) && IsXMM(Destination))
            Destination[0..31] = Source[0..31];
            //Destination[32..127] remains unchanged
            //MOVSS instruction when source operand is XMM register and destination operand is memory location:
        else if(IsXMM(Source) && IsMemory(Destination))
            Destination = Source[0..31];
        //MOVSS instruction when source operand is memory location and destination operand is XMM register:
        else {
                Destination[0..31] = Source;
                Destination[32..127] = 0;
        }
        """
        if dest.type == 'register' and src.type == 'register':
            assert dest.size == 128 and src.size == 128
            dest.write(dest.read() & ~0xffffffff | src.read() & 0xffffffff)
        elif dest.type == 'memory':
            assert src.type == 'register'
            dest.write(Operators.EXTRACT(src.read(), 0, dest.size))
        else:
            assert src.type == 'memory' and dest.type == 'register'
            assert src.size == 32 and dest.size == 128
            dest.write(Operators.ZEXTEND(src.read(), 128))

def MOVSS ( cpu , dest , src ) : if dest . type == 'register' and src . type == 'register' : assert dest . size == 128 and src . size == 128 dest . write ( dest . read ( ) & ~ 0xffffffff | src . read ( ) & 0xffffffff ) elif dest . type == 'memory' : assert src . type == 'register' dest . write ( Operators . EXTRACT ( src . read ( ) , 0 , dest . size ) ) else : assert src . type == 'memory' and dest . type == 'register' assert src . size == 32 and dest . size == 128 dest . write ( Operators . ZEXTEND ( src . read ( ) , 128 ) )

Moves a scalar single - precision floating - point value


def VEXTRACTF128(cpu, dest, src, offset):
        """Extract Packed Floating-Point Values

        Extracts 128-bits of packed floating-point values from the source
        operand (second operand) at an 128-bit offset from imm8[0] into the
        destination operand (first operand). The destination may be either an
        XMM register or an 128-bit memory location.
        """
        offset = offset.read()
        dest.write(Operators.EXTRACT(src.read(), offset * 128, (offset + 1) * 128))

def VEXTRACTF128 ( cpu , dest , src , offset ) : offset = offset . read ( ) dest . write ( Operators . EXTRACT ( src . read ( ) , offset * 128 , ( offset + 1 ) * 128 ) )


def PSRLQ(cpu, dest, src):
        """Shift Packed Data Right Logical

        Shifts the bits in the individual quadword in the destination operand to the right by
        the number of bits specified in the count operand . As the bits in the data elements
        are shifted right, the empty high-order bits are cleared (set to 0). If the value
        specified by the count operand is greater than  63, then the destination operand is set
        to all 0s.

        if(OperandSize == 64) {
                        //PSRLQ instruction with 64-bit operand:
                        if(Count > 63) Destination[64..0] = 0;
                        else Destination = ZeroExtend(Destination >> Count);
                }
                else {
                        //PSRLQ instruction with 128-bit operand:
                        if(Count > 15) Destination[128..0] = 0;
                        else {
                                Destination[0..63] = ZeroExtend(Destination[0..63] >> Count);
                                Destination[64..127] = ZeroExtend(Destination[64..127] >> Count);
                        }
                }
        """

        count = src.read()
        count = Operators.ITEBV(src.size, Operators.UGT(count, 63), 64, count)
        count = Operators.EXTRACT(count, 0, 64)
        if dest.size == 64:
            dest.write(dest.read() >> count)
        else:
            hi = Operators.EXTRACT(dest.read(), 64, 64) >> count
            low = Operators.EXTRACT(dest.read(), 0, 64) >> count
            dest.write(Operators.CONCAT(128, hi, low))

def PSRLQ ( cpu , dest , src ) : count = src . read ( ) count = Operators . ITEBV ( src . size , Operators . UGT ( count , 63 ) , 64 , count ) count = Operators . EXTRACT ( count , 0 , 64 ) if dest . size == 64 : dest . write ( dest . read ( ) >> count ) else : hi = Operators . EXTRACT ( dest . read ( ) , 64 , 64 ) >> count low = Operators . EXTRACT ( dest . read ( ) , 0 , 64 ) >> count dest . write ( Operators . CONCAT ( 128 , hi , low ) )


def constrain(self, constraint):
        """Constrain state.

        :param manticore.core.smtlib.Bool constraint: Constraint to add
        """
        constraint = self.migrate_expression(constraint)
        self._constraints.add(constraint)

def constrain ( self , constraint ) : constraint = self . migrate_expression ( constraint ) self . _constraints . add ( constraint )


def new_symbolic_buffer(self, nbytes, **options):
        """Create and return a symbolic buffer of length `nbytes`. The buffer is
        not written into State's memory; write it to the state's memory to
        introduce it into the program state.

        :param int nbytes: Length of the new buffer
        :param str label: (keyword arg only) The label to assign to the buffer
        :param bool cstring: (keyword arg only) Whether or not to enforce that the buffer is a cstring
                 (i.e. no NULL bytes, except for the last byte). (bool)
        :param taint: Taint identifier of the new buffer
        :type taint: tuple or frozenset

        :return: :class:`~manticore.core.smtlib.expression.Expression` representing the buffer.
        """
        label = options.get('label')
        avoid_collisions = False
        if label is None:
            label = 'buffer'
            avoid_collisions = True
        taint = options.get('taint', frozenset())
        expr = self._constraints.new_array(name=label, index_max=nbytes, value_bits=8, taint=taint, avoid_collisions=avoid_collisions)
        self._input_symbols.append(expr)

        if options.get('cstring', False):
            for i in range(nbytes - 1):
                self._constraints.add(expr[i] != 0)

        return expr

def new_symbolic_buffer ( self , nbytes , * * options ) : label = options . get ( 'label' ) avoid_collisions = False if label is None : label = 'buffer' avoid_collisions = True taint = options . get ( 'taint' , frozenset ( ) ) expr = self . _constraints . new_array ( name = label , index_max = nbytes , value_bits = 8 , taint = taint , avoid_collisions = avoid_collisions ) self . _input_symbols . append ( expr ) if options . get ( 'cstring' , False ) : for i in range ( nbytes - 1 ) : self . _constraints . add ( expr [ i ] != 0 ) return expr

Create and return a symbolic buffer of length nbytes . The buffer is not written into State s memory ; write it to the state s memory to introduce it into the program state .


def new_symbolic_value(self, nbits, label=None, taint=frozenset()):
        """Create and return a symbolic value that is `nbits` bits wide. Assign
        the value to a register or write it into the address space to introduce
        it into the program state.

        :param int nbits: The bitwidth of the value returned
        :param str label: The label to assign to the value
        :param taint: Taint identifier of this value
        :type taint: tuple or frozenset
        :return: :class:`~manticore.core.smtlib.expression.Expression` representing the value
        """
        assert nbits in (1, 4, 8, 16, 32, 64, 128, 256)
        avoid_collisions = False
        if label is None:
            label = 'val'
            avoid_collisions = True

        expr = self._constraints.new_bitvec(nbits, name=label, taint=taint, avoid_collisions=avoid_collisions)
        self._input_symbols.append(expr)
        return expr

def new_symbolic_value ( self , nbits , label = None , taint = frozenset ( ) ) : assert nbits in ( 1 , 4 , 8 , 16 , 32 , 64 , 128 , 256 ) avoid_collisions = False if label is None : label = 'val' avoid_collisions = True expr = self . _constraints . new_bitvec ( nbits , name = label , taint = taint , avoid_collisions = avoid_collisions ) self . _input_symbols . append ( expr ) return expr

Create and return a symbolic value that is nbits bits wide . Assign the value to a register or write it into the address space to introduce it into the program state .


def concretize(self, symbolic, policy, maxcount=7):
        """ This finds a set of solutions for symbolic using policy.
            This raises TooManySolutions if more solutions than maxcount
        """
        assert self.constraints == self.platform.constraints
        symbolic = self.migrate_expression(symbolic)

        vals = []
        if policy == 'MINMAX':
            vals = self._solver.minmax(self._constraints, symbolic)
        elif policy == 'MAX':
            vals = self._solver.max(self._constraints, symbolic)
        elif policy == 'MIN':
            vals = self._solver.min(self._constraints, symbolic)
        elif policy == 'SAMPLED':
            m, M = self._solver.minmax(self._constraints, symbolic)
            vals += [m, M]
            if M - m > 3:
                if self._solver.can_be_true(self._constraints, symbolic == (m + M) // 2):
                    vals.append((m + M) // 2)
            if M - m > 100:
                for i in (0, 1, 2, 5, 32, 64, 128, 320):
                    if self._solver.can_be_true(self._constraints, symbolic == m + i):
                        vals.append(m + i)
                    if maxcount <= len(vals):
                        break
            if M - m > 1000 and maxcount > len(vals):
                vals += self._solver.get_all_values(self._constraints, symbolic,
                                                    maxcnt=maxcount - len(vals), silent=True)
        elif policy == 'ONE':
            vals = [self._solver.get_value(self._constraints, symbolic)]
        else:
            assert policy == 'ALL'
            vals = solver.get_all_values(self._constraints, symbolic, maxcnt=maxcount, silent=True)

        return tuple(set(vals))

def concretize ( self , symbolic , policy , maxcount = 7 ) : assert self . constraints == self . platform . constraints symbolic = self . migrate_expression ( symbolic ) vals = [ ] if policy == 'MINMAX' : vals = self . _solver . minmax ( self . _constraints , symbolic ) elif policy == 'MAX' : vals = self . _solver . max ( self . _constraints , symbolic ) elif policy == 'MIN' : vals = self . _solver . min ( self . _constraints , symbolic ) elif policy == 'SAMPLED' : m , M = self . _solver . minmax ( self . _constraints , symbolic ) vals += [ m , M ] if M - m > 3 : if self . _solver . can_be_true ( self . _constraints , symbolic == ( m + M ) // 2 ) : vals . append ( ( m + M ) // 2 ) if M - m > 100 : for i in ( 0 , 1 , 2 , 5 , 32 , 64 , 128 , 320 ) : if self . _solver . can_be_true ( self . _constraints , symbolic == m + i ) : vals . append ( m + i ) if maxcount <= len ( vals ) : break if M - m > 1000 and maxcount > len ( vals ) : vals += self . _solver . get_all_values ( self . _constraints , symbolic , maxcnt = maxcount - len ( vals ) , silent = True ) elif policy == 'ONE' : vals = [ self . _solver . get_value ( self . _constraints , symbolic ) ] else : assert policy == 'ALL' vals = solver . get_all_values ( self . _constraints , symbolic , maxcnt = maxcount , silent = True ) return tuple ( set ( vals ) )

This finds a set of solutions for symbolic using policy . This raises TooManySolutions if more solutions than maxcount


def solve_buffer(self, addr, nbytes, constrain=False):
        """
        Reads `nbytes` of symbolic data from a buffer in memory at `addr` and attempts to
        concretize it

        :param int address: Address of buffer to concretize
        :param int nbytes: Size of buffer to concretize
        :param bool constrain: If True, constrain the buffer to the concretized value
        :return: Concrete contents of buffer
        :rtype: list[int]
        """
        buffer = self.cpu.read_bytes(addr, nbytes)
        result = []
        with self._constraints as temp_cs:
            cs_to_use = self.constraints if constrain else temp_cs
            for c in buffer:
                result.append(self._solver.get_value(cs_to_use, c))
                cs_to_use.add(c == result[-1])
        return result

def solve_buffer ( self , addr , nbytes , constrain = False ) : buffer = self . cpu . read_bytes ( addr , nbytes ) result = [ ] with self . _constraints as temp_cs : cs_to_use = self . constraints if constrain else temp_cs for c in buffer : result . append ( self . _solver . get_value ( cs_to_use , c ) ) cs_to_use . add ( c == result [ - 1 ] ) return result

Reads nbytes of symbolic data from a buffer in memory at addr and attempts to concretize it


def _hook_xfer_mem(self, uc, access, address, size, value, data):
        """
        Handle memory operations from unicorn.
        """
        assert access in (UC_MEM_WRITE, UC_MEM_READ, UC_MEM_FETCH)

        if access == UC_MEM_WRITE:
            self._cpu.write_int(address, value, size * 8)

        # If client code is attempting to read a value, we need to bring it
        # in from Manticore state. If we try to mem_write it here, Unicorn
        # will segfault. We add the value to a list of things that need to
        # be written, and ask to restart the emulation.
        elif access == UC_MEM_READ:
            value = self._cpu.read_bytes(address, size)

            if address in self._should_be_written:
                return True

            self._should_be_written[address] = value

            self._should_try_again = True
            return False

        return True


def emulate(self, instruction):
        """
        Emulate a single instruction.
        """

        # The emulation might restart if Unicorn needs to bring in a memory map
        # or bring a value from Manticore state.
        while True:

            self.reset()

            # Establish Manticore state, potentially from past emulation
            # attempts
            for base in self._should_be_mapped:
                size, perms = self._should_be_mapped[base]
                self._emu.mem_map(base, size, perms)

            for address, values in self._should_be_written.items():
                for offset, byte in enumerate(values, start=address):
                    if issymbolic(byte):
                        from ..native.cpu.abstractcpu import ConcretizeMemory
                        raise ConcretizeMemory(self._cpu.memory, offset, 8,
                                               "Concretizing for emulation")

                self._emu.mem_write(address, b''.join(values))

            # Try emulation
            self._should_try_again = False

            self._step(instruction)

            if not self._should_try_again:
                break


def must_be_true(self, constraints, expression) -> bool:
        """Check if expression is True and that it can not be False with current constraints"""
        solutions = self.get_all_values(constraints, expression, maxcnt=2, silent=True)
        return solutions == [True]

def must_be_true ( self , constraints , expression ) -> bool : solutions = self . get_all_values ( constraints , expression , maxcnt = 2 , silent = True ) return solutions == [ True ]


def min(self, constraints, X: BitVec, M=10000):
        """
        Iteratively finds the minimum value for a symbol within given constraints.

        :param constraints: constraints that the expression must fulfil
        :param X: a symbol or expression
        :param M: maximum number of iterations allowed
        """
        assert isinstance(X, BitVec)
        return self.optimize(constraints, X, 'minimize', M)

def min ( self , constraints , X : BitVec , M = 10000 ) : assert isinstance ( X , BitVec ) return self . optimize ( constraints , X , 'minimize' , M )

Iteratively finds the minimum value for a symbol within given constraints .


def minmax(self, constraints, x, iters=10000):
        """Returns the min and max possible values for x within given constraints"""
        if issymbolic(x):
            m = self.min(constraints, x, iters)
            M = self.max(constraints, x, iters)
            return m, M
        else:
            return x, x

def minmax ( self , constraints , x , iters = 10000 ) : if issymbolic ( x ) : m = self . min ( constraints , x , iters ) M = self . max ( constraints , x , iters ) return m , M else : return x , x


def _solver_version(self) -> Version:
        """
        If we fail to parse the version, we assume z3's output has changed, meaning it's a newer
        version than what's used now, and therefore ok.

        Anticipated version_cmd_output format: 'Z3 version 4.4.2'
                                               'Z3 version 4.4.5 - 64 bit - build hashcode $Z3GITHASH'
        """
        self._reset()
        if self._received_version is None:
            self._send('(get-info :version)')
            self._received_version = self._recv()
        key, version = shlex.split(self._received_version[1:-1])
        return Version(*map(int, version.split('.')))

def
_solver_version
(
self
)
->
Version
:
self
.
_reset
(
)
if
self
.
_received_version
is
:
self
.
_send
(
'(get-info :version)'
)
self
.
_received_version
=
self
.
_recv
(
)
key
,
version
=
shlex
.
split
(
self
.
_received_version
[
1
:
1
]
)
return
Version
(
*
map
(
int
,
version
.
split
(
'.'
)
)
)

If we fail to parse the version we assume z3 s output has changed meaning it s a newer version than what s used now and therefore ok .


def _start_proc(self):
        """Spawns z3 solver process"""
        assert '_proc' not in dir(self) or self._proc is None
        try:
            self._proc = Popen(shlex.split(self._command), stdin=PIPE, stdout=PIPE, bufsize=0, universal_newlines=True)
        except OSError as e:
            print(e, "Probably too many cached expressions? visitors._cache...")
            # Z3 was removed from the system in the middle of operation
            raise Z3NotFoundError  # TODO(mark) don't catch this exception in two places

        # run solver specific initializations
        for cfg in self._init:
            self._send(cfg)


def _reset(self, constraints=None):
        """Auxiliary method to reset the smtlib external solver to initial defaults"""
        if self._proc is None:
            self._start_proc()
        else:
            if self.support_reset:
                self._send("(reset)")

                for cfg in self._init:
                    self._send(cfg)
            else:
                self._stop_proc()
                self._start_proc()
        if constraints is not None:
            self._send(constraints)

def _reset ( self , constraints = None ) : if self . _proc is None : self . _start_proc ( ) else : if self . support_reset : self . _send ( "(reset)" ) for cfg in self . _init : self . _send ( cfg ) else : self . _stop_proc ( ) self . _start_proc ( ) if constraints is not None : self . _send ( constraints )


def _send(self, cmd: str):
        """
        Send a string to the solver.

        :param cmd: a SMTLIBv2 command (ex. (check-sat))
        """
        logger.debug('>%s', cmd)
        try:
            self._proc.stdout.flush()
            self._proc.stdin.write(f'{cmd}\n')
        except IOError as e:
            raise SolverError(str(e))

def _send ( self , cmd : str ) : logger . debug ( '>%s' , cmd ) try : self . _proc . stdout . flush ( ) self . _proc . stdin . write ( f'{cmd}\n' ) except IOError as e : raise SolverError ( str ( e ) )


def _recv(self) -> str:
        """Reads the response from the solver"""
        buf, left, right = self.__readline_and_count()
        bufl = [buf]

        while left != right:
            buf, l, r = self.__readline_and_count()
            bufl.append(buf)
            left += l
            right += r

        buf = ''.join(bufl).strip()

        logger.debug('<%s', buf)
        if '(error' in bufl[0]:
            raise Exception(f"Error in smtlib: {bufl[0]}")
        return buf

def
_recv
(
self
)
->
str
:
buf
,
left
,
right
=
self
.
__readline_and_count
(
)
bufl
=
[
buf
]
while
left
!=
right
:
buf
,
l
,
r
=
self
.
__readline_and_count
(
)
bufl
.
append
(
buf
)
left
+=
l
right
+=
r
buf
=
''
.
join
(
bufl
)
.
strip
(
)
logger
.
debug
(
'<%s'
,
buf
)
if
'(error'
in
bufl
[
0
]
:
raise
Exception
(
f"Error in smtlib: {bufl[0]}"
)
return
buf


def _is_sat(self) -> bool:
        """
        Check the satisfiability of the current state

        :return: whether current state is satisfiable or not.
        """
        logger.debug("Solver.check() ")
        start = time.time()
        self._send('(check-sat)')
        status = self._recv()
        logger.debug("Check took %s seconds (%s)", time.time() - start, status)
        if status not in ('sat', 'unsat', 'unknown'):
            raise SolverError(status)
        if consider_unknown_as_unsat:
            if status == 'unknown':
                logger.info('Found an unknown core, probably a solver timeout')
                status = 'unsat'

        if status == 'unknown':
            raise SolverUnknown(status)

        return status == 'sat'


def _assert(self, expression: Bool):
        """Auxiliary method to send an assert"""
        assert isinstance(expression, Bool)
        smtlib = translate_to_smtlib(expression)
        self._send('(assert %s)' % smtlib)

def
_assert
(
self
,
expression
:
Bool
)
:
assert
isinstance
(
expression
,
Bool
)
smtlib
=
translate_to_smtlib
(
expression
)
self
.
_send
(
'(assert %s)'
%
smtlib
)


def _getvalue(self, expression):
        """
        Ask the solver for one possible assignment for given expression using current set of constraints.
        The current set of expressions must be sat.

        NOTE: This is an internal method: it uses the current solver state (set of constraints!).
        """
        if not issymbolic(expression):
            return expression
        assert isinstance(expression, Variable)

        if isinstance(expression, Array):
            result = bytearray()
            for c in expression:
                expression_str = translate_to_smtlib(c)
                self._send('(get-value (%s))' % expression_str)
                response = self._recv()
                result.append(int('0x{:s}'.format(response.split(expression_str)[1][3:-2]), 16))
            return bytes(result)
        else:
            self._send('(get-value (%s))' % expression.name)
            ret = self._recv()
            assert ret.startswith('((') and ret.endswith('))'), ret

            if isinstance(expression, Bool):
                return {'true': True, 'false': False}[ret[2:-2].split(' ')[1]]
            elif isinstance(expression, BitVec):
                pattern, base = self._get_value_fmt
                m = pattern.match(ret)
                expr, value = m.group('expr'), m.group('value')
                return int(value, base)

        raise NotImplementedError("_getvalue only implemented for Bool and BitVec")

Ask the solver for one possible assignment for given expression using current set of constraints . The current set of expressions must be sat .


def can_be_true(self, constraints, expression):
        """Check if two potentially symbolic values can be equal"""
        if isinstance(expression, bool):
            if not expression:
                return expression
            else:
                # if True check if constraints are feasible
                self._reset(constraints)
                return self._is_sat()
        assert isinstance(expression, Bool)

        with constraints as temp_cs:
            temp_cs.add(expression)
            self._reset(temp_cs.to_string(related_to=expression))
            return self._is_sat()


def get_all_values(self, constraints, expression, maxcnt=None, silent=False):
        """Returns a list with all the possible values for the symbol x"""
        if not isinstance(expression, Expression):
            return [expression]
        assert isinstance(constraints, ConstraintSet)
        assert isinstance(expression, Expression)
        expression = simplify(expression)
        if maxcnt is None:
            maxcnt = consts.maxsolutions

        with constraints as temp_cs:
            if isinstance(expression, Bool):
                var = temp_cs.new_bool()
            elif isinstance(expression, BitVec):
                var = temp_cs.new_bitvec(expression.size)
            elif isinstance(expression, Array):
                var = temp_cs.new_array(index_max=expression.index_max, value_bits=expression.value_bits, taint=expression.taint).array
            else:
                raise NotImplementedError(f"get_all_values only implemented for {type(expression)} expression type.")

            temp_cs.add(var == expression)
            self._reset(temp_cs.to_string(related_to=var))

            result = []

            while self._is_sat():
                value = self._getvalue(var)
                result.append(value)
                self._assert(var != value)

                if len(result) >= maxcnt:
                    if silent:
                        # do not throw an exception if set to silent
                        # Default is not silent, assume user knows
                        # what they are doing and will check the size
                        # of returned vals list (previous smtlib behavior)
                        break
                    else:
                        raise TooManySolutions(result)

            return result


def get_value(self, constraints, expression):
        """
        Ask the solver for one possible result of given expression using given set of constraints.
        """
        if not issymbolic(expression):
            return expression
        assert isinstance(expression, (Bool, BitVec, Array))
        with constraints as temp_cs:
            if isinstance(expression, Bool):
                var = temp_cs.new_bool()
            elif isinstance(expression, BitVec):
                var = temp_cs.new_bitvec(expression.size)
            elif isinstance(expression, Array):
                var = []
                result = []
                for i in range(expression.index_max):
                    subvar = temp_cs.new_bitvec(expression.value_bits)
                    var.append(subvar)
                    temp_cs.add(subvar == simplify(expression[i]))

                self._reset(temp_cs)
                if not self._is_sat():
                    raise SolverError('Model is not available')

                for i in range(expression.index_max):
                    self._send('(get-value (%s))' % var[i].name)
                    ret = self._recv()
                    assert ret.startswith('((') and ret.endswith('))')
                    pattern, base = self._get_value_fmt
                    m = pattern.match(ret)
                    expr, value = m.group('expr'), m.group('value')
                    result.append(int(value, base))
                return bytes(result)

            temp_cs.add(var == expression)

            self._reset(temp_cs)

        if not self._is_sat():
            raise SolverError('Model is not available')

        self._send('(get-value (%s))' % var.name)
        ret = self._recv()
        if not (ret.startswith('((') and ret.endswith('))')):
            raise SolverError('SMTLIB error parsing response: %s' % ret)

        if isinstance(expression, Bool):
            return {'true': True, 'false': False}[ret[2:-2].split(' ')[1]]
        if isinstance(expression, BitVec):
            pattern, base = self._get_value_fmt
            m = pattern.match(ret)
            expr, value = m.group('expr'), m.group('value')
            return int(value, base)
        raise NotImplementedError("get_value only implemented for Bool and BitVec")

Ask the solver for one possible result of given expression using given set of constraints .


def summarized_name(self, name):
        """
        Produce a summarized record name
          i.e. manticore.core.executor -> m.c.executor
        """
        components = name.split('.')
        prefix = '.'.join(c[0] for c in components[:-1])
        return f'{prefix}.{components[-1]}'

def summarized_name ( self , name ) : components = name . split ( '.' ) prefix = '.' . join ( c [ 0 ] for c in components [ : - 1 ] ) return f'{prefix}.{components[-1]}'

Produce a summarized record name i . e . manticore . core . executor - > m . c . executor


def colored_level_name(self, levelname):
        """
        Colors the logging level in the logging record
        """
        if self.colors_disabled:
            return self.plain_levelname_format.format(levelname)
        else:
            return self.colored_levelname_format.format(self.color_map[levelname], levelname)

def colored_level_name ( self , levelname ) : if self . colors_disabled : return self . plain_levelname_format . format ( levelname ) else : return self . colored_levelname_format . format ( self . color_map [ levelname ] , levelname )


def _find_zero(cpu, constrs, ptr):
    """
    Helper for finding the closest NULL or, effectively NULL byte from a starting address.

    :param Cpu cpu:
    :param ConstraintSet constrs: Constraints for current `State`
    :param int ptr: Address to start searching for a zero from
    :return: Offset from `ptr` to first byte that is 0 or an `Expression` that must be zero
    """

    offset = 0
    while True:
        byt = cpu.read_int(ptr + offset, 8)

        if issymbolic(byt):
            if not solver.can_be_true(constrs, byt != 0):
                break
        else:
            if byt == 0:
                break

        offset += 1

    return offset

def _find_zero ( cpu , constrs , ptr ) : offset = 0 while True : byt = cpu . read_int ( ptr + offset , 8 ) if issymbolic ( byt ) : if not solver . can_be_true ( constrs , byt != 0 ) : break else : if byt == 0 : break offset += 1 return offset

Helper for finding the closest NULL or effectively NULL byte from a starting address .


def strcmp(state, s1, s2):
    """
    strcmp symbolic model.

    Algorithm: Walks from end of string (minimum offset to NULL in either string)
    to beginning building tree of ITEs each time either of the
    bytes at current offset is symbolic.

    Points of Interest:
    - We've been building up a symbolic tree but then encounter two
      concrete bytes that differ. We can throw away the entire symbolic
      tree!
    - If we've been encountering concrete bytes that match
      at the end of the string as we walk forward, and then we encounter
      a pair where one is symbolic, we can forget about that 0 `ret` we've
      been tracking and just replace it with the symbolic subtraction of
      the two

    :param State state: Current program state
    :param int s1: Address of string 1
    :param int s2: Address of string 2
    :return: Symbolic strcmp result
    :rtype: Expression or int
    """

    cpu = state.cpu

    if issymbolic(s1):
        raise ConcretizeArgument(state.cpu, 1)
    if issymbolic(s2):
        raise ConcretizeArgument(state.cpu, 2)

    s1_zero_idx = _find_zero(cpu, state.constraints, s1)
    s2_zero_idx = _find_zero(cpu, state.constraints, s2)
    min_zero_idx = min(s1_zero_idx, s2_zero_idx)

    ret = None

    for offset in range(min_zero_idx, -1, -1):
        s1char = ZEXTEND(cpu.read_int(s1 + offset, 8), cpu.address_bit_size)
        s2char = ZEXTEND(cpu.read_int(s2 + offset, 8), cpu.address_bit_size)

        if issymbolic(s1char) or issymbolic(s2char):
            if ret is None or (not issymbolic(ret) and ret == 0):
                ret = s1char - s2char
            else:
                ret = ITEBV(cpu.address_bit_size, s1char != s2char, s1char - s2char, ret)
        else:
            if s1char != s2char:
                ret = s1char - s2char
            elif ret is None:
                ret = 0

    return ret

def strcmp ( state , s1 , s2 ) : cpu = state . cpu if issymbolic ( s1 ) : raise ConcretizeArgument ( state . cpu , 1 ) if issymbolic ( s2 ) : raise ConcretizeArgument ( state . cpu , 2 ) s1_zero_idx = _find_zero ( cpu , state . constraints , s1 ) s2_zero_idx = _find_zero ( cpu , state . constraints , s2 ) min_zero_idx = min ( s1_zero_idx , s2_zero_idx ) ret = None for offset in range ( min_zero_idx , - 1 , - 1 ) : s1char = ZEXTEND ( cpu . read_int ( s1 + offset , 8 ) , cpu . address_bit_size ) s2char = ZEXTEND ( cpu . read_int ( s2 + offset , 8 ) , cpu . address_bit_size ) if issymbolic ( s1char ) or issymbolic ( s2char ) : if ret is None or ( not issymbolic ( ret ) and ret == 0 ) : ret = s1char - s2char else : ret = ITEBV ( cpu . address_bit_size , s1char != s2char , s1char - s2char , ret ) else : if s1char != s2char : ret = s1char - s2char elif ret is None : ret = 0 return ret


def strlen(state, s):
    """
    strlen symbolic model.

    Algorithm: Walks from end of string not including NULL building ITE tree when current byte is symbolic.

    :param State state: current program state
    :param int s: Address of string
    :return: Symbolic strlen result
    :rtype: Expression or int
    """

    cpu = state.cpu

    if issymbolic(s):
        raise ConcretizeArgument(state.cpu, 1)

    zero_idx = _find_zero(cpu, state.constraints, s)

    ret = zero_idx

    for offset in range(zero_idx - 1, -1, -1):
        byt = cpu.read_int(s + offset, 8)
        if issymbolic(byt):
            ret = ITEBV(cpu.address_bit_size, byt == 0, offset, ret)

    return ret

def strlen ( state , s ) : cpu = state . cpu if issymbolic ( s ) : raise ConcretizeArgument ( state . cpu , 1 ) zero_idx = _find_zero ( cpu , state . constraints , s ) ret = zero_idx for offset in range ( zero_idx - 1 , - 1 , - 1 ) : byt = cpu . read_int ( s + offset , 8 ) if issymbolic ( byt ) : ret = ITEBV ( cpu . address_bit_size , byt == 0 , offset , ret ) return ret


def all_events(cls):
        """
        Return all events that all subclasses have so far registered to publish.
        """
        all_evts = set()
        for cls, evts in cls.__all_events__.items():
            all_evts.update(evts)
        return all_evts

def all_events ( cls ) : all_evts = set ( ) for cls , evts in cls . __all_events__ . items ( ) : all_evts . update ( evts ) return all_evts

Return all events that all subclasses have so far registered to publish .


def forward_events_to(self, sink, include_source=False):
        """This forwards signal to sink"""
        assert isinstance(sink, Eventful), f'{sink.__class__.__name__} is not Eventful'
        self._forwards[sink] = include_source


def get_profiling_stats(self):
        """
        Returns a pstat.Stats instance with profiling results if `run` was called with `should_profile=True`.
        Otherwise, returns `None`.
        """
        profile_file_path = os.path.join(self.workspace, 'profiling.bin')
        try:
            return pstats.Stats(profile_file_path)
        except Exception as e:
            logger.debug(f'Failed to get profiling stats: {e}')
            return None

def
get_profiling_stats
(
self
)
:
profile_file_path
=
os
.
path
.
join
(
self
.
workspace
,
'profiling.bin'
)
try
:
return
pstats
.
Stats
(
profile_file_path
)
except
Exception
as
e
:
logger
.
debug
(
f'Failed to get profiling stats: {e}'
)
return

Returns a pstat . Stats instance with profiling results if run was called with should_profile = True . Otherwise returns None .


def run(self, procs=1, timeout=None, should_profile=False):
        """
        Runs analysis.

        :param int procs: Number of parallel worker processes
        :param timeout: Analysis timeout, in seconds
        """
        assert not self.running, "Manticore is already running."
        self._start_run()

        self._last_run_stats['time_started'] = time.time()
        with self.shutdown_timeout(timeout):
            self._start_workers(procs, profiling=should_profile)

            self._join_workers()
        self._finish_run(profiling=should_profile)

def
run
(
self
,
procs
=
1
,
timeout
=
,
should_profile
=
False
)
:
assert
not
self
.
running
,
"Manticore is already running."
self
.
_start_run
(
)
self
.
_last_run_stats
[
'time_started'
]
=
time
.
time
(
)
with
self
.
shutdown_timeout
(
timeout
)
:
self
.
_start_workers
(
procs
,
profiling
=
should_profile
)
self
.
_join_workers
(
)
self
.
_finish_run
(
profiling
=
should_profile
)


def GetNBits(value, nbits):
    """
    Get the first `nbits` from `value`.

    :param value: Source value from which to extract
    :type value: int or long or BitVec
    :param int nbits: How many bits to extract
    :return: Low `nbits` bits of `value`.
    :rtype int or long or BitVec
    """
    # NOP if sizes are the same
    if isinstance(value, int):
        return Operators.EXTRACT(value, 0, nbits)
    elif isinstance(value, BitVec):
        if value.size < nbits:
            return Operators.ZEXTEND(value, nbits)
        else:
            return Operators.EXTRACT(value, 0, nbits)

def
GetNBits
(
value
,
nbits
)
:
# NOP if sizes are the same
if
isinstance
(
value
,
int
)
:
return
Operators
.
EXTRACT
(
value
,
0
,
nbits
)
elif
isinstance
(
value
,
BitVec
)
:
if
value
.
size
<
nbits
:
return
Operators
.
ZEXTEND
(
value
,
nbits
)
else
:
return
Operators
.
EXTRACT
(
value
,
0
,
nbits
)


def SInt(value, width):
    """
    Convert a bitstring `value` of `width` bits to a signed integer
    representation.

    :param value: The value to convert.
    :type value: int or long or BitVec
    :param int width: The width of the bitstring to consider
    :return: The converted value
    :rtype int or long or BitVec
    """
    return Operators.ITEBV(width, Bit(value, width - 1) == 1,
                           GetNBits(value, width) - 2**width,
                           GetNBits(value, width))

def SInt ( value , width ) : return Operators . ITEBV ( width , Bit ( value , width - 1 ) == 1 , GetNBits ( value , width ) - 2 ** width , GetNBits ( value , width ) )

Convert a bitstring value of width bits to a signed integer representation .


def locked_context(self, key=None, default=dict):
        """ Policy shared context dictionary """
        keys = ['policy']
        if key is not None:
            keys.append(key)
        with self._executor.locked_context('.'.join(keys), default) as policy_context:
            yield policy_context

def locked_context ( self , key = None , default = dict ) : keys = [ 'policy' ] if key is not None : keys . append ( key ) with self . _executor . locked_context ( '.' . join ( keys ) , default ) as policy_context : yield policy_context


def enqueue(self, state):
        """
            Enqueue state.
            Save state on storage, assigns an id to it, then add it to the
            priority queue
        """
        # save the state to secondary storage
        state_id = self._workspace.save_state(state)
        self.put(state_id)
        self._publish('did_enqueue_state', state_id, state)
        return state_id

def
enqueue
(
self
,
state
)
:
# save the state to secondary storage
state_id
=
self
.
_workspace
.
save_state
(
state
)
self
.
put
(
state_id
)
self
.
_publish
(
'did_enqueue_state'
,
state_id
,
state
)
return
state_id

Enqueue state . Save state on storage assigns an id to it then add it to the priority queue


def put(self, state_id):
        """ Enqueue it for processing """
        self._states.append(state_id)
        self._lock.notify_all()
        return state_id

def put ( self , state_id ) : self . _states . append ( state_id ) self . _lock . notify_all ( ) return state_id