Skip to content

Commit

Permalink
x86: movhps support (#1444)
Browse files Browse the repository at this point in the history
* x86: MOVHPS support

Closes #1432.

* Update manticore/native/cpu/x86.py

Co-Authored-By: Eric Hennenfent <[email protected]>

* tests: Add movhps tests

* tests: Fix tests

* tests: Remove relative import

Works locally, fails on CI.

* tests: Fix movhps shellcode

Was using qword and not qword ptr.

* tests: Swap assertions
  • Loading branch information
woodruffw authored and Eric Hennenfent committed May 23, 2019
1 parent d72d556 commit 7de6371
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 0 deletions.
21 changes: 21 additions & 0 deletions manticore/native/cpu/x86.py
Original file line number Diff line number Diff line change
Expand Up @@ -5507,6 +5507,27 @@ def MOVHPD(cpu, dest, src):
value = Operators.EXTRACT(dest.read(), 0, 64) # low part
dest.write(Operators.CONCAT(128, src.read(), value))

@instruction
def MOVHPS(cpu, dest, src):
"""
Moves high packed single-precision floating-point value.
Moves two packed single-precision floating-point values from the source operand
(second operand) to the destination operand (first operand). The source and destination
operands can be an XMM register or a 64-bit memory location. The instruction allows
single-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.
"""
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))

@instruction
def PSUBB(cpu, dest, src):
"""
Expand Down
47 changes: 47 additions & 0 deletions tests/native/test_cpu_manual.py
Original file line number Diff line number Diff line change
Expand Up @@ -1128,6 +1128,53 @@ def test_SAR_3_symbolic(self):
temp_cs.add(condition == False)
self.assertFalse(solver.check(temp_cs))

def test_MOVHPS_1(self):
mem = Memory32()
cpu = I386Cpu(mem)
mem.mmap(0x0041e000, 0x1000, 'rwx')

# 3.14
mem[0x0041e000] = '\x40'
mem[0x0041e001] = '\x48'
mem[0x0041e002] = '\xf5'
mem[0x0041e003] = '\xc3'

# 6.28
mem[0x0041e004] = '\x40'
mem[0x0041e005] = '\xc8'
mem[0x0041e006] = '\xf5'
mem[0x0041e007] = '\xc3'

# movhps xmm0, qword ptr [eax]
mem[0x0041e10a] = '\x0f'
mem[0x0041e10b] = '\x16'
mem[0x0041e10c] = '\x00'

cpu.RIP = 0x41e10a
cpu.EAX = 0x41e000
cpu.XMM0 = 0x0000000000000000ffffffffffffffff
cpu.execute()

self.assertEqual(cpu.XMM0, 0xc3f5c840c3f54840ffffffffffffffff)

def test_MOVHPS_2(self):
mem = Memory32()
cpu = I386Cpu(mem)
mem.mmap(0x0041e000, 0x1000, 'rwx')

# movhps qword ptr [eax], xmm1
mem[0x0041e10a] = '\x0f'
mem[0x0041e10b] = '\x17'
mem[0x0041e10c] = '\x08'

cpu.RIP = 0x41e10a
cpu.EAX = 0x41e000
cpu.XMM1 = 0x4048f5c340c8f5c3ffffffffffffffff
cpu.execute()

self.assertItemsEqual(mem[0x41e000:0x41e004], to_bytelist(b'\x40\xc8\xf5\xc3'))
self.assertItemsEqual(mem[0x41e004:0x41e008], to_bytelist(b'\x40\x48\xf5\xc3'))

def test_symbolic_instruction(self):
cs = ConstraintSet()
mem = SMemory32(cs)
Expand Down

0 comments on commit 7de6371

Please sign in to comment.