class Search(object):
Entry point object to find interesting points in a trace.
This object is not meant to be constructed directly. Use RevenServer.trace.search
(Trace.search
) instead.
The last context of a trace is currently not searchable.
>>> # 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 | symbol |
Search all contexts where the PC register (RIP on x86-64) is pointing to a symbol. |
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. |
Instance Variable | _trace |
Undocumented |
Instance Variable | _rvn |
Undocumented |
Method | _search_range |
Undocumented |
Method | _search |
Undocumented |
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.
Depends on the fast search resources (Binary ranges and PC ranges). If one of them is not available, an exception will be raised.
The last context of a trace is currently not searchable.
>>> # 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 ...
Parameters | symbol | the symbol to search. Must be a `reven.ossi.Symbol`. |
from_context | The context from where the search starts. If None, search from the first context in the trace. | |
to_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 | A generator of trace.Context instances. | |
Raises | TypeError | if `symbol` is not a `reven.ossi.Symbol`. |
TypeError | if `from_context` or `to_context` are not None and not a `reven.trace.Context`. | |
ValueError | if `to_context` is lower than `from_context`. | |
RuntimeError | if binary ranges resource is unavailable. | |
RuntimeError | if pc ranges resource is unavailable. |
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.
Depends on the fast seach binary ranges resource. If unavailable, the binary search is still working but in a very slow mode.
The last context of a trace is currently not searchable.
>>> # 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 ...
Parameters | binary | the binary to search. Must be a `reven.ossi.Binary`. |
from_context | The context from where the search starts. If None, search from the first context in the trace. | |
to_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 | A generator of trace.Context instances. | |
Raises | TypeError | if `binary` is not a `reven.ossi.Binary`. |
TypeError | if `from_context` or `to_context` are not None and not a `reven.trace.Context`. | |
ValueError | if `to_context` is lower than `from_context`. |
Search all slices in memory that match with the specified byte pattern.
Requires the memory history resource. If unavailable, will raise a RuntimeError
.
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.
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)
Parameters | pattern | bytes to search for. |
from_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 | if not None , stop the search before the specified context. | |
Returns | A reven2.search_in_memory.Search instance. | |
Raises | RuntimeError | if the memory history is unavailable. |
ValueError | if to_context is the first context or if from_context is greater than to_context . |
Search all contexts where the PC register (RIP on x86-64) is equal to an address.
Depends on the fast search PC ranges resource. If unavailable, the pc search is still working but in a very slow mode.
The last context of a trace is currently not searchable.
>>> # 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 ...
Parameters | address | the address to search. Must be an int -like object. |
from_context | The context from where the search starts. If None, search from the first context in the trace. | |
to_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 | A generator of trace.Context instances. | |
Raises | TypeError | if `address` is not an `int`. |
TypeError | if `from_context` or `to_context` are not None and not a `reven.trace.Context`. | |
ValueError | if `to_context` is lower than `from_context`. |