From 7de6371983f27d4c273a8cf1c7e508ccd29eccc3 Mon Sep 17 00:00:00 2001 From: William Woodruff Date: Thu, 23 May 2019 12:41:39 -0400 Subject: [PATCH] x86: movhps support (#1444) * x86: MOVHPS support Closes #1432. * Update manticore/native/cpu/x86.py Co-Authored-By: Eric Hennenfent * 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 --- manticore/native/cpu/x86.py | 21 +++++++++++++++ tests/native/test_cpu_manual.py | 47 +++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/manticore/native/cpu/x86.py b/manticore/native/cpu/x86.py index 226ed6ba4..b8b90bd35 100644 --- a/manticore/native/cpu/x86.py +++ b/manticore/native/cpu/x86.py @@ -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): """ diff --git a/tests/native/test_cpu_manual.py b/tests/native/test_cpu_manual.py index 1138d91e9..daed61242 100644 --- a/tests/native/test_cpu_manual.py +++ b/tests/native/test_cpu_manual.py @@ -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)