Expose process MD5/PE to Lua (useful in export-dt-ini)

develop
lethosor 2015-12-27 14:59:18 -05:00
parent a977f274b1
commit d087f4f741
7 changed files with 51 additions and 11 deletions

@ -1908,6 +1908,14 @@ and are only documented here for completeness:
The table used by ``dfhack.run_script()`` to give every script its own The table used by ``dfhack.run_script()`` to give every script its own
global environment, persistent between calls to the script. global environment, persistent between calls to the script.
* ``dfhack.internal.getPE()``
Returns the PE timestamp of the DF executable (only on Windows)
* ``dfhack.internal.getMD5()``
Returns the MD5 of the DF executable (only on OS X and Linux)
* ``dfhack.internal.getAddress(name)`` * ``dfhack.internal.getAddress(name)``
Returns the global address ``name``, or *nil*. Returns the global address ``name``, or *nil*.

@ -2304,6 +2304,24 @@ static const LuaWrapper::FunctionReg dfhack_internal_module[] = {
{ NULL, NULL } { NULL, NULL }
}; };
static int internal_getmd5(lua_State *L)
{
auto p = Core::getInstance().p;
if (p->getDescriptor()->getOS() == OS_WINDOWS)
luaL_error(L, "process MD5 not available on Windows");
lua_pushstring(L, p->getMD5().c_str());
return 1;
}
static int internal_getPE(lua_State *L)
{
auto p = Core::getInstance().p;
if (p->getDescriptor()->getOS() != OS_WINDOWS)
luaL_error(L, "process PE timestamp not available on non-Windows");
lua_pushinteger(L, p->getPE());
return 1;
}
static int internal_getAddress(lua_State *L) static int internal_getAddress(lua_State *L)
{ {
const char *name = luaL_checkstring(L, 1); const char *name = luaL_checkstring(L, 1);
@ -2683,6 +2701,8 @@ static int internal_findScript(lua_State *L)
} }
static const luaL_Reg dfhack_internal_funcs[] = { static const luaL_Reg dfhack_internal_funcs[] = {
{ "getPE", internal_getPE },
{ "getMD5", internal_getmd5 },
{ "getAddress", internal_getAddress }, { "getAddress", internal_getAddress },
{ "setAddress", internal_setAddress }, { "setAddress", internal_setAddress },
{ "getVTable", internal_getVTable }, { "getVTable", internal_getVTable },

@ -60,15 +60,16 @@ Process::Process(VersionInfoFactory * known_versions)
identified = false; identified = false;
my_descriptor = 0; my_descriptor = 0;
my_pe = 0;
md5wrapper md5; md5wrapper md5;
uint32_t length; uint32_t length;
uint8_t first_kb [1024]; uint8_t first_kb [1024];
memset(first_kb, 0, sizeof(first_kb)); memset(first_kb, 0, sizeof(first_kb));
// get hash of the running DF process // get hash of the running DF process
string hash = md5.getHashFromFile(real_path, length, (char *) first_kb); my_md5 = md5.getHashFromFile(real_path, length, (char *) first_kb);
// create linux process, add it to the vector // create linux process, add it to the vector
VersionInfo * vinfo = known_versions->getVersionInfoByMD5(hash); VersionInfo * vinfo = known_versions->getVersionInfoByMD5(my_md5);
if(vinfo) if(vinfo)
{ {
my_descriptor = new VersionInfo(*vinfo); my_descriptor = new VersionInfo(*vinfo);
@ -79,7 +80,7 @@ Process::Process(VersionInfoFactory * known_versions)
char * wd = getcwd(NULL, 0); char * wd = getcwd(NULL, 0);
cerr << "Unable to retrieve version information.\n"; cerr << "Unable to retrieve version information.\n";
cerr << "File: " << real_path << endl; cerr << "File: " << real_path << endl;
cerr << "MD5: " << hash << endl; cerr << "MD5: " << my_md5 << endl;
cerr << "working dir: " << wd << endl; cerr << "working dir: " << wd << endl;
cerr << "length:" << length << endl; cerr << "length:" << length << endl;
cerr << "1KB hexdump follows:" << endl; cerr << "1KB hexdump follows:" << endl;

@ -55,15 +55,16 @@ Process::Process(VersionInfoFactory * known_versions)
identified = false; identified = false;
my_descriptor = 0; my_descriptor = 0;
my_pe = 0;
md5wrapper md5; md5wrapper md5;
uint32_t length; uint32_t length;
uint8_t first_kb [1024]; uint8_t first_kb [1024];
memset(first_kb, 0, sizeof(first_kb)); memset(first_kb, 0, sizeof(first_kb));
// get hash of the running DF process // get hash of the running DF process
string hash = md5.getHashFromFile(exe_link_name, length, (char *) first_kb); my_md5 = md5.getHashFromFile(exe_link_name, length, (char *) first_kb);
// create linux process, add it to the vector // create linux process, add it to the vector
VersionInfo * vinfo = known_versions->getVersionInfoByMD5(hash); VersionInfo * vinfo = known_versions->getVersionInfoByMD5(my_md5);
if(vinfo) if(vinfo)
{ {
my_descriptor = new VersionInfo(*vinfo); my_descriptor = new VersionInfo(*vinfo);
@ -74,7 +75,7 @@ Process::Process(VersionInfoFactory * known_versions)
char * wd = getcwd(NULL, 0); char * wd = getcwd(NULL, 0);
cerr << "Unable to retrieve version information.\n"; cerr << "Unable to retrieve version information.\n";
cerr << "File: " << exe_link_name << endl; cerr << "File: " << exe_link_name << endl;
cerr << "MD5: " << hash << endl; cerr << "MD5: " << my_md5 << endl;
cerr << "working dir: " << wd << endl; cerr << "working dir: " << wd << endl;
cerr << "length:" << length << endl; cerr << "length:" << length << endl;
cerr << "1KB hexdump follows:" << endl; cerr << "1KB hexdump follows:" << endl;

@ -95,7 +95,8 @@ Process::Process(VersionInfoFactory * factory)
{ {
return; return;
} }
VersionInfo* vinfo = factory->getVersionInfoByPETimestamp(d->pe_header.FileHeader.TimeDateStamp); my_pe = d->pe_header.FileHeader.TimeDateStamp;
VersionInfo* vinfo = factory->getVersionInfoByPETimestamp(my_pe);
if(vinfo) if(vinfo)
{ {
identified = true; identified = true;
@ -105,8 +106,7 @@ Process::Process(VersionInfoFactory * factory)
} }
else else
{ {
fprintf(stderr, "Unable to retrieve version information.\nPE timestamp: 0x%x\n", fprintf(stderr, "Unable to retrieve version information.\nPE timestamp: 0x%x\n", my_pe);
d->pe_header.FileHeader.TimeDateStamp);
fflush(stderr); fflush(stderr);
} }
} }

@ -287,6 +287,9 @@ namespace DFHack
EXEC = 4 EXEC = 4
}; };
uint32_t getPE() { return my_pe; }
std::string getMD5() { return my_md5; }
private: private:
VersionInfo * my_descriptor; VersionInfo * my_descriptor;
PlatformSpecific *d; PlatformSpecific *d;
@ -294,6 +297,8 @@ namespace DFHack
uint32_t my_pid; uint32_t my_pid;
uint32_t base; uint32_t base;
std::map<void *, std::string> classNameCache; std::map<void *, std::string> classNameCache;
uint32_t my_pe;
std::string my_md5;
}; };
class DFHACK_EXPORT ClassNameCheck class DFHACK_EXPORT ClassNameCheck

@ -421,8 +421,13 @@ address('uniform_indiv_choice',df.squad_uniform_spec,'indiv_choice')
local out = io.open('therapist.ini', 'w') local out = io.open('therapist.ini', 'w')
out:write('[info]\n') out:write('[info]\n')
-- TODO: add an api function to retrieve the checksum if dfhack.getOSType() == 'windows' and dfhack.internal.getPE then
out:write(('checksum=0x%x\n'):format(dfhack.internal.getPE()))
elseif dfhack.getOSType() ~= 'windows' and dfhack.internal.getMD5 then
out:write(('checksum=0x%s\n'):format(dfhack.internal.getMD5():sub(1, 8)))
else
out:write('checksum=<<fillme>>\n') out:write('checksum=<<fillme>>\n')
end
out:write('version_name='..dfhack.getDFVersion()..'\n') out:write('version_name='..dfhack.getDFVersion()..'\n')
out:write('complete='..(complete and 'true' or 'false')..'\n') out:write('complete='..(complete and 'true' or 'false')..'\n')