def fOutputLogo(): # We will use the above ASCII and color data to create a list of arguments # that can be passed to oConsole.fOutput in order to output the logo in color: oConsole.fLock() try: for uLineIndex in range(len(asBugIdLogo)): uCurrentColor = COLOR_NORMAL bUnderlined = False asBugIdLogoPrintArguments = [""] sCharsLine = asBugIdLogo[uLineIndex] sColorsLine = asBugIdLogoColors[uLineIndex] uColorIndex = 0 for uColumnIndex in range(len(sCharsLine)): sColor = sColorsLine[uColorIndex] uColorIndex += 1 if sColor == "_": bUnderlined = not bUnderlined sColor = sColorsLine[uColorIndex] uColorIndex += 1 uColor = (sColor != " " and (0x0F00 + int(sColor, 16)) or COLOR_NORMAL) + ( bUnderlined and CONSOLE_UNDERLINE or 0) if uColor != uCurrentColor: asBugIdLogoPrintArguments.extend([uColor, ""]) uCurrentColor = uColor sChar = sCharsLine[uColumnIndex] asBugIdLogoPrintArguments[-1] += sChar oConsole.fOutput(*asBugIdLogoPrintArguments) finally: oConsole.fUnlock()
def fVerboseOutputHelper(b0Selected, sItemPath, sRegExpType, rRegExp, o0Match): oConsole.fLock() try: oConsole.fOutput( " ", [COLOR_SELECT_MAYBE, CHAR_SELECT_MAYBE] if b0Selected is None else [COLOR_SELECT_YES, CHAR_SELECT_YES] if b0Selected else [COLOR_SELECT_NO, CHAR_SELECT_NO], COLOR_NORMAL, " ", sItemPath, COLOR_DIM, " (", "matches" if o0Match else "does not match", " ", sRegExpType, " reg.exp. ", str(rRegExp.pattern), ")", ) if o0Match and len(o0Match.groups()): asSubMatchesOutput = [] for sSubMatch in oMatch.groups(): asSubMatchesOutput += [ ", " if len(asSubMatchesOutput) else "", COLOR_NORMAL, sSubMatch, COLOR_DIM ] oConsole.fOutput(COLOR_DIM, " Sub-matches: ", asSubMatchesOutput, ".") finally: oConsole.fUnlock()
def fHandleFolder(oSelf, sFolderPath, asSubItemNames): # Having no reg.exps. means always add: if (oSelf.arPathRegExps or oSelf.arNegativePathRegExps or oSelf.arNameRegExps or oSelf.arNegativeNameRegExps): # Having negative path reg.exps. means not add if matched: for rNegativePathRegExp in oSelf.arNegativePathRegExps: oMatch = rNegativePathRegExp.search(sFolderPath) if oMatch: # Matching negative path reg.exp. means don't add and files in this folder (and stop matching). if oSelf.bVerbose: fVerboseOutputHelper(False, sFolderPath + "\\*", "negative path", rNegativePathRegExp, oMatch) return # Not matching negative path reg.exp. means maybe add: # Having positive reg.exps. means add if matches all: if oSelf.arPathRegExps: for rPathRegExp in oSelf.arPathRegExps: oMatch = rPathRegExp.search(sFolderPath) if not oMatch: if oSelf.bVerbose: fVerboseOutputHelper(False, sFolderPath + "\\*", "path", rPathRegExp, None) return if oSelf.bVerbose: oConsole.fOutput( " ", COLOR_BUSY, CHAR_BUSY, COLOR_NORMAL, " Scanning ", COLOR_INFO, str(len(asSubItemNames)), COLOR_NORMAL, " descendants of folder ", COLOR_INFO, sFolderPath, COLOR_DIM, " (matches all path reg.exp.)", ) oSelf.oNumberOfItemsFound.fuAdd(len(asSubItemNames)) for sSubItemName in asSubItemNames: sSubItemPath = os.path.join(sFolderPath, sSubItemName) # Doing a recursive find means getting sub-items of sub-folders as well, so queue it: if oSelf.bRecursive: oSelf.oUnhandledItemPathsQueue.put(sSubItemPath) else: # Not doing a recursive find means only handle sub-items that are files: if os.path.isfile("\\\\?\\" + sSubItemPath): oSelf.oNumberOfFilesFound.fuIncrease() oSelf.fDebug() oSelf.fHandleFile(sSubItemPath) oSelf.oNumberOfItemsCompleted.fuIncrease() oSelf.fDebug() else: oSelf.oNumberOfFoldersFound.fuIncrease() oSelf.fDebug() oSelf.oNumberOfItemsCompleted.fuIncrease() oSelf.fDebug()
def fCdbStdInInputCallbackHandler(oBugId, sbInput): if dxConfig["bQuiet"]: return; oConsole.fOutput( COLOR_INPUT, "<stdin<", COLOR_NORMAL, str(sbInput, 'latin1'), uConvertTabsToSpaces = 8, );
def __init__( oSelf, uMaxThreads, asFolderPaths, bRecursive, arPathRegExps, arNegativePathRegExps, arNameRegExps, arNegativeNameRegExps, bVerbose, ): oSelf.oUnhandledItemPathsQueue = queue.Queue() oSelf.bRecursive = bRecursive oSelf.arPathRegExps = arPathRegExps oSelf.arNegativePathRegExps = arNegativePathRegExps oSelf.arNameRegExps = arNameRegExps oSelf.arNegativeNameRegExps = arNegativeNameRegExps oSelf.bVerbose = bVerbose oSelf.oMatchesByFilePath = cDict() oSelf.oException = None oSelf.oNumberOfFilesFound = cCounter() oSelf.oNumberOfFoldersFound = cCounter() oSelf.oNumberOfItemsFound = cCounter(0) oSelf.oNumberOfItemsCompleted = cCounter() oSelf.oScanThreadsStarted = cCounter(uMaxThreads) oSelf.oScanThreadsFinished = cCounter(0) if oSelf.bVerbose: oConsole.fOutput( COLOR_BUSY, CHAR_BUSY, COLOR_NORMAL, " Scanning ", COLOR_INFO, str(len(asFolderPaths)), COLOR_NORMAL, " folder paths", " (and descendants)" if bRecursive else "", "...", ) for sFolderPath in set(asFolderPaths): oSelf.oNumberOfItemsFound.fuIncrease() if os.path.isdir(sFolderPath): oSelf.oUnhandledItemPathsQueue.put(sFolderPath) oSelf.fDebug() else: oSelf.oNumberOfItemsCompleted.fuIncrease() oSelf.fDebug() aoThreads = [cThread(oSelf.fScanThread) for x in range(uMaxThreads) ] + [cThread(oSelf.fStatusThread)] for oThread in aoThreads: oThread.fStart(bVital=False) for oThread in aoThreads: oThread.fWait()
def fCdbStdOutOutputCallbackHandler(oBugId, sbOutput): if dxConfig["bQuiet"]: return oConsole.fOutput( COLOR_OUTPUT, "stdout>", COLOR_NORMAL, str(sbOutput, 'latin1'), uConvertTabsToSpaces=8, )
def fOutputProductDetails(oProductDetails, bIsMainProduct, bShowInstallationFolders, bCheckForUpdates, bCheckForUpdatesSuccessful): oConsole.fOutput(*([ "│ ", ([COLOR_WARNING, CHAR_WARNING] if ( (bCheckForUpdates and (not bCheckForUpdatesSuccessful or (not oProductDetails.bVersionIsUpToDate and not oProductDetails.bVersionIsPreRelease))) or (oProductDetails.bHasTrialPeriod and oProductDetails.bInTrialPeriod )) else [COLOR_NORMAL, CHAR_LIST] if bCheckForUpdates and bCheckForUpdatesSuccessful and oProductDetails.bVersionIsPreRelease else [COLOR_OK, CHAR_OK] if oProductDetails.o0License or not oProductDetails.bRequiresLicense else [COLOR_ERROR, CHAR_ERROR]), " ", (COLOR_INFO if (not oProductDetails.bRequiresLicense or oProductDetails.o0License) else COLOR_WARNING if (oProductDetails.bHasTrialPeriod and oProductDetails.bInTrialPeriod ) else COLOR_ERROR) + (CONSOLE_UNDERLINE if oProductDetails.o0License else 0), oProductDetails.sProductName, COLOR_NORMAL, " version: ", (COLOR_WARNING if (bCheckForUpdates and ( not bCheckForUpdatesSuccessful or (not oProductDetails.bVersionIsUpToDate and not oProductDetails.bVersionIsPreRelease))) else COLOR_HILITE), str(oProductDetails.oProductVersion), ] + (bShowInstallationFolders and [ COLOR_NORMAL, " installed at ", COLOR_HILITE, oProductDetails.s0InstallationFolderPath, ] or []) + ([] if ( not oProductDetails.bRequiresLicense or oProductDetails.o0License ) else [COLOR_NORMAL, " ", COLOR_WARNING, "(in trial period)"] if ( oProductDetails.bHasTrialPeriod and oProductDetails.bInTrialPeriod ) else [COLOR_NORMAL, " ", COLOR_ERROR, "(no valid license found)"]) + ( [] if not bCheckForUpdates else [COLOR_NORMAL, " ", COLOR_WARNING, "(no respository)"] if oProductDetails.o0Repository is None else [COLOR_NORMAL, " ", COLOR_ERROR, "(cannot check for updates)"] if not bCheckForUpdatesSuccessful else [ COLOR_NORMAL, " ", COLOR_INFO, "(pre-release, last release version is ", str(oProductDetails.oLatestProductVersion), ")" ] if oProductDetails.bVersionIsPreRelease else [ COLOR_NORMAL, " ", COLOR_WARNING, "(old, latest release version is ", str(oProductDetails.oLatestProductVersion), ")" ] if not oProductDetails.bVersionIsUpToDate else []) + [ COLOR_NORMAL, ".", ]))
def fCollateralCannotIgnoreBugCallbackHandler(oBugId, sReason): oConsole.fOutput( COLOR_ERROR, CHAR_ERROR, COLOR_NORMAL, " This bug cannot be ignored: ", COLOR_INFO, sReason, COLOR_NORMAL, ".", )
def fLogMessageCallbackHandler(oBugId, sMessage, dsData=None): if dxConfig["bQuiet"]: return sData = dsData and ", ".join( ["%s: %s" % (sName, sValue) for (sName, sValue) in dsData.items()]) oConsole.fOutput( COLOR_DIM, "log>", sMessage, sData and " (%s)" % sData or [], )
def fApplicationMaxRunTimeCallbackHandler(oBugId): oConsole.fOutput( COLOR_INFO, CHAR_INFO, COLOR_NORMAL, " T+", COLOR_INFO, "%.1f" % oBugId.fnApplicationRunTimeInSeconds(), COLOR_NORMAL, " The application has been running for ", COLOR_INFO, "%.1f" % dxConfig["n0ApplicationMaxRunTimeInSeconds"], COLOR_NORMAL, " seconds without crashing.", ); oConsole.fOutput(); oConsole.fStatus(COLOR_BUSY, CHAR_BUSY, COLOR_NORMAL, " BugId is stopping..."); oBugId.fStop();
def fCollateralBugIgnoredCallbackHandler(oBugId, sInstruction, asActions): if not dxConfig["bQuiet"]: oConsole.fOutput( COLOR_OK, CHAR_OK, COLOR_NORMAL, " This bug was ignored by skipping the ", COLOR_INFO, sInstruction, COLOR_NORMAL, " instruction:", ); for uIndex in range(len(asActions)): sAction = asActions[uIndex]; oConsole.fOutput( COLOR_NORMAL, " ", COLOR_LIST, CHAR_LIST, COLOR_NORMAL, " ", sAction, "." if uIndex == len(asActions) - 1 else ",", );
def fOutputMessageForProcess(uHeaderColor, s0HeaderChar, oProcess, bIsMainProcess, *txMessage): # oProcess is a mWindowsAPI.cProcess or derivative. sIntegrityLevel = "?" if oProcess.uIntegrityLevel is None else ( str(oProcess.uIntegrityLevel >> 12) + ("+" if oProcess.uIntegrityLevel & 0x100 else "")) axHeader = [ uHeaderColor, s0HeaderChar or " ", COLOR_NORMAL, " ", bIsMainProcess and "Main" or "Sub", " process ", COLOR_INFO, str(oProcess.uId), COLOR_NORMAL, "/", COLOR_INFO, "0x%X" % oProcess.uId, COLOR_NORMAL, " (", COLOR_INFO, oProcess.sBinaryName, COLOR_NORMAL, ", ", COLOR_INFO, oProcess.sISA, COLOR_NORMAL, ", IL:", COLOR_INFO, sIntegrityLevel, COLOR_NORMAL, "): ", ] if s0HeaderChar is None: # Just blanks for the header (used for multi-line output to reduce redundant output). oConsole.fOutput( " " * len("".join(s for s in axHeader if isinstance(s, str))), *txMessage, uConvertTabsToSpaces=8) else: oConsole.fOutput(axHeader, *txMessage, uConvertTabsToSpaces=8)
def fxProcessBooleanArgument(sArgumentName, s0Value, u0CanAlsoBeAnIntegerLargerThan=None): if s0Value is None or s0Value.lower() == "true": return True if s0Value.lower() == "false": return False if u0CanAlsoBeAnIntegerLargerThan is not None: try: uValue = int(s0Value) except: pass else: if uValue > u0CanAlsoBeAnIntegerLargerThan: return uValue oConsole.fOutput( COLOR_ERROR, CHAR_ERROR, COLOR_NORMAL, " The value for ", COLOR_INFO, sArgument, COLOR_NORMAL, " must be \"", COLOR_INFO, "true", COLOR_NORMAL, "\" (default) or \"", COLOR_INFO, "false", COLOR_NORMAL, "\"", [ " or an integer larger than ", COLOR_INFO, str(u0CanAlsoBeAnIntegerLargerThan), COLOR_NORMAL, ] if u0CanAlsoBeAnIntegerLargerThan is not None else [], ".", ) sys.exit(guExitCodeBadArgument)
def fOutputLogo(): # We will use the above ASCII and color data to create a list of arguments # that can be passed to oConsole.fOutput in order to output the logo in color: for uLineIndex in range(len(asLogo)): uCurrentColor = COLOR_NORMAL; bUnderlined = False; asLogoPrintArguments = [""]; sCharsLine = asLogo[uLineIndex]; sColorsLine = asLogoColors[uLineIndex]; uColorIndex = 0; for uColumnIndex in range(len(sCharsLine)): sColor = sColorsLine[uColorIndex]; uColorIndex += 1; if sColor == "_": bUnderlined = not bUnderlined; sColor = sColorsLine[uColorIndex]; uColorIndex += 1; uColor = (sColor != " " and (0x0F00 + int(sColor, 16)) or COLOR_NORMAL) + (bUnderlined and CONSOLE_UNDERLINE or 0); if uColor != uCurrentColor: asLogoPrintArguments.extend([uColor, ""]); uCurrentColor = uColor; sChar = sCharsLine[uColumnIndex]; asLogoPrintArguments[-1] += sChar; oConsole.fOutput(*asLogoPrintArguments);
def fOutputUsageInformation(): oConsole.fLock() try: fOutputLogo() oConsole.fOutput(COLOR_HILITE, "Usage:") oConsole.fOutput( COLOR_INFO, " zyp.py [options] <source file or folder> <destination .zip file>" ) oConsole.fOutput( COLOR_INFO, " unzyp.py [options] <source .zip file> [<destination folder>]") oConsole.fOutput() oConsole.fOutput( COLOR_INFO, " zyp.py", COLOR_NORMAL, " will add the source files or all files in the source folder to the" ) oConsole.fOutput( " destination .zip file. The destination .zip file is created if it does not" ) oConsole.fOutput( " exist but files are added to any existing destination .zip file. If a file" ) oConsole.fOutput( " already exists in the destination .zip file, it is overwritten." ) oConsole.fOutput() oConsole.fOutput( COLOR_INFO, " unzyp.py", COLOR_NORMAL, " will extract all files in the source .zip file to the destination" ) oConsole.fOutput( " folder. The destination folder is created if it does not exist and files" ) oConsole.fOutput( " are added to any existing destination folder. If a file already exists in" ) oConsole.fOutput(" the destination folder, it is overwritten.") oConsole.fOutput() oConsole.fOutput(COLOR_INFO, "Options:") oConsole.fOutput(" ", COLOR_INFO, "-h", COLOR_NORMAL, ", ", COLOR_INFO, "--help") oConsole.fOutput(" This cruft.") oConsole.fOutput(" ", COLOR_INFO, "--version") oConsole.fOutput(" Show version information.") oConsole.fOutput(" ", COLOR_INFO, "--version-check") oConsole.fOutput(" Check for updates and show version information.") oConsole.fOutput(" ", COLOR_INFO, "--license") oConsole.fOutput(" Show license information.") oConsole.fOutput(" ", COLOR_INFO, "--license-update") oConsole.fOutput( " Download license updates and show license information.") oConsole.fOutput(" ", COLOR_INFO, "--arguments", COLOR_NORMAL, "=<", COLOR_INFO, "file path", COLOR_NORMAL, ">") oConsole.fOutput( " Load additional arguments from the provided value and insert them in place" ) oConsole.fOutput(" of this argument.") oConsole.fOutput(COLOR_INFO, " -d", COLOR_NORMAL, ", ", COLOR_INFO, "--debug", COLOR_NORMAL) oConsole.fOutput( " Output debug information while zipping/unzipping files.") oConsole.fOutput(COLOR_INFO, " -l", COLOR_NORMAL, ", ", COLOR_INFO, "--list", COLOR_NORMAL) oConsole.fOutput( " (unzyp only) List all files in a zip file without extracting them." ) oConsole.fOutput() oConsole.fOutput(COLOR_HILITE, "Exit codes:") oConsole.fOutput( " ", 0x0F0A, "0", COLOR_NORMAL, " = zyp/unzyp did not compress/decompress any files.") oConsole.fOutput( " ", 0x0F0A, "1", COLOR_NORMAL, " = zyp/unzyp compressed/decompressed files successfully.") oConsole.fOutput( " ", 0x0F0C, "2", COLOR_NORMAL, " = zyp/unzyp was unable to parse the command-line arguments provided." ) oConsole.fOutput( " ", 0x0F0C, "3", COLOR_NORMAL, " = zyp/unzyp ran into an internal error: please report the details!" ) oConsole.fOutput(" ", 0x0F0C, "4", COLOR_NORMAL, " = zyp/unzyp cannot read from the given source.") oConsole.fOutput( " ", 0x0F0C, "5", COLOR_NORMAL, " = zyp/unzyp cannot write to the given destination.") finally: oConsole.fUnlock()
def fHandleFile(oSelf, sFilePath): o0LastNameMatch = None o0LastPathMatch = None # Having no reg.exps. means always add: if (oSelf.arPathRegExps or oSelf.arNegativePathRegExps or oSelf.arNameRegExps or oSelf.arNegativeNameRegExps): if oSelf.arNameRegExps or oSelf.arNegativeNameRegExps: sItemName = os.path.basename(sFilePath) # Having negative reg.exps. means not add if matched: for rNegativePathRegExp in oSelf.arNegativePathRegExps: o0Match = rNegativePathRegExp.search(sFilePath) if o0Match: # Matching negative reg.exp. means don't add (and stop matching). if oSelf.bVerbose: fVerboseOutputHelper(False, sFilePath, "negative path", rNegativePathRegExp, o0Match) return for rNegativeNameRegExp in oSelf.arNegativeNameRegExps: o0Match = rNegativeNameRegExp.search(sItemName) if o0Match: # Matching negative reg.exp. means don't add (and stop matching). if oSelf.bVerbose: fVerboseOutputHelper(False, sFilePath, "negative name", rNegativeNameRegExp, o0Match) return # Not matching negative reg.exp. means maybe add: # Not having positive reg.exps. means add: # Having positive reg.exps. means add if matches all: if oSelf.arPathRegExps: for rPathRegExp in oSelf.arPathRegExps: o0Match = rPathRegExp.search(sFilePath) if oSelf.bVerbose: fVerboseOutputHelper(None if o0Match else False, sFilePath, "path", rPathRegExp, o0Match) if o0Match: o0LastPathMatch = o0Match else: return if oSelf.arNameRegExps: for rNameRegExp in oSelf.arNameRegExps: o0Match = rNameRegExp.search(sItemName) if oSelf.bVerbose: fVerboseOutputHelper(None if o0Match else False, sFilePath, "name", rNameRegExp, o0Match) if o0Match: o0LastNameMatch = o0Match else: return if oSelf.bVerbose: sMatchedExpressionTypes = " and ".join([ s for s in [ "path" if oSelf.arPathRegExps else None, "name" if oSelf.arNameRegExps else None, ] if s ]) oConsole.fOutput( " ", COLOR_SELECT_YES, CHAR_SELECT_YES, COLOR_NORMAL, " ", sFilePath, COLOR_DIM, " (matches all ", sMatchedExpressionTypes, " reg.exp.)", ) elif oSelf.bVerbose: oConsole.fOutput( " ", COLOR_SELECT_YES, CHAR_SELECT_YES, COLOR_NORMAL, " ", sFilePath, ) oSelf.oMatchesByFilePath.fSet(sFilePath, (o0LastNameMatch, o0LastPathMatch))
def fOutputUsageInformation(): oConsole.fLock() try: fOutputLogo() axBoolean = [ "[=", COLOR_INFO, "true", COLOR_NORMAL, "|", COLOR_INFO, "false", COLOR_NORMAL, "]" ] oConsole.fOutput(COLOR_HILITE, "Usage:") oConsole.fOutput() oConsole.fOutput( COLOR_INFO, " rs.py [options] [<path> [<path> [...]]] [-- <command>]") oConsole.fOutput() oConsole.fOutput(COLOR_HILITE, "Options:") oConsole.fOutput(" ", COLOR_INFO, "-h", COLOR_NORMAL, ", ", COLOR_INFO, "--help") oConsole.fOutput(" This cruft.") oConsole.fOutput(" ", COLOR_INFO, "--version") oConsole.fOutput(" Show version information.") oConsole.fOutput(" ", COLOR_INFO, "--version-check") oConsole.fOutput(" Check for updates and show version information.") oConsole.fOutput(" ", COLOR_INFO, "--license") oConsole.fOutput(" Show license information.") oConsole.fOutput(" ", COLOR_INFO, "--license-update") oConsole.fOutput( " Download license updates and show license information.") oConsole.fOutput(" ", COLOR_INFO, "--arguments", COLOR_NORMAL, "=<", COLOR_INFO, "file path", COLOR_NORMAL, ">") oConsole.fOutput( " Load additional arguments from the provided value and insert them in place" ) oConsole.fOutput(" of this argument.") oConsole.fOutput(" ", COLOR_INFO, "-q", COLOR_NORMAL, ", ", COLOR_INFO, "--quiet", axBoolean) oConsole.fOutput(" Output only essential information.") oConsole.fOutput(" ", COLOR_INFO, "-v", COLOR_NORMAL, ", ", COLOR_INFO, "--verbose", axBoolean) oConsole.fOutput(" Verbose output.") oConsole.fOutput(" ", COLOR_INFO, "-p", COLOR_NORMAL, ", ", COLOR_INFO, "--pause", axBoolean) oConsole.fOutput( " Wait for user to press ENTER before terminating.") oConsole.fOutput(" ", COLOR_INFO, "-u", COLOR_NORMAL, ", ", COLOR_INFO, "--unicode", axBoolean) oConsole.fOutput( " Remove all '\0' chars from the file before scanning to improvise scanning" ) oConsole.fOutput(" utf-16 encoded ASCII characters.") oConsole.fOutput(" ", COLOR_INFO, "-e", COLOR_NORMAL, ", ", COLOR_INFO, "--uedit", axBoolean) oConsole.fOutput( " Start UltraEdit 64-bit for each matched file and scroll to the first matched line (if any)." ) oConsole.fOutput(" ", COLOR_INFO, "-l", COLOR_NORMAL, ", ", COLOR_INFO, "--lines <lines>") oConsole.fOutput( " Show the provided number of lines of the file's content around each match." ) oConsole.fOutput(" ", COLOR_INFO, "<lines>", COLOR_NORMAL, " can take two formats: ", COLOR_INFO, "[-/+]N", COLOR_NORMAL, " and ", COLOR_INFO, "-N+N", COLOR_NORMAL, ".") oConsole.fOutput( " Where N is a integer number, positive/negative numbers determine the number" ) oConsole.fOutput( " of lines to show after/before the match respectively.") oConsole.fOutput(" ", COLOR_INFO, "<path>", COLOR_NORMAL, " [", COLOR_INFO, "<path>", COLOR_NORMAL, " [", COLOR_INFO, "...", COLOR_NORMAL, "]]") oConsole.fOutput( " Apply matching only to the provided files/folders. If not path is" ) oConsole.fOutput( " provided, the current working directory is used.") oConsole.fOutput(" ", COLOR_INFO, "-r", COLOR_NORMAL, ", ", COLOR_INFO, "--recursive") oConsole.fOutput( " Apply matching to all files in all subfolders of the selected folders." ) oConsole.fOutput(" ", COLOR_INFO, "<regular expression> [<regular expression> [...]]") oConsole.fOutput( " Match the content or full path and name of files against the given regular" ) oConsole.fOutput( " expression(s). You must provide at least one regular expression." ) oConsole.fOutput(COLOR_HILITE, "Regular expression syntax:") oConsole.fOutput(" [", COLOR_INFO, "c", COLOR_NORMAL, "|", COLOR_INFO, "p", COLOR_NORMAL, "]", "[", COLOR_INFO, "!", COLOR_NORMAL, "]", "/", COLOR_INFO, "pattern", COLOR_NORMAL, "/", "[", COLOR_INFO, "flags", COLOR_NORMAL, "]") oConsole.fOutput() oConsole.fOutput(" [", COLOR_INFO, "c", COLOR_NORMAL, "|", COLOR_INFO, "p", COLOR_NORMAL, "]") oConsole.fOutput( " ", COLOR_INFO, "c", COLOR_NORMAL, " indicates the regular expression should be matched against the file's content" ) oConsole.fOutput( " (default). ", COLOR_INFO, "p", COLOR_NORMAL, " indicates the regular expression should be matched against the") oConsole.fOutput(" file's full path and name.") oConsole.fOutput(" [", COLOR_INFO, "!", COLOR_NORMAL, "]") oConsole.fOutput( " If ", COLOR_INFO, "!", COLOR_NORMAL, "is present, the match is inverted: files that match this regular expression" ) oConsole.fOutput(" are ", CONSOLE_UNDERLINE, "excluded", COLOR_NORMAL, " from the result instead of included. File that ", CONSOLE_UNDERLINE, "do not", COLOR_NORMAL, " match") oConsole.fOutput(" this regular expression are included.") oConsole.fOutput(" ", COLOR_INFO, "pattern") oConsole.fOutput( " A regular expression pattern following Python syntax.") oConsole.fOutput(" ", COLOR_INFO, "flags") oConsole.fOutput( " Any one of the single-letter regular expression flags available in Python." ) oConsole.fOutput() oConsole.fOutput( " For details on the syntax of Python regular expression patterns and flags" ) oConsole.fOutput(" please visit: ", COLOR_INFO, "https://docs.python.org/3/library/re.html", COLOR_NORMAL, ".") oConsole.fOutput(" ", COLOR_INFO, "--", COLOR_NORMAL, " <", COLOR_INFO, "command", COLOR_NORMAL, "> [", COLOR_INFO, "arguments", COLOR_NORMAL, "]") oConsole.fOutput( " Execute the specified command for all files that matched the given" ) oConsole.fOutput( " regular expressions. The command nad arguments can contain the following" ) oConsole.fOutput( " keys that will be replaced by the appropriate values:") oConsole.fOutput(" ", COLOR_INFO, "{d}", COLOR_NORMAL, " - the drive on which the file was found.") oConsole.fOutput(" ", COLOR_INFO, "{p}", COLOR_NORMAL, " - the folder path in which the file was found.") oConsole.fOutput(" ", COLOR_INFO, "{n}", COLOR_NORMAL, " - the name of the file (excluding the extension).") oConsole.fOutput(" ", COLOR_INFO, "{x}", COLOR_NORMAL, " - the extension of the file (including the dot).") oConsole.fOutput(" ", COLOR_INFO, "{f}", COLOR_NORMAL, " - the full path of the file (== ", COLOR_INFO, "{dpnx}", COLOR_NORMAL, ").") oConsole.fOutput(" Note: The above arguments can be combined: ", COLOR_INFO, "{dp}", COLOR_NORMAL, " will be replaced with the") oConsole.fOutput(" file's drive and path, and ", COLOR_INFO, "{nx}", COLOR_NORMAL, " will be replaced by the file's name and") oConsole.fOutput( " extension. The values for these keys will be surrounded by quotes unless" ) oConsole.fOutput(" preceed them with ", COLOR_INFO, "~", COLOR_NORMAL, " (e.g. ", COLOR_INFO, "\"{~n}{~x}\"", COLOR_NORMAL, " == ", COLOR_INFO, "{nx}", COLOR_NORMAL, ").") oConsole.fOutput( " ", COLOR_INFO, "{l}", COLOR_NORMAL, " - the line number on which the first match was found.") oConsole.fOutput( " Note: Repeating {l} gives you the next line number on which a match was" ) oConsole.fOutput( " found, or -1 if there are no more matches: {l},{l},{l} will be replaced with" ) oConsole.fOutput( " the line numbers of the first three matches, separated by commas." ) oConsole.fOutput(" ", COLOR_INFO, "{1}", COLOR_NORMAL, ", ", COLOR_INFO, "{2}", COLOR_NORMAL, ", ", COLOR_INFO, "{3}", COLOR_NORMAL, "... - the ", CONSOLE_UNDERLINE, "first path", COLOR_NORMAL, " match's sub-matches.") oConsole.fOutput( " Note: You can use numbers to insert groups from the last match against the" ) oConsole.fOutput( " file name or path. This may be useful to mass-rename files. If both a name" ) oConsole.fOutput( " and a path match exists, the name match is used. You can use the prefixes" ) oConsole.fOutput( " \"n\" and \"p\" to force using the name or path match, as in {n1} or {p2}." ) oConsole.fOutput(" For instance ", COLOR_INFO, "rs \"n/(.*)\\.old$/\" -- ren {f} {1}", COLOR_NORMAL, " will remove the \".old\" extension") oConsole.fOutput(" from all files in the current folder.") oConsole.fOutput() oConsole.fOutput(COLOR_HILITE, "Examples:") oConsole.fOutput(" ", COLOR_INFO, "rs /C+/ -p /P+/ -r") oConsole.fOutput( " Match all files in the current directory and all its sub-folders which path" ) oConsole.fOutput( " and name contains a sequence of 1 or more 'P'-s. Match the content of " ) oConsole.fOutput( " these files for a sequence of 1 or more 'C'-s. Output the path and name of" ) oConsole.fOutput( " the files that matched and the line number(s) on which the 'C'-s were found." ) oConsole.fOutput() oConsole.fOutput(" ", COLOR_INFO, "rs -p /P+/i C:\\ -r") oConsole.fOutput( " Match all files in the root of the C: drive and all its sub-folders which" ) oConsole.fOutput( " path and name contains a sequence of 1 or more 'p'-s (either upper- or" ) oConsole.fOutput( " lowercase). Output the path and name of the files that matched." ) oConsole.fOutput() oConsole.fOutput( " ", COLOR_INFO, "rs /class\\s+\\w+/m -p /\\.c(pp|xx)$/i -- notepad {f}") oConsole.fOutput( " Match all files in the current folder that have a .cpp or .cxx extension." ) oConsole.fOutput( " Match the content of these files against a C++ class definitions. Output" ) oConsole.fOutput( " the path, name and line numbers of the files and open each one in Notepad." ) oConsole.fOutput() oConsole.fOutput( " ", COLOR_INFO, "rs /struct\s+some_struct\s*{/m -r -p /\\.[ch](pp|xx)?$/i -l -1+16" ) oConsole.fOutput( " Match all files in the current folder that have a C/C++ extension." ) oConsole.fOutput( " Match the content of these files against the struct some_struct" ) oConsole.fOutput( " definitions. Output the path and name of the matched file(s) and the line" ) oConsole.fOutput(" before and up to 16 lines after each match.") oConsole.fOutput() oConsole.fOutput(COLOR_HILITE, "Exit codes:") oConsole.fOutput(" ", COLOR_INFO, "0", COLOR_NORMAL, " = rs did not match any files.") oConsole.fOutput(" ", COLOR_INFO, "1", COLOR_NORMAL, " = rs matched one or more files.") oConsole.fOutput( " ", COLOR_ERROR, "2", COLOR_NORMAL, " = rs was unable to parse the command-line arguments provided.") oConsole.fOutput( " ", COLOR_ERROR, "3", COLOR_NORMAL, " = rs ran into an internal error: please report the details!") finally: oConsole.fUnlock()
def fOutputVersionInformation(bCheckForUpdates, bShowInstallationFolders, dsAdditionalVersion_by_sName={}): # Read product details for rs and all modules it uses. aoProductDetails = mProductDetails.faoGetProductDetailsForAllLoadedModules( ) o0MainProductDetails = mProductDetails.fo0GetProductDetailsForMainModule() oConsole.fLock() try: aoProductDetailsCheckedForUpdates = [] aoProductDetailsSuccessfullyCheckedForUpdates = [] if bCheckForUpdates: for oProductDetails in aoProductDetails: if oProductDetails.o0Repository is None: continue aoProductDetailsCheckedForUpdates.append(oProductDetails) oConsole.fProgressBar( len(aoProductDetailsCheckedForUpdates) * 1.0 / len(aoProductDetails), "Checking %s for updates..." % oProductDetails.sProductName, ) try: oProductDetails.foGetLatestProductDetailsFromRepository() except mProductDetails.mExceptions.cProductDetailsException as oException: oConsole.fOutput( COLOR_ERROR, CHAR_ERROR, COLOR_NORMAL, " Version check for ", COLOR_INFO, oProductDetails.sProductName, COLOR_NORMAL, " failed: ", COLOR_INFO, str(oException), ) else: aoProductDetailsSuccessfullyCheckedForUpdates.append( oProductDetails) if len(aoProductDetailsSuccessfullyCheckedForUpdates) == 0: oConsole.fOutput( COLOR_WARNING, CHAR_WARNING, COLOR_NORMAL, "Failed to get any product version information.", ) oConsole.fOutput( " (This often indicates you are running a ", COLOR_INFO, "pre-release", COLOR_NORMAL, " version, or a version that is very ", COLOR_INFO, "out of date", COLOR_NORMAL, ").", ) oConsole.fOutput( " To try and resolve this issue, please update this product to the latest", ) oConsole.fOutput(" version and try again.", ) if f0OutputLogo: f0OutputLogo() oConsole.fOutput( "┌───[", COLOR_HILITE, " Version information ", COLOR_NORMAL, "]", sPadding="─", ) # Output the main product information first, then its dependencies alphabetically: if o0MainProductDetails: fOutputProductDetails( o0MainProductDetails, bIsMainProduct=True, bShowInstallationFolders=bShowInstallationFolders, bCheckForUpdates=bCheckForUpdates, bCheckForUpdatesSuccessful=o0MainProductDetails in aoProductDetailsSuccessfullyCheckedForUpdates, ) doRemainingProductDetails_by_sName = dict([ (oProductDetails.sProductName, oProductDetails) for oProductDetails in aoProductDetails if oProductDetails != o0MainProductDetails ]) for sProductName in sorted(doRemainingProductDetails_by_sName.keys()): oProductDetails = doRemainingProductDetails_by_sName[sProductName] fOutputProductDetails( oProductDetails, bIsMainProduct=False, bShowInstallationFolders=bShowInstallationFolders, bCheckForUpdates=bCheckForUpdates, bCheckForUpdatesSuccessful=oProductDetails in aoProductDetailsSuccessfullyCheckedForUpdates, ) asProductNames = (([o0MainProductDetails.sProductName] if o0MainProductDetails else []) + list(doRemainingProductDetails_by_sName.keys())) oConsole.fOutput( "│ ", CHAR_LIST, " ", COLOR_INFO, "Windows", COLOR_NORMAL, " version: ", COLOR_INFO, oSystemInfo.sOSName, COLOR_NORMAL, " release ", COLOR_INFO, oSystemInfo.sOSReleaseId, COLOR_NORMAL, ", build ", COLOR_INFO, oSystemInfo.sOSBuild, COLOR_NORMAL, " ", COLOR_INFO, oSystemInfo.sOSISA, COLOR_NORMAL, ".", ) oConsole.fOutput( "│ ", CHAR_LIST, " ", COLOR_INFO, "Python", COLOR_NORMAL, " version: ", COLOR_INFO, str(platform.python_version()), COLOR_NORMAL, " ", COLOR_INFO, fsGetPythonISA(), COLOR_NORMAL, ".", ) for (sName, sVersion) in dsAdditionalVersion_by_sName.items(): oConsole.fOutput( "│ ", CHAR_LIST, " ", COLOR_INFO, sName, COLOR_NORMAL, " version: ", COLOR_INFO, sVersion, COLOR_NORMAL, ".", ) oConsole.fOutput( "└", sPadding="─", ) finally: oConsole.fUnlock()
def fOutputUsageInformation(): asApplicationKeywords = list(ddxApplicationSettings_by_sKeyword.keys()) oConsole.fLock() try: fOutputLogo() axBoolean = [ "[=", COLOR_INFO, "true", COLOR_NORMAL, "|", COLOR_INFO, "false", COLOR_NORMAL, "]" ] oConsole.fOutput(COLOR_HILITE, "Usage:") oConsole.fOutput() oConsole.fOutput(" ", COLOR_INFO, "BugId.py", COLOR_NORMAL, " [", COLOR_INFO, "options", COLOR_NORMAL, "] <", COLOR_INFO, "target", COLOR_NORMAL, "> [", COLOR_INFO, "options", COLOR_NORMAL, "] [-- ", COLOR_INFO, "argument ", COLOR_NORMAL, "[", COLOR_INFO, "argument ", COLOR_NORMAL, "[", COLOR_INFO, "...", COLOR_NORMAL, "]]]") oConsole.fOutput() oConsole.fOutput(COLOR_HILITE, "Targets:") oConsole.fOutput(" ", COLOR_INFO, "\"path\\to\\binary.exe\"") oConsole.fOutput( " Start the given binary in the debugger with the given arguments." ) oConsole.fOutput(" ", COLOR_INFO, "--pids=pid[,pid[...]]") oConsole.fOutput( " Attach debugger to the process(es) provided in the list. The processes ", COLOR_HILITE, "must") oConsole.fOutput( " all have been suspended, as they will be resumed by the debugger." ) oConsole.fOutput( " Arguments cannot be provided for obvious reasons.") oConsole.fOutput(" ", COLOR_INFO, "--uwp-app=<package name>[!<application id>]") oConsole.fOutput( " Start and debug a Universal Windows Platform App identified by the given" ) oConsole.fOutput( " package name and application id. If no application id is provided and the" ) oConsole.fOutput( " package exposes only one if, it will default to that id. Note that only" ) oConsole.fOutput( " a single argument can be passed to a UWP App; additional arguments will be" ) oConsole.fOutput(" silently ignored.") oConsole.fOutput(" ", COLOR_INFO, "<known application keyword>") oConsole.fOutput( " BugId has a list of known targets that are identified by a keyword. You can" ) oConsole.fOutput( " use such a keyword to have BugId try to automatically find the binary or" ) oConsole.fOutput( " determine the package name and id for that application, optionally apply" ) oConsole.fOutput( " application specific settings and provide default arguments. This makes it" ) oConsole.fOutput( " easier to run these applications without having to manually provide these." ) oConsole.fOutput( " You can optioanlly override any default settings by providing them *after*" ) oConsole.fOutput( " the keyword. You can also provide the path to the application binary after" ) oConsole.fOutput( " the keyword to use a different binary than the one BugId automatically" ) oConsole.fOutput( " detects, or if BugId is unable to detect the binary on your system." ) oConsole.fOutput() oConsole.fOutput(COLOR_HILITE, "Options:") oConsole.fOutput(" ", COLOR_INFO, "-h", COLOR_NORMAL, ", ", COLOR_INFO, "--help") oConsole.fOutput(" This cruft.") oConsole.fOutput(" ", COLOR_INFO, "--version") oConsole.fOutput(" Show version information.") oConsole.fOutput(" ", COLOR_INFO, "--version-check") oConsole.fOutput(" Check for updates and show version information.") oConsole.fOutput(" ", COLOR_INFO, "--license") oConsole.fOutput(" Show license information.") oConsole.fOutput(" ", COLOR_INFO, "--license-update") oConsole.fOutput( " Download license updates and show license information.") oConsole.fOutput(" ", COLOR_INFO, "--arguments", COLOR_NORMAL, "=<", COLOR_INFO, "file path", COLOR_NORMAL, ">") oConsole.fOutput( " Load additional arguments from the provided value and insert them in place" ) oConsole.fOutput(" of this argument.") oConsole.fOutput(" ", COLOR_INFO, "-q", COLOR_NORMAL, ", ", COLOR_INFO, "--quiet", axBoolean) oConsole.fOutput( " Output only essential information. (default is \"false\")") oConsole.fOutput(" ", COLOR_INFO, "-v", COLOR_NORMAL, ", ", COLOR_INFO, "--verbose", axBoolean) oConsole.fOutput( " Output all commands send to cdb.exe and everything it outputs in return." ) oConsole.fOutput( " Note that -q and -v are not mutually exclusive. (default is \"false\")" ) oConsole.fOutput(" ", COLOR_INFO, "-p", COLOR_NORMAL, ", ", COLOR_INFO, "--pause", axBoolean) oConsole.fOutput( " Always wait for the user to press ENTER before terminating at the end." ) oConsole.fOutput(" (default is \"false\")") oConsole.fOutput(" ", COLOR_INFO, "-c", COLOR_NORMAL, ", ", COLOR_INFO, "--collateral", COLOR_NORMAL, "[=", COLOR_INFO, "number of bugs", COLOR_NORMAL, "]") oConsole.fOutput( " When the specified number of bugs is larger than 1 (default 5), BugId will" ) oConsole.fOutput( " go into \"collateral bug handling\" mode. This means that after certain" ) oConsole.fOutput( " access violation bugs are reported, it will attempt to \"fake\" that the" ) oConsole.fOutput( " instruction that caused the exception succeeded without triggering an" ) oConsole.fOutput( " exception. For read operations, it will set the destination register to a" ) oConsole.fOutput( " tainted value (0x41414141...). For write operations, it will simply step" ) oConsole.fOutput( " over the instruction. It will do this for up to the specified number of" ) oConsole.fOutput(" bugs.") oConsole.fOutput( " The upshot of this is that you can get an idea of what would happen if" ) oConsole.fOutput( " you were able to control the bad read/write operation. This can be usedful" ) oConsole.fOutput( " when determining if a particular vulnerability is theoretically exploitable" ) oConsole.fOutput( " or not. E.g. it might show that nothing else happens, that the application" ) oConsole.fOutput( " crashes unavoidably and immediately, both of which indicate that the issue" ) oConsole.fOutput( " is not exploitable. It might also show that reading from or writing to" ) oConsole.fOutput( " otherwise inaccessible parts of memory or controlling execution flow is" ) oConsole.fOutput( " potentially possible, indicating it is exploitable.") oConsole.fOutput(" ", COLOR_INFO, "-d", COLOR_NORMAL, ", ", COLOR_INFO, "--dump", axBoolean) oConsole.fOutput( " Save a mini crash dump when a crash is detected.") oConsole.fOutput(" ", COLOR_INFO, "--full-dump", axBoolean) oConsole.fOutput( " Save a full crash dump when a crash is detected.") oConsole.fOutput(" ", COLOR_INFO, "-f", COLOR_NORMAL, ", ", COLOR_INFO, "--fast", axBoolean) oConsole.fOutput( " Create no HTML report, do not use symbols. This is an alias for:" ) oConsole.fOutput(" ", COLOR_INFO, "--bGenerateReportHTML=false") oConsole.fOutput(" ", COLOR_INFO, "--cBugId.asSymbolServerURLs=[]") oConsole.fOutput(" ", COLOR_INFO, "--cBugId.bUse_NT_SYMBOL_PATH=false") oConsole.fOutput(" ", COLOR_INFO, "-I", COLOR_NORMAL, " [", COLOR_INFO, "arguments", COLOR_NORMAL, "]") oConsole.fOutput( " Install as the default JIT debugger on the system. This allows BugId to" ) oConsole.fOutput( " generate a report whenever an application crashes.") oConsole.fOutput( " All arguments after -I will be passed to BugId whenever it is started as" ) oConsole.fOutput( " the JIT debugger. It might be useful to add arguments such as \"--pause\"" ) oConsole.fOutput( " to leave the BugId window open after it generated a report, \"--full-dump\"" ) oConsole.fOutput( " to generate a full memory dump and \"--reports=<path>\" to have the reports" ) oConsole.fOutput( " stored in a specific folder. If you do not provide \"--reports\", it will" ) oConsole.fOutput( " be added automatically to make sure the reports are saved in a folder that" ) oConsole.fOutput( " BugId can write to, and which you can easily find.") oConsole.fOutput(" Here's what I normally use:") oConsole.fOutput( " ", COLOR_HILITE, "BugId -I --collateral=10 \"--reports=%USERPROFILE%\\BugId reports\" --full-dump" ) oConsole.fOutput(" ", COLOR_INFO, "--jit") oConsole.fOutput( " Show details on the currently installed JIT debugger.") oConsole.fOutput(" ", COLOR_INFO, "--isa", COLOR_NORMAL, "=", COLOR_INFO, "x86", COLOR_NORMAL, "|", COLOR_INFO, "x64") oConsole.fOutput( " Use the x86 or x64 version of cdb to debug the application. The default is" ) oConsole.fOutput( " to use the ISA* of the OS. Applications build to run on x86 systems can be" ) oConsole.fOutput( " debugged using the x64 version of cdb, and you are strongly encouraged to " ) oConsole.fOutput( " do so. But you can use the x86 debugger to debug x86 application if you" ) oConsole.fOutput(" want to. (ISA = Instruction Set Architecture)") oConsole.fOutput(" ", COLOR_INFO, "-r", COLOR_NORMAL, ", ", COLOR_INFO, "--repeat", COLOR_NORMAL, "[=", COLOR_INFO, "number of loops", COLOR_NORMAL, "]") oConsole.fOutput( " Restart the application to run another test as soon as the application is" ) oConsole.fOutput( " terminated. Useful when testing the reliability of a repro, detecting the" ) oConsole.fOutput( " various crashes a non-deterministic repro can cause or while making " ) oConsole.fOutput( " modifications to the repro in order to test how they affect the crash." ) oConsole.fOutput( " A statistics file is created or updated after each run that contains the" ) oConsole.fOutput( " number of occurances of each Bug Id that was detected. If a number is" ) oConsole.fOutput( " provided, the application will be run that many times. Otherwise the" ) oConsole.fOutput(" application will be run indefinitely.") oConsole.fOutput(" ", COLOR_INFO, "--symbols", COLOR_NORMAL, "=", COLOR_INFO, "path\\to\\symbols\\folder") oConsole.fOutput( " Use the given path as a local symbol folder in addition to the symbol paths" ) oConsole.fOutput( " specified in dxConfig. You can provide this option multiple times to add" ) oConsole.fOutput( " as many additional local symbol paths as needed.") oConsole.fOutput(" ", COLOR_INFO, "--reports", COLOR_NORMAL, "=", COLOR_INFO, "path\\to\\reports\\folder") oConsole.fOutput( " Store reports in the given path. Optional cdb output and crash dumps are" ) oConsole.fOutput(" stored in the same location.") oConsole.fOutput() oConsole.fOutput( " Options also include any of the settings in dxConfig.py; you can specify them" ) oConsole.fOutput(" using ", COLOR_INFO, "--", COLOR_NORMAL, "[", COLOR_INFO, "name", COLOR_NORMAL, "]=[", COLOR_INFO, "JSON value", COLOR_NORMAL, "]. Here are some examples:") oConsole.fOutput(" ", COLOR_INFO, "--bGenerateReportHTML=false") oConsole.fOutput( " Do not save a HTML formatted crash report. This should make BugId run" ) oConsole.fOutput( " faster and use less RAM, as it does not need to gather and process the" ) oConsole.fOutput(" information needed for the HTML report.") oConsole.fOutput( " If you only need to confirm a crash can be reproduced, you may want to use" ) oConsole.fOutput( " this: it can make the process of analyzing a crash a lot faster. But if" ) oConsole.fOutput( " no local or cached symbols are available, you'll get less information" ) oConsole.fOutput(" ", COLOR_INFO, "\"--sReportFolderPath=\\\"BugId\\\"\"") oConsole.fOutput( " Save report to the specified folder, in this case \"BugId\". The quotes" ) oConsole.fOutput( " mess is needed because of the Windows quirck explained below." ) oConsole.fOutput(" The remaining dxConfig settings are:") for sSettingName in sorted(dxConfig.keys()): if sSettingName not in [ "bGenerateReportHTML", "sReportFolderPath", "cBugId" ]: xSettingValue = dxConfig[sSettingName] oConsole.fOutput(" ", COLOR_INFO, "--", sSettingName, COLOR_NORMAL, " (default value: ", COLOR_INFO, str(xSettingValue), COLOR_NORMAL, ")") oConsole.fOutput(" See ", COLOR_INFO, "dxConfig.py", COLOR_NORMAL, " for details on each setting.") oConsole.fOutput() oConsole.fOutput( " You can also adjust cBugId specific settings, such as:") oConsole.fOutput( " ", COLOR_INFO, "--cBugId.asSymbolServerURLs=[\"http://msdl.microsoft.com/download/symbols\"]" ) oConsole.fOutput( " Use http://msdl.microsoft.com/download/symbols as a symbol server." ) oConsole.fOutput(" ", COLOR_INFO, "--cBugId.asSymbolCachePaths=[\"C:\\Symbols\"]") oConsole.fOutput(" Use C:\\Symbols to cache symbol files.") oConsole.fOutput(" See ", COLOR_INFO, "cBugId\\dxConfig.py", COLOR_NORMAL, " for details on all available settings.") oConsole.fOutput( " All values must be valid JSON of the appropriate type. No checks are made to" ) oConsole.fOutput( " ensure this! Providing illegal values may result in exceptions at any time" ) oConsole.fOutput(" during execution. You have been warned!") oConsole.fOutput() oConsole.fOutput( " Note that you may need to do a bit of \"quote-juggling\" because Windows likes" ) oConsole.fOutput( " to eat quotes for no obvious reason. So, if you want to specify --a=\"b\", you" ) oConsole.fOutput( " will need to use \"--a=\\\"b\\\"\", or BugId will see --a=b and `b` is not valid" ) oConsole.fOutput(" JSON.") oConsole.fOutput() oConsole.fOutput(COLOR_HILITE, "Known application keywords:") asLine = [" "] uLineLength = 2 for sApplicationKeyword in asApplicationKeywords: if uLineLength > 2: if uLineLength + 2 + len(sApplicationKeyword) + 2 > 80: asLine += [COLOR_NORMAL, ","] oConsole.fOutput(*asLine) asLine = [" "] uLineLength = 2 else: asLine += [COLOR_NORMAL, ", "] uLineLength += 2 asLine += [COLOR_INFO, sApplicationKeyword] uLineLength += len(sApplicationKeyword) asLine += [COLOR_NORMAL, "."] oConsole.fOutput(*asLine) oConsole.fOutput() oConsole.fOutput( " Run ", COLOR_INFO, "BugId.py application?", COLOR_NORMAL, " for an overview of the application specific command") oConsole.fOutput(" line arguments and settings.") oConsole.fOutput() oConsole.fOutput(COLOR_HILITE, "Exit codes:") oConsole.fOutput(" ", COLOR_INFO, "0", COLOR_NORMAL, " = BugId successfully ran the application ", CONSOLE_UNDERLINE, "without detecting a bug", COLOR_NORMAL, ".") oConsole.fOutput(" ", COLOR_INFO, "1", COLOR_NORMAL, " = BugId successfully ran the application and ", CONSOLE_UNDERLINE, "detected a bug", COLOR_NORMAL, ".") oConsole.fOutput( " ", COLOR_ERROR, "2", COLOR_NORMAL, " = BugId was unable to parse the command-line arguments provided." ) oConsole.fOutput( " ", COLOR_ERROR, "3", COLOR_NORMAL, " = BugId ran into an internal error: please report the details!") oConsole.fOutput( " ", COLOR_ERROR, "4", COLOR_NORMAL, " = BugId was unable to start or attach to the application.") oConsole.fOutput(" ", COLOR_ERROR, "5", COLOR_NORMAL, " = You do not have a valid license.") finally: oConsole.fUnlock()
def fOutputCurrentJITDebuggerSettings(): oConsole.fLock() try: oConsole.fOutput("┌───[", COLOR_INFO, " Current JIT Debugger ", COLOR_NORMAL, "]", sPadding="─") xCurrentJITDebuggerCommandLine = fxGetCurrentJITDebuggerCommandLine() if not fbIsProvided(xCurrentJITDebuggerCommandLine): oConsole.fOutput( "│ ", COLOR_INFO, CHAR_INFO, COLOR_NORMAL, "JIT debugger: ", COLOR_INFO, "None", COLOR_NORMAL, ".", ) elif xCurrentJITDebuggerCommandLine is None: oConsole.fOutput( "│ ", COLOR_ERROR, CHAR_ERROR, COLOR_NORMAL, " JIT debugger: ", COLOR_INFO, "Unknown", COLOR_NORMAL, " (unable to read registry).", ) else: sBugIdJITDebuggerCommandLineStartsWith = fsCreateBugIdCommandLine( ) if xCurrentJITDebuggerCommandLine.startswith( sBugIdJITDebuggerCommandLineStartsWith): oConsole.fOutput( "│ ", COLOR_OK, CHAR_OK, COLOR_NORMAL, " JIT debugger: ", COLOR_INFO, "BugId", COLOR_NORMAL, ".", ) sArguments = xCurrentJITDebuggerCommandLine[ len(sBugIdJITDebuggerCommandLineStartsWith) + 1:] oConsole.fOutput( "│ Arguments: ", COLOR_INFO, sArguments, ) else: oConsole.fOutput( "│ ", COLOR_WARNING, CHAR_WARNING, COLOR_NORMAL, " JIT debugger: ", COLOR_INFO, "Other", COLOR_NORMAL, ".", ) oConsole.fOutput( "│ Command line: ", COLOR_INFO, xCurrentJITDebuggerCommandLine, ) oConsole.fOutput("└", sPadding="─") finally: oConsole.fUnlock()
def fCheckPythonVersion(sApplicationName, asTestedPythonVersions, sBugURL): sPythonVersion = platform.python_version() uMajorVersion, uMinorVersion, uMicroVersion = [ int(s) for s in sPythonVersion.split(".") ] auTestedMajorVersions = set() bRunningInTestedMajorVersion = False bRunningInTestedVersion = False bRunningInOlderVersion = False for sTestedPythonVersion in asTestedPythonVersions: uTestedMajorVersion, uTestedMinorVersion, uTestedMicroVersion = [ int(s) for s in sTestedPythonVersion.split(".") ] auTestedMajorVersions.add(uTestedMajorVersion) if uMajorVersion == uTestedMajorVersion: bRunningInTestedMajorVersion = True if uMinorVersion == uTestedMinorVersion: if uMicroVersion == uTestedMicroVersion: # We are running in a tested Python version. bRunningInTestedVersion = True elif uMicroVersion < uTestedMicroVersion: # This application was tested in a later version, so the version we are running in is outdated. bRunningInOlderVersion = True elif uMinorVersion < uTestedMinorVersion: # This application was tested in a later version, so the version we are running in is outdated. bRunningInOlderVersion = True if not bRunningInTestedMajorVersion: asTestedMayorVersions = sorted(str(u) for u in auTestedMajorVersions) oConsole.fOutput( COLOR_ERROR, CHAR_ERROR, COLOR_NORMAL, " ", sApplicationName, " requires Python version ", faxListOutput(asTestedMayorVersions, "or", asTestedMayorVersions, COLOR_INFO, COLOR_NORMAL), COLOR_NORMAL, ".", ) sys.exit(guExitCodeInternalError) if not bRunningInTestedVersion: oConsole.fLock() try: oConsole.fOutput("┌───[", COLOR_WARNING, " Warning ", COLOR_NORMAL, "]", sPadding="─") oConsole.fOutput( "│ You are running a", "n older" if bRunningInOlderVersion else " newer", " version of Python (", COLOR_INFO, sPythonVersion, COLOR_NORMAL, ") in which this version of", ) oConsole.fOutput( "│ ", COLOR_INFO, sApplicationName, COLOR_NORMAL, " ", "was never tested" if bRunningInOlderVersion else "has not been tested yet", ".", ) oConsole.fOutput( "│ The following Python versions have been tested:", ) oConsole.fOutput( "│ ", faxListOutput(asTestedPythonVersions, "and", asTestedPythonVersions, COLOR_INFO, COLOR_NORMAL), COLOR_NORMAL, ".", ) if bRunningInOlderVersion: oConsole.fOutput( "│ Please update Python to the latest version!", ) else: oConsole.fOutput( "│ Please report this so ", sApplicationName, " can be tested with this version of Python at the following URL:", ) oConsole.fOutput( "│ ", COLOR_INFO | CONSOLE_UNDERLINE, sBugURL, ) oConsole.fOutput("└", sPadding="─") finally: oConsole.fUnlock() elif bRunningInOlderVersion: oConsole.fLock() try: oConsole.fOutput("┌───[", COLOR_WARNING, " Warning ", COLOR_NORMAL, "]", sPadding="─") oConsole.fOutput("│ You are running Python ", COLOR_INFO, sPythonVersion, COLOR_NORMAL, ", which is outdated.") oConsole.fOutput("│ Please update Python to the latest version!") oConsole.fOutput("└", sPadding="─") finally: oConsole.fUnlock()
def fDebug(oSelf, sStatus): if bDebug: oConsole.fOutput("%d/%d/%d %s" % (oSelf.oFileScansStarted.uValue, oSelf.oFileScansFinished.uValue, oSelf.uNumberOfFiles, sStatus))
from fatsArgumentLowerNameAndValue import fatsArgumentLowerNameAndValue; from mColorsAndChars import *; from mExitCodes import *; if __name__ == "__main__": # Parse arguments asFilesAndFoldersPathsAndPatterns = []; sOutputZipFilePath = None; bVerbose = False; for (sArgument, s0LowerName, s0Value) in fatsArgumentLowerNameAndValue(): if s0LowerName in ["-v", "/v", "--verbose", "/verbose"]: bVerbose = True; elif s0LowerName in ["-d", "/d", "--debug", "/debug"]: if m0DebugOutput is None: oConsole.fOutput( COLOR_ERROR, CHAR_ERROR, COLOR_NORMAL, " The mDebugOutput module is not available!", ); sys.exit(guExitCodeBadArgument); m0DebugOutput.fEnableAllDebugOutput(); elif s0LowerName: fExitWithError("Unknown argument \"%s\"" % sArgument); else: asFilesAndFoldersPathsAndPatterns.append(sArgument); if len(asFilesAndFoldersPathsAndPatterns) == 0: oConsole.fOutput( COLOR_ERROR, CHAR_ERROR, COLOR_NORMAL, " Missing input file or folder argument!", ); sys.exit(guExitCodeBadArgument); if len(asFilesAndFoldersPathsAndPatterns) == 1: oConsole.fOutput(
bUnicode = fxProcessBooleanArgument(s0LowerName, s0Value) elif s0LowerName in ["e", "uedit"]: bUseUEditCommandTemplate = fxProcessBooleanArgument( s0LowerName, s0Value) elif s0LowerName in ["t", "tabs"]: xValue = fxProcessBooleanArgument( s0LowerName, s0Value, u0CanAlsoBeAnIntegerLargerThan=0) uConvertTabsToSpaces = xValue if isinstance(xValue, int) else 8 elif s0LowerName in ["l", "lines"]: # valid formats : "C" "-B", "-B+A" "+A" o0BeforeAfterMatch = re.match( r"^(?:(\d+)|(?:\-(\d+))?(?:(?:,|,?\+)(\d+))?)$", s0Value) if s0Value else None if o0BeforeAfterMatch is None: oConsole.fOutput(COLOR_ERROR, CHAR_ERROR, COLOR_NORMAL, " The value for ", COLOR_ERROR, s0LowerName, COLOR_NORMAL, " must be a valid range.") oConsole.fOutput(" Try ", COLOR_INFO, "N", COLOR_NORMAL, ", ", COLOR_INFO, "-N", COLOR_NORMAL, ", ", COLOR_INFO, "-N+N", COLOR_NORMAL, ", or ", COLOR_INFO, "+N", COLOR_NORMAL, ".") oConsole.fOutput( " Where each N is an integer. '-' prefix indicates before, '+' prefix indices after the match." ) sys.exit(guExitCodeBadArgument) suBeforeAndAfer, suBefore, suAfter = o0BeforeAfterMatch.groups( ) if suBeforeAndAfer: uNumberOfRelevantLinesBeforeMatch = uNumberOfRelevantLinesAfterMatch = int( suBeforeAndAfer)
def fbApplyConfigSetting( sSettingName, xValue, sIndentation): # sIndentation is None means no output! asGroupNames = sSettingName.split(".") # last element is not a group name sFullName = ".".join(asGroupNames) sSettingName = asGroupNames.pop() # so pop it. dxConfigGroup = dxConfig asHandledGroupNames = [] for sGroupName in asGroupNames: asHandledGroupNames.append(sGroupName) if sGroupName not in dxConfigGroup: oConsole.fOutput( COLOR_ERROR, "Unknown config group ", COLOR_INFO, ".".join(asHandledGroupNames), COLOR_ERROR, " in setting name ", COLOR_INFO, sFullName, COLOR_ERROR, ".", ) return False dxConfigGroup = dxConfigGroup.get(sGroupName, {}) if sSettingName not in dxConfigGroup: if len(asHandledGroupNames) > 0: oConsole.fOutput( COLOR_ERROR, "Unknown setting name ", COLOR_INFO, sSettingName, COLOR_ERROR, " in config group ", COLOR_INFO, ".".join(asHandledGroupNames), COLOR_ERROR, ".", ) else: oConsole.fOutput( COLOR_ERROR, "Unknown setting name ", COLOR_INFO, sSettingName, COLOR_ERROR, ".", ) return False if repr(dxConfigGroup[sSettingName]) == repr(xValue): if sIndentation is not None: oConsole.fOutput(sIndentation, "* The default value for config setting ", COLOR_HILITE, sFullName, COLOR_NORMAL, \ " is ", COLOR_INFO, repr(dxConfigGroup[sSettingName]), COLOR_NORMAL, ".") else: if sIndentation is not None: oConsole.fOutput(sIndentation, "+ Changed config setting ", COLOR_HILITE, sFullName, COLOR_NORMAL, \ " from ", COLOR_HILITE, repr(dxConfigGroup[sSettingName]), COLOR_NORMAL, " to ", COLOR_INFO, repr(xValue), COLOR_NORMAL, ".") dxConfigGroup[sSettingName] = xValue return True
def fOutputLicenseInformation(bUpdateIfNeeded=False): # Read product details for rs and all modules it uses. aoProductDetails = mProductDetails.faoGetProductDetailsForAllLoadedModules( ) o0MainProductDetails = mProductDetails.fo0GetProductDetailsForMainModule() oConsole.fLock() try: aoLicenses = [] asProductNamesWithoutLicenseRequirement = [] asLicensedProductNames = [] asProductNamesInTrial = [] asUnlicensedProductNames = [] for oProductDetails in aoProductDetails: if not oProductDetails.bRequiresLicense: asProductNamesWithoutLicenseRequirement.append( oProductDetails.sProductName) elif oProductDetails.o0License: if oProductDetails.o0License not in aoLicenses: aoLicenses.append(oProductDetails.o0License) asLicensedProductNames.append(oProductDetails.sProductName) elif oProductDetails.bHasTrialPeriod and oProductDetails.bInTrialPeriod: asProductNamesInTrial.append(oProductDetails.sProductName) else: asUnlicensedProductNames.append(oProductDetails.sProductName) if o0MainProductDetails and o0MainProductDetails.sb0LicenseServerURL is not None: oLicenseServer = mProductDetails.cLicenseServer( o0MainProductDetails.sb0LicenseServerURL) uCheckedLicenseCounter = 0 aoUpdatedLicenses = [] for oLicense in aoLicenses: oConsole.fProgressBar( uCheckedLicenseCounter * 1.0 / len(aoLicenses), "Checking license %s with server..." % oLicense.sLicenseId, ) sLicenseServerError = oLicense.fsCheckWithServerAndGetError( oLicenseServer, bForceCheck=True) sServerURL = str(o0MainProductDetails.sb0LicenseServerURL, "ascii", "strict") if sLicenseServerError: oConsole.fOutput( COLOR_ERROR, CHAR_ERROR, COLOR_NORMAL, " License check for ", COLOR_INFO, oLicense.sLicenseId, COLOR_NORMAL, " on server ", COLOR_INFO, sServerURL, COLOR_NORMAL, " failed:", ) oConsole.fOutput( " ", COLOR_INFO, sLicenseServerError, ) uCheckedLicenseCounter += 1 if oLicense.bMayNeedToBeUpdated and bUpdateIfNeeded: oConsole.fProgressBar( uCheckedLicenseCounter * 1.0 / len(aoLicenses), "Downloading updated license %s from server..." % oLicense.sLicenseId, ) oUpdatedLicense = oLicenseServer.foDownloadUpdatedLicense( oLicense) oConsole.fOutput( COLOR_OK, CHAR_OK, COLOR_NORMAL, " Downloaded updated license ", COLOR_INFO, oLicense.sLicenseId, COLOR_NORMAL, " from server ", COLOR_INFO, str(oLicenseServer.sbServerURL, "ascii", "strict"), COLOR_NORMAL, ".", ) aoUpdatedLicenses.append(oUpdatedLicense) if len(aoUpdatedLicenses) > 0: for oProductDetails in aoProductDetails: if oProductDetails.sb0LicenseServerURL is None: continue # No need for a license == do not store license aoUpdatedLicensesForThisProduct = [ oUpdatedLicense for oUpdatedLicense in aoUpdatedLicenses if oProductDetails.sProductName in oUpdatedLicense.asProductNames ] mProductDetails.fWriteLicensesToProductFolder( aoUpdatedLicensesForThisProduct, oProductDetails) oConsole.fOutput( COLOR_OK, CHAR_OK, COLOR_NORMAL, " Saved ", COLOR_INFO, str(len(aoUpdatedLicensesForThisProduct)), COLOR_NORMAL, " updated license", "" if len(aoUpdatedLicensesForThisProduct) == 1 else "s", " for product ", COLOR_INFO, oProductDetails.sProductName, COLOR_NORMAL, " in folder ", COLOR_INFO, oProductDetails.sInstallationFolderPath, COLOR_NORMAL, ".", ) if f0OutputLogo: f0OutputLogo() oConsole.fOutput( "┌───[", COLOR_HILITE, " License information ", COLOR_NORMAL, "]", sPadding="─", ) if aoLicenses: oConsole.fOutput( "│ ", COLOR_OK, CHAR_OK, COLOR_NORMAL, " This system uses system id ", COLOR_INFO, mProductDetails.fsGetSystemId(), COLOR_NORMAL, " with the license server.", ) oConsole.fOutput( "├", sPadding="─", ) for oLicense in aoLicenses: oConsole.fOutput( "│ ", COLOR_OK, CHAR_OK, COLOR_NORMAL, " License ", COLOR_INFO, oLicense.sLicenseId, COLOR_NORMAL, " covers ", COLOR_INFO, oLicense.sUsageTypeDescription, COLOR_NORMAL, " by ", COLOR_INFO, oLicense.sLicenseeName, COLOR_NORMAL, " of ", COLOR_INFO, oLicense.asProductNames[0], COLOR_NORMAL, " on ", COLOR_INFO, str(oLicense.uLicensedInstances), COLOR_NORMAL, " machine", "s" if oLicense.uLicensedInstances != 1 else "", ".", ) oConsole.fOutput( "│ Covered products: ", faxListOutput(oLicense.asProductNames, "and", oLicense.asProductNames, COLOR_INFO, COLOR_NORMAL, COLOR_NORMAL), COLOR_NORMAL, ".", ) oConsole.fOutput( "│ License source: ", COLOR_INFO, oLicense.sLicenseSource, COLOR_NORMAL, ".", ) if asProductNamesInTrial: oConsole.fOutput( "│ ", COLOR_WARNING, CHAR_WARNING, COLOR_NORMAL, " A ", COLOR_INFO, "trial period", COLOR_NORMAL, " is active for the following product", "s" if len(asProductNamesInTrial) > 1 else "", ":", ) oConsole.fOutput( "│ ", faxListOutput(asProductNamesInTrial, "and", asProductNamesInTrial, COLOR_INFO, COLOR_NORMAL, COLOR_NORMAL), COLOR_NORMAL, ".", ) if asProductNamesWithoutLicenseRequirement: oConsole.fOutput( "│ ", COLOR_OK, CHAR_OK, " ", COLOR_INFO, "No license", COLOR_NORMAL, " is required to use the following product", "s" if len(asProductNamesWithoutLicenseRequirement) > 1 else "", ":", ) oConsole.fOutput( "│ ", faxListOutput(asProductNamesWithoutLicenseRequirement, "and", [], COLOR_INFO, COLOR_NORMAL, COLOR_NORMAL), COLOR_NORMAL, ".", ) if asUnlicensedProductNames: oConsole.fOutput( "│ ", COLOR_ERROR, CHAR_ERROR, COLOR_NORMAL, " ", COLOR_INFO, "No valid license", COLOR_NORMAL, " was found and ", COLOR_INFO, "the trial period has been exceeded", COLOR_NORMAL, " for the following product", "s" if len(asUnlicensedProductNames) > 1 else "", ":", ) oConsole.fOutput( "│ ", faxListOutput(asUnlicensedProductNames, "and", asUnlicensedProductNames, COLOR_INFO, COLOR_NORMAL, COLOR_NORMAL), COLOR_NORMAL, ".", ) (asLicenseErrors, asLicenseWarnings ) = mProductDetails.ftasGetLicenseErrorsAndWarnings() if asLicenseErrors: oConsole.fOutput("├───[", COLOR_ERROR, " Software license error ", COLOR_NORMAL, "]", sPadding="─") for sLicenseError in asLicenseErrors: oConsole.fOutput("│ ", COLOR_ERROR, CHAR_ERROR, COLOR_INFO, " ", sLicenseError) if asLicenseWarnings: oConsole.fOutput("├───[", COLOR_WARNING, " Software license warning ", COLOR_NORMAL, "]", sPadding="─") for sLicenseWarning in asLicenseWarnings: oConsole.fOutput("│ ", COLOR_WARNING, CHAR_WARNING, COLOR_INFO, " ", sLicenseWarning) oConsole.fOutput("└", sPadding="─") finally: oConsole.fUnlock()
def fbInstallAsJITDebugger(asAdditionalArguments): # When BugId gets started as a JIT debugger, we can use the string "%ld" in the arguments twice, which will get # replaced by the process id and the JIT event number, in order. We will add arguments to that effect at the start # of the arument list provided by the user (later). asDefaultArguments = [ # '%' gets escaped to avoid environment variable expansion. However, here we do want a '%' in the command line. # We can use '%%' to do so '%': "--pid=%%ld", "--handle-jit-event=%%ld", ]; # To prevent the user from accidentally providing these arguments themselves, we scan the arguments provided by the # user for for these and report an error and return false if we find them. We will also check if the user has provided # a report folder path. s0BugIdReportsFolder = dxConfig["sReportFolderPath"]; for sArgument in asAdditionalArguments: if sArgument.startswith("--") and "=" in sArgument: (sName, sValue) = sArgument[2:].split("="); if sName in ["pid", "pids", "handle-jit-event"]: oConsole.fOutput( COLOR_ERROR, CHAR_ERROR, COLOR_NORMAL, " You cannot use ", COLOR_INFO, sArgument, COLOR_NORMAL, " in combination with ", COLOR_INFO, "-I", COLOR_NORMAL, " in the arguments.", ); return False; if sName in ["report", "reports", "report-folder", "reports-folder", "report-folder-path", "reports-folder-path", "sReportFolderPath"]: s0BugIdReportsFolder = sValue; # By default the python process hosting BugId will be run in the Windows System32 folder. We cannot save bug # reports there. To make sure we will save bug reports somewhere we can write and where the user will likely find # them, we will add an argument if s0BugIdReportsFolder is None: sBugIdReportsFolder = "%s\\BugId reports" % os.getenv("USERPROFILE"); asDefaultArguments.append("--reports=%s" % sBugIdReportsFolder); else: sBugIdReportsFolder = s0BugIdReportsFolder; sBugIdCommandLine = fsCreateBugIdCommandLine( asDefaultArguments + asAdditionalArguments ); oRegistryHiveKey = mRegistry.cRegistryHiveKey( sHiveName = mJITDebuggerRegistry.sComandLineHiveName, sKeyPath = mJITDebuggerRegistry.sComandLineKeyPath, ); oConsole.fStatus("* Installing as JIT debugger..."); bSettingsChanged = False; for (sName, sValue) in { "Auto": "1", "Debugger": sBugIdCommandLine }.items(): # Check if the value is already set correctly: o0RegistryValue = oRegistryHiveKey.fo0GetValueForName(sValueName = "Debugger"); if o0RegistryValue and o0RegistryValue.sTypeName == "REG_SZ" and o0RegistryValue.xValue == sValue: continue; # Yes; no need to modify it. try: oRegistryHiveKey.foSetValueForName(sValueName = sName, sTypeName = "SZ", xValue = sValue); except WindowsError as oException: if oException.winerror == 5: oConsole.fOutput( COLOR_ERROR, CHAR_ERROR, COLOR_NORMAL, " BugId cannot be installed as the default JIT debugger."); oConsole.fOutput(" Access to the relevant registry keys is denied."); oConsole.fOutput(" Please try again with ", COLOR_INFO, "elevated priviledges", COLOR_NORMAL, "."); return False; raise; bSettingsChanged = True; oConsole.fOutput( COLOR_OK, CHAR_OK, COLOR_NORMAL, " BugId is ", "already" if bSettingsChanged else "now", " installed as the default JIT debugger."); oConsole.fOutput(" Command line: ", COLOR_INFO, sBugIdCommandLine); oConsole.fOutput(" Reports folder: ", COLOR_INFO, sBugIdReportsFolder); return True;
def fOutputApplicationKeyWordHelp(sApplicationKeyword, dxApplicationSettings): oConsole.fLock(); try: oConsole.fOutput("Known application settings for ", COLOR_INFO, sApplicationKeyword); if "sBinaryPath" in dxApplicationSettings: sBinaryPath = dxApplicationSettings["sBinaryPath"]; if sBinaryPath is None: oConsole.fOutput( COLOR_WARNING, CHAR_WARNING, COLOR_NORMAL, " The application cannot be found on your system.", ); else: oConsole.fOutput(" Binary path: ", COLOR_INFO, sBinaryPath); elif "dxUWPApplication" in dxApplicationSettings: dxUWPApplication = dxApplicationSettings["dxUWPApplication"]; oConsole.fOutput(" UWP Application information:"); oConsole.fOutput(" Package name: ", COLOR_INFO, dxUWPApplication["sPackageName"]); oConsole.fOutput(" Id: ", COLOR_INFO, dxUWPApplication["sId"]); if "asApplicationAttachToProcessesForExecutableNames" in dxApplicationSettings: asApplicationAttachToProcessesForExecutableNames = dxApplicationSettings["asApplicationAttachToProcessesForExecutableNames"]; oConsole.fOutput(" Attach to additional processes running any of the following binaries:"); for sBinaryName in asApplicationAttachToProcessesForExecutableNames: oConsole.fOutput(" ", COLOR_INFO, sBinaryName); if "fasGetStaticArguments" in dxApplicationSettings: fasGetApplicationStaticArguments = dxApplicationSettings["fasGetStaticArguments"]; asApplicationStaticArguments = fasGetApplicationStaticArguments(bForHelp = True); oConsole.fOutput(" Default static arguments:"); oConsole.fOutput(" ", COLOR_INFO, " ".join(asApplicationStaticArguments)); if "fasGetOptionalArguments" in dxApplicationSettings: fasGetOptionalArguments = dxApplicationSettings["fasGetOptionalArguments"]; asApplicationOptionalArguments = fasGetOptionalArguments(bForHelp = True); oConsole.fOutput(" Default optional arguments:"); oConsole.fOutput(" ", COLOR_INFO, " ".join(asApplicationOptionalArguments)); if "dxConfigSettings" in dxApplicationSettings: dxApplicationConfigSettings = dxApplicationSettings["dxConfigSettings"]; if dxApplicationConfigSettings: oConsole.fOutput(" Application specific settings:"); for sSettingName, xValue in dxApplicationConfigSettings.items(): oConsole.fOutput(" ", COLOR_INFO, sSettingName, COLOR_NORMAL, ": ", COLOR_INFO, json.dumps(xValue)); finally: oConsole.fUnlock();
def fEdgeCleanup(): # RuntimeBroker.exe can apparently hang with dbgsrv.exe attached, preventing Edge from opening new pages. Killing # all processes running either exe appears to resolve this issue. for uProcessId in fauProcessesIdsForExecutableNames( ["dbgsrv.exe", "RuntimeBroker.exe"]): fbTerminateForProcessId(uProcessId) # Delete the recovery path to prevent conserving state between different runs of the application. if not oEdgeRecoveryFolder.fbIsFolder(): return if oEdgeRecoveryFolder.fbDelete(): return # Microsoft Edge will have a lock on these files if its running; terminate it. oConsole.fOutput( COLOR_WARNING, CHAR_WARNING, COLOR_NORMAL, " Microsoft Edge appears to be running because the recovery files cannot be" ) oConsole.fOutput( " deleted. All running Microsoft Edge processes will now be terminated to try" ) oConsole.fOutput(" to fix this...") # Microsoft Edge may attempt to restart killed processes, so we do this in a loop until there are no more processes # running. while 1: auProcessIds = fauProcessesIdsForExecutableNames(["msedge.exe"]) if not auProcessIds: break for uProcessId in auProcessIds: fbTerminateForProcessId(uProcessId) if oEdgeRecoveryFolder.fbDelete(): return oConsole.fOutput( COLOR_ERROR, CHAR_ERROR, COLOR_NORMAL, " The recovery files still cannot be deleted. Please manually terminated all" ) oConsole.fOutput( " processes related to Microsoft Edge and try to delete everything in" ) oConsole.fOutput(" ", COLOR_INFO, oEdgeRecoveryFolder.sPath, COLOR_NORMAL, ".") sys.exit(guExitCodeInternalError)
def fiCollateralInteractiveAskForValue(uProcessId, uThreadId, sInstruction, a0txRegisters, sDestination, i0CurrentValue, u0OriginalValue, iMinValue, iMaxValue, iSuggestedValue): fAssertTypes({ "uProcessId": (uProcessId, int), "uThreadId": (uThreadId, int), "sInstruction": (sInstruction, str), "a0txRegisters": (a0txRegisters, [tuple], None), "sDestination": (sDestination, str), "i0CurrentValue": (i0CurrentValue, int, None), "u0OriginalValue": (u0OriginalValue, int, None), "iMinValue": (iMinValue, int), "iMaxValue": (iMaxValue, int), "iSuggestedValue": (iSuggestedValue, int), }) def fsValueToString(iValue): return ("-" if iValue < 0 else "") + ("0x%X" % abs(iValue)) oConsole.fOutput( COLOR_NORMAL, " The exception happened in process ", COLOR_INFO, "%d" % uProcessId, COLOR_NORMAL, "/", COLOR_INFO, "0x%X" % uProcessId, COLOR_NORMAL, ", thread ", COLOR_INFO, "%d" % uThreadId, COLOR_NORMAL, "/", COLOR_INFO, "0x%X" % uThreadId, COLOR_NORMAL, ".", ) if a0txRegisters is None: oConsole.fOutput( COLOR_NORMAL, " The values of the register at the time of the exception could not be determined.", ) else: oConsole.fOutput(COLOR_NORMAL, " Register values at the time of the exception:") for (sbRegisterName, uRegisterValue, uBitSize, s0Details) in a0txRegisters: sRegisterValueHex = "%X" % uRegisterValue oConsole.fOutput( COLOR_NORMAL, " ", COLOR_INFO, str(sbRegisterName, "ascii", "strict").ljust(6), COLOR_NORMAL, " = ", COLOR_DIM, "0" * ((uBitSize >> 2) - len(sRegisterValueHex)), COLOR_INFO, sRegisterValueHex, [] if s0Details is None else [ COLOR_NORMAL, " => ", COLOR_INFO, s0Details, ], ) oConsole.fOutput(COLOR_NORMAL, " The instruction that triggered the exception:") oConsole.fOutput( COLOR_NORMAL, " ", COLOR_INFO, sInstruction, ) oConsole.fOutput( COLOR_INFO, CHAR_INFO, COLOR_NORMAL, " This bug can be ignore by skipping over the instruction that caused the exception.", ) oConsole.fOutput( COLOR_NORMAL, " In order to do this, you must provide a value for ", COLOR_INFO, sDestination, [ COLOR_NORMAL, " (current value: ", COLOR_INFO, fsValueToString(i0CurrentValue), COLOR_NORMAL, ")", ] if i0CurrentValue is not None else [], ".", ) if u0OriginalValue is not None: iDefaultValue = u0OriginalValue oConsole.fOutput( COLOR_NORMAL, " It would be set to ", COLOR_INFO, fsValueToString(u0OriginalValue), COLOR_NORMAL, " if the instruction had succeeded (the default), but you can set it to ", COLOR_INFO, fsValueToString(iSuggestedValue), COLOR_NORMAL, " to poison the value.", ) else: iDefaultValue = iSuggestedValue oConsole.fOutput( COLOR_NORMAL, " It is suggested you set it to ", COLOR_INFO, fsValueToString(iSuggestedValue), COLOR_NORMAL, " to poison the value (the default).", ) oConsole.fOutput( COLOR_NORMAL, " The value must be between ", COLOR_INFO, fsValueToString(iMinValue), COLOR_NORMAL, " and ", COLOR_INFO, fsValueToString(iMaxValue), COLOR_NORMAL, ".", ) while 1: # Loop until the user accepts the suggested value, or enters a valid value. oConsole.fStatus( COLOR_NORMAL, " ", COLOR_INFO, sDestination, COLOR_NORMAL, " (", fsValueToString(iDefaultValue), ") > ", ) sValue = input().strip() if sValue == "": return iDefaultValue iSignMultiplier = -1 if sValue[0] == "-" else 1 sValue = sValue.lstrip("-") try: if sValue.lower().startswith("0x"): uValue = int(sValue[2:], 16) else: uValue = int(sValue) except ValueError: oConsole.fOutput( COLOR_NORMAL, " ", COLOR_ERROR, CHAR_ERROR, COLOR_NORMAL, " That is not a valid value!", ) else: iValue = iSignMultiplier * uValue if iMinValue <= iValue <= iMaxValue: return iValue oConsole.fOutput( COLOR_NORMAL, " ", COLOR_ERROR, CHAR_ERROR, COLOR_NORMAL, " That value is outside the valid range!", )