class documentation

class Search(object):

View In Hierarchy

Entry point object to find interesting points in a trace.

Warnings

This object is not meant to be constructed directly. Use RevenServer.trace.search (Trace.search) instead.

Limitations

The last context of a trace is currently not searchable.

Examples

>>> # From a reven_server
>>> search = reven_server.trace.search
>>>
>>> # search for rip = 0xdeadbeef in the whole trace.
>>> for context in search.pc(0xdeadbeef):
...     print(context)
Method __init__ Undocumented
Method binary Search all contexts where the PC register (RIP on x86-64) is pointing to a binary.
Method memory Search all slices in memory that match with the specified byte pattern.
Method pc Search all contexts where the PC register (RIP on x86-64) is equal to an address.
Method symbol Search all contexts where the PC register (RIP on x86-64) is pointing to a symbol.
Method _search Undocumented
Method _search_range Undocumented
Instance Variable _rvn Undocumented
Instance Variable _trace Undocumented
def __init__(self, _rvn, trace):

Undocumented

Parameters
_rvn:_reven_api.reven_connectionUndocumented
trace:_trace.TraceUndocumented
def binary(self, binary, from_context=None, to_context=None):

Search all contexts where the PC register (RIP on x86-64) is pointing to a binary.

A valid `ossi.Binary` object must be given. To get one, use the `Ossi.executed_binaries` method.

Warnings

Depends on the fast seach binary ranges resource. If unavailable, the binary search is still working but in a very slow mode.

Limitations

The last context of a trace is currently not searchable.

Examples

>>> # Search for binary "kernelbase.dll"
>>> for binary in reven_server.ossi.executed_binaries('kernelbase\.dll'):
...     for ctx in trace.search.binary(binary):
...         print(ctx)
Context before #240135
Context before #240136
Context before #240137
Context before #240138
Context before #240139
Context before #240140
Context before #240141
...
>>> # Search for binary "kernelbase.dll" until context before transition 240138
>>> for binary in reven_server.ossi.executed_binaries('kernelbase\.dll'):
...     for ctx in trace.search.binary(binary, to_context=trace.context_before(240138)):
...         print(ctx)
Context before #240135
Context before #240136
Context before #240137
>>> # Search for binaries that contains "\.exe"
>>> for binary in reven_server.ossi.executed_binaries('\.exe'):
...     for ctx in trace.search.binary(binary):
...         print(ctx)
Context before #1537879110
Context before #1537879111
Context before #1537879112
Context before #1537879113
Context before #1537879372
Context before #1537879373
Context before #1537879374
...

Information

Parameters
binary:_ossi.Binarythe binary to search. Must be a `reven.ossi.Binary`.
from_context:_Optional[_trace.Context]The context from where the search starts. If None, search from the first context in the trace.
to_context:_Optional[_trace.Context]The context where the search ends. This context is excluded from the search. If None, search until the last context in the trace.
Returns
_Iterator[_trace.Context]A generator of trace.Context instances.
Raises
TypeErrorif `binary` is not a `reven.ossi.Binary`.
TypeErrorif `from_context` or `to_context` are not None and not a `reven.trace.Context`.
ValueErrorif `to_context` is lower than `from_context`.
def memory(self, pattern, from_context=None, to_context=None):

Search all slices in memory that match with the specified byte pattern.

Warnings

Requires the memory history resource. If unavailable, will raise a RuntimeError.

Limitations

As this search is based on the memory history, it will not find slices in memory that would match the specified byte pattern, but that are never accessed in the trace.

Another way of looking at this is to think that the first context is never searched, even if passed as from_context parameter.

If you think you may miss results due to this limitation, combine this function with Context.search_in_memory at context 0.

Examples

Print all the slices of memory that contain address 0x275fcc0 throughout the whole trace:

