package net.contra.obfuscator.trans.ob; import com.sun.org.apache.bcel.internal.Constants; 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.ObfuscationType; 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; public class IntegerBoxer implements ITransformer { private final LogHandler Logger = new LogHandler("AttributeObfuscator"); private String Location = ""; private JarLoader LoadedJar; public IntegerBoxer(String loc) { Location = loc; } public void load() { LoadedJar = new JarLoader(Location); } public void transform() { for (ClassGen cg : LoadedJar.ClassEntries.values()) { MethodGen boxer = getBoxer(cg); INVOKESTATIC inv = new INVOKESTATIC(cg.getConstantPool().addMethodref(boxer)); for (Method method : cg.getMethods()) { MethodGen mg = new MethodGen(method, cg.getClassName(), cg.getConstantPool()); InstructionList list = mg.getInstructionList(); if (list == null) continue; Logger.log("Boxing Constant Integers -> Class: " + cg.getClassName() + " Method: " + method.getName()); InstructionHandle[] handles = list.getInstructionHandles(); for (InstructionHandle handle : handles) { if (handle.getInstruction() instanceof ICONST || handle.getInstruction() instanceof BIPUSH || handle.getInstruction() instanceof SIPUSH || handle.getInstruction() instanceof ILOAD || (handle.getInstruction() instanceof LDC && handle.getNext().getInstruction() instanceof IASTORE)) { int curValue = BCELMethods.getIntegerValue(handle.getInstruction()); InstructionHandle nh; //If it is an even int, it gets replaced with half it's value and appends //an int of the key if (curValue != -9001 && (curValue % 2 == 0) && Settings.OBFUSCATION_LEVEL.getLevel() > ObfuscationType.Normal.getLevel()) { //check if it's even. int tempkey = curValue / 2; Logger.debug("Value: " + curValue + " Key: " + tempkey); Instruction newIns = BCELMethods.getIntegerLoad(handle.getInstruction(), tempkey); handle.setInstruction(newIns); if (tempkey <= 5 && tempkey >= -1) { nh = list.append(handle, new ICONST(tempkey)); } else { nh = list.append(handle, newIns); } } else { //Otherwise just append a 0 key and keep the number the same nh = list.append(handle, new ICONST(0)); } list.append(nh, inv); } } list.setPositions(); mg.setInstructionList(list); mg.setMaxLocals(); mg.setMaxStack(); cg.replaceMethod(method, mg.getMethod()); } if (cg.containsMethod(boxer.getName(), boxer.getSignature()) == null) { Logger.log("Injecting Boxer Method -> Class: " + cg.getClassName()); cg.addMethod(boxer.getMethod()); } else { Logger.error("Boxer Method Already Exists! -> Class: " + cg.getClassName()); } } } MethodGen getBoxer(ClassGen cg) { InstructionList il = new InstructionList(); MethodGen method = new MethodGen(Constants.ACC_PUBLIC | Constants.ACC_STATIC, Type.INT, new Type[]{Type.INT, Type.INT}, new String[]{Settings.BOXER_ARG, Settings.BOXER_ARG + "i"}, Settings.BOXER_NAME, cg.getClassName(), il, cg.getConstantPool()); il.append(InstructionFactory.createLoad(Type.INT, 0)); il.append(InstructionFactory.createLoad(Type.INT, 1)); il.append(new IADD()); il.append(InstructionFactory.createReturn(Type.INT)); method.setMaxStack(); method.setMaxLocals(); return method; } public void save() { String loc = Location.replace(".jar", Settings.FILE_TAG + ".jar"); LoadedJar.saveJar(loc); } }