DBG: resolved issue #224 (print debug strings twice) + StringUtils::Escape function instead of separate code everywhere
This commit is contained in:
parent
620fa50ae9
commit
3378918d13
|
@ -168,42 +168,7 @@ bool modload(uint base, uint size, const char* fullpath)
|
||||||
for(int k = 0; k < len; k++)
|
for(int k = 0; k < len; k++)
|
||||||
if(SectionName[k] == '\\' or SectionName[k] == '\"' or !isprint(SectionName[k]))
|
if(SectionName[k] == '\\' or SectionName[k] == '\"' or !isprint(SectionName[k]))
|
||||||
escape_count++;
|
escape_count++;
|
||||||
Memory<char*> SectionNameEscaped(len + escape_count * 3 + 1, "_dbg_memmap:SectionNameEscaped");
|
strcpy_s(curSection.name, StringUtils::Escape(SectionName).c_str());
|
||||||
memset(SectionNameEscaped, 0, len + escape_count * 3 + 1);
|
|
||||||
for(int k = 0, l = 0; k < len; k++)
|
|
||||||
{
|
|
||||||
switch(SectionName[k])
|
|
||||||
{
|
|
||||||
case '\t':
|
|
||||||
l += sprintf(SectionNameEscaped + l, "\\t");
|
|
||||||
break;
|
|
||||||
case '\f':
|
|
||||||
l += sprintf(SectionNameEscaped + l, "\\f");
|
|
||||||
break;
|
|
||||||
case '\v':
|
|
||||||
l += sprintf(SectionNameEscaped + l, "\\v");
|
|
||||||
break;
|
|
||||||
case '\n':
|
|
||||||
l += sprintf(SectionNameEscaped + l, "\\n");
|
|
||||||
break;
|
|
||||||
case '\r':
|
|
||||||
l += sprintf(SectionNameEscaped + l, "\\r");
|
|
||||||
break;
|
|
||||||
case '\\':
|
|
||||||
l += sprintf(SectionNameEscaped + l, "\\\\");
|
|
||||||
break;
|
|
||||||
case '\"':
|
|
||||||
l += sprintf(SectionNameEscaped + l, "\\\"");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if(!isprint(SectionName[k])) //unknown unprintable character
|
|
||||||
l += sprintf(SectionNameEscaped + l, "\\x%.2X", SectionName[k]);
|
|
||||||
else
|
|
||||||
l += sprintf(SectionNameEscaped + l, "%c", SectionName[k]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
strcpy_s(curSection.name, SectionNameEscaped);
|
|
||||||
info.sections.push_back(curSection);
|
info.sections.push_back(curSection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ static std::vector<ExceptionRange> ignoredExceptionRange;
|
||||||
static std::map<unsigned int, const char*> exceptionNames;
|
static std::map<unsigned int, const char*> exceptionNames;
|
||||||
static SIZE_T cachePrivateUsage = 0;
|
static SIZE_T cachePrivateUsage = 0;
|
||||||
static HANDLE hEvent = 0;
|
static HANDLE hEvent = 0;
|
||||||
|
static String lastDebugText;
|
||||||
|
|
||||||
//Superglobal variables
|
//Superglobal variables
|
||||||
char szFileName[MAX_PATH] = "";
|
char szFileName[MAX_PATH] = "";
|
||||||
|
@ -957,6 +958,7 @@ static void cbUnloadDll(UNLOAD_DLL_DEBUG_INFO* UnloadDll)
|
||||||
|
|
||||||
static void cbOutputDebugString(OUTPUT_DEBUG_STRING_INFO* DebugString)
|
static void cbOutputDebugString(OUTPUT_DEBUG_STRING_INFO* DebugString)
|
||||||
{
|
{
|
||||||
|
|
||||||
hActiveThread = threadgethandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
hActiveThread = threadgethandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||||
PLUG_CB_OUTPUTDEBUGSTRING callbackInfo;
|
PLUG_CB_OUTPUTDEBUGSTRING callbackInfo;
|
||||||
callbackInfo.DebugString = DebugString;
|
callbackInfo.DebugString = DebugString;
|
||||||
|
@ -967,46 +969,15 @@ static void cbOutputDebugString(OUTPUT_DEBUG_STRING_INFO* DebugString)
|
||||||
Memory<char*> DebugText(DebugString->nDebugStringLength + 1, "cbOutputDebugString:DebugText");
|
Memory<char*> DebugText(DebugString->nDebugStringLength + 1, "cbOutputDebugString:DebugText");
|
||||||
if(memread(fdProcessInfo->hProcess, DebugString->lpDebugStringData, DebugText, DebugString->nDebugStringLength, 0))
|
if(memread(fdProcessInfo->hProcess, DebugString->lpDebugStringData, DebugText, DebugString->nDebugStringLength, 0))
|
||||||
{
|
{
|
||||||
int len = (int)strlen(DebugText);
|
String str = String(DebugText);
|
||||||
int escape_count = 0;
|
if(str != lastDebugText) //fix for every string being printed twice
|
||||||
for(int i = 0; i < len; i++)
|
|
||||||
if(DebugText[i] == '\\' or DebugText[i] == '\"' or !isprint(DebugText[i]))
|
|
||||||
escape_count++;
|
|
||||||
Memory<char*> DebugTextEscaped(len + escape_count * 3 + 1, "cbOutputDebugString:DebugTextEscaped");
|
|
||||||
for(int i = 0, j = 0; i < len; i++)
|
|
||||||
{
|
{
|
||||||
switch(DebugText[i])
|
if(str != "\n")
|
||||||
{
|
dprintf("DebugString: \"%s\"\n", StringUtils::Escape(str).c_str());
|
||||||
case '\t':
|
lastDebugText = str;
|
||||||
j += sprintf(DebugTextEscaped + j, "\\t");
|
|
||||||
break;
|
|
||||||
case '\f':
|
|
||||||
j += sprintf(DebugTextEscaped + j, "\\f");
|
|
||||||
break;
|
|
||||||
case '\v':
|
|
||||||
j += sprintf(DebugTextEscaped + j, "\\v");
|
|
||||||
break;
|
|
||||||
case '\n':
|
|
||||||
j += sprintf(DebugTextEscaped + j, "\\n");
|
|
||||||
break;
|
|
||||||
case '\r':
|
|
||||||
j += sprintf(DebugTextEscaped + j, "\\r");
|
|
||||||
break;
|
|
||||||
case '\\':
|
|
||||||
j += sprintf(DebugTextEscaped + j, "\\\\");
|
|
||||||
break;
|
|
||||||
case '\"':
|
|
||||||
j += sprintf(DebugTextEscaped + j, "\\\"");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if(!isprint(DebugText[i])) //unknown unprintable character
|
|
||||||
j += sprintf(DebugTextEscaped + j, "\\%.2x", DebugText[i]);
|
|
||||||
else
|
|
||||||
j += sprintf(DebugTextEscaped + j, "%c", DebugText[i]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
dprintf("DebugString: \"%s\"\n", DebugTextEscaped());
|
else
|
||||||
|
lastDebugText = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1078,47 +1049,9 @@ static void cbException(EXCEPTION_DEBUG_INFO* ExceptionData)
|
||||||
Memory<char*> ThreadName(MAX_THREAD_NAME_SIZE, "cbException:ThreadName");
|
Memory<char*> ThreadName(MAX_THREAD_NAME_SIZE, "cbException:ThreadName");
|
||||||
if(memread(fdProcessInfo->hProcess, nameInfo.szName, ThreadName, MAX_THREAD_NAME_SIZE - 1, 0))
|
if(memread(fdProcessInfo->hProcess, nameInfo.szName, ThreadName, MAX_THREAD_NAME_SIZE - 1, 0))
|
||||||
{
|
{
|
||||||
int len = (int)strlen(ThreadName);
|
String ThreadNameEscaped = StringUtils::Escape(ThreadName);
|
||||||
int escape_count = 0;
|
dprintf("SetThreadName(%X, \"%s\")\n", nameInfo.dwThreadID, ThreadNameEscaped.c_str());
|
||||||
for(int i = 0; i < len; i++)
|
threadsetname(nameInfo.dwThreadID, ThreadNameEscaped.c_str());
|
||||||
if(ThreadName[i] == '\\' or ThreadName[i] == '\"' or !isprint(ThreadName[i]))
|
|
||||||
escape_count++;
|
|
||||||
Memory<char*> ThreadNameEscaped(len + escape_count * 3 + 1, "cbException:ThreadNameEscaped");
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -309,7 +309,7 @@ static bool isunicodestring(const unsigned char* data, int maxlen)
|
||||||
return false;
|
return false;
|
||||||
for(int i = 0; i < len * 2; i += 2)
|
for(int i = 0; i < len * 2; i += 2)
|
||||||
{
|
{
|
||||||
if(data[i + 1])
|
if(data[i + 1]) //Extended ASCII only
|
||||||
return false;
|
return false;
|
||||||
if(!isprint(data[i]) and !isspace(data[i]))
|
if(!isprint(data[i]) and !isspace(data[i]))
|
||||||
return false;
|
return false;
|
||||||
|
@ -327,7 +327,7 @@ bool disasmispossiblestring(uint addr)
|
||||||
memcpy(&test, data, sizeof(uint));
|
memcpy(&test, data, sizeof(uint));
|
||||||
if(memisvalidreadptr(fdProcessInfo->hProcess, test)) //imports/pointers
|
if(memisvalidreadptr(fdProcessInfo->hProcess, test)) //imports/pointers
|
||||||
return false;
|
return false;
|
||||||
if(isasciistring(data, sizeof(data)) or isunicodestring(data, sizeof(data)))
|
if(isasciistring(data, sizeof(data)) or isunicodestring(data, _countof(data)))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,50 @@ StringList StringUtils::Split(const String & s, char delim)
|
||||||
return elems;
|
return elems;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String StringUtils::Escape(const String & s)
|
||||||
|
{
|
||||||
|
String escaped = "";
|
||||||
|
for(size_t i = 0; i < s.length(); i++)
|
||||||
|
{
|
||||||
|
char ch = s[i];
|
||||||
|
switch(ch)
|
||||||
|
{
|
||||||
|
case '\t':
|
||||||
|
escaped += "\\t";
|
||||||
|
break;
|
||||||
|
case '\f':
|
||||||
|
escaped += "\\f";
|
||||||
|
break;
|
||||||
|
case '\v':
|
||||||
|
escaped += "\\v";
|
||||||
|
break;
|
||||||
|
case '\n':
|
||||||
|
escaped += "\\n";
|
||||||
|
break;
|
||||||
|
case '\r':
|
||||||
|
escaped += "\\r";
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
escaped += "\\\\";
|
||||||
|
break;
|
||||||
|
case '\"':
|
||||||
|
escaped += "\\\"";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if(!isprint(ch)) //unknown unprintable character
|
||||||
|
{
|
||||||
|
char buf[16] = "";
|
||||||
|
sprintf_s(buf, "\\%.2X", ch);
|
||||||
|
escaped += buf;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
escaped += ch;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return escaped;
|
||||||
|
}
|
||||||
|
|
||||||
//Trim functions taken from: http://stackoverflow.com/questions/216823/whats-the-best-way-to-trim-stdstring/16743707#16743707
|
//Trim functions taken from: http://stackoverflow.com/questions/216823/whats-the-best-way-to-trim-stdstring/16743707#16743707
|
||||||
const String StringUtils::WHITESPACE = " \n\r\t";
|
const String StringUtils::WHITESPACE = " \n\r\t";
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ class StringUtils
|
||||||
public:
|
public:
|
||||||
static StringList Split(const String & s, char delim, std::vector<String> & elems);
|
static StringList Split(const String & s, char delim, std::vector<String> & elems);
|
||||||
static StringList Split(const String & s, char delim);
|
static StringList Split(const String & s, char delim);
|
||||||
|
static String Escape(const String & s);
|
||||||
static String Trim(const String & s);
|
static String Trim(const String & s);
|
||||||
static String TrimLeft(const String & s);
|
static String TrimLeft(const String & s);
|
||||||
static String TrimRight(const String & s);
|
static String TrimRight(const String & s);
|
||||||
|
|
Loading…
Reference in New Issue