Re: [DynInst_API:] Basic Blocks and Register Access


Date: Mon, 28 Apr 2014 11:06:00 -0500
From: Bill Williams <bill@xxxxxxxxxxx>
Subject: Re: [DynInst_API:] Basic Blocks and Register Access
On 04/26/2014 03:28 PM, Sergej Proskurin wrote:
Hello,

Within my current implementation, I am able to split and inject basic
blocks on the basis of PatchAPI. The newly created and injected basic
blocks are currently filled with raw bytes, as stated within the following:

InsertedCode::Ptr icode = PatchModifier::insert(post_block->object(),
bytes, nbytes);

This method of code injection works fine. However, since it is possible
to convert BPatch_snippets into PatchAPI::Snippets, I thought it might
as well be possible to use predefined library functions to be
instumented into the binary into the specified basic block. The
following shows an idea of what I inteded to do:

---
...

BPatch_Vector<BPatch_function *> funcs;
BPatch_function *func_lib;
BPatch_image* img;

img = app->getImage();

/* look for the predefined library function 'prolog' */
funcs.clear();
img->findFunction("pprolog", funcs);
func_lib = funcs[0];

/* no arguments required for function 'pprolog' */
std::vector<BPatch_snippet *> args;
BPatch_funcCallExpr func_instr(*func_lib, args);

SnippetPtr snippet = PatchAPI::convert(func_instr);

...

/* SEGFAULT: Here, I am not quite sure how to get the right point of the
newly created (empty) basic block */
InsertedCode::Ptr icode = PatchModifier::insert(post_block->object(),
snippet, point);
...
---

Unfortunately, this kind of implementation crashed with a Segfault at
the point of insertion. Which might be the result of the fact that I
don't know exactly how to find an entry point of the type
PatchAPI::Point* to the empty basic block. Any help would be appreciated
at this point.

When you say this crashes with a segfault at the point of insertion, do you mean the mutator crashes when inserting the code, or the mutatee crashes when executing it? In either case, a stack trace will be helpful; in the latter case if you're running the mutatee under Dyninst (rather than as a rewritten binary) setting DYNINST_DEBUG_CRASH=core and enabling core files will get you a mutatee stack trace and core dump.

Also, all of the safety operations that Dyninst performs (register saving, stack alignment, etc) will be absent if you're inserting these calls with PatchAPI directly. Unless that's explicitly desirable, or you're replacing our code generation with something that produces more optimized snippets, there's not a lot of benefit to working at the PatchAPI level.

My second question aims at the use of registers:
Is it possible to change the registers of individual instructions with
help of Dynsinst? The following should explain my idea:

---
changing registers from:
mov   edx, [esp+0x18]
e.g into:
mov   edx, [ebp-0x8]
---

My question is: is it possible to use high level constructs of
DyninstAPI to make these kind of adjustments or is it easier to work on
the level of raw bytes instead? Until now, I was not very successfull in
working with registers with help of DyninstAPI. I would really
appreciate it if someone could provide me a hint how to correctly access
the registers.

Dyninst allows access to original register values (through the BPatch interface). It allows instruction replacement through the PatchAPI interface, which would allow bit-twiddling of this sort. The higher a level of abstraction you can express the change at, the more likely it is that we can do the right thing (or a close approximation thereof)--are you trying to replace one variable with another? Change how a variable is referenced? Compensate for changes elsewhere in the code?

If you want a working example of instruction replacement through PatchAPI, I'd take a look at Mike Lam's CRAFT tool, available on SourceForge here: http://sourceforge.net/projects/crafthpc/

It's replacing every double-precision instruction in a program with code to shadow the calculation in single-precision and evaluate the error introduced by that replacement; if you strip out the evaluation portion of that, the shadow machinery should give you a pretty good idea of where to start with register manipulation. But, as per above, there may be an easier way to do whatever it is you're aiming for.

--bw

Thank you very much in advance.

Best regards,
Sergej



--
--bw

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