From 23630563656e954205db70b7ffbfa6304210ba54 Mon Sep 17 00:00:00 2001 From: PatrickvL Date: Fri, 3 Mar 2017 18:38:14 +0100 Subject: [PATCH] Log sanitization for issue #14 --- src/Common/Logging.h | 143 ++++++++++++++++++++++++++++++-- src/CxbxKrnl/EmuKrnlLogging.cpp | 77 ++++++++++------- src/CxbxKrnl/EmuKrnlLogging.h | 1 + 3 files changed, 182 insertions(+), 39 deletions(-) diff --git a/src/Common/Logging.h b/src/Common/Logging.h index 07aa86253..4aafe3e91 100644 --- a/src/Common/Logging.h +++ b/src/Common/Logging.h @@ -81,9 +81,9 @@ inline Hex1Struct hex1(uint8_t _v) return Hex1Struct(_v); } -inline std::ostream& operator<<(std::ostream& os, const Hex1Struct& hs) +inline std::ostream& operator<<(std::ostream& os, const Hex1Struct& container) { - return os << "0x" << std::hex << std::uppercase << (int)hs.v; + return os << "0x" << std::hex << std::uppercase << (int)container.v; } struct Hex2Struct @@ -97,9 +97,9 @@ inline Hex2Struct hex2(uint16_t _v) return Hex2Struct(_v); } -inline std::ostream& operator<<(std::ostream& os, const Hex2Struct& hs) +inline std::ostream& operator<<(std::ostream& os, const Hex2Struct& container) { - return os << "0x" << std::hex << std::uppercase << (int)hs.v; + return os << "0x" << std::hex << std::uppercase << (int)container.v; } struct Hex4Struct @@ -113,9 +113,134 @@ inline Hex4Struct hex4(uint32_t _v) return Hex4Struct(_v); } -inline std::ostream& operator<<(std::ostream& os, const Hex4Struct& hs) +inline std::ostream& operator<<(std::ostream& os, const Hex4Struct& container) { - return os << "0x" << std::hex << std::uppercase << (int)hs.v; + return os << "0x" << std::hex << std::uppercase << (int)container.v; +} + +struct SanitizedCharStruct +{ + char v; + SanitizedCharStruct(char _v) : v(_v) { } +}; + +inline SanitizedCharStruct sanitized_char(char _v) +{ + return SanitizedCharStruct(_v); +} + +inline std::ostream& operator<<(std::ostream& os, const SanitizedCharStruct& container) +{ + char v = container.v; + + if (isprint(v)) + os << "'" << v << "'"; + else + os << "\\x" << std::hex << std::uppercase << (int)v; + + return os; +} + +struct SanitizedCharPointerStruct +{ + char *v; + SanitizedCharPointerStruct(char *_v) : v(_v) { } +}; + +inline SanitizedCharPointerStruct sanitized_char_pointer(char *_v) +{ + return SanitizedCharPointerStruct(_v); +} + +inline std::ostream& operator<<(std::ostream& os, const SanitizedCharPointerStruct& container) +{ + char *v = container.v; + + os << "(char *)"; + if (v == nullptr) + return os << "nullptr"; + + bool needsConversion = false; + + while (*v) + if (!isprint(*v++)) + { + needsConversion = true; + break; + } + + v = container.v; + os << "0x" << (void *)v << " = \""; + if (needsConversion) + { + while (*v) + { + if (*v == '"') + os << "\\"; + + if (isprint(*v)) + os << *v; + else + os << "\\x" << std::hex << std::uppercase << (int)(*v); + + v++; + } + } + else + os << v; + + return os << "\""; +} + +struct SanitizedWideCharPointerStruct +{ + wchar_t *v; + SanitizedWideCharPointerStruct(wchar_t *_v) : v(_v) { } +}; + +inline SanitizedWideCharPointerStruct sanitized_wchar_pointer(wchar_t *_v) +{ + return SanitizedWideCharPointerStruct(_v); +} + +inline std::ostream& operator<<(std::ostream& os, const SanitizedWideCharPointerStruct& container) +{ + wchar_t *v = container.v; + + os << "(wchar *)"; + if (v == nullptr) + return os << "nullptr"; + + bool needsConversion = false; + + while (*v) + if (!isprint(*v++)) + { + needsConversion = true; + break; + } + + v = container.v; + os << "0x" << (void *)v << " = \""; + if (needsConversion) + { + while (*v) + { + if (*v == '"') + os << "\\"; + + if (isprint(*v)) + os << *v; + else + os << "\\x" << std::hex << std::uppercase << (int)(*v); + + v++; + } + } + else + os << v; + + return os << "\""; } // @@ -127,8 +252,10 @@ template inline T _log_sanitize(T arg) { return arg; } // Sanitize C-style strings by converting NULL to "" to prevent null dereference -inline const char * _log_sanitize(char *arg) { return (NULL == arg) ? "" : arg; } -inline const wchar_t * _log_sanitize(wchar_t *arg) { return (NULL == arg) ? L"" : arg; } +inline SanitizedCharStruct _log_sanitize(char arg) { return sanitized_char(arg); } + +inline SanitizedCharPointerStruct _log_sanitize(char *arg) { return sanitized_char_pointer(arg); } +inline SanitizedWideCharPointerStruct _log_sanitize(wchar_t *arg) { return sanitized_wchar_pointer(arg); } // Convert booleans to strings properly inline const char * _log_sanitize(BOOL value) { return value ? "TRUE" : "FALSE"; } diff --git a/src/CxbxKrnl/EmuKrnlLogging.cpp b/src/CxbxKrnl/EmuKrnlLogging.cpp index fca4ad830..f78fa8fd2 100644 --- a/src/CxbxKrnl/EmuKrnlLogging.cpp +++ b/src/CxbxKrnl/EmuKrnlLogging.cpp @@ -58,7 +58,7 @@ namespace xboxkrnl std::ostream& operator<<(std::ostream& os, const PULONG& value) { os << hex4((uint32_t)value); - if (value) + if (value != nullptr) os << " (*value: " << hex4(*value) << ")"; return os; @@ -86,33 +86,6 @@ std::ostream& operator<<(std::ostream& os, const PULONG& value) // Xbox (Enum)Type-ToString conversions : // -ENUM2STR_START(BUS_DATA_TYPE) - ENUM2STR_CASE(ConfigurationSpaceUndefined) - ENUM2STR_CASE(Cmos) - ENUM2STR_CASE(EisaConfiguration) - ENUM2STR_CASE(Pos) - ENUM2STR_CASE(CbusConfiguration) - ENUM2STR_CASE(PCIConfiguration) - ENUM2STR_CASE(VMEConfiguration) - ENUM2STR_CASE(NuBusConfiguration) - ENUM2STR_CASE(PCMCIAConfiguration) - ENUM2STR_CASE(MPIConfiguration) - ENUM2STR_CASE(MPSAConfiguration) - ENUM2STR_CASE(PNPISAConfiguration) - ENUM2STR_CASE(SgiInternalConfiguration) - ENUM2STR_CASE(MaximumBusDataType) -ENUM2STR_END_and_LOGRENDER(BUS_DATA_TYPE) - -ENUM2STR_START(CREATE_DISPOSITION) - ENUM2STR_CASE_DEF(FILE_SUPERSEDE) - ENUM2STR_CASE_DEF(FILE_OPEN) - ENUM2STR_CASE_DEF(FILE_CREATE) - ENUM2STR_CASE_DEF(FILE_OPEN_IF) - ENUM2STR_CASE_DEF(FILE_OVERWRITE) - ENUM2STR_CASE_DEF(FILE_OVERWRITE_IF) - // ENUM2STR_CASE_DEF(FILE_MAXIMUM_DISPOSITION) Skip, identical to FILE_OVERWRITE_IF -ENUM2STR_END_and_LOGRENDER(CREATE_DISPOSITION) - FLAGS2STR_START(ALLOCATION_TYPE) FLAG2STR(PAGE_NOACCESS) FLAG2STR(PAGE_READONLY) @@ -147,6 +120,33 @@ FLAGS2STR_START(ALLOCATION_TYPE) // WRITE_WATCH_FLAG_RESET = $01; FLAGS2STR_END_and_LOGRENDER(ALLOCATION_TYPE) +ENUM2STR_START(BUS_DATA_TYPE) + ENUM2STR_CASE(ConfigurationSpaceUndefined) + ENUM2STR_CASE(Cmos) + ENUM2STR_CASE(EisaConfiguration) + ENUM2STR_CASE(Pos) + ENUM2STR_CASE(CbusConfiguration) + ENUM2STR_CASE(PCIConfiguration) + ENUM2STR_CASE(VMEConfiguration) + ENUM2STR_CASE(NuBusConfiguration) + ENUM2STR_CASE(PCMCIAConfiguration) + ENUM2STR_CASE(MPIConfiguration) + ENUM2STR_CASE(MPSAConfiguration) + ENUM2STR_CASE(PNPISAConfiguration) + ENUM2STR_CASE(SgiInternalConfiguration) + ENUM2STR_CASE(MaximumBusDataType) +ENUM2STR_END_and_LOGRENDER(BUS_DATA_TYPE) + +ENUM2STR_START(CREATE_DISPOSITION) + ENUM2STR_CASE_DEF(FILE_SUPERSEDE) + ENUM2STR_CASE_DEF(FILE_OPEN) + ENUM2STR_CASE_DEF(FILE_CREATE) + ENUM2STR_CASE_DEF(FILE_OPEN_IF) + ENUM2STR_CASE_DEF(FILE_OVERWRITE) + ENUM2STR_CASE_DEF(FILE_OVERWRITE_IF) + // ENUM2STR_CASE_DEF(FILE_MAXIMUM_DISPOSITION) Skip, identical to FILE_OVERWRITE_IF +ENUM2STR_END_and_LOGRENDER(CREATE_DISPOSITION) + FLAGS2STR_START(CREATE_OPTION) /* #define FILE_VALID_OPTION_FLAGS 0x00ffffff @@ -186,6 +186,13 @@ ENUM2STR_START(EVENT_TYPE) ENUM2STR_CASE(SynchronizationEvent) ENUM2STR_END_and_LOGRENDER(EVENT_TYPE) +ENUM2STR_START(EXCEPTION_DISPOSITION) + ENUM2STR_CASE(ExceptionContinueExecution) + ENUM2STR_CASE(ExceptionContinueSearch) + ENUM2STR_CASE(ExceptionNestedException) + ENUM2STR_CASE(ExceptionCollidedUnwind) +ENUM2STR_END_and_LOGRENDER(EXCEPTION_DISPOSITION) + ENUM2STR_START(FILE_INFORMATION_CLASS) ENUM2STR_CASE(FileDirectoryInformation) ENUM2STR_CASE(FileFullDirectoryInformation) @@ -279,6 +286,12 @@ ENUM2STR_START(KWAIT_REASON) ENUM2STR_END_and_LOGRENDER(KWAIT_REASON) ENUM2STR_START(KOBJECTS) + ENUM2STR_CASE(MutantObject) + ENUM2STR_CASE(QueueObject) + ENUM2STR_CASE(SemaphoreObject) + ENUM2STR_CASE(TimerNotificationObject) + ENUM2STR_CASE(TimerSynchronizationObject) + ENUM2STR_CASE(ApcObject) ENUM2STR_CASE(DpcObject) ENUM2STR_END_and_LOGRENDER(KOBJECTS) @@ -374,6 +387,8 @@ ENUM2STR_END_and_LOGRENDER(XC_VALUE_INDEX) #define LOGRENDER_MEMBER_NAME(Member) << "\n ."#Member": " #define LOGRENDER_MEMBER_VALUE(Member) << value.Member #define LOGRENDER_MEMBER(Member) LOGRENDER_MEMBER_NAME(Member) LOGRENDER_MEMBER_VALUE(Member) +#define LOGRENDER_MEMBER_SANITIZED(Member, Type) LOGRENDER_MEMBER_NAME(Member) << _log_sanitize((Type)value.Member) + LOGRENDER_HEADER(BOOLEAN) { @@ -415,7 +430,7 @@ LOGRENDER_TYPE(LAUNCH_DATA_HEADER) return os LOGRENDER_MEMBER(dwLaunchDataType) LOGRENDER_MEMBER(dwTitleId) - LOGRENDER_MEMBER(szLaunchPath) + LOGRENDER_MEMBER_SANITIZED(szLaunchPath, char *) LOGRENDER_MEMBER(dwFlags); } @@ -455,7 +470,7 @@ LOGRENDER_TYPE(STRING) return os LOGRENDER_MEMBER(Length) LOGRENDER_MEMBER(MaximumLength) - LOGRENDER_MEMBER(Buffer); + LOGRENDER_MEMBER_SANITIZED(Buffer, char *); } LOGRENDER_TYPE(UNICODE_STRING) @@ -463,7 +478,7 @@ LOGRENDER_TYPE(UNICODE_STRING) return os LOGRENDER_MEMBER(Length) LOGRENDER_MEMBER(MaximumLength) - LOGRENDER_MEMBER(Buffer); + LOGRENDER_MEMBER_SANITIZED(Buffer, wchar_t *); } #undef LOGRENDER_MEMBER diff --git a/src/CxbxKrnl/EmuKrnlLogging.h b/src/CxbxKrnl/EmuKrnlLogging.h index 6df4d4db3..cd631fc1c 100644 --- a/src/CxbxKrnl/EmuKrnlLogging.h +++ b/src/CxbxKrnl/EmuKrnlLogging.h @@ -66,6 +66,7 @@ LOGRENDER_HEADER(BUS_DATA_TYPE); LOGRENDER_HEADER(CREATE_DISPOSITION); // Not really an enum LOGRENDER_HEADER(CREATE_OPTION); // Not really an enum LOGRENDER_HEADER(EVENT_TYPE); +LOGRENDER_HEADER(EXCEPTION_DISPOSITION); LOGRENDER_HEADER(FILE_INFORMATION_CLASS); LOGRENDER_HEADER(FS_INFORMATION_CLASS); LOGRENDER_HEADER(KINTERRUPT_MODE);