Skip to content

Tracing local indirect calls

hasherezade edited this page Oct 14, 2021 · 18 revisions

Sometimes calls to local functions are performed in indirect way: using a dynamically retrieved address rather than a hardcoded one.

For example:

CALL DWORD PTR [EAX + 8]
CALL EAX
  • This may happen if the called function is virtual.

  • Such calls are also common in obfuscated code. The address where the execution is redirected to may be calculated at runtime, using some additionally obfuscated functions.

The presence of such calls make the execution very difficult to follow - especially if we want to do static analysis.

In order to help resolving this problem, Tiny Tracer allows to log the addresses of local functions that have been called indirectly. This feature can be enabled in the INI file: by setting LOG_INDIRECT_CALLS to True.

When this type of tracing is enabled, the RVA from where the indirect call/jump was performed is added to the TAG file.

Format:

<RVA>;to: <VA of the called function> [<Module Load Base> + <RVA of the called function>]

Example:

24875;to: c970c7 [c70000 + 270c7]
2487d;to: c79fb0 [c70000 + 9fb0]
24896;to: c970c7 [c70000 + 270c7]
2489e;to: c79fb0 [c70000 + 9fb0]

After loading the TAG file into a disassembler, the view gets enriched with the target addresses:

CALL DWORD PTR [EAX + 4] ;to: c79fb0 [c70000 + 9fb0]

If we load the executable into IDA, at the same base as it was used during the tracing*, the resolved addresses will become clickable and easy to follow.

*- loading at arbitrary base is possible if we select the option Manual load in IDA's load window