From 4e517e10d263b5e74330de12f04b5806d2121452 Mon Sep 17 00:00:00 2001 From: Ilari Liusvaara Date: Sat, 29 Sep 2012 09:14:09 +0300 Subject: [PATCH] Lua: memory.map* --- manual.lyx | 13 +++++ manual.txt | 10 +++- src/lua/memory.cpp | 123 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 145 insertions(+), 1 deletion(-) diff --git a/manual.lyx b/manual.lyx index 66bb0e54..0bc1b811 100644 --- a/manual.lyx +++ b/manual.lyx @@ -3475,6 +3475,19 @@ Read a region of memory. Warning: If the region crosses VMA boundary, the results are undefined. \end_layout +\begin_layout Subsubsection +memory.map([number base, number size]) +\end_layout + +\begin_layout Standard +Returns a table mapping specified memory aperture for read/write. + If parameters are omitted, entiere map space is the aperture. +\end_layout + +\begin_layout Itemize +Type may be one of: byte, sbyte, word, sword, dword, sdword, qword or sqword. +\end_layout + \begin_layout Subsubsection memory.writeregion(number base, number size, table data) \end_layout diff --git a/manual.txt b/manual.txt index db345b0a..b2bcf7ce 100644 --- a/manual.txt +++ b/manual.txt @@ -1765,7 +1765,15 @@ Read a region of memory. • Warning: If the region crosses VMA boundary, the results are undefined. -8.9.19 memory.writeregion(number base, number size, table data) +8.9.19 memory.map([number base, number size]) + +Returns a table mapping specified memory aperture for read/write. +If parameters are omitted, entiere map space is the aperture. + +• Type may be one of: byte, sbyte, word, sword, dword, sdword, + qword or sqword. + +8.9.20 memory.writeregion(number base, number size, table data) Write a region of memory. diff --git a/src/lua/memory.cpp b/src/lua/memory.cpp index f35ee421..be4d9689 100644 --- a/src/lua/memory.cpp +++ b/src/lua/memory.cpp @@ -33,6 +33,113 @@ namespace } }; + class mmap_base + { + public: + ~mmap_base() {} + virtual void read(lua_State* LS, uint64_t addr) = 0; + virtual void write(lua_State* LS, uint64_t addr) = 0; + }; + + + template + class lua_mmap_memory_helper : public mmap_base + { + public: + ~lua_mmap_memory_helper() {} + void read(lua_State* LS, uint64_t addr) + { + lua_pushnumber(LS, static_cast(rfun(addr))); + } + + void write(lua_State* LS, uint64_t addr) + { + T value = get_numeric_argument(LS, 3, "aperture(write)"); + wfun(addr, value); + } + }; + + int aperture_read_fun(lua_State* LS) + { + uint64_t base = lua_tonumber(LS, lua_upvalueindex(1)); + uint64_t size = 0xFFFFFFFFFFFFFFFFULL; + if(lua_type(LS, lua_upvalueindex(2)) == LUA_TNUMBER) + size = lua_tonumber(LS, lua_upvalueindex(2)); + mmap_base* fn = reinterpret_cast(lua_touserdata(LS, lua_upvalueindex(3))); + uint64_t addr = get_numeric_argument(LS, 2, "aperture(read)"); + if(addr > size || addr + base < addr) { + lua_pushnumber(LS, 0); + return 1; + } + addr += base; + fn->read(LS, addr); + return 1; + } + + int aperture_write_fun(lua_State* LS) + { + + uint64_t base = lua_tonumber(LS, lua_upvalueindex(1)); + uint64_t size = 0xFFFFFFFFFFFFFFFFULL; + if(lua_type(LS, lua_upvalueindex(2)) == LUA_TNUMBER) + size = lua_tonumber(LS, lua_upvalueindex(2)); + mmap_base* fn = reinterpret_cast(lua_touserdata(LS, lua_upvalueindex(3))); + uint64_t addr = get_numeric_argument(LS, 2, "aperture(write)"); + if(addr > size || addr + base < addr) + return 0; + addr += base; + fn->write(LS, addr); + return 0; + } + + void aperture_make_fun(lua_State* LS, uint64_t base, uint64_t size, mmap_base& type) + { + lua_newtable(LS); + lua_newtable(LS); + lua_pushstring(LS, "__index"); + lua_pushnumber(LS, base); + if(!(size + 1)) + lua_pushnil(LS); + else + lua_pushnumber(LS, size); + lua_pushlightuserdata(LS, &type); + lua_pushcclosure(LS, aperture_read_fun, 3); + lua_settable(LS, -3); + lua_pushstring(LS, "__newindex"); + lua_pushnumber(LS, base); + if(!(size + 1)) + lua_pushnil(LS); + else + lua_pushnumber(LS, size); + lua_pushlightuserdata(LS, &type); + lua_pushcclosure(LS, aperture_write_fun, 3); + lua_settable(LS, -3); + lua_setmetatable(LS, -2); + } + + class lua_mmap_memory : public lua_function + { + public: + lua_mmap_memory(const std::string& name, mmap_base& _h) : lua_function(name), h(_h) {} + int invoke(lua_State* LS) + { + if(lua_isnoneornil(LS, 1)) { + aperture_make_fun(LS, 0, 0xFFFFFFFFFFFFFFFFULL, h); + return 1; + } + uint64_t addr = get_numeric_argument(LS, 1, fname.c_str()); + uint64_t size = get_numeric_argument(LS, 2, fname.c_str()); + if(!size) { + lua_pushstring(LS, "Aperture with zero size is not valid"); + lua_error(LS); + return 0; + } + aperture_make_fun(LS, addr, size - 1, h); + return 1; + } + mmap_base& h; + }; + function_ptr_luafun vmacount("memory.vma_count", [](lua_State* LS, const std::string& fname) -> int { lua_pushnumber(LS, get_regions().size()); return 1; @@ -177,4 +284,20 @@ namespace lua_write_memory ww("memory.writeword"); lua_write_memory wd("memory.writedword"); lua_write_memory wq("memory.writeqword"); + lua_mmap_memory_helper mhub; + lua_mmap_memory_helper mhsb; + lua_mmap_memory_helper mhuw; + lua_mmap_memory_helper mhsw; + lua_mmap_memory_helper mhud; + lua_mmap_memory_helper mhsd; + lua_mmap_memory_helper mhuq; + lua_mmap_memory_helper mhsq; + lua_mmap_memory mub("memory.mapbyte", mhub); + lua_mmap_memory msb("memory.mapsbyte", mhsb); + lua_mmap_memory muw("memory.mapword", mhuw); + lua_mmap_memory msw("memory.mapsword", mhsw); + lua_mmap_memory mud("memory.mapdword", mhud); + lua_mmap_memory msd("memory.mapsdword", mhsd); + lua_mmap_memory muq("memory.mapqword", mhuq); + lua_mmap_memory msq("memory.mapsqword", mhsq); }