Fix windows/wine version information bugs related to processes without a PE header.

develop
Petr Mrázek 2011-03-31 05:39:12 +02:00
parent 6cd08c3f31
commit 837ea52c22
6 changed files with 71 additions and 28 deletions

@ -155,17 +155,23 @@ NormalProcess::NormalProcess(uint32_t pid, VersionInfoFactory * factory)
my_handle = 0;
return;
}
//cout << "PE Timestamp: " << hex << pe_header.FileHeader.TimeDateStamp << dec << endl;
VersionInfo* vinfo = factory->getVersionInfoByPETimestamp(pe_header.FileHeader.TimeDateStamp);
if(vinfo)
{
/*
cout << "Using version " << vinfo->getName() << ". Offsets follow:" << endl;
cout << "--------------------------------------------------------------" << endl;
cout << vinfo->PrintOffsets();
cout << "--------------------------------------------------------------" << endl;
*/
// only enumerate threads if this is a valid DF process. the enumeration is costly.
vector<uint32_t> threads_ids;
if(!getThreadIDs( threads_ids ))
{
// thread enumeration failed.
my_handle = 0;
CloseHandle(my_handle);
my_handle = 0;
return;
}
identified = true;
@ -174,8 +180,20 @@ NormalProcess::NormalProcess(uint32_t pid, VersionInfoFactory * factory)
my_descriptor->RebaseAll(base);
// keep track of created memory_info object so we can destroy it later
my_descriptor->setParentProcess(this);
try
{
vector_start = my_descriptor->getGroup("vector")->getOffset("start");
stl.init(this);
}
catch (DFHack::Error::UnsetMemoryDefinition & e)
{
//cout << "WHAT THE FUCK WINE?" << endl;
//cout << "PID:" << pid << endl;
CloseHandle(my_handle);
my_handle = 0;
identified = false;
return;
}
for(int i = 0; i < threads_ids.size();i++)
{
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, (DWORD) threads_ids[i]);
@ -184,13 +202,14 @@ NormalProcess::NormalProcess(uint32_t pid, VersionInfoFactory * factory)
else
cerr << "Unable to open thread :" << hex << (DWORD) threads_ids[i] << endl;
}
stl.init(this);
}
else
{
// close handles of processes that aren't DF
my_handle = 0;
//cout << "ABOUT TO FREE HANDLE" << endl;
CloseHandle(my_handle);
//cout << "FREE'D HANDLE" << endl;
my_handle = 0;
}
}

