diff --git a/dev.skidfuscator.obfuscator/src/main/java/dev/skidfuscator/obfuscator/hierarchy/SkidHierarchy.java b/dev.skidfuscator.obfuscator/src/main/java/dev/skidfuscator/obfuscator/hierarchy/SkidHierarchy.java index 1548361..794a2b7 100644 --- a/dev.skidfuscator.obfuscator/src/main/java/dev/skidfuscator/obfuscator/hierarchy/SkidHierarchy.java +++ b/dev.skidfuscator.obfuscator/src/main/java/dev/skidfuscator/obfuscator/hierarchy/SkidHierarchy.java @@ -281,10 +281,30 @@ private void setupInvoke() { assert (e.getBootstrapArgs().length == 3 && e.getBootstrapArgs()[1] instanceof Handle); final Handle boundFunc = (Handle) e.getBootstrapArgs()[1]; - if (boundFunc.getName().equals("handle")) { - /*System.out.println("Invoking dynamic " + invocation.getOwner() + "#" - + invocation.getName() + invocation.getDesc());*/ + if (boundFunc.getName().equals("apply") && false ) { + System.out.println("Invoking dynamic " + invocation.getOwner() + "#" + + invocation.getName() + invocation.getDesc() + " bound to " + boundFunc.getOwner() + "#" + boundFunc.getName() + boundFunc.getDesc() + ); } + + // Patch for implicit funtions + // TODO: Fix this + if (boundFunc.getName().startsWith("lambda$new$")) { + final String returnType = e.getType().getClassName().replace(".", "/"); + //System.out.println("Attempting to locate " + returnType); + final ClassNode targetClass = skidfuscator.getClassSource().findClassNode(returnType); + + if (!(targetClass instanceof SkidClassNode)) + return; + + assert targetClass.getMethods().size() == 1 : "Implicit Function must be single method!"; + final SkidMethodNode methodNode = (SkidMethodNode) targetClass.getMethods().get(0); + + methodNode.getGroup().setImplicitFunction(true); + //System.out.println("Found implicit function: " + methodNode.toString()); + return; + } + target = new ClassMethodHash(boundFunc.getName(), boundFunc.getDesc(), boundFunc.getOwner()); } else if (invocation instanceof InvocationExpr) { @@ -335,6 +355,18 @@ private void setupInvoke() { } }); } + + // Patch for functional interfaces + if (c.node.visibleAnnotations != null) { + final List annotationNodes = c.node.visibleAnnotations; + + if (annotationNodes.stream().anyMatch(e -> e.desc.equals("Ljava/lang/FunctionalInterface;"))) { + for (MethodNode method : c.getMethods()) { + ((SkidMethodNode) method).getGroup().setImplicitFunction(true); + } + } + } + invocationBar.tick(); }); } diff --git a/dev.skidfuscator.obfuscator/src/main/java/dev/skidfuscator/obfuscator/skidasm/SkidGroup.java b/dev.skidfuscator.obfuscator/src/main/java/dev/skidfuscator/obfuscator/skidasm/SkidGroup.java index b99b1dc..b02ca0e 100644 --- a/dev.skidfuscator.obfuscator/src/main/java/dev/skidfuscator/obfuscator/skidasm/SkidGroup.java +++ b/dev.skidfuscator.obfuscator/src/main/java/dev/skidfuscator/obfuscator/skidasm/SkidGroup.java @@ -33,6 +33,7 @@ public class SkidGroup { private int stackHeight; private transient boolean application; + private transient boolean implicitFunction; // TODO: Add parameter and parameter compilation @@ -145,8 +146,13 @@ public MethodNode first() { return methodNodeList.iterator().next(); } + public void setImplicitFunction(boolean implicitFunction) { + this.implicitFunction = implicitFunction; + } + public boolean isEntryPoint() { return !application + || this.isImplicitFunction() || this.getInvokers().isEmpty() || this.getInvokers().stream().anyMatch(SkidInvocation::isDynamic) || this.isAnnotation()