The Embedded ELF Debugger

The Embedded ELF Debugger (e2dbg) is the implementation of a new concept of debugger that run inside the process to be debugged instead of being an external entity accessing from the outside the target address space. Instead of using system-specific API such as ptrace, the debugger is linked into a library that is getting injected in a process using the LD_PRELOAD environment variable. This makes e2dbg very efficient as it does not need context switching for inspecting the target process. The ERESI debugger can also be scripted in the same conditions as a complete ERESI interpreter is embedded into the debugger.

The main features of the Embedded ELF debugger are :

  • Debugging on dynamic ELF binaries without using ptrace
  • Runtime injection of software extension developed in C language.
  • Runtime static and extern functions redirection.
  • Breakpoints and stepping using the sigaction syscall.
  • Possibility of registers reading and writing on such events.
  • Instruction tracing until next event.
  • Runtime access to the linkmap linked list of the runtime linker.
  • Support for debugging of multithread processes.
  • Backtracing capabilities including on multithread processes.
  • Innovative unintrusive debugging technique : Allocation proxying

Allocation proxying is a technique that allow the embedded ELF debugger to run with its own dynamic memory allocator in the debuggee process. Thus the debugger can allocate memory dynamically without interfering with the real heap of the debuggee process, opening the door to debugging of heap related bugs. This feature is not a memory protection feature, as it was reported by third party people in various uninformed online security news portal.

http://s.eresi-project.org/inc/images/e2dbg-diagram.png

Figure 1: E2dbg in action

Latest news

We report here the latest features of the embedded ELF debugger:

June 17 2007 E2dbg has been modified to start handling static binaries
June 16 2007 E2dbg has been ported on the Solaris Operating system

Portability of e2dbg

Some E2dbg features are more portable than others. The current state of portability is as follow:

Architecture INTEL SPARC32 SPARC64 MIPS32 ALPHAOthers
Breakpoint installation Yes WIP WIP No No No
Stepping Yes No No No No No
Runtime injection of C compiled code Yes Yes Yes WIP Yes No
Runtime static Function redirection Yes No No Yes Yes No
Runtime external Function redirection Yes Yes Yes Yes Yes No
Static ELF file debugging WIP No No 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 Embedded ELF debugger depends on other components from the ERESI framework :

  • libelfsh : the binary manipulation library, for runtime ET_REL injection, EXTPLT partial relinking, and function redirection.
  • libasm : the disassembly engine, for full disassembly of binary code with or without symbols of mapped code.
  • librevm : the Reverse Engineering Vector Machine, for dynamic analysis using the ERESI scripting language.
  • libaspect : the types specification library, a lower-level component necessary for the ERESI language interpreter.

There is two part in e2dbg. The client part (e2dbg itself with its user interface) is not mapped in the debuggee process. But for all real analysis and debugging code, all those libraries are linked into a unique relocatable (.o) file before a unique libe2dbg.so is created and injected in the debuggee process. See libe2dbg page for more information.

Articles about e2dbg

The Embedded ELF debugger is the subject of two articles:

  • Next Generation Debuggers for Reverse Engineering

Classical debuggers make use of an interface provided by the operating system in order to access the memory of programs while they execute. As this model is dominating in the industry and the community, we show that our novel embedded architecture is more adapted when debuggee systems are hostile and protected at the operating system level. This alternative modelization is also more performant as the debugger executes from inside the debuggee program and can read the memory of the host process directly. We give detailed information about how to keep memory unintrusiveness using a new technique called allocation proxying. We reveal how we developed the organization of our multiarchitecture framework and its multiple modules so that they allow for graph-based binary code analysis, ad-hoc typing, compositional fingerprinting, program instrumentation, real-time tracing, multithread debugging and general hooking of systems. We reveal the reflective essence of our framework by embedding its internal structures in our own reverse engineering language, thus recalling concepts of aspect oriented programming.

  • Embedded ELF Debugging

This article presented the improvement and runtime extension to the Cerberus ELF interface by disclosing 7 new binary manipulation techniques on the ELF format. Beside the improvement of ALTPLT, the CFLOW technique allowed internal function redirection for INTEL and MIPS architectures, the EXTPLT technique allowed partial relinking of dynamic binary files, the EXTSTATIC technique allowed partial relinking of static binary files, ALTGOT gave a more portable technique for external function redirection on ALPHA, SPARC and MIPS architectures. Last but not least, the article explained how the framework turned into a very effective generic solution for in-process debugging, uncovering the foundations of the Embedded ELF debugger (e2dbg), making all those techniques also available in runtime, perfoming manipulations directly in memory, using a unified ELF API provided by libelfsh.