dbg changes for TEB->LastStatusValue:
- Add LASTSTATUS struct - Add LastStatus members to REGDUMP and THREADALLINFO - Add ThreadGetLastStatus()/ThreadGetLastStatusTEB() - Make "laststatus" a supported pseudo-register in isregister() / getregister() / setregister() similar to "lasterror" - _dbg_getregdump(): copy the full name of the last NTSTATUS value - ThreadGetList(): add the last status value to the thread list for each thread - TraceRecordManager: account for the size change of REGDUMP to keep REGDUMPWORD the same size
This commit is contained in:
parent
8f0f83bdf3
commit
6f1b6b77bb
|
@ -87,8 +87,8 @@ private:
|
|||
{
|
||||
REGDUMP registers;
|
||||
// 172 qwords on x64, 216 dwords on x86. Almost no space left for AVX512
|
||||
// strip off 128 bytes of lastError.name member.
|
||||
duint regword[(sizeof(REGDUMP) - 128) / sizeof(duint)];
|
||||
// strip off lastStatus and 128 bytes of lastError.name member.
|
||||
duint regword[(FIELD_OFFSET(REGDUMP, lastError) + sizeof(DWORD)) / sizeof(duint)];
|
||||
} REGDUMPWORD;
|
||||
|
||||
//Key := page base, value := trace record raw data
|
||||
|
@ -102,7 +102,7 @@ private:
|
|||
HANDLE rtFile;
|
||||
|
||||
REGDUMPWORD rtOldContext;
|
||||
bool rtOldContextChanged[(sizeof(REGDUMP) - 128) / sizeof(duint)];
|
||||
bool rtOldContextChanged[(FIELD_OFFSET(REGDUMP, lastError) + sizeof(DWORD)) / sizeof(duint)];
|
||||
DWORD rtOldThreadId;
|
||||
bool rtNeedThreadId;
|
||||
duint rtOldMemory[32];
|
||||
|
|
|
@ -666,6 +666,11 @@ extern "C" DLL_EXPORT bool _dbg_getregdump(REGDUMP* regdump, size_t size)
|
|||
lastError.code = ThreadGetLastError(ThreadGetId(hActiveThread));
|
||||
strncpy_s(lastError.name, ErrorCodeToName(lastError.code).c_str(), _TRUNCATE);
|
||||
regdump->lastError = lastError;
|
||||
LASTSTATUS lastStatus;
|
||||
memset(&lastStatus.name, 0, sizeof(lastStatus.name));
|
||||
lastStatus.code = ThreadGetLastStatus(ThreadGetId(hActiveThread));
|
||||
strncpy_s(lastStatus.name, NtStatusCodeToName(lastStatus.code).c_str(), _TRUNCATE);
|
||||
regdump->lastStatus = lastStatus;
|
||||
|
||||
if(size >= sizeof(REGDUMP_V2))
|
||||
{
|
||||
|
|
|
@ -129,6 +129,7 @@ void ThreadGetList(THREADLIST* List)
|
|||
List->list[index].SuspendCount = ThreadGetSuspendCount(threadHandle);
|
||||
List->list[index].Priority = ThreadGetPriority(threadHandle);
|
||||
List->list[index].LastError = ThreadGetLastErrorTEB(itr.second.ThreadLocalBase);
|
||||
List->list[index].LastStatus = ThreadGetLastStatusTEB(itr.second.ThreadLocalBase);
|
||||
GetThreadTimes(threadHandle, &List->list[index].CreationTime, &threadExitTime, &List->list[index].KernelTime, &List->list[index].UserTime);
|
||||
List->list[index].Cycles = ThreadQueryCycleTime(threadHandle);
|
||||
index++;
|
||||
|
@ -228,6 +229,27 @@ DWORD ThreadGetLastError(DWORD ThreadId)
|
|||
return 0;
|
||||
}
|
||||
|
||||
NTSTATUS ThreadGetLastStatusTEB(ULONG_PTR ThreadLocalBase)
|
||||
{
|
||||
// Get the offset for the TEB::LastStatusValue and read it
|
||||
NTSTATUS lastStatus = 0;
|
||||
duint structOffset = ThreadLocalBase + offsetof(TEB, LastStatusValue);
|
||||
|
||||
MemReadUnsafe(structOffset, &lastStatus, sizeof(NTSTATUS));
|
||||
return lastStatus;
|
||||
}
|
||||
|
||||
NTSTATUS ThreadGetLastStatus(DWORD ThreadId)
|
||||
{
|
||||
SHARED_ACQUIRE(LockThreads);
|
||||
|
||||
if(threadList.find(ThreadId) != threadList.end())
|
||||
return ThreadGetLastStatusTEB(threadList[ThreadId].ThreadLocalBase);
|
||||
|
||||
ASSERT_ALWAYS("Trying to get last status of a thread that doesn't exist!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ThreadSetName(DWORD ThreadId, const char* Name)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockThreads);
|
||||
|
|
|
@ -19,6 +19,8 @@ int ThreadGetSuspendCount(HANDLE Thread);
|
|||
THREADPRIORITY ThreadGetPriority(HANDLE Thread);
|
||||
DWORD ThreadGetLastErrorTEB(ULONG_PTR ThreadLocalBase);
|
||||
DWORD ThreadGetLastError(DWORD ThreadId);
|
||||
NTSTATUS ThreadGetLastStatusTEB(ULONG_PTR ThreadLocalBase);
|
||||
NTSTATUS ThreadGetLastStatus(DWORD ThreadId);
|
||||
bool ThreadSetName(DWORD dwThreadId, const char* name);
|
||||
bool ThreadGetName(DWORD ThreadId, char* Name);
|
||||
HANDLE ThreadGetHandle(DWORD ThreadId);
|
||||
|
|
|
@ -199,6 +199,8 @@ static bool isregister(const char* string)
|
|||
|
||||
if(scmp(string, "lasterror"))
|
||||
return true;
|
||||
if(scmp(string, "laststatus"))
|
||||
return true;
|
||||
|
||||
if(scmp(string, "gs"))
|
||||
return true;
|
||||
|
@ -711,6 +713,13 @@ duint getregister(int* size, const char* string)
|
|||
return error;
|
||||
}
|
||||
|
||||
if(scmp(string, "laststatus"))
|
||||
{
|
||||
duint status = 0;
|
||||
MemReadUnsafe((duint)GetTEBLocation(hActiveThread) + ArchValue(0xBF4, 0x1250), &status, 4);
|
||||
return status;
|
||||
}
|
||||
|
||||
if(size)
|
||||
*size = 2;
|
||||
if(scmp(string, "ax"))
|
||||
|
@ -1166,6 +1175,8 @@ bool setregister(const char* string, duint value)
|
|||
|
||||
if(scmp(string, "lasterror"))
|
||||
return MemWrite((duint)GetTEBLocation(hActiveThread) + ArchValue(0x34, 0x68), &value, 4);
|
||||
if(scmp(string, "laststatus"))
|
||||
return MemWrite((duint)GetTEBLocation(hActiveThread) + ArchValue(0xBF4, 0x1250), &value, 4);
|
||||
|
||||
if(scmp(string, "gs"))
|
||||
return SetContextDataEx(hActiveThread, UE_SEG_GS, value & 0xFFFF);
|
||||
|
|
Loading…
Reference in New Issue