Closed ndrewh closed 3 months ago
I've realized there's a decent chance directly calling into the executable won't work as intended, depending on how much indirection is imposed by dynamorio in the first place. I don't think dynamorio actually ever jumps directly to app code; it always translates blocks and then jumps to the translation in the code cache. Depending on whether it also translates certain data accesses, we might not find the library in the state we intended.
Instead, I think it would be useful to have a primitive to "run code from X to Y safely". This has several applications, including making it easier to implement a call primitive. The basic flow needs to look something like this:
p.run_until(end_addr)
I've updated the previous comment now that run_until
is implemented.
I think all we need to implement this is a push/pop operation for register state. We can leave the notion of "safety" or "rollback" to another issue (#31).
I think in theory you can just cast an int to a function pointer using
ctypes.cast
and call it, but I'm not sure. It would be cool to make it easier to do make these calls e.g:It would also be nice to do this with some guardrails. For example:
These guardrails would be quite complicated to implement, so some analysis of use-cases is warranted...