DBG: resolved issue #112 (SetThreadName) + fixed possible buffer overflows + fixed 'invalid database' when no db present + fixed file version
This commit is contained in:
parent
31d0bd7d6e
commit
4a8a44764e
|
@ -52,6 +52,7 @@ BRIDGE_IMPEXP int BridgeGetDbgVersion();
|
|||
#define MAX_MODULE_SIZE 256
|
||||
#define MAX_BREAKPOINT_SIZE 256
|
||||
#define MAX_SCRIPT_LINE_SIZE 2048
|
||||
#define MAX_THREAD_NAME_SIZE 256
|
||||
|
||||
#define TYPE_VALUE 1
|
||||
#define TYPE_MEMORY 2
|
||||
|
@ -422,6 +423,7 @@ struct THREADINFO
|
|||
DWORD dwThreadId;
|
||||
duint ThreadStartAddress;
|
||||
duint ThreadLocalBase;
|
||||
char threadName[MAX_THREAD_NAME_SIZE];
|
||||
};
|
||||
|
||||
struct THREADALLINFO
|
||||
|
|
|
@ -129,8 +129,8 @@ extern "C" DLL_EXPORT bool _dbg_memmap(MEMMAP* memmap)
|
|||
for(int k=0; k<len; k++)
|
||||
if(SectionName[k]=='\\' or SectionName[k]=='\"' or !isprint(SectionName[k]))
|
||||
escape_count++;
|
||||
char* SectionNameEscaped=(char*)emalloc(len+escape_count+1, "_dbg_memmap:SectionNameEscaped");
|
||||
memset(SectionNameEscaped, 0, len+escape_count+1);
|
||||
char* SectionNameEscaped=(char*)emalloc(len+escape_count*3+1, "_dbg_memmap:SectionNameEscaped");
|
||||
memset(SectionNameEscaped, 0, len+escape_count*3+1);
|
||||
for(int k=0,l=0; k<len; k++)
|
||||
{
|
||||
switch(SectionName[k])
|
||||
|
|
|
@ -38,6 +38,8 @@ void dbsave()
|
|||
|
||||
void dbload()
|
||||
{
|
||||
if(!FileExists(dbpath)) //no database to load
|
||||
return;
|
||||
dprintf("loading database...");
|
||||
DWORD ticks=GetTickCount();
|
||||
LZ4_STATUS status=LZ4_decompress_file(dbpath, dbpath);
|
||||
|
|
|
@ -798,8 +798,8 @@ static void cbOutputDebugString(OUTPUT_DEBUG_STRING_INFO* DebugString)
|
|||
for(int i=0; i<len; i++)
|
||||
if(DebugText[i]=='\\' or DebugText[i]=='\"' or !isprint(DebugText[i]))
|
||||
escape_count++;
|
||||
char* DebugTextEscaped=(char*)emalloc(len+escape_count+1, "cbOutputDebugString:DebugTextEscaped");
|
||||
memset(DebugTextEscaped, 0, len+escape_count+1);
|
||||
char* DebugTextEscaped=(char*)emalloc(len+escape_count*3+1, "cbOutputDebugString:DebugTextEscaped");
|
||||
memset(DebugTextEscaped, 0, len+escape_count*3+1);
|
||||
for(int i=0,j=0; i<len; i++)
|
||||
{
|
||||
switch(DebugText[i])
|
||||
|
@ -895,6 +895,68 @@ static void cbException(EXCEPTION_DEBUG_INFO* ExceptionData)
|
|||
}
|
||||
SetContextData(UE_CIP, (uint)ExceptionData->ExceptionRecord.ExceptionAddress);
|
||||
}
|
||||
else if(ExceptionData->ExceptionRecord.ExceptionCode==0x406D1388) //SetThreadName exception
|
||||
{
|
||||
if(ExceptionData->ExceptionRecord.NumberParameters==sizeof(THREADNAME_INFO)/sizeof(uint))
|
||||
{
|
||||
THREADNAME_INFO nameInfo;
|
||||
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
|
||||
{
|
||||
char* ThreadName=(char*)emalloc(MAX_THREAD_NAME_SIZE, "cbException:ThreadName");
|
||||
memset(ThreadName, 0, MAX_THREAD_NAME_SIZE);
|
||||
if(memread(fdProcessInfo->hProcess, nameInfo.szName, ThreadName, MAX_THREAD_NAME_SIZE-1, 0))
|
||||
{
|
||||
int len=strlen(ThreadName);
|
||||
int escape_count=0;
|
||||
for(int i=0; i<len; i++)
|
||||
if(ThreadName[i]=='\\' or ThreadName[i]=='\"' or !isprint(ThreadName[i]))
|
||||
escape_count++;
|
||||
char* ThreadNameEscaped=(char*)emalloc(len+escape_count*3+1, "cbException:ThreadNameEscaped");
|
||||
memset(ThreadNameEscaped, 0, len+escape_count*3+1);
|
||||
for(int i=0,j=0; i<len; i++)
|
||||
{
|
||||
switch(ThreadName[i])
|
||||
{
|
||||
case '\t':
|
||||
j+=sprintf(ThreadNameEscaped+j, "\\t");
|
||||
break;
|
||||
case '\f':
|
||||
j+=sprintf(ThreadNameEscaped+j, "\\f");
|
||||
break;
|
||||
case '\v':
|
||||
j+=sprintf(ThreadNameEscaped+j, "\\v");
|
||||
break;
|
||||
case '\n':
|
||||
j+=sprintf(ThreadNameEscaped+j, "\\n");
|
||||
break;
|
||||
case '\r':
|
||||
j+=sprintf(ThreadNameEscaped+j, "\\r");
|
||||
break;
|
||||
case '\\':
|
||||
j+=sprintf(ThreadNameEscaped+j, "\\\\");
|
||||
break;
|
||||
case '\"':
|
||||
j+=sprintf(ThreadNameEscaped+j, "\\\"");
|
||||
break;
|
||||
default:
|
||||
if(!isprint(ThreadName[i])) //unknown unprintable character
|
||||
j+=sprintf(ThreadNameEscaped+j, "\\%.2x", ThreadName[i]);
|
||||
else
|
||||
j+=sprintf(ThreadNameEscaped+j, "%c", ThreadName[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
dprintf("SetThreadName(%X, \"%s\")\n", nameInfo.dwThreadID, ThreadNameEscaped);
|
||||
threadsetname(nameInfo.dwThreadID, ThreadNameEscaped);
|
||||
efree(ThreadNameEscaped, "cbException:ThreadNameEscaped");
|
||||
}
|
||||
efree(ThreadName, "cbException:ThreadName");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(ExceptionData->dwFirstChance) //first chance exception
|
||||
{
|
||||
|
|
|
@ -20,6 +20,16 @@ struct ExceptionRange
|
|||
unsigned int end;
|
||||
};
|
||||
|
||||
#pragma pack(push,8)
|
||||
typedef struct _THREADNAME_INFO
|
||||
{
|
||||
DWORD dwType; // Must be 0x1000.
|
||||
LPCSTR szName; // Pointer to name (in user addr space).
|
||||
DWORD dwThreadID; // Thread ID (-1=caller thread).
|
||||
DWORD dwFlags; // Reserved for future use, must be zero.
|
||||
} THREADNAME_INFO;
|
||||
#pragma pack(pop)
|
||||
|
||||
//functions
|
||||
void dbgdisablebpx();
|
||||
void dbgenablebpx();
|
||||
|
|
|
@ -15,6 +15,9 @@ void threadcreate(CREATE_THREAD_DEBUG_INFO* CreateThread)
|
|||
curInfo.dwThreadId=((DEBUG_EVENT*)GetDebugData())->dwThreadId;
|
||||
curInfo.ThreadStartAddress=(uint)CreateThread->lpStartAddress;
|
||||
curInfo.ThreadLocalBase=(uint)CreateThread->lpThreadLocalBase;
|
||||
*curInfo.threadName='\0';
|
||||
if(!threadNum)
|
||||
strcpy(curInfo.threadName, "Main Thread");
|
||||
threadList.push_back(curInfo);
|
||||
threadNum++;
|
||||
GuiUpdateThreadView();
|
||||
|
@ -75,3 +78,24 @@ void threadgetlist(THREADLIST* list)
|
|||
}
|
||||
list->CurrentThread=currentThread;
|
||||
}
|
||||
|
||||
bool threadisvalid(DWORD dwThreadId)
|
||||
{
|
||||
for(unsigned int i=0; i<threadList.size(); i++)
|
||||
if(threadList.at(i).dwThreadId==dwThreadId)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool threadsetname(DWORD dwThreadId, const char* name)
|
||||
{
|
||||
for(unsigned int i=0; i<threadList.size(); i++)
|
||||
if(threadList.at(i).dwThreadId==dwThreadId)
|
||||
{
|
||||
if(name)
|
||||
strcpy(threadList.at(i).threadName, name);
|
||||
else
|
||||
*threadList.at(i).threadName='\0';
|
||||
}
|
||||
return false;
|
||||
}
|
|
@ -9,5 +9,7 @@ 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);
|
||||
|
||||
#endif //_THREAD_H
|
||||
|
|
|
@ -23,8 +23,8 @@ IDI_ICON1 ICON "..\\bug.ico"
|
|||
//
|
||||
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
||||
1 VERSIONINFO
|
||||
FILEVERSION 0,0,1,7
|
||||
PRODUCTVERSION 0,0,1,7
|
||||
FILEVERSION 0,0,1,9
|
||||
PRODUCTVERSION 0,0,1,9
|
||||
FILEOS VOS_UNKNOWN
|
||||
FILETYPE VFT_UNKNOWN
|
||||
FILESUBTYPE VFT2_UNKNOWN
|
||||
|
|
|
@ -16,7 +16,7 @@ ThreadView::ThreadView(StdTable *parent) : StdTable(parent)
|
|||
addColumnAt(8+charwidth*12, "Priority", false);
|
||||
addColumnAt(8+charwidth*16, "WaitReason", false);
|
||||
addColumnAt(8+charwidth*10, "LastError", false);
|
||||
addColumnAt(0, "", false);
|
||||
addColumnAt(0, "Name", false);
|
||||
|
||||
connect(Bridge::getBridge(), SIGNAL(updateThreads()), this, SLOT(updateThreadList()));
|
||||
}
|
||||
|
@ -187,6 +187,7 @@ void ThreadView::updateThreadList()
|
|||
}
|
||||
setCellContent(i, 7, waitReasonString);
|
||||
setCellContent(i, 8, QString("%1").arg(threadList.list[i].LastError, sizeof(unsigned int) * 2, 16, QChar('0')).toUpper());
|
||||
setCellContent(i, 9, threadList.list[i].BasicInfo.threadName);
|
||||
}
|
||||
if(threadList.count)
|
||||
BridgeFree(threadList.list);
|
||||
|
|
Loading…
Reference in New Issue