1
0
Fork 0

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:
Mattiwatti 2017-10-21 22:59:38 +02:00 committed by Duncan Ogilvie
parent 8f0f83bdf3
commit 6f1b6b77bb
5 changed files with 43 additions and 3 deletions

View File

@ -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];

View File

@ -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))
{

View File

@ -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);

View File

@ -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);

View File

@ -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);