|
|
|
@ -1535,6 +1535,81 @@ static int internal_patchMemory(lua_State *L)
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int internal_memmove(lua_State *L)
|
|
|
|
|
{
|
|
|
|
|
void *dest = checkaddr(L, 1);
|
|
|
|
@ -1626,6 +1701,7 @@ static const luaL_Reg dfhack_internal_funcs[] = {
|
|
|
|
|
{ "getVTable", internal_getVTable },
|
|
|
|
|
{ "getMemRanges", internal_getMemRanges },
|
|
|
|
|
{ "patchMemory", internal_patchMemory },
|
|
|
|
|
{ "patchBytes", internal_patchBytes },
|
|
|
|
|
{ "memmove", internal_memmove },
|
|
|
|
|
{ "memcmp", internal_memcmp },
|
|
|
|
|
{ "memscan", internal_memscan },
|
|
|
|
|