poke-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

use case: function replacement in ELF binaries


From: Unai Martinez Corral
Subject: use case: function replacement in ELF binaries
Date: Tue, 1 Oct 2019 00:57:28 +0200

Hi all!

As commented at ORConf last weekend, the purpose of this message is to explain a PIE ELF manipulation use case, in order to discuss whether it is a suitable target for poke or if it falls out of scope.

I am currently using Dynamic Binary Modification/Instrumentation (DBM) tools, such as MAMBO (arm, arm64) or DynamoRIO (amd64, arm, arm64), to replace functions in apps/tools available as ELF binaries only. There are four main files in the case:

- app: ELF binary with symbols (not stripped).
- replace.c: replacement C source file.
- plugin/client: C/C++ source of a plugin for MAMBO, or a client for DynamoRIO.
- dbm: MAMBO/DynamoRIO.

The workflow is as follows:

- Given a target function signature (say `void matrix_multiply(char* A, char* B, uint32_t length)`), a user/developer/hacker writes a replacement function in `replace.c` ( e.g. `void my_mm(char* A, char* B, uint32_t length)`).
- In the DBM plugin/client, the API of the corresponding tool is used. For example, with DynamoRIO:

app_pc orig_pc = (app_pc)dr_get_proc_address(mod->handle, matrix_multiply);
if (orig_pc != NULL) {
  drwrap_replace_native ( orig_pc , (app_pc)my_mm , false , 0 , NULL , false );
}

- The plugin/client is compiled, including `replace.c`.
- The app is executed on top of the DBM tool with the plugin/client enabled. Each time `matrix_multiply` is called, `my_mm` is executed instead.

In practice, `replace.c` is `replace.o`, and it contains the simulation of HDL sources; which are generated with GHDL (for VHDL) or Verilator (for verilog). Hence, this procedure is used for behavioural/functional validation of hardware accelerators during development (https://github.com/dbhi). Moreover, when accelerators are synthesised and configured in a SoC with FPGA, the replacement function is used to offload the task to the coprocessor. To be presented at ORConf 2020?

On the one hand, using full-fledged DBM tools allows to further instrument the target app, in order to gain insight about which areas are to be enhanced/accelerated. On the other hand, once the function to be replaced is identified, using DBM tools feels overkill. Therefore, I looked for alternatives:

- In certain cases, it is possible to use LD_PRELOAD. However, AFAIK, this requires the app to load the function from a shared library in the first place. I.e., it does not work with 'internal' functions and/or with statically linked apps.
- For finer grained control, libelf can be used: https://www.apriorit.com/dev-blog/181-elf-hook. Again, I am unsure about the limitations of this approach. Nevertheless, this is kind of a subset of what a DBM tool does.
- https://www.blackhat.com/presentations/bh-asia-02/Clowes/bh-asia-02-clowes.pdf (video https://www.youtube.com/watch?v=18DKETYfvjg) includes the previous approaches, and also file patching and injectso.

As a result, I'd like to explore the possibility of modifying the target app binary statically. I.e., write a pickle for poke which is equivalent to `elf_hook` in the ref above; given the binary and a ` replacement.o` object. After the talk and demo last weekend, it seems that poke might already be aware of all the details of the ELF format, and the language is powerful enough. Nonetheless, my knowledge is pretty limited in this field, and I might be missing many issues. Precisely, *file patching* is defined as "complex and error prone" in the talk from BlackHat2002. Hence, I'm afraid that the pickle might not be trivial.

wdyt?

Salud!

reply via email to

[Prev in Thread] Current Thread [Next in Thread]