Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

State Copy? #532

Open
bannsec opened this issue May 6, 2017 · 17 comments
Open

State Copy? #532

bannsec opened this issue May 6, 2017 · 17 comments

Comments

@bannsec
Copy link
Contributor

bannsec commented May 6, 2017

It's not clear if it's possible to copy a given state. The examples I'm seeing are single traces through an application.

For instance, take state1 and return state1.copy that have the same information but are separate so that changes in one do not affect changes in the other.

@JonathanSalwan
Copy link
Owner

It's currently not really possible (takeSnapshot into the pintool module is a hack). But! we will add this feature for sure into the new API (dev-pb). For example, we could do something like this:

ctx = TritonContext()
# ...
bck = TritonContext(ctx) # do the state copy.

What do you think @pbrunet?

@bannsec
Copy link
Contributor Author

bannsec commented May 7, 2017

Hmm... How much different is this dev-pb API going to be? Is it still using the core API now and adding to it or are those calls changing?

@JonathanSalwan
Copy link
Owner

JonathanSalwan commented May 7, 2017

All methods are kept the same. The main difference is that you need to instance a context.

@JonathanSalwan JonathanSalwan modified the milestones: v0.6, v0.5 May 15, 2017
@JonathanSalwan JonathanSalwan modified the milestones: v0.6, v0.x Dec 6, 2017
@illera88
Copy link
Contributor

illera88 commented May 6, 2020

Hey, are you still gonna pursue this?
Why is the takesnapshot a hack?

@JonathanSalwan
Copy link
Owner

Hey, are you still gonna pursue this?

Yep, I should...

Why is the takesnapshot a hack?

takesnapshot starts to record all modifications on memory and restoresnapshot undo all these modifications. This is a hack compared to what I've in mind with bck = TritonContext(ctx). In this case, we have to make copy of every object so that contexts are independent of each others.

@dvcrn
Copy link

dvcrn commented Jul 7, 2020

Are there news on copying a context/state? For example I'd like to create a base context, load a binary and some memory, and then branch off for individual functions

@DarkaMaul
Copy link

I'm working on it but no ETA yet ;)

@dvcrn
Copy link

dvcrn commented Jul 18, 2020

I've been wondering if there is a hacky solution that is usable from the python binding (snapshot isn't exposed)?

I wanted to ship my own, but getting all internal state such as all concretized memory to copy to a new state is not easy

@JonathanSalwan
Copy link
Owner

Note to myself: See #1012

@namreeb
Copy link

namreeb commented Aug 14, 2022

Just came here to say this would be useful to me as well when conducting recursive branch exploration to prove basic blocks and identify compounded opaque predicates.

@JonathanSalwan
Copy link
Owner

JonathanSalwan commented Aug 14, 2022

It's not an easy task, especially copying all shared_ptr (AbstractNode and SymbolicExpression). However, you can easily snapshot a state if you do not care about that states share pointers. Below an example of a snapshot function.

void SymbolicExplorator::snapshotContext(triton::Context* dst, triton::Context* src) {
  /* Synch concrete state */
  switch (src->getArchitecture()) {
    case triton::arch::ARCH_X86_64:
      *static_cast<triton::arch::x86::x8664Cpu*>(dst->getCpuInstance()) = *static_cast<triton::arch::x86::x8664Cpu*>(src->getCpuInstance());
      break;
    case triton::arch::ARCH_X86:
      *static_cast<triton::arch::x86::x86Cpu*>(dst->getCpuInstance()) = *static_cast<triton::arch::x86::x86Cpu*>(src->getCpuInstance());
      break;
    case triton::arch::ARCH_ARM32:
      *static_cast<triton::arch::arm::arm32::Arm32Cpu*>(dst->getCpuInstance()) = *static_cast<triton::arch::arm::arm32::Arm32Cpu*>(src->getCpuInstance());
      break;
    case triton::arch::ARCH_AARCH64:
      *static_cast<triton::arch::arm::aarch64::AArch64Cpu*>(dst->getCpuInstance()) = *static_cast<triton::arch::arm::aarch64::AArch64Cpu*>(src->getCpuInstance());
      break;
    default:
      throw triton::exceptions::Engines("SymbolicExplorator::snapshotContext(): Invalid architecture");
  }

  /* Synch symbolic register */
  dst->concretizeAllRegister();
  for (const auto& item : src->getSymbolicRegisters()) {
    dst->assignSymbolicExpressionToRegister(item.second, dst->getRegister(item.first));
  }

  /* Synch symbolic memory */
  dst->concretizeAllMemory();
  for (const auto& item : src->getSymbolicMemory()) {
    dst->assignSymbolicExpressionToMemory(item.second, triton::arch::MemoryAccess(item.first, triton::size::byte));
  }

  /* Synch path predicate */
  dst->clearPathConstraints();
  for (const auto& pc : src->getPathConstraints()) {
    dst->pushPathConstraint(pc);
  }
}

Then, you can do something like this:

/* backup the current context */
this->bck_ctx = new triton::Context(this->cur_ctx->getArchitecture());
this->snapshotContext(this->bck_ctx, this->cur_ctx);

/* do what you want */

/* restore the context */
this->snapshotContext(this->cur_ctx, this->bck_ctx);

The main point you have to keep in mind with this method is that if you modify an AST from a state (like in cur_ctx), it will affect all the others state (like bck_ctx).

@jmm14304
Copy link

I was wondering, is it possible the method Context::processing could change an AST from a state and affect the others?
I'm just trying to follow the registers state in a recursive branch exploration and processing instructions is pretty much the only thing I need. I'm not sure if there is something that could mess the snapshots (such as the mode AST_OPTIMIZATIONS) while processing instructions.

@JonathanSalwan
Copy link
Owner

Yes, AST will be shared between context (they are shared_ptr).

@MellowNight
Copy link

Does anyone know of any other symex libraries with a C++ API that allow you to fork the symbolic execution context along with AST state?

Exploring all code paths and forking context using Angr is very easy, however Angr does everything in python.

@bannsec
Copy link
Contributor Author

bannsec commented Jan 6, 2023

S2E comes to mind: https://s2e.systems/docs/

However, note it will likely be a lot heavier as it does not summarize the environment, but rather integrates symbolic execution into a full virtual machine.

@ZehMatt
Copy link
Contributor

ZehMatt commented Jul 28, 2023

I would also like to see this feature, I'll give it a shot and see how far I can get.

@ZehMatt
Copy link
Contributor

ZehMatt commented Jul 31, 2023

I definitely did not anticipate to how convoluted everything is, the fact that the AST nodes store the Context makes this a bit harder than I initially thought, I will continue to pursue this but I might have to put a stop to it as the better course of action would be to first do some major cleaning up. I think it would be better to pass the Context to the individual functions as parameters for when its really needed, but I'll see what can be done.

Edit: Nope, not gonna do it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants