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

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

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

@ -112,26 +112,33 @@ VersionInfo * VersionInfoFactory::getVersionInfoByMD5(string hash)
for(uint32_t i = 0; i < versions.size();i++) for(uint32_t i = 0; i < versions.size();i++)
{ {
vinfo = versions[i]; vinfo = versions[i];
if(vinfo->getMD5() == hash) string test_hash;
if(vinfo->getMD5(test_hash) && hash == test_hash)
{ {
return vinfo; return vinfo;
} }
} }
return NULL; return 0;
} }
VersionInfo * VersionInfoFactory::getVersionInfoByPETimestamp(uint32_t timestamp) VersionInfo * VersionInfoFactory::getVersionInfoByPETimestamp(uint32_t timestamp)
{ {
VersionInfo * vinfo; VersionInfo * vinfo;
//cout << "lookup size:" << versions.size() << endl;
for(uint32_t i = 0; i < versions.size();i++) for(uint32_t i = 0; i < versions.size();i++)
{ {
vinfo = versions[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; 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); versions.push_back(version);
} }
} }
// process found things here
} }
error = false; error = false;
return true; return true;

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

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