public static InvokeDynamic getTransformerFromString(String s) { switch (s.toLowerCase()) { case "light": { return new LightInvokeDynamic(); } case "normal": { return new NormalInvokeDynamic(); } case "heavy": { return new HeavyInvokeDynamic(); } default: { throw new IllegalConfigurationValueException("Did not expect " + s + " as a invokedynamic obfuscation mode"); } } } }
private InvokeDynamic getInvokeDynamicTransformer() { Object o = map.get(ConfigurationSettings.INVOKEDYNAMIC.getValue()); if (o == null) return null; if (!(o instanceof String)) throw new IllegalConfigurationValueException(ConfigurationSettings.INVOKEDYNAMIC.getValue(), String.class, o.getClass()); String s = (String) o; if (!"Light".equals(s) && !"Normal".equals(s) && !"Heavy".equals(s)) throw new IllegalConfigurationValueException("Expected Light, Normal or Heavy as mode for invokedynamic " + "obfuscation. Got " + s + " instead."); return InvokeDynamic.getTransformerFromString(s); }
@Override public void transform() { AtomicInteger counter = new AtomicInteger(); MemberNames memberNames = new MemberNames(); Handle bsmHandle = new Handle(H_INVOKESTATIC, memberNames.className, memberNames.bootstrapMethodName, "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", false); this.getClassWrappers().parallelStream().filter(classWrapper -> !"java/lang/Enum".equals(classWrapper.classNode.superName) && !excluded(classWrapper) && classWrapper.classNode.version >= V1_7).forEach(classWrapper -> { ClassNode classNode = classWrapper.classNode; classWrapper.methods.parallelStream().filter(methodWrapper -> !excluded(methodWrapper) && hasInstructions(methodWrapper.methodNode)).forEach(methodWrapper -> { MethodNode methodNode = methodWrapper.methodNode; encrypt(sb.toString(), memberNames), newSig, bsmHandle ClassWrapper cw = getClassPath().get(fieldInsnNode.owner); if (cw == null) { throw new MissingClassException(fieldInsnNode.owner + " does not exist in classpath"); encrypt(sb.toString(), memberNames), newSig, bsmHandle ClassNode decryptor = createBootstrap(memberNames); this.getClasses().put(decryptor.name, new ClassWrapper(decryptor, false)); LoggerUtils.stdOut(String.format("Hid %d field and/or method accesses with invokedynamics.", counter.get()));
@Override public void transform() { AtomicInteger counter = new AtomicInteger(); String className = StringUtils.randomClassName(getClasses().keySet()); String bsmName = randomString(4); Handle bsmHandle = new Handle(Opcodes.H_INVOKESTATIC, className, bsmName, "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;" + "Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", false); this.getClassWrappers().stream().filter(classWrapper -> !classWrapper.classNode.superName.equals("java/lang/Enum") && !excluded(classWrapper) && classWrapper.classNode.version >= V1_7).forEach(classWrapper -> classWrapper.methods.stream().filter(methodWrapper -> !excluded(methodWrapper) && hasInstructions(methodWrapper.methodNode)).forEach(methodWrapper -> { MethodNode methodNode = methodWrapper.methodNode; bsmHandle, opcode, encrypt(methodInsnNode.owner.replace("/", "."), 1029), encrypt(methodInsnNode.name, 2038), encrypt(methodInsnNode.desc, 1928)); methodNode.instructions.set(insn, indy); if (returnType.getSort() == Type.ARRAY) { bsmHost.name = className; bsmHost.version = V1_7; bsmHost.methods.add(createBootstrap(bsmName, bsmHost.name)); bsmHost.superName = "java/lang/Object"; bsmHost.access = ACC_PUBLIC | ACC_SUPER; getClasses().put(className, new ClassWrapper(bsmHost, false)); LoggerUtils.stdOut(String.format("Replaced %d method invocations with invokedynamics.", counter.get()));
@Override public void transform() { AtomicInteger counter = new AtomicInteger(); String className = StringUtils.randomClassName(getClasses().keySet()); String bsmName = randomString(4); Handle bsmHandle = new Handle(Opcodes.H_INVOKESTATIC, className, bsmName, "(Ljava/lang/Object;" + "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;" + "Ljava/lang/Object;)Ljava/lang/Object;", false); this.getClassWrappers().stream().filter(classWrapper -> !classWrapper.classNode.superName.equals("java/lang/Enum") && !excluded(classWrapper) && classWrapper.classNode.version >= V1_7).forEach(classWrapper -> classWrapper.methods.stream().filter(methodWrapper -> !excluded(methodWrapper) && hasInstructions(methodWrapper.methodNode)).forEach(methodWrapper -> { MethodNode methodNode = methodWrapper.methodNode; bsmHandle, opcode, encrypt(methodInsnNode.owner.replace("/", "."), 2893), encrypt(methodInsnNode.name, 2993), encrypt(methodInsnNode.desc, 8372)); methodNode.instructions.set(insn, indy); if (returnType.getSort() == Type.ARRAY) { bsmHost.name = className; bsmHost.version = V1_7; bsmHost.methods.add(createBootstrap(bsmName, bsmHost.name)); bsmHost.superName = "java/lang/Object"; bsmHost.access = ACC_PUBLIC | ACC_SUPER; getClasses().put(className, new ClassWrapper(bsmHost, false)); LoggerUtils.stdOut(String.format("Replaced %d method invocations with invokedynamics.", counter.get()));
public InvokeDynamic getInvokeDynamic() { if (invokeDynamicCheckBox.isSelected()) { switch (invokeDynamicComboBox.getSelectedIndex()) { case 0: { return new LightInvokeDynamic(); } case 1: { return new NormalInvokeDynamic(); } case 2: { return new HeavyInvokeDynamic(); } default: { throw new IllegalStateException(String.format("Bad invokedynamic type %d.", invokeDynamicComboBox.getSelectedIndex())); } } } else { return null; } }