diff --git a/.build_number b/.build_number index 6991c767..7105d937 100644 --- a/.build_number +++ b/.build_number @@ -1 +1 @@ -1454 +1455 diff --git a/src/libtriton/arch/x86/x8664Cpu.cpp b/src/libtriton/arch/x86/x8664Cpu.cpp index 55495518..fadca5b9 100644 --- a/src/libtriton/arch/x86/x8664Cpu.cpp +++ b/src/libtriton/arch/x86/x8664Cpu.cpp @@ -142,6 +142,12 @@ namespace triton { std::memcpy(this->fs, other.fs, sizeof(this->fs)); std::memcpy(this->gs, other.gs, sizeof(this->gs)); std::memcpy(this->ss, other.ss, sizeof(this->ss)); + std::memcpy(this->dr0, other.dr0, sizeof(this->dr0)); + std::memcpy(this->dr1, other.dr1, sizeof(this->dr1)); + std::memcpy(this->dr2, other.dr2, sizeof(this->dr2)); + std::memcpy(this->dr3, other.dr3, sizeof(this->dr3)); + std::memcpy(this->dr6, other.dr6, sizeof(this->dr6)); + std::memcpy(this->dr7, other.dr7, sizeof(this->dr7)); } @@ -231,6 +237,12 @@ namespace triton { std::memset(this->fs, 0x00, sizeof(this->fs)); std::memset(this->gs, 0x00, sizeof(this->gs)); std::memset(this->ss, 0x00, sizeof(this->ss)); + std::memset(this->dr0, 0x00, sizeof(this->dr0)); + std::memset(this->dr1, 0x00, sizeof(this->dr1)); + std::memset(this->dr2, 0x00, sizeof(this->dr2)); + std::memset(this->dr3, 0x00, sizeof(this->dr3)); + std::memset(this->dr6, 0x00, sizeof(this->dr6)); + std::memset(this->dr7, 0x00, sizeof(this->dr7)); } @@ -258,6 +270,7 @@ namespace triton { this->isAVX256(regId) || this->isAVX512(regId) || this->isControl(regId) || + this->isDebug(regId) || this->isSegment(regId) ); } @@ -298,6 +311,11 @@ namespace triton { } + bool x8664Cpu::isDebug(triton::arch::register_e regId) const { + return ((regId >= triton::arch::ID_REG_X86_DR0 && regId <= triton::arch::ID_REG_X86_DR7) ? true : false); + } + + bool x8664Cpu::isSegment(triton::arch::register_e regId) const { return ((regId >= triton::arch::ID_REG_X86_CS && regId <= triton::arch::ID_REG_X86_SS) ? true : false); } @@ -358,6 +376,10 @@ namespace triton { else if (this->isControl(regId)) ret.insert(®); + /* Add Debug */ + else if (this->isDebug(regId)) + ret.insert(®); + /* Add Segment */ else if (this->isSegment(regId)) ret.insert(®); @@ -736,6 +758,13 @@ namespace triton { case triton::arch::ID_REG_X86_CR14: return (*((triton::uint64*)(this->cr14))); case triton::arch::ID_REG_X86_CR15: return (*((triton::uint64*)(this->cr15))); + case triton::arch::ID_REG_X86_DR0: return (*((triton::uint64*)(this->dr0))); + case triton::arch::ID_REG_X86_DR1: return (*((triton::uint64*)(this->dr1))); + case triton::arch::ID_REG_X86_DR2: return (*((triton::uint64*)(this->dr2))); + case triton::arch::ID_REG_X86_DR3: return (*((triton::uint64*)(this->dr3))); + case triton::arch::ID_REG_X86_DR6: return (*((triton::uint64*)(this->dr6))); + case triton::arch::ID_REG_X86_DR7: return (*((triton::uint64*)(this->dr7))); + case triton::arch::ID_REG_X86_IE: return (((*((triton::uint64*)(this->mxcsr))) >> 0) & 1); case triton::arch::ID_REG_X86_DE: return (((*((triton::uint64*)(this->mxcsr))) >> 1) & 1); case triton::arch::ID_REG_X86_ZE: return (((*((triton::uint64*)(this->mxcsr))) >> 2) & 1); @@ -1182,12 +1211,19 @@ namespace triton { case triton::arch::ID_REG_X86_CR14: (*((triton::uint64*)(this->cr14))) = value.convert_to(); break; case triton::arch::ID_REG_X86_CR15: (*((triton::uint64*)(this->cr15))) = value.convert_to(); break; - case triton::arch::ID_REG_X86_CS: (*((triton::uint64*)(this->cs))) = value.convert_to(); break; - case triton::arch::ID_REG_X86_DS: (*((triton::uint64*)(this->ds))) = value.convert_to(); break; - case triton::arch::ID_REG_X86_ES: (*((triton::uint64*)(this->es))) = value.convert_to(); break; - case triton::arch::ID_REG_X86_FS: (*((triton::uint64*)(this->fs))) = value.convert_to(); break; - case triton::arch::ID_REG_X86_GS: (*((triton::uint64*)(this->gs))) = value.convert_to(); break; - case triton::arch::ID_REG_X86_SS: (*((triton::uint64*)(this->ss))) = value.convert_to(); break; + case triton::arch::ID_REG_X86_DR0: (*((triton::uint64*)(this->dr0))) = value.convert_to(); break; + case triton::arch::ID_REG_X86_DR1: (*((triton::uint64*)(this->dr1))) = value.convert_to(); break; + case triton::arch::ID_REG_X86_DR2: (*((triton::uint64*)(this->dr2))) = value.convert_to(); break; + case triton::arch::ID_REG_X86_DR3: (*((triton::uint64*)(this->dr3))) = value.convert_to(); break; + case triton::arch::ID_REG_X86_DR6: (*((triton::uint64*)(this->dr6))) = value.convert_to(); break; + case triton::arch::ID_REG_X86_DR7: (*((triton::uint64*)(this->dr7))) = value.convert_to(); break; + + case triton::arch::ID_REG_X86_CS: (*((triton::uint64*)(this->cs))) = value.convert_to(); break; + case triton::arch::ID_REG_X86_DS: (*((triton::uint64*)(this->ds))) = value.convert_to(); break; + case triton::arch::ID_REG_X86_ES: (*((triton::uint64*)(this->es))) = value.convert_to(); break; + case triton::arch::ID_REG_X86_FS: (*((triton::uint64*)(this->fs))) = value.convert_to(); break; + case triton::arch::ID_REG_X86_GS: (*((triton::uint64*)(this->gs))) = value.convert_to(); break; + case triton::arch::ID_REG_X86_SS: (*((triton::uint64*)(this->ss))) = value.convert_to(); break; default: throw triton::exceptions::Cpu("x8664Cpu:setConcreteRegisterValue(): Invalid register."); diff --git a/src/libtriton/arch/x86/x86Cpu.cpp b/src/libtriton/arch/x86/x86Cpu.cpp index 2e482c51..bf9a2c06 100644 --- a/src/libtriton/arch/x86/x86Cpu.cpp +++ b/src/libtriton/arch/x86/x86Cpu.cpp @@ -110,6 +110,12 @@ namespace triton { std::memcpy(this->fs, other.fs, sizeof(this->fs)); std::memcpy(this->gs, other.gs, sizeof(this->gs)); std::memcpy(this->ss, other.ss, sizeof(this->ss)); + std::memcpy(this->dr0, other.dr0, sizeof(this->dr0)); + std::memcpy(this->dr1, other.dr1, sizeof(this->dr1)); + std::memcpy(this->dr2, other.dr2, sizeof(this->dr2)); + std::memcpy(this->dr3, other.dr3, sizeof(this->dr3)); + std::memcpy(this->dr6, other.dr6, sizeof(this->dr6)); + std::memcpy(this->dr7, other.dr7, sizeof(this->dr7)); } @@ -167,6 +173,12 @@ namespace triton { std::memset(this->fs, 0x00, sizeof(this->fs)); std::memset(this->gs, 0x00, sizeof(this->gs)); std::memset(this->ss, 0x00, sizeof(this->ss)); + std::memset(this->dr0, 0x00, sizeof(this->dr0)); + std::memset(this->dr1, 0x00, sizeof(this->dr1)); + std::memset(this->dr2, 0x00, sizeof(this->dr2)); + std::memset(this->dr3, 0x00, sizeof(this->dr3)); + std::memset(this->dr6, 0x00, sizeof(this->dr6)); + std::memset(this->dr7, 0x00, sizeof(this->dr7)); } @@ -193,6 +205,7 @@ namespace triton { this->isSSE(regId) || this->isAVX256(regId) || this->isControl(regId) || + this->isDebug(regId) || this->isSegment(regId) ); } @@ -228,6 +241,11 @@ namespace triton { } + bool x86Cpu::isDebug(triton::arch::register_e regId) const { + return ((regId >= triton::arch::ID_REG_X86_DR0 && regId <= triton::arch::ID_REG_X86_DR7) ? true : false); + } + + bool x86Cpu::isSegment(triton::arch::register_e regId) const { return ((regId >= triton::arch::ID_REG_X86_CS && regId <= triton::arch::ID_REG_X86_SS) ? true : false); } @@ -285,6 +303,10 @@ namespace triton { else if (this->isControl(regId)) ret.insert(®); + /* Add Debug */ + else if (this->isDebug(regId)) + ret.insert(®); + /* Add Segment */ else if (this->isSegment(regId)) ret.insert(®); @@ -565,6 +587,13 @@ namespace triton { case triton::arch::ID_REG_X86_CR14: return (*((triton::uint32*)(this->cr14))); case triton::arch::ID_REG_X86_CR15: return (*((triton::uint32*)(this->cr15))); + case triton::arch::ID_REG_X86_DR0: return (*((triton::uint32*)(this->dr0))); + case triton::arch::ID_REG_X86_DR1: return (*((triton::uint32*)(this->dr1))); + case triton::arch::ID_REG_X86_DR2: return (*((triton::uint32*)(this->dr2))); + case triton::arch::ID_REG_X86_DR3: return (*((triton::uint32*)(this->dr3))); + case triton::arch::ID_REG_X86_DR6: return (*((triton::uint32*)(this->dr6))); + case triton::arch::ID_REG_X86_DR7: return (*((triton::uint32*)(this->dr7))); + case triton::arch::ID_REG_X86_IE: return (((*((triton::uint32*)(this->mxcsr))) >> 0) & 1); case triton::arch::ID_REG_X86_DE: return (((*((triton::uint32*)(this->mxcsr))) >> 1) & 1); case triton::arch::ID_REG_X86_ZE: return (((*((triton::uint32*)(this->mxcsr))) >> 2) & 1); @@ -913,6 +942,13 @@ namespace triton { case triton::arch::ID_REG_X86_CR14: (*((triton::uint32*)(this->cr14))) = value.convert_to(); break; case triton::arch::ID_REG_X86_CR15: (*((triton::uint32*)(this->cr15))) = value.convert_to(); break; + case triton::arch::ID_REG_X86_DR0: (*((triton::uint32*)(this->dr0))) = value.convert_to(); break; + case triton::arch::ID_REG_X86_DR1: (*((triton::uint32*)(this->dr1))) = value.convert_to(); break; + case triton::arch::ID_REG_X86_DR2: (*((triton::uint32*)(this->dr2))) = value.convert_to(); break; + case triton::arch::ID_REG_X86_DR3: (*((triton::uint32*)(this->dr3))) = value.convert_to(); break; + case triton::arch::ID_REG_X86_DR6: (*((triton::uint32*)(this->dr6))) = value.convert_to(); break; + case triton::arch::ID_REG_X86_DR7: (*((triton::uint32*)(this->dr7))) = value.convert_to(); break; + case triton::arch::ID_REG_X86_CS: (*((triton::uint32*)(this->cs))) = value.convert_to(); break; case triton::arch::ID_REG_X86_DS: (*((triton::uint32*)(this->ds))) = value.convert_to(); break; case triton::arch::ID_REG_X86_ES: (*((triton::uint32*)(this->es))) = value.convert_to(); break; diff --git a/src/libtriton/includes/triton/x86.spec b/src/libtriton/includes/triton/x86.spec index 7482f31c..69e0487a 100644 --- a/src/libtriton/includes/triton/x86.spec +++ b/src/libtriton/includes/triton/x86.spec @@ -199,6 +199,14 @@ REG_SPEC(CR13, cr13, QWORD_SIZE_BIT-1, 0, CR13, DWORD_SIZE_BIT-1, 0, CR13, true) REG_SPEC(CR14, cr14, QWORD_SIZE_BIT-1, 0, CR14, DWORD_SIZE_BIT-1, 0, CR14, true) // cr14 REG_SPEC(CR15, cr15, QWORD_SIZE_BIT-1, 0, CR15, DWORD_SIZE_BIT-1, 0, CR15, true) // cr15 +/* Debug */ +REG_SPEC(DR0, dr0, QWORD_SIZE_BIT-1, 0, DR0, DWORD_SIZE_BIT-1, 0, DR0, true) // dr0 +REG_SPEC(DR1, dr1, QWORD_SIZE_BIT-1, 0, DR1, DWORD_SIZE_BIT-1, 0, DR1, true) // dr1 +REG_SPEC(DR2, dr2, QWORD_SIZE_BIT-1, 0, DR2, DWORD_SIZE_BIT-1, 0, DR2, true) // dr2 +REG_SPEC(DR3, dr3, QWORD_SIZE_BIT-1, 0, DR3, DWORD_SIZE_BIT-1, 0, DR3, true) // dr3 +REG_SPEC(DR6, dr6, QWORD_SIZE_BIT-1, 0, DR6, DWORD_SIZE_BIT-1, 0, DR6, true) // dr6 +REG_SPEC(DR7, dr7, QWORD_SIZE_BIT-1, 0, DR7, DWORD_SIZE_BIT-1, 0, DR7, true) // dr7 + /* Flags ID used in the Taint and Symbolic Engines */ REG_SPEC_NO_CAPSTONE(AC, ac, 0, 0, AC, 0, 0, AC, true) // ac REG_SPEC_NO_CAPSTONE(AF, af, 0, 0, AF, 0, 0, AF, true) // af diff --git a/src/libtriton/includes/triton/x8664Cpu.hpp b/src/libtriton/includes/triton/x8664Cpu.hpp index 99278712..033f19f9 100644 --- a/src/libtriton/includes/triton/x8664Cpu.hpp +++ b/src/libtriton/includes/triton/x8664Cpu.hpp @@ -239,6 +239,18 @@ namespace triton { triton::uint8 gs[QWORD_SIZE]; //! Concrete value of SS triton::uint8 ss[QWORD_SIZE]; + //! Concrete value of dr0 + triton::uint8 dr0[QWORD_SIZE]; + //! Condete value of dr1 + triton::uint8 dr1[QWORD_SIZE]; + //! Condete value of dr2 + triton::uint8 dr2[QWORD_SIZE]; + //! Condete value of dr3 + triton::uint8 dr3[QWORD_SIZE]; + //! Condete value of dr6 + triton::uint8 dr6[QWORD_SIZE]; + //! Condete value of dr7 + triton::uint8 dr7[QWORD_SIZE]; public: //! Constructor. @@ -271,6 +283,9 @@ namespace triton { //! Returns true if regId is a control (cr) register. TRITON_EXPORT bool isControl(triton::arch::register_e regId) const; + //! Returns true if regId is a debug (dr) register. + TRITON_EXPORT bool isDebug(triton::arch::register_e regId) const; + //! Returns true if regId is a Segment. TRITON_EXPORT bool isSegment(triton::arch::register_e regId) const; diff --git a/src/libtriton/includes/triton/x86Cpu.hpp b/src/libtriton/includes/triton/x86Cpu.hpp index 40124a75..b22efe11 100644 --- a/src/libtriton/includes/triton/x86Cpu.hpp +++ b/src/libtriton/includes/triton/x86Cpu.hpp @@ -175,6 +175,18 @@ namespace triton { triton::uint8 gs[DWORD_SIZE]; //! Concrete value of SS triton::uint8 ss[DWORD_SIZE]; + //! Concrete value of dr0 + triton::uint8 dr0[DWORD_SIZE]; + //! Condete value of dr1 + triton::uint8 dr1[DWORD_SIZE]; + //! Condete value of dr2 + triton::uint8 dr2[DWORD_SIZE]; + //! Condete value of dr3 + triton::uint8 dr3[DWORD_SIZE]; + //! Condete value of dr6 + triton::uint8 dr6[DWORD_SIZE]; + //! Condete value of dr7 + triton::uint8 dr7[DWORD_SIZE]; public: //! Constructor. @@ -204,6 +216,9 @@ namespace triton { //! Returns true if regId is a control (cr) register. TRITON_EXPORT bool isControl(triton::arch::register_e regId) const; + //! Returns true if regId is a debug (dr) register. + TRITON_EXPORT bool isDebug(triton::arch::register_e regId) const; + //! Returns true if regId is a Segment. TRITON_EXPORT bool isSegment(triton::arch::register_e regId) const; diff --git a/src/testers/unittests/test_registers.py b/src/testers/unittests/test_registers.py index f31aefb3..904146a7 100644 --- a/src/testers/unittests/test_registers.py +++ b/src/testers/unittests/test_registers.py @@ -120,7 +120,16 @@ class TestRegisterValues(unittest.TestCase): self.ctx = TritonContext() self.ctx.setArchitecture(ARCH.X86_64) - def test_set_concrete_value(self): + def set_concrete_value(self, ctx): + for reg in ctx.getParentRegisters(): + i = random.randrange(0, 0xffffffffffffffff) & reg.getBitvector().getMaxValue() + self.assertEqual(ctx.getConcreteRegisterValue(reg), 0) + ctx.setConcreteRegisterValue(reg, i) + self.assertEqual(ctx.getConcreteRegisterValue(reg), i) + ctx.setConcreteRegisterValue(reg, 0) + self.assertEqual(ctx.getConcreteRegisterValue(reg), 0) + + def test_set_concrete_value1(self): """Check register value modification.""" for reg in (REG.X86_64.AH, REG.X86_64.AL): # OK @@ -135,6 +144,12 @@ class TestRegisterValues(unittest.TestCase): with self.assertRaises(Exception): self.ctx.setConcreteRegisterValue(reg, 2) + def test_set_concrete_value2(self): + ctx1 = TritonContext(ARCH.X86_64) + ctx2 = TritonContext(ARCH.X86) + self.set_concrete_value(ctx1) + self.set_concrete_value(ctx2) + def test_overlap(self): """Check register overlapping.""" self.assertTrue(self.ctx.registers.ax.isOverlapWith(self.ctx.registers.eax), "overlap with upper")