rendered paste bodyvoid *hook( void *func, void *newFunc )
{
if ( (func is null) || (newFunc is null) )
{
throw new Exception( "null pointer passed as function" );
}
ubyte* startPtr = cast(ubyte *)func;
uint codeLen; //length of our trampoline
ubyte* jmpFunc; //our trampoline function
ubyte[] jmpCode; //code that will be placed at the beginning of func
while ( codeLen < 5 )
{
codeLen += instructionLen( startPtr + codeLen );
}
jmpFunc = cast(ubyte *)VirtualAlloc( null, codeLen+5, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE );
memcpy( jmpFunc, func, codeLen );
jmpFunc[codeLen] = 0xE9;
*cast(uint *)&jmpFunc[codeLen+1] = (cast(uint)func - cast(uint)jmpFunc) - 5;
jmpCode = new ubyte[5];
jmpCode[0] = 0xE9;
*cast(uint *)&jmpCode[1] = (cast(uint)newFunc - cast(uint)func) - 5;
uint oldProtection;
VirtualProtect( func, codeLen, PAGE_EXECUTE_READWRITE, &oldProtection );
memcpy( func, jmpCode.ptr, jmpCode.length );
memset( func + jmpCode.length, 0x90, codeLen - jmpCode.length );
VirtualProtect( func, codeLen, oldProtection, &oldProtection );
return jmpFunc;
}