Reputation: 862
I am attempting to hook a function of a linux program. Basically searching unprotecting the function with mprotect and then putting a jmp inside the original function address re-directing to my function hook.
However I would like to copy the original function so I can call it when the modified function is not needed. I would have a kind of hook like this
int CallHookedFunctionFoobar(int param1, int param2)
{
if (g_somevariable)
Foobar_original(param1, param2);
else
Foobar_modified(param1, param2);
}
So my question is... how could I know the size of a function, in bytes, so I could memcpy() it to a dynamically allocated buffer to execute it?
I thought about maybe embedding a small length disassembler and parse the opcode until I find the RETN optocode, but I'm unsure it would work in absolutely all cases (for example if more than one RETN resides in the same function :[)
Another reason because I want to do this is because the same function could have been hooked by another library..
Upvotes: 0
Views: 832
Reputation:
Firstly, if this is Linux-specific, then most probably your executable file is an ELF
binary. So you can just parse the ELF header (using libelf
, for example) to find/calculate the length of a function.
However, I don't see why you would need this. A simpler approach I can think of is patching the function on-the-fly, replacing its first few instructions with a JMP
or CALL
to the hook function meanwhile saving those overwritten instructions to patch it back later. Something like:
void call_hooked(void (*fn)(), unsigned char *ctx, size_t *n)
{
unsigned char hook_patch[] = { 0x15, 0x20, 0x7f, 0x48 }; // I bluffed
*n = sizeof(hook_patch);
memcpy(ctx, fn, sizeof(hook_patch));
memcpy(fn, hook_patch, sizeof(hook_patch));
fn();
}
void call_orig(void (*fn)(), unsigned char *ctx, size_t n)
{
memcpy(fn, ctx, n);
fn();
}
Upvotes: 3