From a4d9762a31402c5e5298ef22870a7e25124a7af2 Mon Sep 17 00:00:00 2001 From: Martin Nowack Date: Mon, 7 Jun 2021 16:26:12 +0100 Subject: Correctly update symbolic variables that have been changed externally Before, external changes to symbolic variables have not been propagated back to their internal representation. Do a byte-by-byte comparison and update object state if required. --- lib/Core/AddressSpace.cpp | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/lib/Core/AddressSpace.cpp b/lib/Core/AddressSpace.cpp index ab3bbb8c..bb77f0fc 100644 --- a/lib/Core/AddressSpace.cpp +++ b/lib/Core/AddressSpace.cpp @@ -336,13 +336,33 @@ bool AddressSpace::copyInConcretes() { bool AddressSpace::copyInConcrete(const MemoryObject *mo, const ObjectState *os, uint64_t src_address) { auto address = reinterpret_cast(src_address); - if (memcmp(address, os->concreteStore, mo->size) != 0) { - if (os->readOnly) { - return false; - } else { - ObjectState *wos = getWriteable(mo, os); - memcpy(wos->concreteStore, address, mo->size); - } + + // Don't do anything if the underlying representation has not been changed + // externally. + if (std::memcmp(address, os->concreteStore, mo->size) == 0) + return true; + + // External object representation has been changed + + // Return `false` if the object is marked as read-only + if (os->readOnly) + return false; + + ObjectState *wos = getWriteable(mo, os); + // Check if the object is fully concrete object. If so, use the fast + // path and `memcpy` the new values from the external object to the internal + // representation + if (!wos->unflushedMask) { + std::memcpy(wos->concreteStore, address, mo->size); + return true; + } + + // The object is partially symbolic, it needs to be updated byte-by-byte + // via object state's `write` function + for (size_t i = 0, ie = mo->size; i < ie; ++i) { + u_int8_t external_byte_value = *(address + i); + if (external_byte_value != wos->concreteStore[i]) + wos->write8(i, external_byte_value); } return true; } -- cgit 1.4.1