public int ChangeSuperClassName(string NewName) { ConstantClassInfo ClassInfo = (ConstantClassInfo)FConstantPool.Item(FSuperClass); ConstantUtf8Info UtfInfo = (ConstantUtf8Info)FConstantPool.Item(ClassInfo.NameIndex); // skip this coz we already passing the full name in //NewName = Common.NewClassName(FSuperClassName, NewName); if (UtfInfo.References <= 1) { // if this is the only reference to the name/type descriptor // we can overwrite the value UtfInfo.SetName(NewName); } else { // we have to make a new one ! UtfInfo.References--; // add a new string constant to the pool ConstantUtf8Info NewUtf = new ConstantUtf8Info(NewName); ushort NewIndex = ConstantPool.Add(NewUtf); // set the method its new name ClassInfo.NameIndex = NewIndex; NewUtf.References = 1; } FSuperClassName = ((ConstantClassInfo)FConstantPool.Item(FSuperClass)).Name; return FSuperClass; }
/// <summary> /// Stage 2 simply goes through the constant pool searching for a ClassInfo structure that matches /// the obfuscated class name, and replaces it with the de-obfuscated class name. /// /// This is to ensure that any field/variable that references that class will be updated, simply by /// changing the class info structure at the source. /// </summary> /// <param name="Index">Index of the class file we want to update</param> /// <param name="ChangeList">The array of changes we made deobfuscating a file</param> private void FixReferencePass2(int Index, ArrayList ChangeList) { TClassFile ClassFile = (TClassFile)FClassFiles[Index]; if (ClassFile == null) return; string OldParentName = (string)ChangeList[0]; string NewParentName = (string)ChangeList[1]; // iterate through the constant pool looking for class references // that match the old class name for (int i = 0; i < ClassFile.ConstantPool.MaxItems(); i++) { if (ClassFile.ConstantPool.Item(i) is ConstantClassInfo) { ConstantClassInfo ci = (ConstantClassInfo)ClassFile.ConstantPool.Item(i); // if we found a ClassInfo constant with the same name as the old name if (ci.Name == OldParentName) { // create a new UTF string constant ConstantUtf8Info ui = new ConstantUtf8Info(); // set it to the new parent name ui.SetName(NewParentName); // add it to the constant pool ushort index = ClassFile.ConstantPool.Add(ui); // set our original ClassInfo constant's name to the newly added UTF string constant ci.SetName(index, ClassFile.ConstantPool); } // special condition for array type references else if (ci.Name.IndexOf("L" + OldParentName + ";") >= 0) { // create a new UTF string constant ConstantUtf8Info ui = new ConstantUtf8Info(); // set it to the new parent name ui.SetName(ci.Name.Replace("L" + OldParentName + ";", "L" + NewParentName + ";")); // add it to the constant pool ushort index = ClassFile.ConstantPool.Add(ui); // set our original ClassInfo constant's name to the newly added UTF string constant ci.SetName(index, ClassFile.ConstantPool); } } else if (ClassFile.ConstantPool.Item(i) is ConstantPoolMethodInfo) { // check the descriptor // - for fields this is the field type // - for methods this is the parameter list ClassFile.ChangeConstantFieldType(i, OldParentName, NewParentName); } } }
public int AddConstantClassName(string NewName) { ConstantClassInfo ClassInfo = new ConstantClassInfo(); ConstantUtf8Info UtfInfo = new ConstantUtf8Info(); ushort NewClassIndex = FConstantPool.Add(ClassInfo); ushort NewUtfIndex = FConstantPool.Add(UtfInfo); UtfInfo.SetName(NewName); ClassInfo.SetName(NewUtfIndex, FConstantPool); return NewClassIndex; }
public void ChangeInterfaceName(int InterfaceNumber, string NewName) { // takes an index into the interface list // simple changes the name of a method/field in the constant pool // TODO: check this! InterfaceInfo IntInfo = FInterfaces.Item(InterfaceNumber); if (IntInfo.Name == NewName) return; ConstantUtf8Info NewTypeString = new ConstantUtf8Info(NewName); ushort NewTypeIndex = FConstantPool.Add(NewTypeString); // set the interface its new name ConstantClassInfo cci = (ConstantClassInfo)ConstantPool.Item(IntInfo.Value); cci.SetName(NewTypeIndex, FConstantPool); }
public string ChangeClassName(string Name) { ConstantClassInfo ClassInfo = (ConstantClassInfo)FConstantPool.Item(FThisClass); ConstantUtf8Info UtfInfo = (ConstantUtf8Info)FConstantPool.Item(ClassInfo.NameIndex); // change the class name, not the directory structure Name = Common.NewClassName(ThisClassName, Name); // we have to make a new one ! UtfInfo.References--; // add a new string constant to the pool ConstantUtf8Info NewUtf = new ConstantUtf8Info(Name); ushort NewIndex = ConstantPool.Add(NewUtf); // set the method its new name ClassInfo.SetName(NewIndex, FConstantPool); NewUtf.References = 1; FThisClassName = ((ConstantClassInfo)FConstantPool.Item(FThisClass)).Name; return Name; }
public TConstantPool(BinaryReader Reader) { FReader = Reader; FMaxItems = Common.ReadWord(FReader) - 1; FItems = new ArrayList(); int count = 0; // goes from 1 -> constantpoolcount - 1 while (count < FMaxItems) { byte tag = Common.ReadByte(FReader); switch (tag) { case (byte)ConstantPoolInfoTag.ConstantClass: { ConstantClassInfo cc = new ConstantClassInfo(); cc.Read(tag, FReader); FItems.Add(cc); break; } case (byte)ConstantPoolInfoTag.ConstantString: { ConstantStringInfo cc = new ConstantStringInfo(); cc.Read(tag, FReader); FItems.Add(cc); break; } case (byte)ConstantPoolInfoTag.ConstantFieldref: { ConstantFieldrefInfo cc = new ConstantFieldrefInfo(); cc.Read(tag, FReader); FItems.Add(cc); break; } case (byte)ConstantPoolInfoTag.ConstantMethodref: { ConstantMethodrefInfo cc = new ConstantMethodrefInfo(); cc.Read(tag, FReader); FItems.Add(cc); break; } case (byte)ConstantPoolInfoTag.ConstantInterfaceMethodref: { ConstantInterfaceMethodrefInfo cc = new ConstantInterfaceMethodrefInfo(); cc.Read(tag, FReader); FItems.Add(cc); break; } case (byte)ConstantPoolInfoTag.ConstantInteger: { ConstantIntegerInfo cc = new ConstantIntegerInfo(); cc.Read(tag, FReader); FItems.Add(cc); break; } case (byte)ConstantPoolInfoTag.ConstantFloat: { ConstantFloatInfo cc = new ConstantFloatInfo(); cc.Read(tag, FReader); FItems.Add(cc); break; } case (byte)ConstantPoolInfoTag.ConstantLong: { ConstantLongInfo cc = new ConstantLongInfo(); cc.Read(tag, FReader); FItems.Add(cc); // longs take up two entries in the pool table count++; FItems.Add(cc); break; } case (byte)ConstantPoolInfoTag.ConstantDouble: { ConstantDoubleInfo cc = new ConstantDoubleInfo(); cc.Read(tag, FReader); FItems.Add(cc); // so do doubles count++; FItems.Add(cc); break; } case (byte)ConstantPoolInfoTag.ConstantNameAndType: { ConstantNameAndTypeInfo cc = new ConstantNameAndTypeInfo(); cc.Read(tag, FReader); FItems.Add(cc); break; } case (byte)ConstantPoolInfoTag.ConstantUtf8: { ConstantUtf8Info cc = new ConstantUtf8Info(); cc.Read(tag, FReader); FItems.Add(cc); break; } default: // fail safe ? count++; break; } count++; } foreach (ConstantPoolInfo cc in FItems) { cc.Resolve(FItems); } }
public void Write(BinaryWriter Writer) { // i am assuming we have a valid constant pool list... // i dont do any error checking here except bare minimum! // write the number of constant pool entries Common.WriteWord(Writer, FMaxItems + 1); int count = 0; // goes from 1 -> constantpoolcount - 1 while (count < FMaxItems) { ConstantPoolInfo Item = (ConstantPoolInfo)FItems[count]; switch (Item.Tag) { case (byte)ConstantPoolInfoTag.ConstantClass: { ConstantClassInfo cc = (ConstantClassInfo)Item; cc.Write(Writer); break; } case (byte)ConstantPoolInfoTag.ConstantString: { ConstantStringInfo cc = (ConstantStringInfo)Item; cc.Write(Writer); break; } case (byte)ConstantPoolInfoTag.ConstantFieldref: { ConstantFieldrefInfo cc = (ConstantFieldrefInfo)Item; cc.Write(Writer); break; } case (byte)ConstantPoolInfoTag.ConstantMethodref: { ConstantMethodrefInfo cc = (ConstantMethodrefInfo)Item; cc.Write(Writer); break; } case (byte)ConstantPoolInfoTag.ConstantInterfaceMethodref: { ConstantInterfaceMethodrefInfo cc = (ConstantInterfaceMethodrefInfo)Item; cc.Write(Writer); break; } case (byte)ConstantPoolInfoTag.ConstantInteger: { ConstantIntegerInfo cc = (ConstantIntegerInfo)Item; cc.Write(Writer); break; } case (byte)ConstantPoolInfoTag.ConstantFloat: { ConstantFloatInfo cc = (ConstantFloatInfo)Item; cc.Write(Writer); break; } case (byte)ConstantPoolInfoTag.ConstantLong: { ConstantLongInfo cc = (ConstantLongInfo)Item; cc.Write(Writer); // longs take up two entries in the pool table count++; break; } case (byte)ConstantPoolInfoTag.ConstantDouble: { ConstantDoubleInfo cc = (ConstantDoubleInfo)Item; cc.Write(Writer); // so do doubles count++; break; } case (byte)ConstantPoolInfoTag.ConstantNameAndType: { ConstantNameAndTypeInfo cc = (ConstantNameAndTypeInfo)Item; cc.Write(Writer); break; } case (byte)ConstantPoolInfoTag.ConstantUtf8: { ConstantUtf8Info cc = (ConstantUtf8Info)Item; cc.Write(Writer); break; } default: // fail safe ? // BADDDDDDDDDDDDDDDDDDDDD, prolly should check/fix this count++; break; } count++; } }