public bool Open() { if (File.Exists(FClassFileName)) { try { // read the .class file systematically FileStream fs = new FileStream(FClassFileName, FileMode.Open, FileAccess.Read); FReader = new BinaryReader(fs); // read header FMagic = Common.ReadDWord(FReader); if (FMagic != 0x0CAFEBABE) return false; FMinorVersion = Common.ReadWord(FReader); FMajorVersion = Common.ReadWord(FReader); // read constant pool // this also reads the "FConstantPoolCount" // so instead use FConstantPool.MaxItems or somesuch FConstantPool = new TConstantPool(FReader); // more constants FAccessFlags = (AccessFlags)Common.ReadWord(FReader); FThisClass = Common.ReadWord(FReader); FThisClass--; FSuperClass = Common.ReadWord(FReader); FSuperClass--; FThisClassName = ((ConstantClassInfo)FConstantPool.Item(FThisClass)).Name; (FConstantPool.Item(FThisClass)).References++; FSuperClassName = ((ConstantClassInfo)FConstantPool.Item(FSuperClass)).Name; (FConstantPool.Item(FSuperClass)).References++; FInterfaces = new TInterfaces(FReader, FConstantPool); FFields = new TFields(FReader, FConstantPool); FMethods = new TMethods(FReader, FConstantPool); FAttributes = new TAttributes(FReader, FConstantPool); //FHasBeenOpened = true; fs.Close(); return true; } catch (Exception e) { // catch any unhandled exceptions here // and exit gracefully. // garbage collection does the rest ;D return false; } } return false; }
public TAttributes(BinaryReader Reader, TConstantPool ConstantPool) { FReader = Reader; FMaxItems = Common.ReadWord(FReader) - 1; FItems = new ArrayList(); int count = 0; // goes from 1 -> attributescount - 1 while (count <= FMaxItems) { ushort NameIndex = Common.ReadWord(FReader); NameIndex--; ConstantUtf8Info Name = (ConstantUtf8Info)ConstantPool.Item(NameIndex); switch (Name.Value) { case AttributeType.Code: { CodeAttributeInfo ai = new CodeAttributeInfo(NameIndex, FReader, ConstantPool); FItems.Add(ai); break; } case AttributeType.ConstantValue: { ConstantValueAttributeInfo ai = new ConstantValueAttributeInfo(NameIndex, FReader, ConstantPool); FItems.Add(ai); break; } case AttributeType.Deprecated: { DeprecatedAttributeInfo ai = new DeprecatedAttributeInfo(NameIndex, FReader, ConstantPool); FItems.Add(ai); break; } case AttributeType.Exceptions: { ExceptionsAttributeInfo ai = new ExceptionsAttributeInfo(NameIndex, FReader, ConstantPool); FItems.Add(ai); break; } case AttributeType.InnerClasses: { InnerClassesAttributeInfo ai = new InnerClassesAttributeInfo(NameIndex, FReader, ConstantPool); FItems.Add(ai); break; } case AttributeType.LineNumberTable: { LineNumberAttributeInfo ai = new LineNumberAttributeInfo(NameIndex, FReader, ConstantPool); FItems.Add(ai); break; } case AttributeType.LocalVariableTable: { LocalVariablesAttributeInfo ai = new LocalVariablesAttributeInfo(NameIndex, FReader, ConstantPool); FItems.Add(ai); break; } case AttributeType.SourceFile: { SourceFileAttributeInfo ai = new SourceFileAttributeInfo(NameIndex, FReader, ConstantPool); FItems.Add(ai); break; } case AttributeType.Synthetic: { SyntheticAttributeInfo ai = new SyntheticAttributeInfo(NameIndex, FReader, ConstantPool); FItems.Add(ai); break; } default: { AttributeInfo ai = new UnknownAttributeInfo(NameIndex, FReader, ConstantPool); FItems.Add(ai); break; } } count++; } }
public TChangeRecord ChangeMethodName(int MethodNumber, string NewName) { MethodInfo Method = (MethodInfo)FMethods.Items[MethodNumber]; //MethodInfo OriginalMethod = Method.Clone(); //MethodInfo NewMethod = null; TChangeRecord Result = null; ConstantMethodrefInfo MethodRef = null; ushort NewNameIndex; // first we need to loop through the constant pool for method // references that match our new method name for (int i = 0; i < FConstantPool.MaxItems(); i++) { if (FConstantPool.Item(i).Tag == (byte)ConstantPoolInfoTag.ConstantMethodref) { MethodRef = (ConstantMethodrefInfo)FConstantPool.Item(i); if (MethodRef.ParentClass.Name == FThisClassName && MethodRef.NameAndType.Name == Method.Name.Value && MethodRef.NameAndType.Descriptor == Method.Descriptor) { // jackpot, we found the reference! // there should be only one, so we will break and fix it up after we generate the new name break; } } MethodRef = null; } Method.Name.References--; // add a new string constant to the pool ConstantUtf8Info NewUtf = new ConstantUtf8Info(NewName); NewNameIndex = ConstantPool.Add(NewUtf); // set the method its new name Method.SetName(NewNameIndex, ConstantPool); Method.Name.References = 1; //NewMethod = Method.Clone(); if (MethodRef == null) return Result; if (MethodRef.NameAndType.References <= 1) { // if this is the only reference to the name/type descriptor // we can overwrite the value MethodRef.NameAndType.SetName(NewNameIndex, FConstantPool); } else { // we have to make a new one ! MethodRef.NameAndType.References--; // add a new string constant to the pool ConstantNameAndTypeInfo NewNaT = new ConstantNameAndTypeInfo(NewNameIndex, MethodRef.NameAndType.TypeIndex, FConstantPool); ushort NewIndex = ConstantPool.Add(NewNaT); // set the method its new name MethodRef.SetNameAndType(NewIndex, ConstantPool); MethodRef.NameAndType.References = 1; } return Result; }