void *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; }