Refactor Thread.cpp/.h
This commit is contained in:
parent
125f07ff6c
commit
47306590cc
|
@ -540,8 +540,8 @@ typedef struct
|
|||
typedef struct
|
||||
{
|
||||
int ThreadNumber;
|
||||
HANDLE hThread;
|
||||
DWORD dwThreadId;
|
||||
HANDLE Handle;
|
||||
DWORD ThreadId;
|
||||
duint ThreadStartAddress;
|
||||
duint ThreadLocalBase;
|
||||
char threadName[MAX_THREAD_NAME_SIZE];
|
||||
|
|
|
@ -719,7 +719,7 @@ extern "C" DLL_EXPORT uint _dbg_sendmessage(DBGMSG type, void* param1, void* par
|
|||
|
||||
case DBG_GET_THREAD_LIST:
|
||||
{
|
||||
threadgetlist((THREADLIST*)param1);
|
||||
ThreadGetList((THREADLIST*)param1);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -203,14 +203,14 @@ void DebugUpdateGui(uint disasm_addr, bool stack)
|
|||
else
|
||||
sprintf(modtext, "Module: %s - ", modname);
|
||||
char title[1024] = "";
|
||||
sprintf(title, "File: %s - PID: %X - %sThread: %X", szBaseFileName, fdProcessInfo->dwProcessId, modtext, threadgetid(hActiveThread));
|
||||
sprintf(title, "File: %s - PID: %X - %sThread: %X", szBaseFileName, fdProcessInfo->dwProcessId, modtext, ThreadGetId(hActiveThread));
|
||||
GuiUpdateWindowTitle(title);
|
||||
GuiUpdateAllViews();
|
||||
}
|
||||
|
||||
void cbUserBreakpoint()
|
||||
{
|
||||
hActiveThread = threadgethandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
BREAKPOINT bp;
|
||||
BRIDGEBP pluginBp;
|
||||
PLUG_CB_BREAKPOINT bpInfo;
|
||||
|
@ -260,7 +260,7 @@ void cbUserBreakpoint()
|
|||
|
||||
void cbHardwareBreakpoint(void* ExceptionAddress)
|
||||
{
|
||||
hActiveThread = threadgethandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
uint cip = GetContextDataEx(hActiveThread, UE_CIP);
|
||||
BREAKPOINT bp;
|
||||
BRIDGEBP pluginBp;
|
||||
|
@ -335,7 +335,7 @@ void cbHardwareBreakpoint(void* ExceptionAddress)
|
|||
|
||||
void cbMemoryBreakpoint(void* ExceptionAddress)
|
||||
{
|
||||
hActiveThread = threadgethandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
uint cip = GetContextDataEx(hActiveThread, UE_CIP);
|
||||
uint size;
|
||||
uint base = memfindbaseaddr((uint)ExceptionAddress, &size, true);
|
||||
|
@ -540,7 +540,7 @@ static bool cbRemoveModuleBreakpoints(const BREAKPOINT* bp)
|
|||
|
||||
void cbStep()
|
||||
{
|
||||
hActiveThread = threadgethandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
isStepping = false;
|
||||
GuiSetDebugState(paused);
|
||||
DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true);
|
||||
|
@ -559,7 +559,7 @@ void cbStep()
|
|||
|
||||
static void cbRtrFinalStep()
|
||||
{
|
||||
hActiveThread = threadgethandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
GuiSetDebugState(paused);
|
||||
DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true);
|
||||
//lock
|
||||
|
@ -605,7 +605,7 @@ static void cbCreateProcess(CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo)
|
|||
dprintf("Process Started: "fhex" %s\n", base, DebugFileName);
|
||||
|
||||
memupdatemap(fdProcessInfo->hProcess);
|
||||
GuiDumpAt(memfindbaseaddr(GetContextData(UE_CIP), 0)+PAGE_SIZE); //dump somewhere
|
||||
GuiDumpAt(memfindbaseaddr(GetContextData(UE_CIP), 0) + PAGE_SIZE); //dump somewhere
|
||||
|
||||
//init program database
|
||||
int len = (int)strlen(szFileName);
|
||||
|
@ -704,7 +704,7 @@ static void cbCreateThread(CREATE_THREAD_DEBUG_INFO* CreateThread)
|
|||
{
|
||||
threadcreate(CreateThread); //update thread list
|
||||
DWORD dwThreadId = ((DEBUG_EVENT*)GetDebugData())->dwThreadId;
|
||||
hActiveThread = threadgethandle(dwThreadId);
|
||||
hActiveThread = ThreadGetHandle(dwThreadId);
|
||||
|
||||
if(settingboolget("Events", "ThreadEntry"))
|
||||
{
|
||||
|
@ -739,7 +739,7 @@ static void cbCreateThread(CREATE_THREAD_DEBUG_INFO* CreateThread)
|
|||
|
||||
static void cbExitThread(EXIT_THREAD_DEBUG_INFO* ExitThread)
|
||||
{
|
||||
hActiveThread = threadgethandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
DWORD dwThreadId = ((DEBUG_EVENT*)GetDebugData())->dwThreadId;
|
||||
PLUG_CB_EXITTHREAD callbackInfo;
|
||||
callbackInfo.ExitThread = ExitThread;
|
||||
|
@ -765,7 +765,7 @@ static void cbExitThread(EXIT_THREAD_DEBUG_INFO* ExitThread)
|
|||
|
||||
static void cbSystemBreakpoint(void* ExceptionData)
|
||||
{
|
||||
hActiveThread = threadgethandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
//log message
|
||||
if(bIsAttached)
|
||||
dputs("Attach breakpoint reached!");
|
||||
|
@ -797,7 +797,7 @@ static void cbSystemBreakpoint(void* ExceptionData)
|
|||
|
||||
static void cbLoadDll(LOAD_DLL_DEBUG_INFO* LoadDll)
|
||||
{
|
||||
hActiveThread = threadgethandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
void* base = LoadDll->lpBaseOfDll;
|
||||
char DLLDebugFileName[deflen] = "";
|
||||
if(!GetFileNameFromHandle(LoadDll->hFile, DLLDebugFileName))
|
||||
|
@ -900,7 +900,7 @@ static void cbLoadDll(LOAD_DLL_DEBUG_INFO* LoadDll)
|
|||
|
||||
static void cbUnloadDll(UNLOAD_DLL_DEBUG_INFO* UnloadDll)
|
||||
{
|
||||
hActiveThread = threadgethandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
PLUG_CB_UNLOADDLL callbackInfo;
|
||||
callbackInfo.UnloadDll = UnloadDll;
|
||||
plugincbcall(CB_UNLOADDLL, &callbackInfo);
|
||||
|
@ -934,7 +934,7 @@ static void cbUnloadDll(UNLOAD_DLL_DEBUG_INFO* UnloadDll)
|
|||
static void cbOutputDebugString(OUTPUT_DEBUG_STRING_INFO* DebugString)
|
||||
{
|
||||
|
||||
hActiveThread = threadgethandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
PLUG_CB_OUTPUTDEBUGSTRING callbackInfo;
|
||||
callbackInfo.DebugString = DebugString;
|
||||
plugincbcall(CB_OUTPUTDEBUGSTRING, &callbackInfo);
|
||||
|
@ -973,7 +973,7 @@ static void cbOutputDebugString(OUTPUT_DEBUG_STRING_INFO* DebugString)
|
|||
|
||||
static void cbException(EXCEPTION_DEBUG_INFO* ExceptionData)
|
||||
{
|
||||
hActiveThread = threadgethandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
PLUG_CB_EXCEPTION callbackInfo;
|
||||
callbackInfo.Exception = ExceptionData;
|
||||
unsigned int ExceptionCode = ExceptionData->ExceptionRecord.ExceptionCode;
|
||||
|
@ -1019,14 +1019,14 @@ static void cbException(EXCEPTION_DEBUG_INFO* ExceptionData)
|
|||
memcpy(&nameInfo, ExceptionData->ExceptionRecord.ExceptionInformation, sizeof(THREADNAME_INFO));
|
||||
if(nameInfo.dwThreadID == -1) //current thread
|
||||
nameInfo.dwThreadID = ((DEBUG_EVENT*)GetDebugData())->dwThreadId;
|
||||
if(nameInfo.dwType == 0x1000 and nameInfo.dwFlags == 0 and threadisvalid(nameInfo.dwThreadID)) //passed basic checks
|
||||
if(nameInfo.dwType == 0x1000 and nameInfo.dwFlags == 0 and ThreadIsValid(nameInfo.dwThreadID)) //passed basic checks
|
||||
{
|
||||
Memory<char*> ThreadName(MAX_THREAD_NAME_SIZE, "cbException:ThreadName");
|
||||
if(memread(fdProcessInfo->hProcess, nameInfo.szName, ThreadName, MAX_THREAD_NAME_SIZE - 1, 0))
|
||||
{
|
||||
String ThreadNameEscaped = StringUtils::Escape(ThreadName);
|
||||
dprintf("SetThreadName(%X, \"%s\")\n", nameInfo.dwThreadID, ThreadNameEscaped.c_str());
|
||||
threadsetname(nameInfo.dwThreadID, ThreadNameEscaped.c_str());
|
||||
ThreadSetName(nameInfo.dwThreadID, ThreadNameEscaped.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1035,13 +1035,13 @@ CMDRESULT cbDebugSwitchthread(int argc, char* argv[])
|
|||
if(argc > 1)
|
||||
if(!valfromstring(argv[1], &threadid, false))
|
||||
return STATUS_ERROR;
|
||||
if(!threadisvalid((DWORD)threadid)) //check if the thread is valid
|
||||
if(!ThreadIsValid((DWORD)threadid)) //check if the thread is valid
|
||||
{
|
||||
dprintf("Invalid thread %X\n", threadid);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
//switch thread
|
||||
hActiveThread = threadgethandle((DWORD)threadid);
|
||||
hActiveThread = ThreadGetHandle((DWORD)threadid);
|
||||
DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true);
|
||||
dputs("Thread switched!");
|
||||
return STATUS_CONTINUE;
|
||||
|
@ -1053,13 +1053,13 @@ CMDRESULT cbDebugSuspendthread(int argc, char* argv[])
|
|||
if(argc > 1)
|
||||
if(!valfromstring(argv[1], &threadid, false))
|
||||
return STATUS_ERROR;
|
||||
if(!threadisvalid((DWORD)threadid)) //check if the thread is valid
|
||||
if(!ThreadIsValid((DWORD)threadid)) //check if the thread is valid
|
||||
{
|
||||
dprintf("Invalid thread %X\n", threadid);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
//suspend thread
|
||||
if(SuspendThread(threadgethandle((DWORD)threadid)) == -1)
|
||||
if(SuspendThread(ThreadGetHandle((DWORD)threadid)) == -1)
|
||||
{
|
||||
dputs("Error suspending thread");
|
||||
return STATUS_ERROR;
|
||||
|
@ -1075,13 +1075,13 @@ CMDRESULT cbDebugResumethread(int argc, char* argv[])
|
|||
if(argc > 1)
|
||||
if(!valfromstring(argv[1], &threadid, false))
|
||||
return STATUS_ERROR;
|
||||
if(!threadisvalid((DWORD)threadid)) //check if the thread is valid
|
||||
if(!ThreadIsValid((DWORD)threadid)) //check if the thread is valid
|
||||
{
|
||||
dprintf("Invalid thread %X\n", threadid);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
//resume thread
|
||||
if(ResumeThread(threadgethandle((DWORD)threadid)) == -1)
|
||||
if(ResumeThread(ThreadGetHandle((DWORD)threadid)) == -1)
|
||||
{
|
||||
dputs("Error resuming thread");
|
||||
return STATUS_ERROR;
|
||||
|
@ -1101,13 +1101,13 @@ CMDRESULT cbDebugKillthread(int argc, char* argv[])
|
|||
if(argc > 2)
|
||||
if(!valfromstring(argv[2], &exitcode, false))
|
||||
return STATUS_ERROR;
|
||||
if(!threadisvalid((DWORD)threadid)) //check if the thread is valid
|
||||
if(!ThreadIsValid((DWORD)threadid)) //check if the thread is valid
|
||||
{
|
||||
dprintf("Invalid thread %X\n", threadid);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
//terminate thread
|
||||
if(TerminateThread(threadgethandle((DWORD)threadid), (DWORD)exitcode) != 0)
|
||||
if(TerminateThread(ThreadGetHandle((DWORD)threadid), (DWORD)exitcode) != 0)
|
||||
{
|
||||
GuiUpdateAllViews();
|
||||
dputs("Thread terminated");
|
||||
|
@ -1119,8 +1119,8 @@ CMDRESULT cbDebugKillthread(int argc, char* argv[])
|
|||
|
||||
CMDRESULT cbDebugSuspendAllThreads(int argc, char* argv[])
|
||||
{
|
||||
int threadCount = threadgetcount();
|
||||
int suspendedCount = threadsuspendall();
|
||||
int threadCount = ThreadGetCount();
|
||||
int suspendedCount = ThreadSuspendAll();
|
||||
dprintf("%d/%d thread(s) suspended\n", suspendedCount, threadCount);
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
|
@ -1128,8 +1128,8 @@ CMDRESULT cbDebugSuspendAllThreads(int argc, char* argv[])
|
|||
|
||||
CMDRESULT cbDebugResumeAllThreads(int argc, char* argv[])
|
||||
{
|
||||
int threadCount = threadgetcount();
|
||||
int resumeCount = threadresumeall();
|
||||
int threadCount = ThreadGetCount();
|
||||
int resumeCount = ThreadResumeAll();
|
||||
dprintf("%d/%d thread(s) resumed\n", resumeCount, threadCount);
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
|
@ -1185,13 +1185,13 @@ CMDRESULT cbDebugSetPriority(int argc, char* argv[])
|
|||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
if(!threadisvalid((DWORD)threadid)) //check if the thread is valid
|
||||
if(!ThreadIsValid((DWORD)threadid)) //check if the thread is valid
|
||||
{
|
||||
dprintf("Invalid thread %X\n", threadid);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
//set thread priority
|
||||
if(SetThreadPriority(threadgethandle((DWORD)threadid), (int)priority) == 0)
|
||||
if(SetThreadPriority(ThreadGetHandle((DWORD)threadid), (int)priority) == 0)
|
||||
{
|
||||
dputs("Error setting thread priority");
|
||||
return STATUS_ERROR;
|
||||
|
@ -1817,7 +1817,7 @@ CMDRESULT cbDebugLoadLib(int argc, char* argv[])
|
|||
}
|
||||
|
||||
LoadLibThreadID = fdProcessInfo->dwThreadId;
|
||||
HANDLE LoadLibThread = threadgethandle((DWORD)LoadLibThreadID);
|
||||
HANDLE LoadLibThread = ThreadGetHandle((DWORD)LoadLibThreadID);
|
||||
|
||||
DLLNameMem = VirtualAllocEx(fdProcessInfo->hProcess, NULL, strlen(argv[1]) + 1, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
||||
ASMAddr = VirtualAllocEx(fdProcessInfo->hProcess, NULL, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
|
@ -1869,7 +1869,7 @@ CMDRESULT cbDebugLoadLib(int argc, char* argv[])
|
|||
SetContextDataEx(LoadLibThread, UE_CIP, (uint)ASMAddr);
|
||||
SetBPX((uint)ASMAddr + counter, UE_SINGLESHOOT | UE_BREAKPOINT_TYPE_INT3, (void*)cbLoadLibBPX);
|
||||
|
||||
threadsuspendall();
|
||||
ThreadSuspendAll();
|
||||
ResumeThread(LoadLibThread);
|
||||
|
||||
unlock(WAITID_RUN);
|
||||
|
@ -1880,7 +1880,7 @@ CMDRESULT cbDebugLoadLib(int argc, char* argv[])
|
|||
void cbLoadLibBPX()
|
||||
{
|
||||
uint LibAddr = 0;
|
||||
HANDLE LoadLibThread = threadgethandle((DWORD)LoadLibThreadID);
|
||||
HANDLE LoadLibThread = ThreadGetHandle((DWORD)LoadLibThreadID);
|
||||
#ifdef _WIN64
|
||||
LibAddr = GetContextDataEx(LoadLibThread, UE_RAX);
|
||||
#else
|
||||
|
@ -1891,7 +1891,7 @@ void cbLoadLibBPX()
|
|||
SetFullContextDataEx(LoadLibThread, &backupctx);
|
||||
VirtualFreeEx(fdProcessInfo->hProcess, DLLNameMem, 0, MEM_RELEASE);
|
||||
VirtualFreeEx(fdProcessInfo->hProcess, ASMAddr, 0, MEM_RELEASE);
|
||||
threadresumeall();
|
||||
ThreadResumeAll();
|
||||
//update GUI
|
||||
GuiSetDebugState(paused);
|
||||
DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true);
|
||||
|
|
|
@ -6,150 +6,239 @@
|
|||
|
||||
static std::vector<THREADINFO> threadList;
|
||||
static int threadNum;
|
||||
static int currentThread;
|
||||
|
||||
void threadcreate(CREATE_THREAD_DEBUG_INFO* CreateThread)
|
||||
{
|
||||
THREADINFO curInfo;
|
||||
curInfo.ThreadNumber = threadNum;
|
||||
curInfo.hThread = CreateThread->hThread;
|
||||
curInfo.dwThreadId = ((DEBUG_EVENT*)GetDebugData())->dwThreadId;
|
||||
curInfo.ThreadStartAddress = (uint)CreateThread->lpStartAddress;
|
||||
curInfo.ThreadLocalBase = (uint)CreateThread->lpThreadLocalBase;
|
||||
*curInfo.threadName = '\0';
|
||||
if(!threadNum)
|
||||
memset(&curInfo, 0, sizeof(THREADINFO));
|
||||
|
||||
curInfo.ThreadNumber = threadNum;
|
||||
curInfo.Handle = CreateThread->hThread;
|
||||
curInfo.ThreadId = ((DEBUG_EVENT*)GetDebugData())->dwThreadId;
|
||||
curInfo.ThreadStartAddress = (uint)CreateThread->lpStartAddress;
|
||||
curInfo.ThreadLocalBase = (uint)CreateThread->lpThreadLocalBase;
|
||||
|
||||
// The first thread (#0) is always the main program thread
|
||||
if(threadNum <= 0)
|
||||
strcpy_s(curInfo.threadName, "Main Thread");
|
||||
CriticalSectionLocker locker(LockThreads);
|
||||
|
||||
// Modify global thread list
|
||||
EXCLUSIVE_ACQUIRE(LockThreads);
|
||||
threadList.push_back(curInfo);
|
||||
threadNum++;
|
||||
locker.unlock(); //prevent possible deadlocks
|
||||
EXCLUSIVE_RELEASE();
|
||||
|
||||
// Notify GUI
|
||||
GuiUpdateThreadView();
|
||||
}
|
||||
|
||||
void threadexit(DWORD dwThreadId)
|
||||
{
|
||||
CriticalSectionLocker locker(LockThreads);
|
||||
for(unsigned int i = 0; i < threadList.size(); i++)
|
||||
if(threadList.at(i).dwThreadId == dwThreadId)
|
||||
EXCLUSIVE_ACQUIRE(LockThreads);
|
||||
|
||||
for(auto itr = threadList.begin(); itr != threadList.end(); itr++)
|
||||
{
|
||||
if(itr->ThreadId == dwThreadId)
|
||||
{
|
||||
threadList.erase(threadList.begin() + i);
|
||||
threadList.erase(itr);
|
||||
break;
|
||||
}
|
||||
locker.unlock(); //prevent possible deadlocks
|
||||
}
|
||||
|
||||
EXCLUSIVE_RELEASE();
|
||||
GuiUpdateThreadView();
|
||||
}
|
||||
|
||||
void threadclear()
|
||||
{
|
||||
threadNum = 0;
|
||||
CriticalSectionLocker locker(LockThreads);
|
||||
std::vector<THREADINFO>().swap(threadList);
|
||||
locker.unlock(); //prevent possible deadlocks
|
||||
|
||||
// Clear the current array of threads
|
||||
EXCLUSIVE_ACQUIRE(LockThreads);
|
||||
threadList.clear();
|
||||
EXCLUSIVE_RELEASE();
|
||||
|
||||
// Update the GUI's list
|
||||
GuiUpdateThreadView();
|
||||
}
|
||||
|
||||
static THREADWAITREASON GetThreadWaitReason(DWORD dwThreadId)
|
||||
bool ThreadGetTeb(uint TEBAddress, TEB* Teb)
|
||||
{
|
||||
//TODO: implement this
|
||||
//
|
||||
// TODO: Keep a cached copy of this inside of the vector
|
||||
//
|
||||
memset(Teb, 0, sizeof(TEB));
|
||||
|
||||
return memread(fdProcessInfo->hProcess, (void*)TEBAddress, Teb, sizeof(TEB), nullptr);
|
||||
}
|
||||
|
||||
int ThreadGetSuspendCount(HANDLE Thread)
|
||||
{
|
||||
//
|
||||
// Suspend a thread in order to get the previous suspension count
|
||||
// WARNING: This function is very bad (threads should not be randomly interrupted)
|
||||
//
|
||||
int suspendCount = (int)SuspendThread(Thread);
|
||||
|
||||
if(suspendCount == -1)
|
||||
return 0;
|
||||
|
||||
// Resume the thread's normal execution
|
||||
ResumeThread(Thread);
|
||||
|
||||
return suspendCount;
|
||||
}
|
||||
|
||||
THREADPRIORITY ThreadGetPriority(HANDLE Thread)
|
||||
{
|
||||
return (THREADPRIORITY)GetThreadPriority(Thread);
|
||||
}
|
||||
|
||||
THREADWAITREASON ThreadGetWaitReason(HANDLE Thread)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Thread);
|
||||
|
||||
//TODO: Implement this
|
||||
return _Executive;
|
||||
}
|
||||
|
||||
static DWORD GetThreadLastError(uint tebAddress)
|
||||
DWORD ThreadGetLastError(uint tebAddress)
|
||||
{
|
||||
TEB teb;
|
||||
memset(&teb, 0, sizeof(TEB));
|
||||
if(!memread(fdProcessInfo->hProcess, (void*)tebAddress, &teb, sizeof(TEB), 0))
|
||||
if(!ThreadGetTeb(tebAddress, &teb))
|
||||
{
|
||||
// TODO: Assert
|
||||
return 0;
|
||||
}
|
||||
|
||||
return teb.LastErrorValue;
|
||||
}
|
||||
|
||||
void threadgetlist(THREADLIST* list)
|
||||
void ThreadGetList(THREADLIST* list)
|
||||
{
|
||||
CriticalSectionLocker locker(LockThreads);
|
||||
int count = (int)threadList.size();
|
||||
list->count = count;
|
||||
if(!count)
|
||||
EXCLUSIVE_ACQUIRE(LockThreads);
|
||||
|
||||
//
|
||||
// This function converts a C++ std::vector to a C-style THREADLIST[]
|
||||
// Also assume BridgeAlloc zeros the returned buffer
|
||||
//
|
||||
size_t count = threadList.size();
|
||||
|
||||
if(count <= 0)
|
||||
return;
|
||||
list->list = (THREADALLINFO*)BridgeAlloc(count * sizeof(THREADALLINFO));
|
||||
for(int i = 0; i < count; i++)
|
||||
|
||||
list->count = (int)count;
|
||||
list->list = (THREADALLINFO*)BridgeAlloc(count * sizeof(THREADALLINFO));
|
||||
|
||||
// Fill out the list data
|
||||
for(size_t i = 0; i < count; i++)
|
||||
{
|
||||
if(hActiveThread == threadList.at(i).hThread)
|
||||
currentThread = i;
|
||||
memset(&list->list[i], 0, sizeof(THREADALLINFO));
|
||||
memcpy(&list->list[i].BasicInfo, &threadList.at(i), sizeof(THREADINFO));
|
||||
HANDLE hThread = list->list[i].BasicInfo.hThread;
|
||||
list->list[i].ThreadCip = GetContextDataEx(hThread, UE_CIP);
|
||||
list->list[i].SuspendCount = SuspendThread(hThread);
|
||||
ResumeThread(hThread);
|
||||
list->list[i].Priority = (THREADPRIORITY)GetThreadPriority(list->list[i].BasicInfo.hThread);
|
||||
list->list[i].WaitReason = GetThreadWaitReason(list->list[i].BasicInfo.dwThreadId);
|
||||
list->list[i].LastError = GetThreadLastError(list->list[i].BasicInfo.ThreadLocalBase);
|
||||
HANDLE threadHandle = threadList[i].Handle;
|
||||
|
||||
// Get the debugger's current thread index
|
||||
if(threadHandle == hActiveThread)
|
||||
list->CurrentThread = (int)i;
|
||||
|
||||
memcpy(&list->list[i].BasicInfo, &threadList[i], sizeof(THREADINFO));
|
||||
|
||||
list->list[i].ThreadCip = GetContextDataEx(threadHandle, UE_CIP);
|
||||
list->list[i].SuspendCount = ThreadGetSuspendCount(threadHandle);
|
||||
list->list[i].Priority = ThreadGetPriority(threadHandle);
|
||||
list->list[i].WaitReason = ThreadGetWaitReason(threadHandle);
|
||||
list->list[i].LastError = ThreadGetLastError(list->list[i].BasicInfo.ThreadLocalBase);
|
||||
}
|
||||
list->CurrentThread = currentThread;
|
||||
}
|
||||
|
||||
bool threadisvalid(DWORD dwThreadId)
|
||||
bool ThreadIsValid(DWORD dwThreadId)
|
||||
{
|
||||
CriticalSectionLocker locker(LockThreads);
|
||||
for(unsigned int i = 0; i < threadList.size(); i++)
|
||||
if(threadList.at(i).dwThreadId == dwThreadId)
|
||||
EXCLUSIVE_ACQUIRE(LockThreads);
|
||||
|
||||
for(auto itr = threadList.begin(); itr != threadList.end(); itr++)
|
||||
{
|
||||
if(itr->ThreadId == dwThreadId)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool threadsetname(DWORD dwThreadId, const char* name)
|
||||
bool ThreadSetName(DWORD dwThreadId, const char* name)
|
||||
{
|
||||
CriticalSectionLocker locker(LockThreads);
|
||||
for(unsigned int i = 0; i < threadList.size(); i++)
|
||||
if(threadList.at(i).dwThreadId == dwThreadId)
|
||||
EXCLUSIVE_ACQUIRE(LockThreads);
|
||||
|
||||
for(auto itr = threadList.begin(); itr != threadList.end(); itr++)
|
||||
{
|
||||
if(itr->ThreadId == dwThreadId)
|
||||
{
|
||||
if(name)
|
||||
strcpy_s(threadList.at(i).threadName, name);
|
||||
strcpy_s(itr->threadName, name);
|
||||
else
|
||||
*threadList.at(i).threadName = '\0';
|
||||
itr->threadName[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
HANDLE threadgethandle(DWORD dwThreadId)
|
||||
HANDLE ThreadGetHandle(DWORD dwThreadId)
|
||||
{
|
||||
CriticalSectionLocker locker(LockThreads);
|
||||
for(unsigned int i = 0; i < threadList.size(); i++)
|
||||
if(threadList.at(i).dwThreadId == dwThreadId)
|
||||
return threadList.at(i).hThread;
|
||||
EXCLUSIVE_ACQUIRE(LockThreads);
|
||||
|
||||
for(auto itr = threadList.begin(); itr != threadList.end(); itr++)
|
||||
{
|
||||
if(itr->ThreadId == dwThreadId)
|
||||
return itr->Handle;
|
||||
}
|
||||
|
||||
// TODO: Set an assert if the handle is never found,
|
||||
// using a bad handle causes random/silent issues everywhere
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD threadgetid(HANDLE hThread)
|
||||
DWORD ThreadGetId(HANDLE hThread)
|
||||
{
|
||||
CriticalSectionLocker locker(LockThreads);
|
||||
for(unsigned int i = 0; i < threadList.size(); i++)
|
||||
if(threadList.at(i).hThread == hThread)
|
||||
return threadList.at(i).dwThreadId;
|
||||
EXCLUSIVE_ACQUIRE(LockThreads);
|
||||
|
||||
for(auto itr = threadList.begin(); itr != threadList.end(); itr++)
|
||||
{
|
||||
if(itr->Handle == hThread)
|
||||
return itr->ThreadId;
|
||||
}
|
||||
|
||||
// TODO: Same problem with threadgethandle()
|
||||
// TODO: Different handles can map to the same thread
|
||||
return 0;
|
||||
}
|
||||
|
||||
int threadgetcount()
|
||||
int ThreadGetCount()
|
||||
{
|
||||
return (int)threadList.size();
|
||||
}
|
||||
|
||||
int threadsuspendall()
|
||||
int ThreadSuspendAll()
|
||||
{
|
||||
CriticalSectionLocker locker(LockThreads);
|
||||
EXCLUSIVE_ACQUIRE(LockThreads);
|
||||
|
||||
int count = 0;
|
||||
for(unsigned int i = 0; i < threadList.size(); i++)
|
||||
if(SuspendThread(threadList.at(i).hThread) != -1)
|
||||
for(auto itr = threadList.begin(); itr != threadList.end(); itr++)
|
||||
{
|
||||
if(SuspendThread(itr->Handle) != -1)
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int threadresumeall()
|
||||
int ThreadResumeAll()
|
||||
{
|
||||
CriticalSectionLocker locker(LockThreads);
|
||||
EXCLUSIVE_ACQUIRE(LockThreads);
|
||||
|
||||
int count = 0;
|
||||
for(unsigned int i = 0; i < threadList.size(); i++)
|
||||
if(ResumeThread(threadList.at(i).hThread) != -1)
|
||||
for(auto itr = threadList.begin(); itr != threadList.end(); itr++)
|
||||
{
|
||||
if(ResumeThread(itr->Handle) != -1)
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
|
@ -8,13 +8,13 @@
|
|||
void threadcreate(CREATE_THREAD_DEBUG_INFO* CreateThread);
|
||||
void threadexit(DWORD dwThreadId);
|
||||
void threadclear();
|
||||
void threadgetlist(THREADLIST* list);
|
||||
bool threadisvalid(DWORD dwThreadId);
|
||||
bool threadsetname(DWORD dwTHreadId, const char* name);
|
||||
HANDLE threadgethandle(DWORD dwThreadId);
|
||||
DWORD threadgetid(HANDLE hThread);
|
||||
int threadgetcount();
|
||||
int threadsuspendall();
|
||||
int threadresumeall();
|
||||
void ThreadGetList(THREADLIST* list);
|
||||
bool ThreadIsValid(DWORD dwThreadId);
|
||||
bool ThreadSetName(DWORD dwTHreadId, const char* name);
|
||||
HANDLE ThreadGetHandle(DWORD dwThreadId);
|
||||
DWORD ThreadGetId(HANDLE hThread);
|
||||
int ThreadGetCount();
|
||||
int ThreadSuspendAll();
|
||||
int ThreadResumeAll();
|
||||
|
||||
#endif //_THREAD_H
|
||||
|
|
Loading…
Reference in New Issue