private void ExtractThreadRegisters(CIThread aThread) { CIThreadRegisterListCollection threadRegs = aThread.Registers; CIRegisterList regListUser = threadRegs[TArmRegisterBank.ETypeUser]; CIRegisterList regListEXC = threadRegs[TArmRegisterBank.ETypeException]; CIRegisterList regListCOP = threadRegs[TArmRegisterBank.ETypeCoProcessor]; CIRegisterList regListSVC = threadRegs[TArmRegisterBank.ETypeSupervisor]; #region User registers foreach (string line in iData[DExcExtractorListType.EListRegistersUser]) { Match m = EM.RegistersUserSet.Match(line); if (m.Success) { GroupCollection groups = m.Groups; int firstReg = int.Parse(groups[1].Value); for (int i = firstReg; i < firstReg + 4; i++) { Group gp = groups[2 + (i - firstReg)]; uint value = uint.Parse(gp.Value, System.Globalization.NumberStyles.HexNumber); TArmRegisterType regType = (TArmRegisterType)i; regListUser[regType].Value = value; } } else { m = EM.RegistersUserCPSR.Match(line); if (m.Success) { // Get CPSR value and set it uint cpsrValue = uint.Parse(m.Groups[1].Value, System.Globalization.NumberStyles.HexNumber); threadRegs.CPSR = cpsrValue; } } } #endregion #region Exception registers foreach (string line in iData[DExcExtractorListType.EListRegistersException]) { Match m = EM.RegistersExceptionSet1.Match(line); if (m.Success) { GroupCollection groups = m.Groups; // regListEXC[TArmRegisterType.EArmReg_EXCCODE].Value = uint.Parse(m.Groups[1].Value, System.Globalization.NumberStyles.HexNumber); regListEXC[TArmRegisterType.EArmReg_EXCPC].Value = uint.Parse(m.Groups[2].Value, System.Globalization.NumberStyles.HexNumber); // regListCOP[TArmRegisterType.EArmReg_FAR].Value = uint.Parse(m.Groups[3].Value, System.Globalization.NumberStyles.HexNumber); regListCOP[TArmRegisterType.EArmReg_FSR].Value = uint.Parse(m.Groups[4].Value, System.Globalization.NumberStyles.HexNumber); if (regListEXC.Contains(TArmRegisterType.EArmReg_EXCCODE)) { CIRegister reg = regListEXC[TArmRegisterType.EArmReg_EXCCODE]; System.Diagnostics.Debug.Assert(reg is CIRegisterExcCode); CIRegisterExcCode excReg = (CIRegisterExcCode)reg; // excReg.ExpandToFullExceptionRange(); } // It also means it was an exception aThread.ExitInfo.Type = CrashItemLib.Crash.ExitInfo.CIExitInfo.TExitType.EExitTypeException; } else { m = EM.RegistersExceptionSet2.Match(line); if (m.Success) { GroupCollection groups = m.Groups; // regListSVC[TArmRegisterType.EArmReg_SP].Value = uint.Parse(m.Groups[1].Value, System.Globalization.NumberStyles.HexNumber); regListSVC[TArmRegisterType.EArmReg_LR].Value = uint.Parse(m.Groups[2].Value, System.Globalization.NumberStyles.HexNumber); regListSVC[TArmRegisterType.EArmReg_SPSR].Value = uint.Parse(m.Groups[3].Value, System.Globalization.NumberStyles.HexNumber); } } } #endregion }
public override void Check(CIContainer aContainer) { CISummarisableEntityList list = aContainer.Summaries; foreach (CISummarisableEntity entry in list) { // Check that each stack contains some registers and at least the SP. bool stackAvailable = entry.IsAvailable(CISummarisableEntity.TElement.EElementStack); bool regsAvailable = entry.IsAvailable(CISummarisableEntity.TElement.EElementRegisters); // if (stackAvailable) { CIStack stack = entry.Stack; // if (regsAvailable) { CIRegisterList regs = stack.Registers; // Check that SP, LR and PC are available bool pointerAvailable = regs.Contains(TArmRegisterType.EArmReg_SP); if (!pointerAvailable) { base.CreateWarning(aContainer, stack, LibResources.CIPDRegAvailability_MissingSP_Title, string.Format(LibResources.CIPDRegAvailability_MissingSP_Description, base.CreateIdentifierText(entry)) ); } // bool lrAvailable = regs.Contains(TArmRegisterType.EArmReg_LR); if (!lrAvailable) { base.CreateWarning(aContainer, stack, LibResources.CIPDRegAvailability_MissingLR_Title, string.Format(LibResources.CIPDRegAvailability_MissingLR_Description, base.CreateIdentifierText(entry)) ); } // bool pcAvailable = regs.Contains(TArmRegisterType.EArmReg_PC); if (!pcAvailable) { base.CreateWarning(aContainer, stack, LibResources.CIPDRegAvailability_MissingPC_Title, string.Format(LibResources.CIPDRegAvailability_MissingPC_Description, base.CreateIdentifierText(entry)) ); } // If R0 is available, check if it is 0 and check whether an exception occurred - if so, it was possibly // caused by de-referencing a NULL this pointer. bool threadAvailable = entry.IsAvailable(CISummarisableEntity.TElement.EElementThread); if (threadAvailable) { if (regs.Contains(TArmRegisterType.EArmReg_00)) { CIRegister r0 = regs[TArmRegisterType.EArmReg_00]; // bool r0WasNull = (r0.Value == 0); bool wasException = entry.IsAbnormalTermination && (entry.Thread.ExitInfo.Type == CrashItemLib.Crash.ExitInfo.CIExitInfo.TExitType.EExitTypeException); bool wasKernExec3 = entry.IsAbnormalTermination && (entry.Thread.ExitInfo.Type == CrashItemLib.Crash.ExitInfo.CIExitInfo.TExitType.EExitTypePanic && entry.Thread.ExitInfo.Category.ToUpper() == "KERN-EXEC" && entry.Thread.ExitInfo.Reason == 3); // if (r0WasNull && (wasException || wasKernExec3)) { base.CreateWarning(aContainer, r0, LibResources.CIPDRegAvailability_NullThisPointer_Title, string.Format(LibResources.CIPDRegAvailability_NullThisPointer_Description, base.CreateIdentifierText(entry)) ); } } } } else { base.CreateWarning(aContainer, stack, LibResources.CIPDRegAvailability_NoRegsForStack_Title, string.Format(LibResources.CIPDRegAvailability_NoRegsForStack_Description, base.CreateIdentifierText(entry)) ); } } } }