def foCreate(cSelf, oCrashInfo, oProcess, pAddress): asData = oCrashInfo._fasSendCommandAndReadData("dd /c0xA @@masm(poi(0x%X)) L0xA" % pAddress); # 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: oSelf = cSelf(oProcess, uCode, uAddress = adwData[4], pStackTrace = adwData[7], uStackTraceSize = adwData[6]); else: oSelf = 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. oSelf.sTypeId = "%s(Stowed)" + fsGetExceptionTypeId(oSelf.uCode); oSelf.sDescription = "Stowed exception code 0x%08X" % oSelf.uCode; # Get the stack oSelf.oStack = cStack.foCreateFromAddress(oCrashInfo, oProcess, oSelf.pStackTrace, oSelf.uStackTraceSize); if oSelf.oStack is None: return None; return oSelf;
def cBugReport_foAnalyzeException_STATUS_STOWED_EXCEPTION( oBugReport, oCdbWrapper, oException): # Parameter[0] = paStowedExceptionInformationArray; # Parameter[1] = uStowedExceptionInformationArrayLength; assert len(oException.auParameters) == 2, \ "Unexpected number of WinRT language exception parameters (%d vs 2)" % len(oException.auParameters) pStowedExceptionsAddresses = oException.auParameters[0] uStowedExceptionsCount = oException.auParameters[1] assert uStowedExceptionsCount <= 1, \ "Unexpected number of WinRT language exception stowed exceptions (%d vs 1)" % uStowedExceptionsCount # Get the stowed exception and replace information in the bug report: oStowedException = cStowedException.foCreate(oCdbWrapper, pStowedExceptionsAddresses) oBugReport.sBugTypeId = oStowedException.sTypeId oBugReport.sBugDescription = oStowedException.sDescription oBugReport.sSecurityImpact = oStowedException.sSecurityImpact oBugReport.oProcess = cProcess.foCreate(oCdbWrapper) oBugReport.oStack = cStack.foCreateFromAddress( oCdbWrapper, oStowedException.pStackTrace, oStowedException.uStackTraceSize) return oBugReport
def foGetStack(oStowedException, oCdbWrapper): # This is not going to chance, so we can cache it: if not hasattr(oStowedException, "oStack"): # We may need to change the current process to oStowedException.oProcess, but I'm not sure. oStowedException.oStack = cStack.foCreateFromAddress(oCdbWrapper, oStowedException.pStackTrace, oStowedException.uStackTraceSize); return oStowedException.oStack;
def foCreate(cSelf, oCrashInfo, oProcess, pAddress): asData = oCrashInfo._fasSendCommandAndReadData( "dd /c0xA @@masm(poi(0x%X)) L0xA" % pAddress) # 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: oSelf = cSelf(oProcess, uCode, uAddress=adwData[4], pStackTrace=adwData[7], uStackTraceSize=adwData[6]) else: oSelf = 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. oSelf.sTypeId = "%s(Stowed)" + fsGetExceptionTypeId(oSelf.uCode) oSelf.sDescription = "Stowed exception code 0x%08X" % oSelf.uCode # Get the stack oSelf.oStack = cStack.foCreateFromAddress(oCrashInfo, oProcess, oSelf.pStackTrace, oSelf.uStackTraceSize) if oSelf.oStack is None: return None return oSelf
def foGetStack(oSelf, oCrashInfo): # This is not going to chance, so we can cache it: if not hasattr(oSelf, "oStack"): oSelf.oStack = cStack.foCreateFromAddress(oCrashInfo, oSelf.oProcess, oSelf.pStackTrace, oSelf.uStackTraceSize); return oSelf.oStack;