Skip to content

Commit

Permalink
Fix #889: ALIGNED_MEMORY was broken
Browse files Browse the repository at this point in the history
  • Loading branch information
JonathanSalwan committed Apr 25, 2020
1 parent 2a4ad9d commit 72cf02b
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 19 deletions.
2 changes: 1 addition & 1 deletion .build_number
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1463
1464
11 changes: 7 additions & 4 deletions src/libtriton/ast/astContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,13 @@ namespace triton {

SharedAbstractNode AstContext::collect(const SharedAbstractNode& node) {
/*
* We keep a shared reference of nodes in a deep AST. Instead of keeping
* each node (which does not scales), we only keep one reference at each
* deep step of 10000. Thus, it will avoid the stack recursion on destructor
* calls of shared_ptr.
* We keep references to nodes which belong to a depth in the AST which is
* a multiple of 10000. Thus, when the root node is destroyed, the stack recursivity
* stops when the depth level of 10000 is reached, because the nodes there still
* have a reference to them in the AST manager. The destruction will continue at the
* next allocation of nodes and so on. So, it means that ASTs are destroyed by steps
* of depth of 10000 which avoids the overflow while keeping a good scale.
*
* See: #753.
*/
triton::uint32 lvl = node->getLevel();
Expand Down
16 changes: 4 additions & 12 deletions src/libtriton/engines/symbolic/symbolicEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,22 +148,15 @@ namespace triton {


/* Gets an aligned entry. */
inline SharedSymbolicExpression SymbolicEngine::getAlignedMemory(triton::uint64 address, triton::uint32 size) {
return this->alignedMemoryReference[std::make_pair(address, size)].lock();
const SharedSymbolicExpression& SymbolicEngine::getAlignedMemory(triton::uint64 address, triton::uint32 size) {
return this->alignedMemoryReference[std::make_pair(address, size)];
}


/* Checks if the aligned memory is recored. */
bool SymbolicEngine::isAlignedMemory(triton::uint64 address, triton::uint32 size) {
if (this->alignedMemoryReference.find(std::make_pair(address, size)) != this->alignedMemoryReference.end()) {
/* Also check if the symbolic expression is alive */
if (this->alignedMemoryReference[std::make_pair(address, size)].lock()) {
return true;
}
/* Also check if the symbolic expression is alive */
else {
this->removeAlignedMemory(address, size);
}
return true;
}
return false;
}
Expand Down Expand Up @@ -783,8 +776,7 @@ namespace triton {
* If the memory access is aligned, don't split the memory.
*/
if (this->modes->isModeEnabled(triton::modes::ALIGNED_MEMORY) && this->isAlignedMemory(address, size)) {
triton::ast::SharedAbstractNode anode = this->getAlignedMemory(address, size)->getAst();
return anode;
return this->getAlignedMemory(address, size)->getAst();
}

/* If the memory access is 1 byte long, just return the appropriate 8-bit vector */
Expand Down
4 changes: 2 additions & 2 deletions src/libtriton/includes/triton/symbolicEngine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ namespace triton {
* **item1**: <addr:size><br>
* **item2**: shared symbolic expression
*/
std::map<std::pair<triton::uint64, triton::uint32>, WeakSymbolicExpression> alignedMemoryReference;
std::map<std::pair<triton::uint64, triton::uint32>, SharedSymbolicExpression> alignedMemoryReference;

/*! \brief map of address -> symbolic expression
*
Expand Down Expand Up @@ -128,7 +128,7 @@ namespace triton {
triton::usize getUniqueSymVarId(void);

//! Gets an aligned entry.
inline SharedSymbolicExpression getAlignedMemory(triton::uint64 address, triton::uint32 size);
const SharedSymbolicExpression& getAlignedMemory(triton::uint64 address, triton::uint32 size);

//! Adds an aligned entry.
void addAlignedMemory(triton::uint64 address, triton::uint32 size, const SharedSymbolicExpression& expr);
Expand Down
40 changes: 40 additions & 0 deletions src/testers/unittests/test_symbolic_optimizations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/usr/bin/env python
# coding: utf-8
"""Test Symbolic Optimizations."""

import unittest
from triton import *


class TestSymbolicOptimizations(unittest.TestCase):

"""Testing ALIGNED_MEMORY."""

def setUp(self):
self.ctx = TritonContext(ARCH.X86_64)


def test_without_optim(self):
self.ctx.setMode(MODE.ALIGNED_MEMORY, False)

self.ctx.processing(Instruction(b"\x48\xc7\xc0\x01\x00\x00\x00")) # mov rax, 1
self.ctx.processing(Instruction(b"\x48\x89\x03")) # mov [rbx], rax
self.ctx.processing(Instruction(b"\x48\x8b\x0b")) # mov rcx, [rbx]

rcx = self.ctx.getMemoryAst(MemoryAccess(0, CPUSIZE.QWORD))
self.assertEqual(rcx.getType(), AST_NODE.CONCAT)
self.assertEqual(rcx.evaluate(), 1)
return


def test_with_optim(self):
self.ctx.setMode(MODE.ALIGNED_MEMORY, True)

self.ctx.processing(Instruction(b"\x48\xc7\xc0\x01\x00\x00\x00")) # mov rax, 1
self.ctx.processing(Instruction(b"\x48\x89\x03")) # mov [rbx], rax
self.ctx.processing(Instruction(b"\x48\x8b\x0b")) # mov rcx, [rbx]

rcx = self.ctx.getMemoryAst(MemoryAccess(0, CPUSIZE.QWORD))
self.assertEqual(rcx.getType(), AST_NODE.REFERENCE)
self.assertEqual(rcx.evaluate(), 1)
return

0 comments on commit 72cf02b

Please sign in to comment.