package net.contra.obfuscator.trans.ob; import com.sun.org.apache.bcel.internal.classfile.Method; import com.sun.org.apache.bcel.internal.generic.*; import net.contra.obfuscator.ITransformer; import net.contra.obfuscator.Settings; import net.contra.obfuscator.util.bcel.BCELMethods; import net.contra.obfuscator.util.bcel.JarLoader; import net.contra.obfuscator.util.misc.LogHandler; import net.contra.obfuscator.util.misc.Misc; import java.util.HashMap; import java.util.Map; public class ClassNameObfuscator implements ITransformer { private final LogHandler Logger = new LogHandler("ClassNameObfuscator"); private final Map<String, String> ChangedClasses = new HashMap<String, String>(); private String Location = ""; private JarLoader LoadedJar; public ClassNameObfuscator(String loc) { Location = loc; } public void load() { LoadedJar = new JarLoader(Location); } //TODO: NEW, FIELDS, NEWARRAY, EXCLUSIONS, NOT MAIN public void transform() { //We rename methods for (ClassGen cg : LoadedJar.ClassEntries.values()) { if (cg.isAbstract()) continue; //TODO: Probably more shit we shouldn't rename String newName = Misc.getRandomClassName(); byte[] manifest = LoadedJar.NonClassEntries.get("META-INF/MANIFEST.MF"); if (manifest != null) { String man = new String(manifest); if (man.contains("Main-Class: " + cg.getClassName())) { Logger.debug("Updating Manifest -> Main Class: " + cg.getClassName()); man = man.replace("Main-Class: " + cg.getClassName(), "Main-Class: " + newName); LoadedJar.NonClassEntries.put("META-INF/MANIFEST.MF", man.getBytes()); } } String oldName = cg.getClassName(); cg.setClassName(newName); Logger.log("Obfuscating Method Names -> Class: " + oldName + " - " + cg.getClassName()); ChangedClasses.put(oldName, cg.getClassName()); } //We fix all of the method/field calls for (ClassGen cg : LoadedJar.ClassEntries.values()) { for (Method method : cg.getMethods()) { MethodGen mg = new MethodGen(method, cg.getClassName(), cg.getConstantPool()); InstructionList list = mg.getInstructionList(); if (list == null) continue; Logger.log("Fixing Method Calls -> Class: " + cg.getClassName() + " Method: " + method.getName()); InstructionHandle[] handles = list.getInstructionHandles(); for (InstructionHandle handle : handles) { if (BCELMethods.isInvoke(handle.getInstruction())) { String clazz = BCELMethods.getInvokeClassName(handle.getInstruction(), cg.getConstantPool()); String methname = BCELMethods.getInvokeMethodName(handle.getInstruction(), cg.getConstantPool()); String methsig = BCELMethods.getInvokeSignature(handle.getInstruction(), cg.getConstantPool()); if (!ChangedClasses.containsKey(clazz)) continue; Logger.debug("Swapping Call -> Class: " + clazz + " Name: " + methname + " Sig: " + methsig); String newname = ChangedClasses.get(clazz); int index = cg.getConstantPool().addMethodref(newname, methname, methsig); handle.setInstruction(BCELMethods.getNewInvoke(handle.getInstruction(), index)); } else if (BCELMethods.isFieldInvoke(handle.getInstruction())) { String clazz = BCELMethods.getFieldInvokeClassName(handle.getInstruction(), cg.getConstantPool()); String fieldname = BCELMethods.getFieldInvokeName(handle.getInstruction(), cg.getConstantPool()); String fieldsig = BCELMethods.getFieldInvokeSignature(handle.getInstruction(), cg.getConstantPool()); if (!ChangedClasses.containsKey(clazz)) continue; Logger.debug("Swapping Call -> Class: " + clazz + " Name: " + fieldname + " Sig: " + fieldsig); String newname = ChangedClasses.get(clazz); int index = cg.getConstantPool().addFieldref(newname, fieldname, fieldsig); handle.setInstruction(BCELMethods.getNewFieldInvoke(handle.getInstruction(), index)); } else if (handle.getInstruction() instanceof NEW) { NEW in = ((NEW) handle.getInstruction()); String clazz = in.getLoadClassType(cg.getConstantPool()).getClassName(); if (!ChangedClasses.containsKey(clazz)) continue; String newname = ChangedClasses.get(clazz); int index = cg.getConstantPool().addClass(newname); NEW out = new NEW(index); handle.setInstruction(out); } } list.setPositions(); mg.setInstructionList(list); mg.removeLocalVariables(); mg.setMaxLocals(); mg.setMaxStack(); cg.replaceMethod(method, mg.getMethod()); } } } public void save() { String loc = Location.replace(".jar", Settings.FILE_TAG + ".jar"); LoadedJar.saveJar(loc); } }