@ -119,18 +119,25 @@ Process * BadProcesses::operator[](uint32_t index)
//FIXME: wasteful
Process *ProcessEnumerator::Private::GetProcessObject(ProcessID ID)
{
/*
Process *p1 = createSHMProcess(ID.pid, meminfo);
if(p1->isIdentified())
return p1;
else
delete p1;
*/
Process *p2 = createNormalProcess(ID.pid, meminfo);
if(p2->isIdentified())
{
//cout << "IS OK" << endl;
return p2;
}
else
{
//cout << "ABOUT TO DELETE" << endl;
delete p2;
//cout << "AFTER DELETE" << endl;
}
#ifdef LINUX_BUILD
Process *p3 = createWineProcess(ID.pid, meminfo);
if(p3->isIdentified())

@ -602,7 +602,9 @@ namespace DFHack
string version;
OSType OS;
std::string md5;
bool has_md5;
uint32_t PE_timestamp;
bool has_timestamp;
};
}
@ -616,8 +618,8 @@ VersionInfo::VersionInfo()
d->classindex = 0;
d->levels.reserve(NUM_RESERVE_LVLS);
d->moods.reserve(NUM_RESERVE_MOODS);
d->md5 = "invalid";
d->PE_timestamp = 0;
d->has_md5 = false;
d->has_timestamp = false;
OffsetGroup();
}
@ -648,7 +650,9 @@ void VersionInfo::copy(const VersionInfo * old)
d->version = old->d->version;
d->OS = old->d->OS;
d->md5 = old->d->md5;
d->has_md5 = old->d->has_md5;
d->PE_timestamp = old->d->PE_timestamp;
d->has_timestamp = old->d->has_timestamp;
d->base = old->d->base;
//d->classes = old.d->classes;
for(uint32_t i = 0; i < old->d->classes.size(); i++)
@ -709,21 +713,27 @@ string VersionInfo::getVersion()
void VersionInfo::setMD5(const string &v)
{
d->md5 = v;
d->has_md5 = true;
}
string VersionInfo::getMD5()
bool VersionInfo::getMD5( string & output )
{
return d->md5;
if(!d->has_md5) return false;
output = d->md5;
return true;
}
void VersionInfo::setPE(uint32_t v)
{
d->PE_timestamp = v;
d->has_timestamp = true;
}
uint32_t VersionInfo::getPE()
bool VersionInfo::getPE(uint32_t & output)
{
return d->PE_timestamp;
if(!d->has_timestamp) return false;
output = d->PE_timestamp;
return true;
}
void VersionInfo::setOS(const char *os)
@ -1186,17 +1196,19 @@ std::string VersionInfo::getMood(const uint32_t moodID)
std::string VersionInfo::PrintOffsets()
{
ostringstream ss;
string md5;
uint32_t PE;
indentr i;
ss << i << "<Version name=\"" << getVersion() << "\">" << endl;
i.indent();
switch (getOS())
{
case OS_LINUX:
ss << i << "<MD5 value=\"" << getMD5() << "\" />" << endl;
break;
case OS_WINDOWS:
ss << i << "<PETimeStamp value=\"" << hex << "0x" << getPE() << "\" />" << endl;
ss << i << "<MD5 value=\"" << getMD5() << "\" />" << endl;
if(getPE(PE))
ss << i << "<PETimeStamp value=\"" << hex << "0x" << PE << "\" />" << endl;
case OS_LINUX:
if(getMD5(md5))
ss << i << "<MD5 value=\"" << md5 << "\" />" << endl;
break;
default:
ss << i << " UNKNOWN" << endl;

@ -112,26 +112,33 @@ VersionInfo * VersionInfoFactory::getVersionInfoByMD5(string hash)
for(uint32_t i = 0; i < versions.size();i++)
{
vinfo = versions[i];
if(vinfo->getMD5() == hash)
string test_hash;
if(vinfo->getMD5(test_hash) && hash == test_hash)
{
return vinfo;
}
}
return NULL;
return 0;
}
VersionInfo * VersionInfoFactory::getVersionInfoByPETimestamp(uint32_t timestamp)
{
VersionInfo * vinfo;
//cout << "lookup size:" << versions.size() << endl;
for(uint32_t i = 0; i < versions.size();i++)
{
vinfo = versions[i];
if(vinfo->getPE() == timestamp)
uint32_t test_PE;
//cout << "Testing version: " << hex << vinfo <<" No:" << dec << i << endl;
//cout << vinfo->getName() << endl;
if(vinfo->getPE(test_PE) && test_PE == timestamp)
{
return vinfo;
}
//cout << "LOOP ENDS" << endl;
}
return NULL;
//cout << "NOTHING!" << endl;
return 0;
}
@ -746,8 +753,6 @@ bool VersionInfoFactory::loadFile(string path_to_xml)
versions.push_back(version);
}
}
// process found things here
}
error = false;
return true;

@ -117,10 +117,10 @@ namespace DFHack
void setBase (const uint32_t);
void setMD5 (const std::string & _md5);
std::string getMD5();
bool getMD5(std::string & output);
void setPE (uint32_t PE_);
uint32_t getPE();
bool getPE(uint32_t & output);
std::string getMood(const uint32_t moodID);
std::string getString (const std::string&);

@ -166,7 +166,7 @@ Maps::Maps(DFContextShared* _d)
{
off.world_data = OG_Maps->getAddress("world_data");
d->usesWorldDataPtr = true;
cout << "uses world ptr" << endl;
//cout << "uses world ptr" << endl;
}catch(Error::AllMemdef &){}
{