Skip to content

Commit 3378918

Browse files
committed
DBG: resolved issue x64dbg#224 (print debug strings twice) + StringUtils::Escape function instead of separate code everywhere
1 parent 620fa50 commit 3378918

File tree

5 files changed

+60
-117
lines changed

5 files changed

+60
-117
lines changed

x64_dbg_dbg/addrinfo.cpp

Lines changed: 1 addition & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -168,42 +168,7 @@ bool modload(uint base, uint size, const char* fullpath)
168168
for(int k = 0; k < len; k++)
169169
if(SectionName[k] == '\\' or SectionName[k] == '\"' or !isprint(SectionName[k]))
170170
escape_count++;
171-
Memory<char*> SectionNameEscaped(len + escape_count * 3 + 1, "_dbg_memmap:SectionNameEscaped");
172-
memset(SectionNameEscaped, 0, len + escape_count * 3 + 1);
173-
for(int k = 0, l = 0; k < len; k++)
174-
{
175-
switch(SectionName[k])
176-
{
177-
case '\t':
178-
l += sprintf(SectionNameEscaped + l, "\\t");
179-
break;
180-
case '\f':
181-
l += sprintf(SectionNameEscaped + l, "\\f");
182-
break;
183-
case '\v':
184-
l += sprintf(SectionNameEscaped + l, "\\v");
185-
break;
186-
case '\n':
187-
l += sprintf(SectionNameEscaped + l, "\\n");
188-
break;
189-
case '\r':
190-
l += sprintf(SectionNameEscaped + l, "\\r");
191-
break;
192-
case '\\':
193-
l += sprintf(SectionNameEscaped + l, "\\\\");
194-
break;
195-
case '\"':
196-
l += sprintf(SectionNameEscaped + l, "\\\"");
197-
break;
198-
default:
199-
if(!isprint(SectionName[k])) //unknown unprintable character
200-
l += sprintf(SectionNameEscaped + l, "\\x%.2X", SectionName[k]);
201-
else
202-
l += sprintf(SectionNameEscaped + l, "%c", SectionName[k]);
203-
break;
204-
}
205-
}
206-
strcpy_s(curSection.name, SectionNameEscaped);
171+
strcpy_s(curSection.name, StringUtils::Escape(SectionName).c_str());
207172
info.sections.push_back(curSection);
208173
}
209174
}

x64_dbg_dbg/debugger.cpp

Lines changed: 12 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ static std::vector<ExceptionRange> ignoredExceptionRange;
2727
static std::map<unsigned int, const char*> exceptionNames;
2828
static SIZE_T cachePrivateUsage = 0;
2929
static HANDLE hEvent = 0;
30+
static String lastDebugText;
3031

3132
//Superglobal variables
3233
char szFileName[MAX_PATH] = "";
@@ -957,6 +958,7 @@ static void cbUnloadDll(UNLOAD_DLL_DEBUG_INFO* UnloadDll)
957958

958959
static void cbOutputDebugString(OUTPUT_DEBUG_STRING_INFO* DebugString)
959960
{
961+
960962
hActiveThread = threadgethandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
961963
PLUG_CB_OUTPUTDEBUGSTRING callbackInfo;
962964
callbackInfo.DebugString = DebugString;
@@ -967,46 +969,15 @@ static void cbOutputDebugString(OUTPUT_DEBUG_STRING_INFO* DebugString)
967969
Memory<char*> DebugText(DebugString->nDebugStringLength + 1, "cbOutputDebugString:DebugText");
968970
if(memread(fdProcessInfo->hProcess, DebugString->lpDebugStringData, DebugText, DebugString->nDebugStringLength, 0))
969971
{
970-
int len = (int)strlen(DebugText);
971-
int escape_count = 0;
972-
for(int i = 0; i < len; i++)
973-
if(DebugText[i] == '\\' or DebugText[i] == '\"' or !isprint(DebugText[i]))
974-
escape_count++;
975-
Memory<char*> DebugTextEscaped(len + escape_count * 3 + 1, "cbOutputDebugString:DebugTextEscaped");
976-
for(int i = 0, j = 0; i < len; i++)
972+
String str = String(DebugText);
973+
if(str != lastDebugText) //fix for every string being printed twice
977974
{
978-
switch(DebugText[i])
979-
{
980-
case '\t':
981-
j += sprintf(DebugTextEscaped + j, "\\t");
982-
break;
983-
case '\f':
984-
j += sprintf(DebugTextEscaped + j, "\\f");
985-
break;
986-
case '\v':
987-
j += sprintf(DebugTextEscaped + j, "\\v");
988-
break;
989-
case '\n':
990-
j += sprintf(DebugTextEscaped + j, "\\n");
991-
break;
992-
case '\r':
993-
j += sprintf(DebugTextEscaped + j, "\\r");
994-
break;
995-
case '\\':
996-
j += sprintf(DebugTextEscaped + j, "\\\\");
997-
break;
998-
case '\"':
999-
j += sprintf(DebugTextEscaped + j, "\\\"");
1000-
break;
1001-
default:
1002-
if(!isprint(DebugText[i])) //unknown unprintable character
1003-
j += sprintf(DebugTextEscaped + j, "\\%.2x", DebugText[i]);
1004-
else
1005-
j += sprintf(DebugTextEscaped + j, "%c", DebugText[i]);
1006-
break;
1007-
}
975+
if(str != "\n")
976+
dprintf("DebugString: \"%s\"\n", StringUtils::Escape(str).c_str());
977+
lastDebugText = str;
1008978
}
1009-
dprintf("DebugString: \"%s\"\n", DebugTextEscaped());
979+
else
980+
lastDebugText = "";
1010981
}
1011982
}
1012983

