Re: [DynInst_API:] Binary Rewriting using wrapFunction


Date: Tue, 16 Dec 2014 23:02:09 +0100
From: Sergej Proskurin <prosig@xxxxxxx>
Subject: Re: [DynInst_API:] Binary Rewriting using wrapFunction
On 16.12.2014 22:33, Bill Williams wrote:
>>> ELF symbol tables don't lock in which library it comes from, which is
>>> why I hedged about loading order above.  If your wrapper function is
>>> named the same as the original symbol, then you'll only win if your
>>> library is loaded first.  If you give your functions unique names, then
>>> I'd think (hope) it should work.  :)
>>>
>>
>> This makes sense :) This is exactly, what I have been trying within my
>> program: The resulted binary, however results with wrapped functions
>> calls to either functions that are part of the binary itself or to
>> statically linked functions (whereas I haven't tried to wrap statically
>> linked library function calls, yet -- these should behave like the
>> remaining functions located within the binary). Unique symbols of the
>> wrappers to dynamically linked functions unfortunately do not even
>> appear within the symbol table after rewriting.
>>
>> My guidelines are as follows:
>> * printf() // library function to be wrapped
>> * bg_prinf() // wrapper function
>> * orig_printf() // represents the original printf() after wrapping
>>
>> But maybe, I have not thought about some details within my
>> implementation. Here is a short snippet from my code concerning the
>> function wrapping:
>>
>> ---
>> ...
>> /* function names in question: providing unique names */
>> string newFuncName = "bp_" + oldFuncName;
>> string origFuncName = "orig_" + oldFuncName;
>>
>> /* find functions in question */
>> img->findFunction(oldFuncName.c_str(), funcs);
>> BPatch_function *oldFunc = funcs[0];
>>
>> img->findFunction(newFuncName.c_str(), funcs);
>> BPatch_function *newFunc = funcs[0];
>>
>> /* find the symbol, the orig func shall be referred to from now on */
>> Module *mod = SymtabAPI::convert(newFunc->getModule());
>> for (auto s=symbols.begin(); s!=symbols.end(); s++) {
>>     if (!(*s)->getPrettyName().compare(origFuncName))
>>         bp_as->wrapFunction(oldFunc, newFunc, (*s));
>> }
>>
>> ---
>>
>> PS: In contrast to the solution provided by the Dyninst documentation
>> (which utilizes the function "findSymbol(...)" to get the symbol of the
>> function, which should represent the original library function from now
>> on), I am using the for loop to get the right symbol, since the
>> documented solution did not work (I am using Dyninst 8.2.1).
>>
> Going through the entire pile of functions by pretty name seems
> suboptimal, even if we've somehow misfiled things into the wrong
> module(s). What's going wrong with the manual example? No symbol comes
> back, or we find a non-useful one?
> 

It definitely is.

First, the example in the documentation makes use of the
SymtabAPI::convert(...) function, which according to the proposed
example converts a BPatch_module* to Symtab*. However, the
implementation I am using (Dyninst 8.2.1 including remaining APIs) does
not support a direct conversion to Symtab. Because of this, I adopted my
implementation to use the an instance of type Module* to access the symbols.

BTW: I just realized that the part of getting the actual symbols is
missing in the example above, here is the missing part:

---
vector<Symbol *> symbols;
mod->getAllSymbols(symbols);
---

This however is not the main issue, since you can access the Symtab
through the acquired Module with an eqally named function:
mod->findSymbol(...). However, when I was trying to find a particular
symbol with findSymbol(...), the function did not return any symbol.
While trying to get the function to work, I have tested different Symbol
types, such as Symbol::ST_FUNCTION and Symbol::ST_UNKNOWN.

Best regards,
Sergej
[← Prev in Thread] Current Thread [Next in Thread→]