>>> for match in search.memory(b"\xc0\xfc\x75\x02").matches():
...     print(match)
id: 0 | @lin:0x275fc68 (mapped at Context before #5667065) | [Context before #0 - Context before #5667088] | 1 access(es)
id: 1 | @lin:0x275fb48 (mapped at Context before #5667142) | [Context before #5667142 - Context before #5689290] | 1 access(es)
id: 2 | @lin:0x275fb30 (mapped at Context before #5667145) | [Context before #5667145 - Context before #5690136] | 1 access(es)
id: 3 | @lin:0x275f9f8 (mapped at Context before #5667209) | [Context before #5667209 - Context before #5670884] | 1 access(es)
id: 4 | @lin:0x275f848 (mapped at Context before #5667340) | [Context before #5667340 - Context before #5670663] | 1 access(es)
id: 5 | @lin:0x275f750 (mapped at Context before #5670549) | [Context before #5670549 - Context before #5670763] | 1 access(es)
id: 6 | @lin:0x275fad8 (mapped at Context before #5670866) | [Context before #5670866 - Context before #6189756] | 1 access(es)
id: 7 | @lin:0x275fb50 (mapped at Context before #5689290) | [Context before #5689290 - Context before #5689307] | 1 access(es)
id: 8 | @lin:0x275fb48 (mapped at Context before #5689291) | [Context before #5689291 - Context before #5689308] | 1 access(es)
id: 9 | @lin:0x275fb50 (mapped at Context before #5689308) | [Context before #5689308 - Context after #16899152] | 1 access(es)
id: 10 | @lin:0x275fc48 (mapped at Context before #5689372) | [Context before #5689372 - Context before #5690008] | 1 access(es)
id: 11 | @lin:0x275fc68 (mapped at Context before #5690005) | [Context before #5690005 - Context after #16899152] | 0 access(es)

Print all the slices of memory that contain "Bob" around the 6_000_000th context:

>>> for match in search.memory(b"Bob", trace.context_before(5700000), trace.context_before(6300000)).matches():
...     print(match)
id: 0 | @lin:0xc7e600 (mapped at Context before #6225933) | [Context before #5700000 - Context before #6299999] | 3 access(es)
id: 1 | @lin:0xc67771 (mapped at Context before #6227260) | [Context before #6227260 - Context before #6299999] | 4 access(es)

Access the events performed by the search rather than the resulting matches (see reven2.search_in_memory.Search for more information):

>>> for event in search.memory(b"Bob", trace.context_before(5700000), trace.context_before(6300000)).events():
...     print(event)
First Access match: 0 | #Context before #6225933 (6225933) | @lin:0xc7e600
Access match: 0 | [#6225933 movzx eax, byte ptr [r12 + rdi]]Read access at @1987147264 (virtual address: lin:0xc7e600) of size 1
Access match: 0 | [#6226404 movzx eax, byte ptr [r12 + rdi]]Read access at @1987147265 (virtual address: lin:0xc7e601) of size 1
Access match: 0 | [#6226875 movzx eax, byte ptr [r12 + rdi]]Read access at @1987147266 (virtual address: lin:0xc7e602) of size 1
Created match: 1 | #6227259 | @lin:0xc67771
Access match: 1 | [#6250476 or rsi, qword ptr [rdx + rax]]Read access at @1166944112 (virtual address: lin:0xc67770) of size 8
Access match: 1 | [#6251934 movzx ebp, byte ptr [r13]]Read access at @1166944113 (virtual address: lin:0xc67771) of size 1
Access match: 1 | [#6251953 movzx ebp, byte ptr [r13]]Read access at @1166944114 (virtual address: lin:0xc67772) of size 1
Access match: 1 | [#6251972 movzx ebp, byte ptr [r13]]Read access at @1166944115 (virtual address: lin:0xc67773) of size 1

Search for a Windows string (UTF-16 encoded):

>>> for match in search.memory("Bob".encode("utf-16-le"), trace.context_before(6000000), trace.context_before(6300000)).matches():
...     print(match)
id: 0 | @lin:0xc7bb32 (mapped at Context before #6251983) | [Context before #6251983 - Context before #6299999] | 1 access(es)
id: 1 | @lin:0xc6a2f2 (mapped at Context before #6252526) | [Context before #6252526 - Context before #6299999] | 2 access(es)
id: 2 | @lin:0xffffd000ae335aa2 (mapped at Context before #6261506) | [Context before #6261506 - Context before #6299999] | 0 access(es)
id: 3 | @lin:0x1f52a28a832 (mapped at Context before #6264365) | [Context before #6264365 - Context before #6299999] | 6 access(es)
id: 4 | @lin:0x605f03f512 (mapped at Context before #6268591) | [Context before #6268591 - Context before #6299999] | 1 access(es)
id: 5 | @lin:0x1f52c4a8512 (mapped at Context before #6272558) | [Context before #6272558 - Context before #6299999] | 1 access(es)
id: 6 | @lin:0x1f52a323502 (mapped at Context before #6274116) | [Context before #6274116 - Context before #6299999] | 4 access(es)
id: 7 | @lin:0xfffff9014008105a (mapped at Context before #6281269) | [Context before #6281269 - Context before #6299999] | 3 access(es)

Information

Parameters
pattern:bytesbytes to search for.
from_context:_Optional[_trace.Context]If not None, start the search at the specified context. The from_context is never inspected entirely, to have information on from_context, use Context.search_in_memory.
to_context:_Optional[_trace.Context]if not None, stop the search before the specified context.
Returns
_search_in_memory.SearchA reven2.search_in_memory.Search instance.
Raises
RuntimeErrorif the memory history is unavailable.
ValueErrorif to_context is the first context or if from_context is greater than to_context.
def pc(self, address, from_context=None, to_context=None):

Search all contexts where the PC register (RIP on x86-64) is equal to an address.

Warnings

Depends on the fast search PC ranges resource. If unavailable, the pc search is still working but in a very slow mode.

Limitations

The last context of a trace is currently not searchable.

Examples

>>> # Search for RIP = 0x7fff57263b2f
>>> for ctx in trace.search.pc(0x7fff57263b2f):
...     print(ctx)
Context before #240135
Context before #281211
Context before #14608067
Context before #14690369
Context before #15756067
Context before #15787089
...
>>> # Search for RIP = 0x7fff57263b2f until context before transition 14608067
>>> for ctx in trace.search.pc(0x7fff57263b2f, to_context=trace.context_before(14608067)):
...     print(ctx)
Context before #240135
Context before #281211
>>> # Search for RIP = 0x7fff57263b2f from context before transition 14608067
>>> for ctx in trace.search.pc(0x7fff57263b2f, from_context=trace.context_before(14608067)):
...     print(ctx)
Context before #14608067
Context before #14690369
Context before #15756067
Context before #15787089
...

Information

Parameters
address:_SupportsIntthe address to search. Must be an int-like object.
from_context:_Optional[_trace.Context]The context from where the search starts. If None, search from the first context in the trace.
to_context:_Optional[_trace.Context]The context where the search ends. This context is excluded from the search. If None, search until the last context in the trace.
Returns
_Iterator[_trace.Context]A generator of trace.Context instances.
Raises
TypeErrorif `address` is not an `int`.
TypeErrorif `from_context` or `to_context` are not None and not a `reven.trace.Context`.
ValueErrorif `to_context` is lower than `from_context`.
def symbol(self, symbol, from_context=None, to_context=None):

Search all contexts where the PC register (RIP on x86-64) is pointing to a symbol.

A valid `ossi.Symbol` object must be given. To get one, use the `Ossi.symbols` method.

Warnings

Depends on the fast search resources (Binary ranges and PC ranges). If one of them is not available, an exception will be raised.

Limitations

The last context of a trace is currently not searchable.

Examples

>>> # Search for symbol "CreateProcessW" in binary "kernelbase.dll"
>>> for symbol in reven_server.ossi.symbols('^CreateProcessW$', binary_hint='kernelbase\.dll'):
...     for ctx in trace.search.symbol(symbol):
...         print(ctx)
Context before #23886919
Context before #1370448535
Context before #2590849986
>>> # Search for symbol "CreateProcessW" in binary "kernelbase.dll" until context before transition 25000000
>>> for symbol in reven_server.ossi.symbols('^CreateProcessW$', binary_hint='kernelbase\.dll'):
...     for ctx in trace.search.symbol(symbol, to_context=trace.context_before(25000000)):
...         print(ctx)
Context before #23886919
>>> # Search for all symbol symbols that contains "acpi"
>>> for symbol in reven_server.ossi.symbols('acpi'):
...     for ctx in trace.search.symbol(symbol):
...         print(ctx)
Context before #1471900961
Context before #1471903808
Context before #1471908093
Context before #1471914935
Context before #1472413834
Context before #1472416173
Context before #1472419063
...

Information

Parameters
symbol:_ossi.Symbolthe symbol to search. Must be a `reven.ossi.Symbol`.
from_context:_Optional[_trace.Context]The context from where the search starts. If None, search from the first context in the trace.
to_context:_Optional[_trace.Context]The context where the search ends. This context is excluded from the search. If None, search until the last context in the trace.
Returns
_Iterator[_trace.Context]A generator of trace.Context instances.
Raises
TypeErrorif `symbol` is not a `reven.ossi.Symbol`.
TypeErrorif `from_context` or `to_context` are not None and not a `reven.trace.Context`.
ValueErrorif `to_context` is lower than `from_context`.
RuntimeErrorif binary ranges resource is unavailable.
RuntimeErrorif pc ranges resource is unavailable.
def _search(self, criteria, from_context, to_context):

Undocumented

Parameters
criteria:_reven_api.criterionUndocumented
from_context:_Optional[_trace.Context]Undocumented
to_context:_Optional[_trace.Context]Undocumented
Returns
_Iterator[_trace.Context]Undocumented
def _search_range(self, from_context, to_context):

Undocumented

Parameters
from_context:_Optional[_trace.Context]Undocumented
to_context:_Optional[_trace.Context]Undocumented
Returns
_reven_api.execution_rangeUndocumented
_rvn =

Undocumented

_trace =

Undocumented