GJDuck / e9patch

A powerful static binary rewriting tool
GNU General Public License v3.0
986 stars 67 forks source link

Some warnings when Instrumenting openssl via e9path #78

Closed komorogrov closed 5 months ago

komorogrov commented 5 months ago

Hello GJDuck: E9patch is a very useful tool that helps me a lot in my daily work!

But, when I used the trampoline pattern to instrumentation openssl programs, the following issues occurred: ./e9tool -M 'plugin(e9AFLPlugin).match()' -P 'entry(random)@afl-rt' ./e9-test/openssl/apps/openssl -o ./e9-test/openssl/apps/openssl-e9-0607

e9patch-2

Based on the experience of previous runs, the number of instrumentation is unusual. Given the code size of openssl programs, the number of instrumentation is clearly low. And through the actual AFL running test, it is found that compared with the afl-clang-fast instrumentation, the e9 instrumentation program is indeed problematic.

`----------------------------------------------- mode = Linux ELF executable input_binary = ./e9-test/openssl/apps/openssl output_binary = ./e9-test/openssl/apps/openssl-e9-0607 num_patched = 1815 / 1815 (100.00%) num_patched_B1 = 1703 / 1815 (93.83%) num_patched_B2 = 92 / 1815 (5.07%) num_patched_T1 = 17 / 1815 (0.94%) num_patched_T2 = 0 / 1815 (0.00%) num_patched_T3 = 3 / 1815 (0.17%) num_virtual_mappings = 98 num_physical_mappings = 75 (76.53%) num_virtual_bytes = 401408 num_physical_bytes = 307200 (76.53%) input_file_size = 13081632 output_file_size = 13475285 (103.01%) time_elapsed = 80ms memory_used = 30676KB

`

openssl is the only program I've encountered so far that fails to instrumentation, so I wonder why, and if there is a solution?

openssl can be obtained as follows:

git clone https://github.com/openssl/openssl.git cd openssl git checkout 0437435a CC=gcc ./config no-shared --debug --with-rand-seed=none CC=gcc make include/openssl/configuration.h include/openssl/opensslv.h include/crypto/bn_conf.h include/crypto/dso_conf.h CC=gcc make apps/openssl

GJDuck commented 5 months ago

The problem is that openssl puts data in the code (.text) section. Since the E9Patch rewriting transformations must only be applied to code, this data must be left untouched, meaning that the disassembler must somehow differentiate between code and data.

However, this is a difficult problem in general, and is a problem that E9Tool/E9Patch does not aim to solve. Most binaries do not put data in the code sections, so are not affected.

However, if the binary does put data-in-code, there are three main options:

  1. Use the default E9Tool detection and recovery. However, this is not very good and tends to overapproximate.
  2. Manually determine the address range(s) of data in the code sections. These ranges can be excluded from E9Tool disassembly using the -E option. If you can accurately determine these ranges then the problem will be solved.
  3. Use a third-party disassembler that better handles data-in-code, such as ddisasm. You'll need to convert the disassembly output into a CSV file of addresses (the base address of each instruction), and pass this file to E9Tool's --use-disasm option. This option will override the default linear disassembler of E9Tool in favour of the disassembly represented by the CSV file.

I have previous considered integrating recursive disassemblers into E9Tool, but this would be a lot of work, and in practice most binaries do not need it.

komorogrov commented 5 months ago

OK, thanks for your detailed replay.

GJDuck commented 5 months ago

No problem.