Re: [DynInst_API:] Dyninst binary rewriting and ldd/gdb problem


Date: Wed, 20 Aug 2014 13:54:43 -0500
From: Bill Williams <bill@xxxxxxxxxxx>
Subject: Re: [DynInst_API:] Dyninst binary rewriting and ldd/gdb problem
On 08/20/2014 01:36 PM, Mohamed Elsabagh wrote:
Hello everyone,

I am having a problem with binaries rewritten by Dyninst. Both ldd and
gdb cannot handle the rewritten binaries. Specifically, ldd says that
the binaries are not dynamically linked, and gcc does not correctly
disassemble them (some bad instructions and garbled backtraces). This
happens whether there was any instrumentation done on the mutatees or
not. The patched binaries execute properly, regardless of the
discrepancies though.

Follows is a minimal working example that reproduces the problem at my
end. Any help with this is highly appreciated.

Mo--

All of these are known issues, and should be cosmetic. Details follow:

* ldd has been confused by a small bug in our rewriting code for, it turns out, the past three years. .dynamic sections were one entry too big. This should be fixed in 8.2 (now tagged in our git repository, packages coming soon!). * We do not produce separate code and data sections for code/data that we add or instrument. gdb and objdump are both easily confused by this, as we'll often have a few words of data at the beginning of the .dyninstInst section and it will take some time for the code to realign. It should be straightforward to add NOP padding to the next 16-byte aligned location (for example) before we drop code into the section; it just hasn't been a priority. If you're interested in experimenting with that I can show you where to poke the code. * gdb will likewise be confused by backtraces as we don't currently update DWARF unwinding information when we relocate functions. Our stackwalkerAPI component is capable of understanding traces in relocated code (and if you use the stack walking functionality in dyninst itself, it comes with the ability to understand whether we're in generated instrumentation code as well--bonus!). The dyninst functionality is most useful if you're modifying a live process, but it's not hard to collect a stack trace from a rewritten binary with stackwalker, and that should get you reasonable results--we're emitting function symbols in .dyninstInst, we're just not emitting DWARF. This is under consideration for a future release (not 8.2) but it's going to take a fair bit of time and work.

Let me know if you've got more detailed questions about how to debug a rewritten binary effectively--we do a lot of that sort of thing around here.

Thanks,
Mo

Mutatee: hello.c
------------------------
#include <stdio.h>

int main(void) {
   printf("Hello, World!");
   return 0;
}

compile with:
$ gcc -g -o hello hello.c


Mutator: patcher.cpp
------------------------------
#include "BPatch.h"
#include "BPatch_binaryEdit.h"

int main() {
   BPatch bpatch;

   BPatch_addressSpace *app = bpatch.openBinary("hello");
   BPatch_image *appImage = app->getImage();

   BPatch_binaryEdit *appBin = dynamic_cast<BPatch_binaryEdit *>(app);
   appBin->writeFile("hello.patched");

   return 0;
}

compile with:
g++ -I/usr/include/dyninst -o patcher patcher.cpp -ldyninstAPI

My environment specs:
----------------------------------
libdyninst-dev 8.1.2-1 amd64
gcc 4.8.2-21
ldd 2.18-5
gdb 7.6.2-1.1
Debian Jessie 2.6.32-042 stable x86_64.





_______________________________________________
Dyninst-api mailing list
Dyninst-api@xxxxxxxxxxx
https://lists.cs.wisc.edu/mailman/listinfo/dyninst-api



--
--bw

Bill Williams
Paradyn Project
bill@xxxxxxxxxxx
[← Prev in Thread] Current Thread [Next in Thread→]