Skip to content

Commit 7de6371

Browse files
woodruffwEric Hennenfent
authored andcommitted
x86: movhps support (#1444)
* x86: MOVHPS support Closes #1432. * Update manticore/native/cpu/x86.py Co-Authored-By: Eric Hennenfent <ecapstone@gmail.com> * 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
1 parent d72d556 commit 7de6371

2 files changed

Lines changed: 68 additions & 0 deletions

File tree

manticore/native/cpu/x86.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5507,6 +5507,27 @@ def MOVHPD(cpu, dest, src):
55075507
value = Operators.EXTRACT(dest.read(), 0, 64) # low part
55085508
dest.write(Operators.CONCAT(128, src.read(), value))
55095509

5510+
@instruction
5511+
def MOVHPS(cpu, dest, src):
5512+
"""
5513+
Moves high packed single-precision floating-point value.
5514+
5515+
Moves two packed single-precision floating-point values from the source operand
5516+
(second operand) to the destination operand (first operand). The source and destination
5517+
operands can be an XMM register or a 64-bit memory location. The instruction allows
5518+
single-precision floating-point values to be moved to and from the high quadword of
5519+
an XMM register and memory. It cannot be used for register to register or memory to
5520+
memory moves. When the destination operand is an XMM register, the low quadword
5521+
of the register remains unchanged.
5522+
"""
5523+
if src.size == 128:
5524+
assert dest.size == 64
5525+
dest.write(Operators.EXTRACT(src.read(), 64, 64))
5526+
else:
5527+
assert src.size == 64 and dest.size == 128
5528+
value = Operators.EXTRACT(dest.read(), 0, 64) # low part
5529+
dest.write(Operators.CONCAT(128, src.read(), value))
5530+
55105531
@instruction
55115532
def PSUBB(cpu, dest, src):
55125533
"""

tests/native/test_cpu_manual.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1128,6 +1128,53 @@ def test_SAR_3_symbolic(self):
11281128
temp_cs.add(condition == False)
11291129
self.assertFalse(solver.check(temp_cs))
11301130

1131+
def test_MOVHPS_1(self):
1132+
mem = Memory32()
1133+
cpu = I386Cpu(mem)
1134+
mem.mmap(0x0041e000, 0x1000, 'rwx')
1135+
1136+
# 3.14
1137+
mem[0x0041e000] = '\x40'
1138+
mem[0x0041e001] = '\x48'
1139+
mem[0x0041e002] = '\xf5'
1140+
mem[0x0041e003] = '\xc3'
1141+
1142+
# 6.28
1143+
mem[0x0041e004] = '\x40'
1144+
mem[0x0041e005] = '\xc8'
1145+
mem[0x0041e006] = '\xf5'
1146+
mem[0x0041e007] = '\xc3'
1147+
1148+
# movhps xmm0, qword ptr [eax]
1149+
mem[0x0041e10a] = '\x0f'
1150+
mem[0x0041e10b] = '\x16'
1151+
mem[0x0041e10c] = '\x00'
1152+
1153+
cpu.RIP = 0x41e10a
1154+
cpu.EAX = 0x41e000
1155+
cpu.XMM0 = 0x0000000000000000ffffffffffffffff
1156+
cpu.execute()
1157+
1158+
self.assertEqual(cpu.XMM0, 0xc3f5c840c3f54840ffffffffffffffff)
1159+
1160+
def test_MOVHPS_2(self):
1161+
mem = Memory32()
1162+
cpu = I386Cpu(mem)
1163+
mem.mmap(0x0041e000, 0x1000, 'rwx')
1164+
1165+
# movhps qword ptr [eax], xmm1
1166+
mem[0x0041e10a] = '\x0f'
1167+
mem[0x0041e10b] = '\x17'
1168+
mem[0x0041e10c] = '\x08'
1169+
1170+
cpu.RIP = 0x41e10a
1171+
cpu.EAX = 0x41e000
1172+
cpu.XMM1 = 0x4048f5c340c8f5c3ffffffffffffffff
1173+
cpu.execute()
1174+
1175+
self.assertItemsEqual(mem[0x41e000:0x41e004], to_bytelist(b'\x40\xc8\xf5\xc3'))
1176+
self.assertItemsEqual(mem[0x41e004:0x41e008], to_bytelist(b'\x40\x48\xf5\xc3'))
1177+
11311178
def test_symbolic_instruction(self):
11321179
cs = ConstraintSet()
11331180
mem = SMemory32(cs)

0 commit comments

Comments
 (0)