private void ReadMethodDataSections(BinaryReader assemblyReader) { bool moreSections = true; byte moreSectionsValue = (byte)CorILMethodSect.CorILMethod_Sect_MoreSects; byte fatFormatValue = (byte)CorILMethodSect.CorILMethod_Sect_FatFormat; byte exceptionHandlingTableValue = (byte)CorILMethodSect.CorILMethod_Sect_EHTable; while (moreSections) { int bytesToRead = Convert.ToInt32(assemblyReader.BaseStream.Position % 4); if (bytesToRead > 0) { assemblyReader.ReadBytes(4 - bytesToRead); } byte kind = assemblyReader.ReadByte(); if ((kind & exceptionHandlingTableValue) != exceptionHandlingTableValue) { throw new NotImplementedException("The method data section is not an exception handling table."); } moreSections = ((kind & moreSectionsValue) == moreSectionsValue); int dataSize = 0; int clauseNumber = 0; bool fatFormat = ((kind & fatFormatValue) == fatFormatValue); if (fatFormat) { dataSize = assemblyReader.ReadByte() + assemblyReader.ReadByte() * 0x100 + assemblyReader.ReadByte() * 0x10000; clauseNumber = dataSize / 24; } else { dataSize = assemblyReader.ReadByte(); //Read padding. assemblyReader.ReadBytes(2); clauseNumber = dataSize / 12; } for (int clauseIndex = 0; clauseIndex < clauseNumber; clauseIndex++) { NuGenExceptionClause clause = new NuGenExceptionClause(); if (fatFormat) { clause.Flags = (CorExceptionFlag)assemblyReader.ReadUInt32(); clause.TryOffset = assemblyReader.ReadUInt32(); clause.TryLength = assemblyReader.ReadUInt32(); clause.HandlerOffset = assemblyReader.ReadUInt32(); clause.HandlerLength = assemblyReader.ReadUInt32(); } else { clause.Flags = (CorExceptionFlag)assemblyReader.ReadUInt16(); clause.TryOffset = assemblyReader.ReadUInt16(); clause.TryLength = assemblyReader.ReadByte(); clause.HandlerOffset = assemblyReader.ReadUInt16(); clause.HandlerLength = assemblyReader.ReadByte(); } if (clause.Flags == CorExceptionFlag.COR_ILEXCEPTION_CLAUSE_NONE) { clause.ClassToken = assemblyReader.ReadUInt32(); } else { clause.FilterOffset = assemblyReader.ReadUInt32(); } AddExceptionHandlingCodeLines(clause); } } }
private void AddExceptionHandlingCodeLines(NuGenExceptionClause clause) { if (clause.Flags == CorExceptionFlag.COR_ILEXCEPTION_CLAUSE_FILTER) { string filter = string.Format(".try IL_{0} to IL_{1} filter IL_{2} handler IL_{3} to IL_{4}", NuGenHelperFunctions.FormatAsHexNumber(clause.TryOffset, 4), NuGenHelperFunctions.FormatAsHexNumber(clause.TryOffset + clause.TryLength, 4), NuGenHelperFunctions.FormatAsHexNumber(clause.FilterOffset, 4), NuGenHelperFunctions.FormatAsHexNumber(clause.HandlerOffset, 4), NuGenHelperFunctions.FormatAsHexNumber(clause.HandlerOffset + clause.HandlerLength, 4)); int position = FindCodeLine(clause.HandlerOffset + clause.HandlerLength); CodeLines.Insert(position + 1, new NuGenCodeLine(0, filter)); } else { bool finallyClause = (clause.Flags == CorExceptionFlag.COR_ILEXCEPTION_CLAUSE_FINALLY); AddExceptionCodeLines(clause.TryOffset, clause.TryLength, ".try", "// end try", finallyClause); if (finallyClause) { AddExceptionCodeLines(clause.HandlerOffset, clause.HandlerLength, "finally", "// end finally", false); } else { string handlerName = string.Format("catch {0}", BaseTypeDefinition.ModuleScope.Assembly.AllTokens[clause.ClassToken]); AddExceptionCodeLines(clause.HandlerOffset, clause.HandlerLength, handlerName, "// end handler", false); } } }