bool virtual_identity::set_vmethod_ptr(MemoryPatcher &patcher, int idx, void *ptr) { assert(idx >= 0); void **vtable = (void**)vtable_ptr; if (!vtable) return NULL; return patcher.write(&vtable[idx], &ptr, sizeof(void*)); }
static void Remove_Hook(void *target, uint8_t(&real)[6], const void *) { MemoryPatcher patcher; patcher.verifyAccess(target, 6, true); *((uint8_t *)target + 0) = real[0]; *((uint8_t *)target + 1) = real[1]; *((uint8_t *)target + 2) = real[2]; *((uint8_t *)target + 3) = real[3]; *((uint8_t *)target + 4) = real[4]; *((uint8_t *)target + 5) = real[5]; #if defined(_WIN32) FlushInstructionCache(GetCurrentProcess(), target, 6); #endif }
static void Add_Hook(void *target, uint8_t(&real)[6], const void *fake) { MemoryPatcher patcher; patcher.verifyAccess(target, 6, true); int32_t jump_offset((uint8_t *)fake - (uint8_t *)target - 4 - 1); real[0] = *((uint8_t *)target + 0); real[1] = *((uint8_t *)target + 1); real[2] = *((uint8_t *)target + 2); real[3] = *((uint8_t *)target + 3); real[4] = *((uint8_t *)target + 4); real[5] = *((uint8_t *)target + 5); *((uint8_t *)target + 0) = 0xE9; *((uint8_t *)target + 1) = *((uint8_t *)&jump_offset + 0); *((uint8_t *)target + 2) = *((uint8_t *)&jump_offset + 1); *((uint8_t *)target + 3) = *((uint8_t *)&jump_offset + 2); *((uint8_t *)target + 4) = *((uint8_t *)&jump_offset + 3); *((uint8_t *)target + 5) = 0x90; #if defined(_WIN32) FlushInstructionCache(GetCurrentProcess(), target, 6); #endif }
static int internal_patchBytes(lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); lua_settop(L, 2); MemoryPatcher patcher; if (!lua_isnil(L, 2)) { luaL_checktype(L, 2, LUA_TTABLE); lua_pushnil(L); while (lua_next(L, 2)) { uint8_t *addr = (uint8_t*)checkaddr(L, -2, true); int isnum; uint8_t value = (uint8_t)lua_tounsignedx(L, -1, &isnum); if (!isnum) luaL_error(L, "invalid value in verify table"); lua_pop(L, 1); if (!patcher.verifyAccess(addr, 1, false)) { lua_pushnil(L); lua_pushstring(L, "invalid verify address"); lua_pushvalue(L, -3); return 3; } if (*addr != value) { lua_pushnil(L); lua_pushstring(L, "wrong verify value"); lua_pushvalue(L, -3); return 3; } } } lua_pushnil(L); while (lua_next(L, 1)) { uint8_t *addr = (uint8_t*)checkaddr(L, -2, true); int isnum; uint8_t value = (uint8_t)lua_tounsignedx(L, -1, &isnum); if (!isnum) luaL_error(L, "invalid value in write table"); lua_pop(L, 1); if (!patcher.verifyAccess(addr, 1, true)) { lua_pushnil(L); lua_pushstring(L, "invalid write address"); lua_pushvalue(L, -3); return 3; } } lua_pushnil(L); while (lua_next(L, 1)) { uint8_t *addr = (uint8_t*)checkaddr(L, -2, true); uint8_t value = (uint8_t)lua_tounsigned(L, -1); lua_pop(L, 1); *addr = value; } lua_pushboolean(L, true); return 1; }