Re: [DynInst_API:] Directly reassemble and patch instructions


Date: Mon, 19 Sep 2016 16:02:14 +0000
From: Bill Williams <bill@xxxxxxxxxxx>
Subject: Re: [DynInst_API:] Directly reassemble and patch instructions
Mohamed--

First, apologies on the delay; I was out of the office the end of last week.

PatchAPI does need a code generation plugin in order to have an effect on the binary; this is why I suggested starting from the Relocation module inside DyninstAPI, where all of the code generation is implemented. Basically, PatchAPI is responsible for recording the graph transformations, and you extend it by inheritance to implement those transformations and whatever other code generation you require.

Hope this helps; I can dive further into the details of the Relocation classes as needed (and it would be really good to assemble a user's guide to them and extract them to a component--while Drew's papers are quite readable, they're not actually a substitute for manuals).

--bw

________________________________________
From: melsabag@xxxxxxx <melsabag@xxxxxxx> on behalf of Mohamed Elsabagh <melsabag@xxxxxxx>
Sent: Wednesday, September 14, 2016 8:36 AM
To: Bill Williams; dyninst-api
Subject: Re: [DynInst_API:] Directly reassemble and patch instructions

Thanks, Bill. Wouldn't the PatchAPI::ReplaceCallCommand help here? I have tried to use it but it doesn't seem to be having any effect. For instance, the following snippet does not change the binary in any way:

patcher.add(ReplaceCallCommand::create(mgr, block, func, nullptr));
if (!patcher.run()) {
  cerr << "patch failed";
  exit(EXIT_FAILURE);
}
appBin->writeFile(output_path);

Am I doing something wrong? Do I need to implement any stubs for the PatchAPI to function? I can provide a MWE if needed.

On Mon, Sep 12, 2016 at 12:21 PM Bill Williams <bill@xxxxxxxxxxx<mailto:bill@xxxxxxxxxxx>> wrote:
The way I'd go about this would be with PatchAPI and pulling some of the abstract classes out of dyninstAPI/src/Relocation. (And yes, I am about to outline use of a machine gun to kill a mosquito, but I trust you want that mosquito *dead*.)

The raw call that's most relevant is PatchModifier::redirectEdge, which will update the CFG representation to reflect the new target you want. However, you'll want a thin Transformer/Widget wrapper (and something doing the equivalent of dyninst's AddressSpace::relocate, again very thin) that goes through each redirected edge and ensures that you can generate a new branch that fits precisely over the old one (and either fails gracefully or falls back to relocation/springboards if for some reason you can't). That's also what will need to emit the modified branches.

(And if you want to cannibalize the branch target modification from the CFWidget class in Relocation, that may be sufficient. But I tend to be paranoid about what the code will/won't do when things go wrong.)

--bw

________________________________________
From: Dyninst-api <dyninst-api-bounces@xxxxxxxxxxx<mailto:dyninst-api-bounces@xxxxxxxxxxx>> on behalf of Mohamed Elsabagh <melsabag@xxxxxxx<mailto:melsabag@xxxxxxx>>
Sent: Sunday, September 11, 2016 12:08 PM
To: dyninst-api
Subject: [DynInst_API:] Directly reassemble and patch instructions

Hello,

Is there a way to directly modify the target of a branch without manually assembling the instruction? I don't want to insert trampolines or relocate the code; only modify the target of a specific call/branch instruction. I am currently doing that by manually re-assembling the instruction, then patch the binary directly via patchData() from SymtabAPI.  However, that is error prone and there are many cases to handle. I am wondering if there is a better way.

Thanks.
[← Prev in Thread] Current Thread [Next in Thread→]