Suspend all DF threads on Windows.

develop
Petr Mrázek 2011-03-31 01:14:08 +02:00
parent d6bd4d47fb
commit 6cd08c3f31
1 changed files with 31 additions and 14 deletions

@ -36,7 +36,8 @@ namespace
private: private:
VersionInfo * my_descriptor; VersionInfo * my_descriptor;
HANDLE my_handle; HANDLE my_handle;
HANDLE my_main_thread; vector <HANDLE> threads;
vector <HANDLE> stoppedthreads;
uint32_t my_pid; uint32_t my_pid;
string memFile; string memFile;
bool attached; bool attached;
@ -112,7 +113,6 @@ NormalProcess::NormalProcess(uint32_t pid, VersionInfoFactory * factory)
: my_pid(pid) : my_pid(pid)
{ {
my_descriptor = NULL; my_descriptor = NULL;
my_main_thread = NULL;
attached = false; attached = false;
suspended = false; suspended = false;
base = 0; base = 0;
@ -140,7 +140,6 @@ NormalProcess::NormalProcess(uint32_t pid, VersionInfoFactory * factory)
// got base ;) // got base ;)
base = (uint32_t)hmod; base = (uint32_t)hmod;
my_main_thread = 0;
// read from this process // read from this process
try try
{ {
@ -160,6 +159,15 @@ NormalProcess::NormalProcess(uint32_t pid, VersionInfoFactory * factory)
VersionInfo* vinfo = factory->getVersionInfoByPETimestamp(pe_header.FileHeader.TimeDateStamp); VersionInfo* vinfo = factory->getVersionInfoByPETimestamp(pe_header.FileHeader.TimeDateStamp);
if(vinfo) if(vinfo)
{ {
// 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);
return;
}
identified = true; identified = true;
// give the process a data model and memory layout fixed for the base of first module // give the process a data model and memory layout fixed for the base of first module
my_descriptor = new VersionInfo(*vinfo); my_descriptor = new VersionInfo(*vinfo);
@ -168,10 +176,14 @@ NormalProcess::NormalProcess(uint32_t pid, VersionInfoFactory * factory)
my_descriptor->setParentProcess(this); my_descriptor->setParentProcess(this);
vector_start = my_descriptor->getGroup("vector")->getOffset("start"); vector_start = my_descriptor->getGroup("vector")->getOffset("start");
// TODO: detect errors in thread enumeration for(int i = 0; i < threads_ids.size();i++)
vector<uint32_t> threads; {
getThreadIDs( threads ); HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, (DWORD) threads_ids[i]);
my_main_thread = OpenThread(THREAD_ALL_ACCESS, FALSE, (DWORD) threads[0]); if(hThread)
threads.push_back(hThread);
else
cerr << "Unable to open thread :" << hex << (DWORD) threads_ids[i] << endl;
}
stl.init(this); stl.init(this);
} }
else else
@ -194,10 +206,8 @@ NormalProcess::~NormalProcess()
{ {
CloseHandle(my_handle); CloseHandle(my_handle);
} }
if(my_main_thread != NULL) for(int i = 0; i < threads.size(); i++)
{ CloseHandle(threads[i]);
CloseHandle(my_main_thread);
}
if(sections != NULL) if(sections != NULL)
free(sections); free(sections);
} }
@ -239,7 +249,11 @@ bool NormalProcess::suspend()
{ {
return true; return true;
} }
SuspendThread(my_main_thread); for(int i = 0; i < threads.size(); i++)
{
stoppedthreads.push_back(threads[i]);
SuspendThread(threads[i]);
}
suspended = true; suspended = true;
return true; return true;
} }
@ -248,7 +262,8 @@ bool NormalProcess::forceresume()
{ {
if(!attached) if(!attached)
return false; return false;
while (ResumeThread(my_main_thread) > 1); for(int i = 0; i < threads.size(); i++)
while (ResumeThread(threads[i]) > 1);
suspended = false; suspended = false;
return true; return true;
} }
@ -262,7 +277,9 @@ bool NormalProcess::resume()
{ {
return true; return true;
} }
ResumeThread(my_main_thread); for(int i = 0; i < stoppedthreads.size(); i++)
ResumeThread(stoppedthreads[i]);
stoppedthreads.clear();
suspended = false; suspended = false;
return true; return true;
} }