private void ReadILCode() { NuGenCodeLine start = new NuGenCodeLine(); start.Text = "{"; CodeLines.Add(start); if (EntryPoint) { CodeLines.Add(new NuGenCodeLine(1, ".entrypoint")); } if (Overrides != 0) { NuGenTokenBase overridenMember = BaseTypeDefinition.ModuleScope.Assembly.AllTokens[Overrides]; Type overridenMemberType = overridenMember.GetType(); string memberName; if (GenericParameters != null && overridenMember is NuGenIHasSignature) { NuGenIHasSignature hasSignature = (NuGenIHasSignature)overridenMember; hasSignature.SignatureReader.SetGenericParametersOfMethod(GenericParameters); } if (overridenMemberType == typeof(NuGenMemberReference)) { NuGenMemberReference memberReference = (NuGenMemberReference)overridenMember; memberName = memberReference.Text; } else if (overridenMemberType == typeof(NuGenMethodDefinition)) { NuGenMethodDefinition methodDefinition = (NuGenMethodDefinition)overridenMember; memberName = string.Format("{0}::{1}", methodDefinition.BaseTypeDefinition.FullName, methodDefinition.Name); } else { throw new NotImplementedException(string.Format("Unhandled overriden member type ('{0}').", overridenMemberType.FullName)); } CodeLines.Add(new NuGenCodeLine(1, ".override method " + memberName)); } if (CustomAttributes != null) { NuGenAssembly assembly = BaseTypeDefinition.ModuleScope.Assembly; foreach (NuGenCustomAttribute customAttribute in CustomAttributes) { CodeLines.Add(new NuGenCodeLine(1, customAttribute.Name)); } } int codeSizePosition = 2; if (Parameters != null) { NuGenAssembly assembly = BaseTypeDefinition.ModuleScope.Assembly; try { assembly.OpenMetadataInterfaces(); foreach (NuGenParameter parameter in Parameters) { parameter.LazyInitialize(BaseTypeDefinition.ModuleScope.Assembly.AllTokens); bool hasDefault = ((parameter.AttributeFlags & CorParamAttr.pdHasDefault) == CorParamAttr.pdHasDefault); if (hasDefault) { NuGenCodeLine defaultParameter = new NuGenCodeLine(); defaultParameter.Indentation = 1; defaultParameter.Text = parameter.DefaultValueAsString; CodeLines.Add(defaultParameter); codeSizePosition++; } if (parameter.CustomAttributes != null) { if (!hasDefault) { NuGenCodeLine parameterLine = new NuGenCodeLine(1, string.Format(".param [{0}]", parameter.OrdinalIndex)); CodeLines.Add(parameterLine); codeSizePosition++; } foreach (NuGenCustomAttribute customAttribute in parameter.CustomAttributes) { NuGenCodeLine customAttributeLine = new NuGenCodeLine(1, customAttribute.Name); CodeLines.Add(customAttributeLine); codeSizePosition++; } } } } finally { assembly.CloseMetadataInterfaces(); } } if (PermissionSets != null) { foreach (NuGenPermissionSet permissionSet in PermissionSets) { NuGenCodeLine permissionSetLine = new NuGenCodeLine(1, permissionSet.Name); CodeLines.Add(permissionSetLine); codeSizePosition++; } } if (((Rva > 0) || BaseTypeDefinition.ModuleScope.Assembly.IsInMemory) && ((ImplementationFlags & CorMethodImpl.miCodeTypeMask) != CorMethodImpl.miNative)) { NuGenAssembly assembly = BaseTypeDefinition.ModuleScope.Assembly; BinaryReader assemblyReader = null; if (assembly.IsInMemory) { NuGenInMemoryMethodStream methodStream = new NuGenInMemoryMethodStream(assembly.DebuggedProcess, FindMethodHeader()); assemblyReader = new BinaryReader(methodStream); } else { assembly.OpenAssemblyReader(); assemblyReader = assembly.AssemblyReader; assemblyReader.BaseStream.Position = assembly.GetMethodAddress(Rva); } byte methodHeader = assemblyReader.ReadByte(); int methodLength = 0; bool moreSects = false; if ((methodHeader & (byte)ILMethodHeader.CorILMethod_FatFormat) == (byte)ILMethodHeader.CorILMethod_FatFormat) { byte methodHeaderByte2 = assemblyReader.ReadByte(); moreSects = ((methodHeader & (byte)CorILMethodFlags.CorILMethod_MoreSects) == (byte)CorILMethodFlags.CorILMethod_MoreSects); byte sizeOfHeader = Convert.ToByte((methodHeaderByte2 >> 4) * 4); ushort maxStack = assemblyReader.ReadUInt16(); methodLength = assemblyReader.ReadInt32(); uint localVarSigToken = assemblyReader.ReadUInt32(); NuGenCodeLine maxStackLine = new NuGenCodeLine(1, string.Format(".maxstack {0}", maxStack)); CodeLines.Add(maxStackLine); if (localVarSigToken != 0 && BaseTypeDefinition.ModuleScope.Assembly.StandAloneSignatures != null && BaseTypeDefinition.ModuleScope.Assembly.StandAloneSignatures.ContainsKey(localVarSigToken)) { string initLocals = string.Empty; if ((methodHeader & (byte)CorILMethodFlags.CorILMethod_InitLocals) == (byte)CorILMethodFlags.CorILMethod_InitLocals) { initLocals = "init "; } NuGenStandAloneSignature standAloneSignature = BaseTypeDefinition.ModuleScope.Assembly.StandAloneSignatures[localVarSigToken]; if (GenericParameters != null && standAloneSignature.SignatureReader.HasGenericMethodParameter) { standAloneSignature.SignatureReader.SetGenericParametersOfMethod(GenericParameters); standAloneSignature.LazyInitialize(BaseTypeDefinition.ModuleScope.Assembly.AllTokens); } NuGenCodeLine variablesLine = new NuGenCodeLine(1, string.Format(".locals {0}{1}", initLocals, standAloneSignature.Text)); CodeLines.Add(variablesLine); } } else if ((methodHeader & (byte)ILMethodHeader.CorILMethod_TinyFormat) == (byte)ILMethodHeader.CorILMethod_TinyFormat) { methodLength = methodHeader >> 2; } NuGenCodeLine codeSize = new NuGenCodeLine(1, string.Format("// Code size {0} (0x{1:x})", methodLength, methodLength)); if (CustomAttributes != null) { codeSizePosition++; } if (EntryPoint) { codeSizePosition++; } if (Overrides != 0) { codeSizePosition++; } CodeLines.Insert(codeSizePosition, codeSize); if ((ImplementationFlags & CorMethodImpl.miNative) != CorMethodImpl.miNative) { byte[] methodCode = new byte[methodLength]; assemblyReader.Read(methodCode, 0, methodLength); int methodCodeIndex = 0; while (methodCodeIndex < methodCode.Length) { int offset = methodCodeIndex; short opCodeValue = methodCode[methodCodeIndex++]; if (opCodeValue == 0xFE) { opCodeValue = (short)(opCodeValue * 0x100 + methodCode[methodCodeIndex++]); } if (NuGenOpCodeGroups.OpCodesByValue.ContainsKey(opCodeValue)) { OpCode opCode = NuGenOpCodeGroups.OpCodesByValue[opCodeValue]; OpCodeGroup opCodeGroup = NuGenOpCodeGroups.GetGroupOfOpCode(opCode); int parameterSize = 0; switch (opCodeGroup) { case OpCodeGroup.ByteArgumentParameter: case OpCodeGroup.ByteParameter: case OpCodeGroup.ByteVariableParameter: case OpCodeGroup.SbyteLocationParameter: case OpCodeGroup.SbyteParameter: parameterSize = 1; break; case OpCodeGroup.UshortArgumentParameter: case OpCodeGroup.UshortParameter: case OpCodeGroup.UshortVariableParameter: parameterSize = 2; break; case OpCodeGroup.FloatParameter: case OpCodeGroup.FieldParameter: case OpCodeGroup.IntLocationParameter: case OpCodeGroup.IntParameter: case OpCodeGroup.MethodParameter: case OpCodeGroup.StringParameter: case OpCodeGroup.TypeParameter: case OpCodeGroup.Calli: case OpCodeGroup.Ldtoken: case OpCodeGroup.Switch: parameterSize = 4; break; case OpCodeGroup.DoubleParameter: case OpCodeGroup.LongParameter: parameterSize = 8; break; } ulong parameter = 0; if (parameterSize > 0) { parameter = NuGenHelperFunctions.GetILCodeParameter(methodCode, methodCodeIndex, parameterSize); } NuGenBaseILCode code = null; switch (opCodeGroup) { case OpCodeGroup.Parameterless: code = new NuGenBaseILCode(); break; case OpCodeGroup.FieldParameter: NuGenFieldILCode fieldILCode = new NuGenFieldILCode(); code = fieldILCode; fieldILCode.Parameter = Convert.ToUInt32(parameter); fieldILCode.DecodedParameter = assembly.AllTokens[fieldILCode.Parameter]; if (GenericParameters != null) { fieldILCode.SetGenericsMethodParameters(assembly.AllTokens, GenericParameters); } break; case OpCodeGroup.MethodParameter: NuGenMethodILCode methodILCode = new NuGenMethodILCode(); code = methodILCode; methodILCode.Parameter = Convert.ToUInt32(parameter); methodILCode.DecodedParameter = assembly.AllTokens[methodILCode.Parameter]; if (GenericParameters != null) { methodILCode.SetGenericsMethodParameters(assembly.AllTokens, GenericParameters); } break; case OpCodeGroup.StringParameter: NuGenStringILCode stringILCode = new NuGenStringILCode(); code = stringILCode; stringILCode.Parameter = Convert.ToUInt32(parameter); stringILCode.DecodedParameter = assembly.UserStrings[stringILCode.Parameter]; break; case OpCodeGroup.TypeParameter: NuGenTypeILCode typeILCode = new NuGenTypeILCode(); code = typeILCode; typeILCode.Parameter = Convert.ToUInt32(parameter); typeILCode.DecodedParameter = assembly.AllTokens[typeILCode.Parameter]; if (GenericParameters != null) { typeILCode.SetGenericsMethodParameters(assembly.AllTokens, GenericParameters); } break; case OpCodeGroup.IntLocationParameter: LocationILCode<int> intLocationILCode = new LocationILCode<int>(); code = intLocationILCode; intLocationILCode.Parameter = (int)parameter; intLocationILCode.DecodedParameter = intLocationILCode.Parameter; break; case OpCodeGroup.SbyteLocationParameter: LocationILCode<sbyte> sbyteLocationILCode = new LocationILCode<sbyte>(); code = sbyteLocationILCode; sbyteLocationILCode.Parameter = (sbyte)parameter; sbyteLocationILCode.DecodedParameter = sbyteLocationILCode.Parameter; break; case OpCodeGroup.ByteParameter: NumberILCode<byte> byteNumberILCode = new NumberILCode<byte>(); code = byteNumberILCode; byteNumberILCode.Parameter = (byte)parameter; byteNumberILCode.DecodedParameter = byteNumberILCode.Parameter; break; case OpCodeGroup.UshortParameter: NumberILCode<ushort> ushortNumberILCode = new NumberILCode<ushort>(); code = ushortNumberILCode; ushortNumberILCode.Parameter = (ushort)parameter; ushortNumberILCode.DecodedParameter = ushortNumberILCode.Parameter; break; case OpCodeGroup.SbyteParameter: NumberILCode<sbyte> sbyteNumberILCode = new NumberILCode<sbyte>(); code = sbyteNumberILCode; sbyteNumberILCode.Parameter = (sbyte)parameter; sbyteNumberILCode.DecodedParameter = sbyteNumberILCode.Parameter; break; case OpCodeGroup.IntParameter: NumberILCode<int> intNumberILCode = new NumberILCode<int>(); code = intNumberILCode; intNumberILCode.Parameter = (int)parameter; intNumberILCode.DecodedParameter = intNumberILCode.Parameter; break; case OpCodeGroup.LongParameter: NumberILCode<long> longNumberILCode = new NumberILCode<long>(); code = longNumberILCode; longNumberILCode.Parameter = (long)parameter; longNumberILCode.DecodedParameter = longNumberILCode.Parameter; break; case OpCodeGroup.FloatParameter: NumberILCode<float> floatNumberILCode = new NumberILCode<float>(); code = floatNumberILCode; floatNumberILCode.Parameter = NuGenHelperFunctions.ConvertToSingle(parameter); floatNumberILCode.DecodedParameter = floatNumberILCode.Parameter; break; case OpCodeGroup.DoubleParameter: NumberILCode<double> doubleNumberILCode = new NumberILCode<double>(); code = doubleNumberILCode; doubleNumberILCode.Parameter = NuGenHelperFunctions.ConvertToDouble(parameter); doubleNumberILCode.DecodedParameter = doubleNumberILCode.Parameter; break; case OpCodeGroup.ByteArgumentParameter: ArgumentILCode<byte> byteArgumentILCode = new ArgumentILCode<byte>(); code = byteArgumentILCode; byteArgumentILCode.Parameter = (byte)parameter; byteArgumentILCode.DecodedParameter = NameOfParameter(parameter); break; case OpCodeGroup.UshortArgumentParameter: ArgumentILCode<ushort> ushortArgumentILCode = new ArgumentILCode<ushort>(); code = ushortArgumentILCode; ushortArgumentILCode.Parameter = (ushort)parameter; ushortArgumentILCode.DecodedParameter = NameOfParameter(parameter); break; case OpCodeGroup.ByteVariableParameter: VariableILCode<byte> byteVariableILCode = new VariableILCode<byte>(); code = byteVariableILCode; byteVariableILCode.Parameter = (byte)parameter; byteVariableILCode.DecodedParameter = byteVariableILCode.Parameter; break; case OpCodeGroup.UshortVariableParameter: VariableILCode<ushort> ushortVariableILCode = new VariableILCode<ushort>(); code = ushortVariableILCode; ushortVariableILCode.Parameter = (ushort)parameter; ushortVariableILCode.DecodedParameter = ushortVariableILCode.Parameter; break; case OpCodeGroup.Calli: NuGenCalliILCode calliILCode = new NuGenCalliILCode(); code = calliILCode; calliILCode.Parameter = Convert.ToUInt32(parameter); calliILCode.DecodedParameter = assembly.StandAloneSignatures[calliILCode.Parameter]; break; case OpCodeGroup.Ldtoken: NuGenLdtokenILCode ldtokenILCode = new NuGenLdtokenILCode(); code = ldtokenILCode; ldtokenILCode.Parameter = Convert.ToUInt32(parameter); ldtokenILCode.DecodedParameter = assembly.AllTokens[ldtokenILCode.Parameter]; if (GenericParameters != null) { ldtokenILCode.SetGenericsMethodParameters(assembly.AllTokens, GenericParameters); } break; case OpCodeGroup.Switch: NuGenSwitchILCode switchILCode = new NuGenSwitchILCode(); code = switchILCode; ulong addressIndex = 0; switchILCode.Parameter = new int[parameter]; parameterSize += Convert.ToInt32(parameter * 4); while (addressIndex < parameter) { int jumpAddress = (int)NuGenHelperFunctions.GetILCodeParameter(methodCode, methodCodeIndex + Convert.ToInt32((addressIndex + 1) * 4), 4); switchILCode.Parameter[addressIndex++] = jumpAddress; } break; } if (code != null) { code.Offset = offset; code.OpCode = opCode; code.DecodeParameter(); } code.Indentation = 1; CodeLines.Add(code); methodCodeIndex += parameterSize; } } NuGenCodeLine end = new NuGenCodeLine(); StringBuilder endText = new StringBuilder(); endText.Append("} //end of method "); if (BaseTypeDefinition.FullName != null && BaseTypeDefinition.FullName.Length > 0) { endText.Append(BaseTypeDefinition.FullName); endText.Append("::"); } endText.Append(Name); end.Text = endText.ToString(); CodeLines.Add(end); if (moreSects) { ReadMethodDataSections(assemblyReader); } } if (assembly.IsInMemory) { assemblyReader.Close(); } else { assembly.CloseAssemblyReader(); } } else { NuGenCodeLine end = new NuGenCodeLine(); end.Text = string.Format("}} // end of method {0}{1}{2}", BaseTypeDefinition.Name, (BaseTypeDefinition.Name.Length > 0 ? "::" : string.Empty), Name); CodeLines.Add(end); } }
private int FindPositionOfILCodeByOffset(int offset, out string line, out NuGenBaseILCode ilCode) { int result = 0; int codeLineIndex = 0; int lineIndex = 0; bool found = false; line = string.Empty; ilCode = null; while (!found && codeLineIndex < CodeObject.CodeLines.Count) { NuGenCodeLine codeLine = CodeObject.CodeLines[codeLineIndex]; ilCode = codeLine as NuGenBaseILCode; if (ilCode != null && ilCode.Offset >= offset) { line = Lines[lineIndex]; found = true; } else { for (int lineNumber = 0; lineNumber < codeLine.TextLineNumber + 1; lineNumber++) { result += Lines[lineIndex].Length + 1; lineIndex++; } } codeLineIndex++; } return result; }