@@ -1078,47 +1049,9 @@ static void cbException(EXCEPTION_DEBUG_INFO* ExceptionData)
10781049
Memory<char*> ThreadName(MAX_THREAD_NAME_SIZE, "cbException:ThreadName");
10791050
if(memread(fdProcessInfo->hProcess, nameInfo.szName, ThreadName, MAX_THREAD_NAME_SIZE - 1, 0))
10801051
{
1081-
int len = (int)strlen(ThreadName);
1082-
int escape_count = 0;
1083-
for(int i = 0; i < len; i++)
1084-
if(ThreadName[i] == '\\' or ThreadName[i] == '\"' or !isprint(ThreadName[i]))
1085-
escape_count++;
1086-
Memory<char*> ThreadNameEscaped(len + escape_count * 3 + 1, "cbException:ThreadNameEscaped");
1087-
for(int i = 0, j = 0; i < len; i++)
1088-
{
1089-
switch(ThreadName[i])
1090-
{
1091-
case '\t':
1092-
j += sprintf(ThreadNameEscaped + j, "\\t");
1093-
break;
1094-
case '\f':
1095-
j += sprintf(ThreadNameEscaped + j, "\\f");
1096-
break;
1097-
case '\v':
1098-
j += sprintf(ThreadNameEscaped + j, "\\v");
1099-
break;
1100-
case '\n':
1101-
j += sprintf(ThreadNameEscaped + j, "\\n");
1102-
break;
1103-
case '\r':
1104-
j += sprintf(ThreadNameEscaped + j, "\\r");
1105-
break;
1106-
case '\\':
1107-
j += sprintf(ThreadNameEscaped + j, "\\\\");
1108-
break;
1109-
case '\"':
1110-
j += sprintf(ThreadNameEscaped + j, "\\\"");
1111-
break;
1112-
default:
1113-
if(!isprint(ThreadName[i])) //unknown unprintable character
1114-
j += sprintf(ThreadNameEscaped + j, "\\%.2x", ThreadName[i]);
1115-
else
1116-
j += sprintf(ThreadNameEscaped + j, "%c", ThreadName[i]);
1117-
break;
1118-
}
1119-
}
1120-
dprintf("SetThreadName(%X, \"%s\")\n", nameInfo.dwThreadID, ThreadNameEscaped());
1121-
threadsetname(nameInfo.dwThreadID, ThreadNameEscaped);
1052+
String ThreadNameEscaped = StringUtils::Escape(ThreadName);
1053+
dprintf("SetThreadName(%X, \"%s\")\n", nameInfo.dwThreadID, ThreadNameEscaped.c_str());
1054+
threadsetname(nameInfo.dwThreadID, ThreadNameEscaped.c_str());
11221055
}
11231056
}
11241057
}

x64_dbg_dbg/disasm_helper.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ static bool isunicodestring(const unsigned char* data, int maxlen)
309309
return false;
310310
for(int i = 0; i < len * 2; i += 2)
311311
{
312-
if(data[i + 1])
312+
if(data[i + 1]) //Extended ASCII only
313313
return false;
314314
if(!isprint(data[i]) and !isspace(data[i]))
315315
return false;
@@ -327,7 +327,7 @@ bool disasmispossiblestring(uint addr)
327327
memcpy(&test, data, sizeof(uint));
328328
if(memisvalidreadptr(fdProcessInfo->hProcess, test)) //imports/pointers
329329
return false;
330-
if(isasciistring(data, sizeof(data)) or isunicodestring(data, sizeof(data)))
330+
if(isasciistring(data, sizeof(data)) or isunicodestring(data, _countof(data)))
331331
return true;
332332
return false;
333333
}

x64_dbg_dbg/stringutils.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,50 @@ StringList StringUtils::Split(const String & s, char delim)
2323
return elems;
2424
}
2525

26+
String StringUtils::Escape(const String & s)
27+
{
28+
String escaped = "";
29+
for(size_t i = 0; i < s.length(); i++)
30+
{
31+
char ch = s[i];
32+
switch(ch)
33+
{
34+
case '\t':
35+
escaped += "\\t";
36+
break;
37+
case '\f':
38+
escaped += "\\f";
39+
break;
40+
case '\v':
41+
escaped += "\\v";
42+
break;
43+
case '\n':
44+
escaped += "\\n";
45+
break;
46+
case '\r':
47+
escaped += "\\r";
48+
break;
49+
case '\\':
50+
escaped += "\\\\";
51+
break;
52+
case '\"':
53+
escaped += "\\\"";
54+
break;
55+
default:
56+
if(!isprint(ch)) //unknown unprintable character
57+
{
58+
char buf[16] = "";
59+
sprintf_s(buf, "\\%.2X", ch);
60+
escaped += buf;
61+
}
62+
else
63+
escaped += ch;
64+
break;
65+
}
66+
}
67+
return escaped;
68+
}
69+
2670
//Trim functions taken from: http://stackoverflow.com/questions/216823/whats-the-best-way-to-trim-stdstring/16743707#16743707
2771
const String StringUtils::WHITESPACE = " \n\r\t";
2872

x64_dbg_dbg/stringutils.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class StringUtils
1414
public:
1515
static StringList Split(const String & s, char delim, std::vector<String> & elems);
1616
static StringList Split(const String & s, char delim);
17+
static String Escape(const String & s);
1718
static String Trim(const String & s);
1819
static String TrimLeft(const String & s);
1920
static String TrimRight(const String & s);

0 commit comments

Comments
 (0)