package documentation

Package related to function prototypes parsing.

Parse function prototypes and get arguments and return value at specific points in the trace.

Starting with the Prototypes API

Get arguments and return value on a call transition

>>> import reven2.preview
>>> # Get a handle on the prototypes capability from a reven server
>>> rvnproto = reven2.preview.prototypes.RevenPrototypes(reven_server)
>>> # Parse a prototype and set a calling convention
>>> proto_str = "struct FILE{}; FILE *fopen(const char *pathname, const char *mode);"
>>> calling_convention = rvnproto.calling_conventions.Sysv64
>>> fopen_proto = rvnproto.parse_one_function(proto_str, calling_convention)
>>> # Apply the prototype on same `call` transition
>>> call_tr = reven_server.trace.transition(104981438)
>>> print(call_tr)
#104981438 call 0x7fc3889d3230
>>> fopen = fopen_proto.call_site_values(call_tr)
>>> # get arguments as a dict
>>> print(fopen.args())
{'pathname': '/etc/passwd', 'mode': 'rce'}
>>> # get the returned value
>>> print(hex(fopen.ret()))
0x557c1ffee7c0
>>> # get argument by name
>>> print(fopen.arg("pathname"))
/etc/passwd
>>> # get argument by index
>>> print(fopen.arg_n(1))
rce

Sample use case

Search fopen on /etc/passwd

>>> # assuming fopen_proto from the starting example
>>> from_context = reven_server.trace.context_after(104900000)
>>> for symbol in reven_server.ossi.symbols(pattern="^fopen$", binary_hint="libc"):
...    for context in rvn.trace.search.symbol(symbol, from_context=from_context):
...        call_tr = context.transition_after().step_out(is_forward=False)
...        fopen = fopen_proto.call_site_values(call_tr)
...        if fopen.arg("pathname") == "/etc/passwd":
...            print(call_tr)
...            break  # break on first match
#104981438 call 0x7fc3889d3230

Calling conventions

The calling convention is a mapping between the arguments of a function and the means they can be accessed at a low-level in the code of that function, such as the register each argument lives in, depending on the type of the arguments.

Because the calling convention is a convention between the caller and callee of a function, it cannot (reliably) be detected as runtime, which is why it has to be provided by the user of this API.

Selecting the wrong calling convention is likely to result in the wrong location to be read, and so incorrect values being found for arguments.

The available calling conventions are:

  • Ms64 Microsoft x64 calling convention, used by Windows 64-bit
  • Sysv64 System V ABI AMD64 calling convention, used by Linux 64-bit
  • Cdecl32 cdecl calling convention, used by 32-bit systems
  • Stdcall32 stdcall calling convention, used by Windows 32-bit to call Win32 API functions.
  • Fastcall32 fastcall calling convention, sometimes used by Windows 32-bit

Unimplemented calling conventions:

  • thiscall, vectorcall: currently not implemented.

Known limitations

  • For C++, this is not handled and would shift arguments. A workaround is to add a void* this argument in the prototype.
  • Arguments and return bigger than 64bit are not handled.
Module callconv_helper Implementation details of a helper to use calling convention implementations.
Package calling_conventions Implementation details for each calling convention.
Module parsing_types Binding of the reven low level parsing API types
Module prototype Prototype: a function and a calling convention Get arguments and return values at given points in the trace.
Module reven_prototypes C and C++ prototypes parsing.