def foCreate(cSelf, oCrashInfo, oProcess, uCode, sCodeDescription): asExceptionRecord = oCrashInfo._fasSendCommandAndReadOutput(".exr -1"); oSelf = cSelf(oProcess, uCode, sCodeDescription, asExceptionRecord); if not oCrashInfo._bCdbRunning: return None; uParameterCount = None; uParameterIndex = None; for sLine in asExceptionRecord: oNameValueMatch = re.match(r"^\s*%s\s*$" % ( r"(\w+)(?:\[(\d+)\])?\:\s+" # (name) optional{ "[" (index) "]" } ":" whitespace r"([0-9A-F`]+)" # (value) r"(?:\s+\((.*)\))?" # optional{ whitespace "(" (symbol || description) ")" } ), sLine, re.I); if oNameValueMatch: sName, sIndex, sValue, sDetails = oNameValueMatch.groups(); uValue = int(sValue.replace("`", ""), 16); if sName == "ExceptionAddress": oSelf.uAddress = uValue; oSelf.sAddressSymbol = sDetails; elif sName == "ExceptionCode": assert uValue == uCode, \ "Exception record has an unexpected ExceptionCode value (0x%08X vs 0x%08X)" % (uValue, uCode); assert sDetails is None or sDetails == sCodeDescription, \ "Exception record has an unexpected ExceptionCode description (%s vs %s)" % \ (repr(sDetails), repr(sCodeDescription)); elif sName == "ExceptionFlags": oSelf.uFlags = uValue; elif sName == "NumberParameters": uParameterCount = uValue; uParameterIndex = 0; oSelf.auParameters = []; elif sName == "Parameter": assert int(sIndex, 16) == uParameterIndex, \ "Unexpected parameter #0x%s vs 0x%X" % (sIndex, uParameterIndex); oSelf.auParameters.append(uValue); uParameterIndex += 1; else: raise AssertionError("Unknown exception record value %s" % sLine); elif oSelf.sDetails is None: oSelf.sDetails = sLine; else: raise AssertionError("Superfluous exception record line %s" % sLine); assert oSelf.uAddress is not None, \ "Exception record is missing an ExceptionAddress value"; assert oSelf.uFlags is not None, \ "Exception record is missing an ExceptionFlags value"; assert uParameterCount is not None, \ "Exception record is missing an NumberParameters value"; assert uParameterCount == len(oSelf.auParameters), \ "Unexpected number of parameters (%d vs %d)" % (len(oSelf.auParameters), uParameterCount); # Now handle the information in the exception record to create an exception id that uniquely identifies the # type of exception and a description of the exception. cException_fSetTypeId(oSelf); oSelf.sDescription = "%s (code 0x%08X)" % (sCodeDescription, uCode); cException_fSetSecurityImpact(oSelf); return oSelf;
def foCreate(cSelf, oCdbWrapper, oProcess, pAddresses): pFirstAddress = oCdbWrapper.fuEvaluateExpression("poi(0x%X)" % pAddresses); asData = oCdbWrapper.fasSendCommandAndReadOutput("dd /c0xA @@masm(poi(0x%X)) L0xA" % pFirstAddress); # https://msdn.microsoft.com/en-us/library/windows/desktop/dn600343%28v=vs.85%29.aspx # https://msdn.microsoft.com/en-us/library/windows/desktop/dn600342%28v=vs.85%29.aspx #StowedExceptionInformation = { # 0000 DWORD dsSize # 0004 char[4] sSignature // "SE01" or "SE02" # 0008 HRESULT hResultCode # 000C :2 bits ExceptionForm // LSB, &3 1 => with exception address and call stack, 2 => with error text # :30 bits ThreadId // MSB, &0xfffffffc # { # 0010 VOID* pExceptionAddress # 0014 DWORD dwStackTraceWordSize (4) # 0018 DWORD StackTraceWords # 001c VOID* pStackTrace # } or { # 0010 WCHAR* sErrorText # } # 0020 ULONG NestedExceptionType; // "SE02" only # 0024 VOID* NestedException; // "SE02" only #} adwData = []; for sLine in asData: asData = re.split(r"\s+", sLine); asData.pop(0); # first value is address, the rest is data adwData.extend([int(sData, 16) for sData in asData]); assert len(adwData) == 10, "Unexpected data size %d extracted from %s" % (len(adwData), repr(asLines)); dwSignature = adwData[1]; assert dwSignature in [0x53453031, 0x53453032], "Unexpected signature 0x%X" % dwSignature; uCode = adwData[2]; uExceptionForm = adwData[3] & 3; assert uExceptionForm in [1, 2], "Unexpected exception form %d" % uExceptionForm; if uExceptionForm == 1: oStowedException = cSelf(oProcess, uCode, uAddress = adwData[4], pStackTrace = adwData[7], uStackTraceSize = adwData[6]); else: oStowedException = cSelf(oProcess, uCode, sErrorText = adwData[4]); uNestedExceptionType = adwData[8]; assert dwSignature == 0x53453031 or uNestedExceptionType == 0, "Unexpected nested exception type 0x%X" % adwData[8]; # Create an exception id that uniquely identifies the exception and a description of the exception. cException_fSetTypeId(oStowedException); oStowedException.sTypeId += "(Stowed)"; oStowedException.sDescription = "Stowed exception code 0x%08X" % oStowedException.uCode; cException_fSetSecurityImpact(oStowedException); return oStowedException;
def foCreate(cException, oCdbWrapper, oProcess, uCode, sCodeDescription): if dxBugIdConfig["bEnhancedSymbolLoading"]: # Turn noisy symbol loading off as it mixes with the stack output and makes it unparsable asOutput = oCdbWrapper.fasSendCommandAndReadOutput(".symopt- 0x80000000"); if not oCdbWrapper.bCdbRunning: return None; asExceptionRecord = oCdbWrapper.fasSendCommandAndReadOutput(".exr -1"); oException = cException(oProcess, uCode, sCodeDescription, asExceptionRecord); if not oCdbWrapper.bCdbRunning: return None; if dxBugIdConfig["bEnhancedSymbolLoading"]: # Turn noisy symbol loading back on oCdbWrapper.fasSendCommandAndReadOutput(".symopt+ 0x80000000"); if not oCdbWrapper.bCdbRunning: return None; # Sample output: # |ExceptionAddress: 00007ff6b0f81204 (Tests_x64!fJMP+0x0000000000000004) # | ExceptionCode: c0000005 (Access violation) # | ExceptionFlags: 00000000 # |NumberParameters: 2 # | Parameter[0]: 0000000000000000 # | Parameter[1]: ffffffffffffffff # |Attempt to read from address ffffffffffffffff uParameterCount = None; uParameterIndex = None; for sLine in asExceptionRecord: oNameValueMatch = re.match(r"^\s*%s\s*$" % ( r"(\w+)(?:\[(\d+)\])?\:\s+" # (name) optional{ "[" (index) "]" } ":" whitespace r"([0-9A-F`]+)" # (value) r"(?:\s+\((.*)\))?" # optional{ whitespace "(" (symbol || description) ")" } ), sLine, re.I); if oNameValueMatch: sName, sIndex, sValue, sDetails = oNameValueMatch.groups(); uValue = long(sValue.replace("`", ""), 16); if sName == "ExceptionAddress": oException.uAddress = uValue; oException.sAddressSymbol = sDetails; elif sName == "ExceptionCode": assert uValue == uCode, \ "Exception record has an unexpected ExceptionCode value (0x%08X vs 0x%08X)\r\n%s" % \ (uValue, uCode, "\r\n".join(asExceptionRecord)); assert sDetails is None or sDetails == sCodeDescription, \ "Exception record has an unexpected ExceptionCode description (%s vs %s)\r\n%s" % \ (repr(sDetails), repr(sCodeDescription), "\r\n".join(asExceptionRecord)); elif sName == "ExceptionFlags": oException.uFlags = uValue; elif sName == "NumberParameters": uParameterCount = uValue; uParameterIndex = 0; oException.auParameters = []; elif sName == "Parameter": assert long(sIndex, 16) == uParameterIndex, \ "Unexpected parameter #0x%s vs 0x%X\r\n%s" % (sIndex, uParameterIndex, "\r\n".join(asExceptionRecord)); oException.auParameters.append(uValue); uParameterIndex += 1; else: raise AssertionError("Unknown exception record value %s\r\n%s" % (sLine, "\r\n".join(asExceptionRecord))); elif oException.sDetails is None: oException.sDetails = sLine; else: raise AssertionError("Superfluous exception record line %s\r\n%s" % (sLine, "\r\n".join(asExceptionRecord))); assert oException.uAddress is not None, \ "Exception record is missing an ExceptionAddress value\r\n%s" % "\r\n".join(asExceptionRecord); assert oException.uFlags is not None, \ "Exception record is missing an ExceptionFlags value\r\n%s" % "\r\n".join(asExceptionRecord); assert uParameterCount is not None, \ "Exception record is missing an NumberParameters value\r\n%s" % "\r\n".join(asExceptionRecord); assert uParameterCount == len(oException.auParameters), \ "Unexpected number of parameters (%d vs %d)" % (len(oException.auParameters), uParameterCount); # Now handle the information in the exception record to create an exception id that uniquely identifies the # type of exception and a description of the exception. cException_fSetTypeId(oException); oException.sDescription = "%s (code 0x%08X)" % (sCodeDescription, uCode); cException_fSetSecurityImpact(oException); return oException;
def foCreate(cException, oCdbWrapper, oProcess, uCode, sCodeDescription): if dxBugIdConfig["bEnhancedSymbolLoading"]: # Turn noisy symbol loading off as it mixes with the stack output and makes it unparsable asOutput = oCdbWrapper.fasSendCommandAndReadOutput( ".symopt- 0x80000000") if not oCdbWrapper.bCdbRunning: return None asExceptionRecord = oCdbWrapper.fasSendCommandAndReadOutput(".exr -1") oException = cException(oProcess, uCode, sCodeDescription, asExceptionRecord) if not oCdbWrapper.bCdbRunning: return None if dxBugIdConfig["bEnhancedSymbolLoading"]: # Turn noisy symbol loading back on oCdbWrapper.fasSendCommandAndReadOutput(".symopt+ 0x80000000") if not oCdbWrapper.bCdbRunning: return None # Sample output: # |ExceptionAddress: 00007ff6b0f81204 (Tests_x64!fJMP+0x0000000000000004) # | ExceptionCode: c0000005 (Access violation) # | ExceptionFlags: 00000000 # |NumberParameters: 2 # | Parameter[0]: 0000000000000000 # | Parameter[1]: ffffffffffffffff # |Attempt to read from address ffffffffffffffff uParameterCount = None uParameterIndex = None for sLine in asExceptionRecord: oNameValueMatch = re.match( r"^\s*%s\s*$" % ( r"(\w+)(?:\[(\d+)\])?\:\s+" # (name) optional{ "[" (index) "]" } ":" whitespace r"([0-9A-F`]+)" # (value) r"(?:\s+\((.*)\))?" # optional{ whitespace "(" (symbol || description) ")" } ), sLine, re.I) if oNameValueMatch: sName, sIndex, sValue, sDetails = oNameValueMatch.groups() uValue = long(sValue.replace("`", ""), 16) if sName == "ExceptionAddress": oException.uAddress = uValue oException.sAddressSymbol = sDetails elif sName == "ExceptionCode": assert uValue == uCode, \ "Exception record has an unexpected ExceptionCode value (0x%08X vs 0x%08X)\r\n%s" % \ (uValue, uCode, "\r\n".join(asExceptionRecord)) assert sDetails is None or sDetails == sCodeDescription, \ "Exception record has an unexpected ExceptionCode description (%s vs %s)\r\n%s" % \ (repr(sDetails), repr(sCodeDescription), "\r\n".join(asExceptionRecord)) elif sName == "ExceptionFlags": oException.uFlags = uValue elif sName == "NumberParameters": uParameterCount = uValue uParameterIndex = 0 oException.auParameters = [] elif sName == "Parameter": assert long(sIndex, 16) == uParameterIndex, \ "Unexpected parameter #0x%s vs 0x%X\r\n%s" % (sIndex, uParameterIndex, "\r\n".join(asExceptionRecord)) oException.auParameters.append(uValue) uParameterIndex += 1 else: raise AssertionError( "Unknown exception record value %s\r\n%s" % (sLine, "\r\n".join(asExceptionRecord))) elif oException.sDetails is None: oException.sDetails = sLine else: raise AssertionError( "Superfluous exception record line %s\r\n%s" % (sLine, "\r\n".join(asExceptionRecord))) assert oException.uAddress is not None, \ "Exception record is missing an ExceptionAddress value\r\n%s" % "\r\n".join(asExceptionRecord) assert oException.uFlags is not None, \ "Exception record is missing an ExceptionFlags value\r\n%s" % "\r\n".join(asExceptionRecord) assert uParameterCount is not None, \ "Exception record is missing an NumberParameters value\r\n%s" % "\r\n".join(asExceptionRecord) assert uParameterCount == len(oException.auParameters), \ "Unexpected number of parameters (%d vs %d)" % (len(oException.auParameters), uParameterCount) # Now handle the information in the exception record to create an exception id that uniquely identifies the # type of exception and a description of the exception. cException_fSetTypeId(oException) oException.sDescription = "%s (code 0x%08X)" % (sCodeDescription, uCode) cException_fSetSecurityImpact(oException) return oException