class Transition(object):
Entry point object for data related to a transition.
A transition is anything that changes the state of the virtual machine, from `context_before` to `context_after`. Most of the time, that would be an instruction executed by the CPU. Sometimes, it will be an exception (CPU fault or IRQ) instead. In that case, an instruction might still be related to the exception, if for instance it is the source of the fault. In that case, the instruction has not been fully executed by the CPU.
This object is not meant to be constructed directly. Use Trace.transition
instead.
Spawning: >>> # From a trace >>> tr = reven_server.trace.transition(id) >>> >>> # From a context >>> tr = context.transition_before(transition_id) >>> >>> # From a transition >>> tr = reven_server.trace.transition(id) >>> next_tr = tr + 1 >>> prev_tr = tr - 1 >>> other_tr = tr + 10000
Usage: >>> print(tr) >>> if tr.type == TransitionType.Instruction: >>> print(tr.instruction)
Method | __init__ |
Undocumented |
Property | id |
Property: Unique ID of this transition. |
Property | type |
Property: The transition's type. |
Property | instruction |
Property: The associated Instruction if one exists. |
Property | exception |
Property: The associated CPUException if one exists. |
Method | context_before |
Get the Context object before this transition was executed |
Method | context_after |
Get the Context object after this transition was executed |
Method | memory_accesses |
Get a generator over the reven2.memhist.MemoryAccess es at this transition. |
Method | find_inverse |
This method is a helper to get the transition that performs the inverse operation to this transition. |
Method | step_out |
Step out of the current function. |
Method | step_over |
Step over this transition. |
Method | __str__ |
Undocumented |
Method | __repr__ |
Undocumented |
Method | format_as_html |
This method gets an html formatting string representation for this class instance. |
Method | __eq__ |
Undocumented |
Method | __ne__ |
Undocumented |
Method | __lt__ |
Undocumented |
Method | __le__ |
Undocumented |
Method | __gt__ |
Undocumented |
Method | __ge__ |
Undocumented |
Method | __add__ |
Undocumented |
Method | __sub__ |
Undocumented |
Instance Variable | __trace |
Undocumented |
Instance Variable | _data_source |
Undocumented |
Instance Variable | _ossi_data_source |
Undocumented |
Instance Variable | _id |
Undocumented |
Instance Variable | _data_fetched |
Undocumented |
Instance Variable | _context_before |
Undocumented |
Instance Variable | _context_after |
Undocumented |
Class Variable | _unique_count |
Undocumented |
Class Method | _unique_id |
Undocumented |
Property | _trace |
Undocumented |
Property | _data |
Undocumented |
Method | _repr_html_ |
Representation used by Jupyter Notebook when an instance of the Transition class is displayed in a cell. |
Property: Unique ID of this transition.
Can be used to spawn the object from the corresponding `Trace` object.
Returns | An integer . |
Property: The transition's type.
The type of a transition can be one of the following:
Returns | A TransitionType instance. |
Property: The associated Instruction
if one exists.
If this transition is not of type Instruction
of TransitionType
, None
will be returned.
Returns | An Instruction , or None . |
Property: The associated CPUException
if one exists.
If this transition is not of type Exception
of TransitionType
, None
will be returned.
Returns | An CPUException , or None . |
Get the Context object before this transition was executed
>>> Context before -> This transition
Returns | A Context . |
Get the Context object after this transition was executed
>>> This transition -> Context after
Returns | A Context . |
Get a generator over the reven2.memhist.MemoryAccess
es at this transition.
>>> # Getting all accesses as a list at transition 42 (can be long if there are a lots of accesses): >>> list(trace.transition(42).memory_accesses()) [MemoryAccess(transition=Transition(id=42), physical_address=PhysicalAddress(offset=0x7fc03eb8), size=8, operation=MemoryAccessOperation.Write, virtual_address=LinearAddress(offset=0xffff88007fc03eb8))]
>>> # Getting the first memory access at transition 14 >>> next(trace.transition(14).memory_accesses()) MemoryAccess(transition=Transition(id=14), physical_address=PhysicalAddress(offset=0x1f270a2), size=1, operation=MemoryAccessOperation.Read, virtual_address=LinearAddress(offset=0xffffffff81f270a2))
>>> # Getting all addresses that are read at transition 0. >>> addresses = set() >>> for access in trace.transition(0).memory_accesses(operation=reven2.memhist.MemoryAccessOperation.Read): >>> physical_offset = access.physical_address.offset >>> for address in range(physical_offset, physical_offset + access.size) >>> addresses.add(address) >>> for address in addresses: >>> print reven2.address.PhysicalAddress(address) phy:0x36f05080 phy:0x36f05081 phy:0x36f05082 phy:0x36f05083 phy:0x36f05084 phy:0x36f05085 phy:0x36f05086 phy:0x36f05087
Parameters | operation | Only return accesses whose operation equals the specified reven2.memhist.MemoryAccessOperation . If None, return all accesses. |
Returns | a generator of reven2.memhist.MemoryAccess . | |
Raises | RuntimeError | if the memory history resource has not been generated |
This method is a helper to get the transition that performs the inverse
operation to this transition.
The transition switches between user and kernel land. Examples:
syscall
transition => the related sysret
transitionsysret
transition => the related syscall
transitioniretq
transitioniretq
transition => the related exception transitionThe transition does memory accesses:
ret
transition on an indirect call transition e.g. call [rax + 10]
.If the selected access is a write then the next read access on the same memory range is searched for.
If the selected access is a read then the previous write access on the same memory range is searched for.
Example find_inverse
on:
call
transition => the related ret
transition.ret
transition => the related call
transition.push
transition => the related pop
or mov
transition.pop
transition => the related push
transition.store
transition => the related load
transition.load
transition => the related store
transition.Due to the fact that find_inverse
matches with memory accesses to find the inverse instruction, in some special cases, such as ROP chain, the inverse of e.g. a ret
will not be a call
instruction, but could be a mov
to the memory, for example.
This method requires that the REVEN2 server have the Memory history enabled.
It can be combined with other features like backtrace to obtain interesting results.
For example, to jump to the end of the current function:
>>> import reven2 >>> reven_server = reven2.RevenServer('localhost', 13370) >>> current_transition = reven_server.trace.transition(10000000) >>> ret_transition = current_transition.find_inverse()
Returns | reven2.trace.Transition or None if no inverse found. |
Step out of the current function.
Step out forward: exit the current function by returning the transition after the ret.
Step out backward: exit the current function by returning the call transition.
Parameters | is_forward | bool , True to step out forward and False to step out backward |
Returns | reven2.trace.Transition or None if the transition is not in the recorded trace. | |
Raises | RuntimeError | if the debugger interface is not available. |
Step over this transition.
Step over forward:
Step over backward:
Parameters | is_forward | bool , True to step over forward and False to step over backward. |
Returns | reven2.trace.Transition or None if the transition is not in the recorded trace. | |
Raises | RuntimeError | if the debugger interface is not available. |
This method gets an html formatting string representation for this class instance.
Returns | String |
Representation used by Jupyter Notebook when an instance of the Transition class is displayed in a cell.
The transition is returned as a clickable link containing the transition id, that publishes the transition to all tracked reven2.session.Sessions
.