diff --git a/Lua API.html b/Lua API.html
index 226afa98a..d2e0da1ef 100644
--- a/Lua API.html
+++ b/Lua API.html
@@ -1763,9 +1763,17 @@ global environment, persistent between calls to the script.
dfhack.internal.getVTable(name)
Returns the pre-extracted vtable address name, or nil.
+dfhack.internal.getImageBase()
+Returns the mmap base of the executable.
+
dfhack.internal.getRebaseDelta()
Returns the ASLR rebase offset of the DF executable.
+dfhack.internal.adjustOffset(offset[,to_file])
+Returns the re-aligned offset, or nil if invalid.
+If to_file is true, the offset is adjusted from memory to file.
+This function returns the original value everywhere except windows.
+
dfhack.internal.getMemRanges()
Returns a sequence of tables describing virtual memory ranges of the process.
diff --git a/Lua API.rst b/Lua API.rst
index d06e3d2e6..f89750e88 100644
--- a/Lua API.rst
+++ b/Lua API.rst
@@ -1618,10 +1618,20 @@ and are only documented here for completeness:
Returns the pre-extracted vtable address ``name``, or *nil*.
+* ``dfhack.internal.getImageBase()``
+
+ Returns the mmap base of the executable.
+
* ``dfhack.internal.getRebaseDelta()``
Returns the ASLR rebase offset of the DF executable.
+* ``dfhack.internal.adjustOffset(offset[,to_file])``
+
+ Returns the re-aligned offset, or *nil* if invalid.
+ If ``to_file`` is true, the offset is adjusted from memory to file.
+ This function returns the original value everywhere except windows.
+
* ``dfhack.internal.getMemRanges()``
Returns a sequence of tables describing virtual memory ranges of the process.
diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp
index 0151ed404..3862530dd 100644
--- a/library/LuaApi.cpp
+++ b/library/LuaApi.cpp
@@ -1718,9 +1718,11 @@ static void *checkaddr(lua_State *L, int idx, bool allow_null = false)
return rv;
}
+static uint32_t getImageBase() { return Core::getInstance().p->getBase(); }
static int getRebaseDelta() { return Core::getInstance().vinfo->getRebaseDelta(); }
static const LuaWrapper::FunctionReg dfhack_internal_module[] = {
+ WRAP(getImageBase),
WRAP(getRebaseDelta),
{ NULL, NULL }
};
@@ -1774,6 +1776,18 @@ static int internal_getVTable(lua_State *L)
return 1;
}
+static int internal_adjustOffset(lua_State *L)
+{
+ lua_settop(L, 2);
+ int off = luaL_checkint(L, 1);
+ int rv = Core::getInstance().p->adjustOffset(off, lua_toboolean(L, 2));
+ if (rv >= 0)
+ lua_pushinteger(L, rv);
+ else
+ lua_pushnil(L);
+ return 1;
+}
+
static int internal_getMemRanges(lua_State *L)
{
std::vector ranges;
@@ -1981,6 +1995,7 @@ static const luaL_Reg dfhack_internal_funcs[] = {
{ "getAddress", internal_getAddress },
{ "setAddress", internal_setAddress },
{ "getVTable", internal_getVTable },
+ { "adjustOffset", internal_adjustOffset },
{ "getMemRanges", internal_getMemRanges },
{ "patchMemory", internal_patchMemory },
{ "patchBytes", internal_patchBytes },
diff --git a/library/Process-darwin.cpp b/library/Process-darwin.cpp
index c5e4e4b85..d081c8c5c 100644
--- a/library/Process-darwin.cpp
+++ b/library/Process-darwin.cpp
@@ -220,9 +220,14 @@ void Process::getMemRanges( vector & ranges )
}*/
}
-uint32_t Process::getBase()
+uintptr_t Process::getBase()
{
- return 0;
+ return 0x1000000;
+}
+
+int Process::adjustOffset(int offset, bool /*to_file*/)
+{
+ return offset;
}
static int getdir (string dir, vector &files)
diff --git a/library/Process-linux.cpp b/library/Process-linux.cpp
index f88279b3f..046b7696d 100644
--- a/library/Process-linux.cpp
+++ b/library/Process-linux.cpp
@@ -155,9 +155,14 @@ void Process::getMemRanges( vector & ranges )
fclose(mapFile);
}
-uint32_t Process::getBase()
+uintptr_t Process::getBase()
{
- return 0;
+ return 0x8048000;
+}
+
+int Process::adjustOffset(int offset, bool /*to_file*/)
+{
+ return offset;
}
static int getdir (string dir, vector &files)
diff --git a/library/Process-windows.cpp b/library/Process-windows.cpp
index 966468fb5..6f79236f9 100644
--- a/library/Process-windows.cpp
+++ b/library/Process-windows.cpp
@@ -160,7 +160,7 @@ Process::Process(VersionInfoFactory * factory)
identified = true;
// give the process a data model and memory layout fixed for the base of first module
my_descriptor = new VersionInfo(*vinfo);
- my_descriptor->rebaseTo((uint32_t)d->base);
+ my_descriptor->rebaseTo(getBase());
for(size_t i = 0; i < threads_ids.size();i++)
{
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, (DWORD) threads_ids[i]);
@@ -394,13 +394,46 @@ void Process::getMemRanges( vector & ranges )
}
}
-uint32_t Process::getBase()
+uintptr_t Process::getBase()
{
if(d)
- return (uint32_t) d->base;
+ return (uintptr_t) d->base;
return 0x400000;
}
+int Process::adjustOffset(int offset, bool to_file)
+{
+ if (!d)
+ return -1;
+
+ for(int i = 0; i < d->pe_header.FileHeader.NumberOfSections; i++)
+ {
+ auto §ion = d->sections[i];
+
+ if (to_file)
+ {
+ unsigned delta = offset - section.VirtualAddress;
+ if (delta >= section.Misc.VirtualSize)
+ continue;
+ if (!section.PointerToRawData || delta >= section.SizeOfRawData)
+ return -1;
+ return (int)(section.PointerToRawData + delta);
+ }
+ else
+ {
+ unsigned delta = offset - section.PointerToRawData;
+ if (!section.PointerToRawData || delta >= section.SizeOfRawData)
+ continue;
+ if (delta >= section.Misc.VirtualSize)
+ return -1;
+ return (int)(section.VirtualAddress + delta);
+ }
+ }
+
+ return -1;
+}
+
+
string Process::doReadClassName (void * vptr)
{
char * rtti = readPtr((char *)vptr - 0x4);
diff --git a/library/VersionInfoFactory.cpp b/library/VersionInfoFactory.cpp
index e8c0561cd..7142233d8 100644
--- a/library/VersionInfoFactory.cpp
+++ b/library/VersionInfoFactory.cpp
@@ -103,13 +103,13 @@ void VersionInfoFactory::ParseVersion (TiXmlElement* entry, VersionInfo* mem)
{
mem->setOS(OS_LINUX);
// this is wrong... I'm not going to do base image relocation on linux though.
- mem->setBase(0x0);
+ mem->setBase(0x8048000);
}
else if(os == "darwin")
{
mem->setOS(OS_APPLE);
// this is wrong... I'm not going to do base image relocation on linux though.
- mem->setBase(0x0);
+ mem->setBase(0x1000000);
}
else
{
diff --git a/library/include/MemAccess.h b/library/include/MemAccess.h
index 1b8e687b9..22f15eecf 100644
--- a/library/include/MemAccess.h
+++ b/library/include/MemAccess.h
@@ -275,11 +275,13 @@ namespace DFHack
{
return my_descriptor;
};
- uint32_t getBase();
+ uintptr_t getBase();
/// get the DF Process ID
int getPID();
/// get the DF Process FilePath
std::string getPath();
+ /// Adjust between in-memory and in-file image offset
+ int adjustOffset(int offset, bool to_file = false);
/// millisecond tick count, exactly as DF uses
uint32_t getTickCount();