The Embedded ELF tracer : Etrace

The ERESI tracer is an embedded tracer which operates directly from within the traced the binary itself. We acheive this modus operandi by using binary module injection and function redirection. A new binary is created where all functions are hooked so we can display the program entering and leaving functions. As the tracer is directly into the traced binary, we gain performance as we dont need to single-step, in comparison with others tracers relying on a kernel interface like its ptrace debugging API. Another major difference is that etrace works on all functions without using a predefined list, as done by most other tracers. Etrace was designed for reverse engineering targets with not only glibc functions, but also a custom function present in your binary or in a specific library.

The main features of the ELF tracer (etrace) are :

  • Command-line tracing on ELF binaries without using ptrace.
  • A logical organization of trace events fully integrated in the scripting language.
  • Support debug format information (if available) to display names and types of function parameters.
  • Advanced user control over selection of traced functions with regular expressions.

Our approach of tracing is a new innovation of the ERESI project. We are working on making this component more stable and reliable. It is however already usable incrementally by specifying functions not to be traced when necessary.

Latest news

This list shows major modifications in Etrace since the fist version:

June 15 2007 Improving function argument counting engine for intel x86.
May 21 2007 Tracing made easier with etrace command line.
March 20 2007 Initial version of etrace.

Portability of Etrace

For the moment the tracer is unable to trace some internal functions optimized by compilers. Those functions can crash the program or create unknown behavior if you trace them. We are currently working to support those functions.

Features Linux INTEL FreeBSD INTEL Solaris INTEL Linux SPARC FreeBSD SPARC Solaris SPARC
Tracing of external functions Yes Yes Yes No No No
Tracing of internal functions Yes Yes Yes No No No
Tracing functions of variable arguments number WIP WIP WIP No No No
Tracing of Aggressively optimized functions WIP WIP WIP No No No
Multi-threads tracing WIP WIP WIP No No No

Unavailable features are the subject of contributions, if someone else has not taken over the implementation of the feature on the bts.

Dependencies

The ELF tracer depends on other components from the ERESI framework :

  • libelfsh: the binary manipulation library, for binary injection, function redirection and argument counting.
  • libedfmt: the debug format support library, to retrieve function information from uniform debug format.
  • libasm: the disassembly engine, for argument counting algorithm.
  • librevm : the Reverse Engineering Vector Machine, for trace interface.

Articles about etrace

The ELF tracer (etrace) is featured in one article:

  • Next Generation Debuggers for Reverse Engineering

Etrace is an embedded tracer which was built for tracing internal and external calls. Most tracers do not trace internal calls because they rely on a statically stored function prototypes list. Despite the fact that it provides a correct prototype on those functions, you cannot deal with unknown functions. Etrace is a tracer built to deal with every functions. It means you do not have to create a function prototypes database. Our tracing technology is dynamic and supports multiple architectures. We take advantage of the debugging format information of libedfmt to retrieve exact function prototypes. In case the debugging information is not available, an architecture dependent analysis allows to retrieve a deduced prototype. We present our tracer as embedded because we redirect traced functions directly in the target binary. Then we create a new file that includes and reports tracing information. Etrace does not use any kernel debugging interface and only relies on analysis of parameters. This is done using an architecture dependent function that is hooked using a reflective vector as provided by libaspect .