frida-gum icon indicating copy to clipboard operation
frida-gum copied to clipboard

Instrument branch instruction

Open sherifmagdy opened this issue 5 years ago • 3 comments

Hi, I have a tool implemented on top of Pin and i want to migrate it to frida. My objective is to capture any control flow transfer in terms of (branch instruction address => taken target ) When i'm instrumenting at instruction granularity for branch instructions in Pin, i can choose to put my analysis function in different positions : 1- BEFORE (put my analysis function (callout) before the branch instruction) 2- AFTER (put my analysis function after the branch instruction which is the fall-through edge) 3- Taken_branch (put my analysis function at the start of the control transfer(jump) ) in my current implementation using Pin, i can put 2 different analysis function(callout) : 1- one using After (fall-through) edge. 2- the second one using Taken_branch keyword. This way, i will have two analysis function that will log the control transfer whether the jump is taken or not and the (branch instruction address => taken target) mapping will be available. These options in Pin was giving the flexibility for capturing the branch instruction address alongside with the taken edge target.

In frida, how i can manage to get the 2 cases and log the control transfer in the same way (branch instruction address => taken target) ?

if i did that :

if(instruction.groups.indexOf("jump") > -1 ){
iterator.putCallout(analysis);
iterator.keep();
}

my analysis function will get executed whether the jump is taken or not, but the analysis function will not be able to log the target of the control transfer. if i did that :

if(instruction.groups.indexOf("jump") > -1 ){
iterator.keep();
iterator.putCallout(analysis);
}

i think this is equivalent to Pin AFTER option, my analysis function will get executed only if the jump is not taken, but will miss the case if the branch taken.

is there any way to achieve this, i might be missing something in the stalker API that can manage this requirement.

Thanks

sherifmagdy avatar Oct 29 '19 14:10 sherifmagdy

iterator.keep(); iterator.putCallout(analysis);

is this order supposed to put the callout after the instruction ? as it seems to be not adding anything.

@oleavr

sherifmagdy avatar Oct 29 '19 16:10 sherifmagdy

Cool!

iterator.keep(); iterator.putCallout(analysis);

is this order supposed to put the callout after the instruction ? as it seems to be not adding anything.

This will result in unreachable code, as you will be putting the callout after the branch that Stalker puts to the next block. (Or into the runtime initially – until it applies backpatching optimizations.)

But, if you put a callout at the start of every block, it will get called at that point, so you will know where the branch went. This switch into the runtime has a cost though, so you should consider implementing that callout in C using CModule. (Or, even faster: pre-allocate a ring-buffer and generate machine code that writes to the ring-buffer.)

oleavr avatar Oct 30 '19 00:10 oleavr

Thanks, i put the callout at the start of every basic block and another callout before every jump instruction to log the source of the control transfer, then the BB callout will merge the logged source with the current PC, it's work well now.

sherifmagdy avatar Oct 30 '19 17:10 sherifmagdy