private ArrayList DeObfuscateSingleFile(int index, RenameDatabase RenameStore) { TClassFile ClassFile = (TClassFile)FClassFiles[index]; if (ClassFile == null) return null; // add the class name to the head of the changelist FChangeList = new ArrayList(); FChangeList.Add(ClassFile.ThisClassName); string OriginalClassName = ClassFile.ThisClassName; string OriginalClassAndType = ClassFile.ThisClassName + " : " + ClassFile.SuperClassName; // rename the class and add the new class name to the changelist at [1] if (FRenameClasses && RenameStore.GetNewClassNameOnly(OriginalClassAndType) != null) { // check if we need to use a user-supplied class name first string NewClassName = RenameStore.GetNewClassNameOnly(OriginalClassAndType); while (ClassNameExists(NewClassName)) { NewClassName += "_"; } FChangeList.Add(ClassFile.ChangeClassName(NewClassName)); } else if (FRenameClasses && DoRename(OriginalClassName)) { string NewClassName; if (UseUniqueNums) { string format = "{0:D" + (FClassFiles.Count.ToString().Length + 2) + "}"; string uniqueNum = string.Format(format, Convert.ToInt64(ClassFile.ThisClassCode.ToString() + index.ToString())); NewClassName = String.Format("Class_{0}_{1}", Common.GetClassName(OriginalClassName), uniqueNum); } else NewClassName = String.Format("Class_{0}", Common.GetClassName(OriginalClassName)); // test if the filename we are changing to hasnt already been used! while (ClassNameExists(NewClassName)) { NewClassName += "_"; } FChangeList.Add(ClassFile.ChangeClassName(NewClassName)); } else FChangeList.Add(OriginalClassName); // process the Methods for (int i = 0; i < ClassFile.Methods.Items.Count; i++) { MethodInfo mi = (MethodInfo)ClassFile.Methods.Items[i]; RenameData rd = RenameStore.GetNewMethodInfo(OriginalClassAndType, mi.Descriptor, mi.Name.Value); // this is the rule for renaming if (DoRename(mi.Name.Value) || rd != null) { // clone the original method TMethodChangeRecord mcr = new TMethodChangeRecord(mi); // rename all of the functions something meaningful string NewName; // if the offset is zero, it probably means its an abstract method if (ClassFile.AccessFlags == AccessFlags.ACC_INTERFACE) NewName = String.Format("sub_iface_{0:x}", i); else if (mi.Offset != 0) NewName = String.Format("sub_{0:x}", mi.Offset); else NewName = String.Format("sub_null_{0:x}", i); /*if (FThoroughMode) { int j = 0; while (ClassFile.Methods.MethodNameExists(NewName)) { // rename the method NewName = NewName + "_" + j; j++; } }*/ // user supplied names take precedence if (rd != null) { NewName = rd.FieldName; } // change the method name ClassFile.ChangeMethodName(i, NewName); // set the mcr.ChangedTo(mi); FChangeList.Add(mcr); } // fix the descriptor regardless ClassFile.ChangeMethodParam(i, OriginalClassName, ClassFile.ThisClassName); } // process the Fields for (int i = 0; i < ClassFile.Fields.Items.Count; i++) { FieldInfo fi = (FieldInfo)ClassFile.Fields.Items[i]; RenameData rd = RenameStore.GetNewFieldInfo(OriginalClassAndType, fi.Descriptor, fi.Name.Value); if (DoRename(fi.Name.Value) || rd != null) { // clone the original method TFieldChangeRecord fcr = new TFieldChangeRecord(fi); // rename all of the fields something meaningful string NewName; // if the offset is zero, it probably means its a null/abstract method if (fi.Offset != 0) NewName = String.Format("var_{0:x}", fi.Offset); else NewName = String.Format("var_null_{0:x}", fi.Offset); /*if (FThoroughMode) { int j = 0; while (ClassFile.Methods.FieldNameExists(NewName)) { // rename the field NewName = NewName + "_" + j; j++; } }*/ if (rd != null) { NewName = rd.FieldName; } ClassFile.ChangeFieldName(i, NewName); fcr.ChangedTo(fi); FChangeList.Add(fcr); } // fix the descriptor regardless ClassFile.ChangeFieldType(i, OriginalClassName, ClassFile.ThisClassName); } return FChangeList; }
/// <summary> /// This function runs over a class, fixing up any references from a deobfuscated file. /// </summary> /// <param name="Index">This is the index of the ClassFile to have its references updated</param> /// <param name="ChangeList">This is a list of before/after values from a previously deobfuscated file</param> private void FixReferencePass1(int Index, ArrayList ChangeList, ArrayList OwnerChangeList) { /* the first pass does the following: * - replaces the Super Class name (if it needs replacing) * - replaces any constant method/field names (if they need replacing) * - replaces the class field names (if needed) * it does NOT change the original class name */ TClassFile ClassFile = (TClassFile)FClassFiles[Index]; if (ClassFile == null) return; // - ChangeList[0] is always a string, which is the parent name of the deobfuscated class // - ChangeList[1] is always the deobfuscated (new) class name... yes i know this is lame :P string OldParentName = (string)ChangeList[0]; string NewParentName = (string)ChangeList[1]; // check the Super class name if it needs renaming if (ClassFile.SuperClassName == OldParentName) { ClassFile.ChangeSuperClassName(NewParentName); } // loop through the constant pool for field/method references // check the parent of each, and if the parent is the class we have // just modified, try and match it to one of the changes // in the changearray for (int i = 0; i < ClassFile.ConstantPool.MaxItems(); i++) { if (ClassFile.ConstantPool.Item(i) is ConstantPoolMethodInfo) { ConstantPoolMethodInfo ci = (ConstantPoolMethodInfo)ClassFile.ConstantPool.Item(i); // check its parent if (ci.ParentClass.Name == OldParentName || ci.ParentClass.Name == NewParentName) { // check the descriptor // - for fields this is the field type // - for methods this is the parameter list // if parents are the same, check the name and descriptor // against the list of originals for (int j = 2; j < ChangeList.Count; j++) { if ((ChangeList[j] is TMethodChangeRecord) && (ci is ConstantMethodrefInfo || ci is ConstantInterfaceMethodrefInfo)) { if (ci is ConstantInterfaceMethodrefInfo) { // handle interface references differently TMethodChangeRecord mcr = (TMethodChangeRecord)ChangeList[j]; // if found update it to the overridden version if (mcr.OriginalMethod.Name.Value == ci.NameAndType.Name && mcr.OriginalMethod.Descriptor == ci.NameAndType.Descriptor) { // find the overridden version for (int k = 2; k < OwnerChangeList.Count; k++) { if (OwnerChangeList[k] is TMethodChangeRecord) { TMethodChangeRecord mcr2 = (TMethodChangeRecord)OwnerChangeList[k]; if (mcr2.OriginalMethod.Name.Value == mcr.OriginalMethod.Name.Value && mcr2.OriginalMethod.Descriptor == mcr.OriginalMethod.Descriptor) { ClassFile.ChangeConstantFieldName(i, mcr2.NewMethod.Name.Value); break; } } } } } else { TMethodChangeRecord mcr = (TMethodChangeRecord)ChangeList[j]; // if found update it to the new version... if (mcr.OriginalMethod.Name.Value == ci.NameAndType.Name && mcr.OriginalMethod.Descriptor == ci.NameAndType.Descriptor) { ClassFile.ChangeConstantFieldName(i, mcr.NewMethod.Name.Value); break; } } } else if ((ChangeList[j] is TFieldChangeRecord) && (ci is ConstantFieldrefInfo)) { TFieldChangeRecord fcr = (TFieldChangeRecord)ChangeList[j]; // if found update it to the new version... if (fcr.OriginalField.Name.Value == ci.NameAndType.Name && fcr.OriginalField.Descriptor == ci.NameAndType.Descriptor) { ClassFile.ChangeConstantFieldName(i, fcr.NewField.Name.Value); break; } } } } } } // also loop through the Fields array to change all the Types for (int i = 0; i < ClassFile.Fields.MaxItems(); i++) { ClassFile.ChangeFieldType(i, OldParentName, NewParentName); } // do the same for methods (fix the parameter list) for (int i = 0; i < ClassFile.Methods.MaxItems(); i++) { ClassFile.ChangeMethodParam(i, OldParentName, NewParentName); } // and the same for all the interfaces for (int i = 0; i < ClassFile.Interfaces.Items.Count; i++) { if (ClassFile.Interfaces.Item(i).Name == OldParentName) ClassFile.ChangeInterfaceName(i, NewParentName); } }
private ArrayList DeObfuscateSingleFile(int index, RenameDatabase RenameStore) { TClassFile ClassFile = (TClassFile)FClassFiles[index]; if (ClassFile == null) return null; // add the class name to the head of the changelist FChangeList = new ArrayList(); FChangeList.Add(ClassFile.ThisClassName); string OriginalClassName = ClassFile.ThisClassName; string OriginalClassAndType = ClassFile.ThisClassName + " : " + ClassFile.SuperClassName; // rename the class and add the new class name to the changelist at [1] if (FRenameClasses && RenameStore.GetNewClassNameOnly(OriginalClassAndType) != null) { // check if we need to use a user-supplied class name first string NewClassName = RenameStore.GetNewClassNameOnly(OriginalClassAndType); while (ClassNameExists(NewClassName)) { NewClassName += "_"; } FChangeList.Add(ClassFile.ChangeClassName(NewClassName)); } else if (FRenameClasses && DoRename(OriginalClassName)) { string NewClassName; NewClassName = ClassFile.FileName; // test if the filename we are changing to hasnt already been used! while (ClassNameExists(NewClassName)) { NewClassName += "_"; } FChangeList.Add(ClassFile.ChangeClassName(NewClassName)); } else FChangeList.Add(OriginalClassName); // process the Methods for (int i = 0; i < ClassFile.Methods.Items.Count; i++) { MethodInfo mi = (MethodInfo)ClassFile.Methods.Items[i]; RenameData rd = RenameStore.GetNewMethodInfo(OriginalClassAndType, mi.Descriptor, mi.Name.Value); // this is the rule for renaming if (DoRename(mi.Name.Value) || rd != null) { // clone the original method TMethodChangeRecord mcr = new TMethodChangeRecord(mi); // rename all of the functions something meaningful string NewName; // user supplied names take precedence if (rd != null) { NewName = rd.FieldName; } else { NewName = mi.Name.Value; } // change the method name ClassFile.ChangeMethodName(i, NewName); // set the mcr.ChangedTo(mi); FChangeList.Add(mcr); } // fix the descriptor regardless ClassFile.ChangeMethodParam(i, OriginalClassName, ClassFile.ThisClassName); } // process the Fields for (int i = 0; i < ClassFile.Fields.Items.Count; i++) { FieldInfo fi = (FieldInfo)ClassFile.Fields.Items[i]; RenameData rd = RenameStore.GetNewFieldInfo(OriginalClassAndType, fi.Descriptor, fi.Name.Value); if (DoRename(fi.Name.Value) || rd != null) { // clone the original method TFieldChangeRecord fcr = new TFieldChangeRecord(fi); // rename all of the fields something meaningful string NewName; /*if (FThoroughMode) { int j = 0; while (ClassFile.Methods.FieldNameExists(NewName)) { // rename the field NewName = NewName + "_" + j; j++; } }*/ if (rd != null) { NewName = rd.FieldName; } else { NewName = fi.Name.Value; } ClassFile.ChangeFieldName(i, NewName); fcr.ChangedTo(fi); FChangeList.Add(fcr); } // fix the descriptor regardless ClassFile.ChangeFieldType(i, OriginalClassName, ClassFile.ThisClassName); } return FChangeList; }