Displaying the value of arguments and return value of a call

Reven v2.10.0
API preview
OS Windows 64-bit
OS Linux 64-bit

When the prototype is known

Automatically detecting the calling convention from the OS

Reven v2.12.0
from typing import Optional def auto_calling_convention( server: reven2.RevenServer, ) -> Optional[reven2.preview.prototypes.callconv_helper.CallConvHelper]: prototypes = reven2.preview.prototypes.RevenPrototypes(server) if server.ossi.os().architecture != reven2.ossi.Architecture.X64: return None if server.ossi.os().family == reven2.ossi.OsFamily.Windows: return prototypes.calling_conventions.Ms64 elif server.ossi.os().family == reven2.ossi.OsFamily.Linux: return prototypes.calling_conventions.Sysv64 return None

Windows 64-bit example

call_tr = tr.step_out(is_forward=False) import reven2.preview.prototypes prototypes = reven2.preview.prototypes.RevenPrototypes(server) call_conv = auto_calling_convention(server) prototype = "char * __cdecl OaGetEnv(char const *);" f = prototypes.parse_one_function(prototype, call_conv) call = f.call_site_values(call_tr) call.arg_n(0) call.ret()

Sample output:

'OACACHEPARAMS' 0

Linux 64-bit example

Use the Sysv64 calling convention.

call_tr = tr.step_out(is_forward=False) import reven2.preview.prototypes prototypes = reven2.preview.prototypes.RevenPrototypes(server) call_conv = auto_calling_convention(server) prototype = "struct FILE; FILE* fopen64(const char *filename, const char *mode);" f = prototypes.parse_one_function(prototype, call_conv) call = f.call_site_values(call_tr) call.args() call.ret()

Sample output:

{'filename': '/proc/spl/kstat/zfs/arcstats', 'mode': 'r'} 0

Using a default prototype

Example with 5 parameters.

call_tr = tr.step_out(is_forward=False) import reven2.preview.prototypes prototypes = reven2.preview.prototypes.RevenPrototypes(server) call_conv = prototypes.calling_conventions.Ms64 prototype = "void* f(void* p0, void* p1, void* p2, void* p3, void* p4);" f = prototypes.parse_one_function(prototype, call_conv) call = f.call_site_values(call_tr) call.args() call.ret()

Sample output:

{'p0': 18446735287469384880, 'p1': 0, 'p2': 18446735287473289024, 'p3': 0, 'p4': 0} 1364968393473
Limitations apply

Using a default prototype works as long as the replaced parameters behave as void*.

This is notably not the case for structs passed by value that are larger than a pointer (in some calling conventions) and for floating-point arguments (in Sysv64).