Implementation changes for function pointers

  • Thread starter Thread starter A Wieser
  • Start date Start date
A

A Wieser

Hello,

It seems something's going on with regard to the way Visual Studio 2005
implements function pointers.

Once upon a time, it was possible to have unmanaged code as follows:

__declspec(naked) void HookJump(...)
{
_asm
{
nop
nop
nop
nop
nop
nop // six bytes for the original data...
nop
nop
nop
nop
nop
nop // six bytes for indirect jump
}
}

And then elsewhere, change the implementation at runtime as follows:

if (0!=VirtualProtect(HookJump, 12, PAGE_EXECUTE_WRITECOPY, &dwOrigProtect))
{
memcpy(HookJump, "newcod", 6);
}

However, it now appears that where the compiler used to return the actual
address of the function HookJump, the compiler instead returns the address
of a jump instead, although the debugger still claims that the symbol
HookJump points to the address above.

I've come up with this,
void * offsetHookCall = reinterpret_cast<void *>(HookJump);
offsetHookCall = reinterpret_cast<void *>((long) offsetHookCall + 5 +
*((long *) ((void *) ((long)offsetHookCall+1))));



but as I don't understand why the compiler has handed me a relative jump
instead of the actual address, I'm unhappy with it being a stable solution.

Is there some compiler setting I've missed somewhere to control this
behavior?

How can I find the actual address of the real implementation reliably?

Anthony Wieser
Wieser Software Ltd
 
A Wieser said:
It seems something's going on with regard to the way
Visual Studio 2005 implements function pointers.

Once upon a time, it was possible to have unmanaged code
as follows:

__declspec(naked) void HookJump(...)
{
_asm
{
nop
nop
nop
...
And then elsewhere, change the implementation at runtime as follows:

if (0!=VirtualProtect(HookJump, 12, PAGE_EXECUTE_WRITECOPY,
&dwOrigProtect))
{
memcpy(HookJump, "newcod", 6);
}

However, it now appears that where the compiler used to return the actual
address of the function HookJump, the compiler instead returns the address
of a jump instead, although the debugger still claims that the symbol
HookJump points to the address above.

I can't say for certain that this is your issue but do you have incremental
linking turned on in that project? If so, I vaguely recall being bitten by
that when the compiler put stuff where I wasn't expecting stuff.

Further, do you call FlushInstructionCache() after you rewrite those
locations? I believe that it is required for doing self-modification
reliably.

Regards,
Will
 
| > It seems something's going on with regard to the way
| > Visual Studio 2005 implements function pointers.
| >
| >
| > if (0!=VirtualProtect(HookJump, 12, PAGE_EXECUTE_WRITECOPY,
| > &dwOrigProtect))
| > {
| > memcpy(HookJump, "newcod", 6);
| > }
| >
| > However, it now appears that where the compiler used to return the
actual
| > address of the function HookJump, the compiler instead returns the
address
| > of a jump instead, although the debugger still claims that the symbol
| > HookJump points to the address above.
|
| I can't say for certain that this is your issue but do you have
incremental
| linking turned on in that project? If so, I vaguely recall being bitten by
| that when the compiler put stuff where I wasn't expecting stuff.

Turning off incremental linking returned it to its previous behavior.

Thanks for that.

|
| Further, do you call FlushInstructionCache() after you rewrite those
| locations? I believe that it is required for doing self-modification
| reliably.

Thanks for the heads up on this one too. The program was developed for
win9x, and so it wasn't necessary. I'll make sure to include this one as
well.


|
| Regards,
| Will


Anthony Wieser
Wieser Software Ltd
 
Back
Top