From 247d79f81adb468af890aeddcceb37dd47c00c3b Mon Sep 17 00:00:00 2001 From: Thibaut Gautier Date: Sat, 28 Nov 2020 19:50:37 +0100 Subject: [PATCH 01/19] Added lombok --- org.mapleir.ir/pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/org.mapleir.ir/pom.xml b/org.mapleir.ir/pom.xml index 8ea07f3e..fb12e4fb 100644 --- a/org.mapleir.ir/pom.xml +++ b/org.mapleir.ir/pom.xml @@ -31,5 +31,11 @@ app-services 0.0.1-ALPHA + + org.projectlombok + lombok + 1.18.12 + provided + \ No newline at end of file From 9028a4c01946d6735f5f4b0eb6c3117ca75ebe2e Mon Sep 17 00:00:00 2001 From: Thibaut Gautier Date: Sat, 28 Nov 2020 19:52:02 +0100 Subject: [PATCH 02/19] Fixed JavaDoc --- .../java/org/mapleir/ir/algorithms/BoissinotDestructor.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/org.mapleir.ir/src/main/java/org/mapleir/ir/algorithms/BoissinotDestructor.java b/org.mapleir.ir/src/main/java/org/mapleir/ir/algorithms/BoissinotDestructor.java index 09125dbe..91433590 100644 --- a/org.mapleir.ir/src/main/java/org/mapleir/ir/algorithms/BoissinotDestructor.java +++ b/org.mapleir.ir/src/main/java/org/mapleir/ir/algorithms/BoissinotDestructor.java @@ -34,8 +34,8 @@ * @see Revisiting * Out-of-SSA Translation for Correctness, CodeQuality, and Efficiency * - * Ref: Boissinot's PhD thesis: https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.385.8510&rep=rep1&type=pdf - * Ref: Slides: https://compilers.cs.uni-saarland.de/ssasem/talks/Alain.Darte.pdf + * @see Boissinot's PhD thesis + * @see Slides */ public class BoissinotDestructor { // private boolean DO_VALUE_INTERFERENCE = true; From b9f3800e3b17bad9aad4d29e38fcd24b0239bb40 Mon Sep 17 00:00:00 2001 From: Thibaut Gautier Date: Sat, 28 Nov 2020 19:52:20 +0100 Subject: [PATCH 03/19] No clue where these commits are from --- .../service/CompleteResolvingJarDumper.java | 131 ++++++++++-------- .../main/java/org/mapleir/deob/PassGroup.java | 10 +- 2 files changed, 78 insertions(+), 63 deletions(-) diff --git a/org.mapleir.app-services/src/main/java/org/mapleir/app/service/CompleteResolvingJarDumper.java b/org.mapleir.app-services/src/main/java/org/mapleir/app/service/CompleteResolvingJarDumper.java index b9d0ba2b..68d0c316 100644 --- a/org.mapleir.app-services/src/main/java/org/mapleir/app/service/CompleteResolvingJarDumper.java +++ b/org.mapleir.app-services/src/main/java/org/mapleir/app/service/CompleteResolvingJarDumper.java @@ -77,7 +77,35 @@ public int dumpClass(JarOutputStream out, String name, ClassNode cn) throws IOEx out.putNextEntry(entry); ClassTree tree = source.getClassTree(); - ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES) { + + + for(MethodNode m : cn.getMethods()) { + if(m.node.instructions.size() > 10000) { + System.out.println("large method: " + m + " @" + m.node.instructions.size()); + } + } + + try { + try { + ClassWriter writer = this.buildClassWriter(tree, ClassWriter.COMPUTE_FRAMES); + cn.node.accept(writer); // must use custom writer which overrides getCommonSuperclass + out.write(writer.toByteArray()); + } catch (Exception e) { + ClassWriter writer = this.buildClassWriter(tree, ClassWriter.COMPUTE_MAXS); + cn.node.accept(writer); // must use custom writer which overrides getCommonSuperclass + out.write(writer.toByteArray()); + System.err.println("Failed to write " + cn.getName() + "! Writing with COMPUTE_MAXS, " + + "which may cause runtime abnormalities"); + } + } catch (Exception e) { + System.err.println("Failed to write " + cn.getName() + "! Skipping class..."); + } + + return 1; + } + + public ClassWriter buildClassWriter(ClassTree tree, int flags) { + return new ClassWriter(flags) { // this method in ClassWriter uses the systemclassloader as // a stream location to load the super class, however, most of // the time the class is loaded/read and parsed by us so it @@ -85,12 +113,12 @@ public int dumpClass(JarOutputStream out, String name, ClassNode cn) throws IOEx // we may not even want it to be loaded/resolved and we can // bypass this by implementing the hierarchy scanning algorithm // with ClassNodes rather than Classes. - @Override + @Override protected String getCommonSuperClass(String type1, String type2) { - ClassNode ccn = source.findClassNode(type1); - ClassNode dcn = source.findClassNode(type2); - - if(ccn == null) { + ClassNode ccn = source.findClassNode(type1); + ClassNode dcn = source.findClassNode(type2); + + if(ccn == null) { // return "java/lang/Object"; ClassNode c; try { @@ -99,14 +127,14 @@ protected String getCommonSuperClass(String type1, String type2) { return "java/lang/Object"; } if(c == null) { - return "java/lang/Object"; - } - throw new UnsupportedOperationException(c.toString()); - // classTree.build(c); - // return getCommonSuperClass(type1, type2); - } - - if(dcn == null) { + return "java/lang/Object"; + } + throw new UnsupportedOperationException(c.toString()); + // classTree.build(c); + // return getCommonSuperClass(type1, type2); + } + + if(dcn == null) { // return "java/lang/Object"; ClassNode c; @@ -116,52 +144,37 @@ protected String getCommonSuperClass(String type1, String type2) { return "java/lang/Object"; } if(c == null) { - return "java/lang/Object"; - } - throw new UnsupportedOperationException(c.toString()); - // classTree.build(c); - // return getCommonSuperClass(type1, type2); - } - - Collection c = tree.getAllParents(ccn); - Collection d = tree.getAllParents(dcn); - - if(c.contains(dcn)) - return type1; - - if(d.contains(ccn)) - return type2; - - if(Modifier.isInterface(ccn.node.access) || Modifier.isInterface(dcn.node.access)) { - // enums as well? - return "java/lang/Object"; - } else { - do { - ClassNode nccn = source.findClassNode(ccn.node.superName); - if(nccn == null) - break; - ccn = nccn; - c = tree.getAllParents(ccn); - } while(!c.contains(dcn)); - return ccn.getName(); - } - } - }; - - for(MethodNode m : cn.getMethods()) { - if(m.node.instructions.size() > 10000) { - System.out.println("large method: " + m + " @" + m.node.instructions.size()); - } - } + return "java/lang/Object"; + } + throw new UnsupportedOperationException(c.toString()); + // classTree.build(c); + // return getCommonSuperClass(type1, type2); + } - try { - cn.node.accept(writer); // must use custom writer which overrides getCommonSuperclass - out.write(writer.toByteArray()); - } catch (Exception e) { - System.err.println("Failed to write " + cn.getName()); - throw e; - } - return 1; + Collection c = tree.getAllParents(ccn); + Collection d = tree.getAllParents(dcn); + + if(c.contains(dcn)) + return type1; + + if(d.contains(ccn)) + return type2; + + if(Modifier.isInterface(ccn.node.access) || Modifier.isInterface(dcn.node.access)) { + // enums as well? + return "java/lang/Object"; + } else { + do { + ClassNode nccn = source.findClassNode(ccn.node.superName); + if(nccn == null) + break; + ccn = nccn; + c = tree.getAllParents(ccn); + } while(!c.contains(dcn)); + return ccn.getName(); + } + } + }; } /** diff --git a/org.mapleir.main/src/main/java/org/mapleir/deob/PassGroup.java b/org.mapleir.main/src/main/java/org/mapleir/deob/PassGroup.java index 8ab0004b..a9fd471c 100644 --- a/org.mapleir.main/src/main/java/org/mapleir/deob/PassGroup.java +++ b/org.mapleir.main/src/main/java/org/mapleir/deob/PassGroup.java @@ -1,9 +1,6 @@ package org.mapleir.deob; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -23,6 +20,11 @@ public PassGroup add(IPass p) { passes.add(p); return this; } + + public PassGroup add(IPass... p) { + passes.addAll(Arrays.asList(p)); + return this; + } public PassGroup remove(IPass p) { passes.remove(p); From c2c8fae4a9d7b1fb8b226819224fb1c4f1e06e44 Mon Sep 17 00:00:00 2001 From: Thibaut Gautier Date: Sat, 28 Nov 2020 19:52:35 +0100 Subject: [PATCH 04/19] Beginning works on production class --- .../src/main/java/org/mapleir/Boot.java | 64 ++++++++++++++----- .../src/main/java/org/mapleir/Boot2.java | 10 ++- .../src/main/java/org/mapleir/Main.java | 8 +++ 3 files changed, 63 insertions(+), 19 deletions(-) create mode 100644 org.mapleir.main/src/main/java/org/mapleir/Main.java diff --git a/org.mapleir.main/src/main/java/org/mapleir/Boot.java b/org.mapleir.main/src/main/java/org/mapleir/Boot.java index fa11f40a..46635ed3 100644 --- a/org.mapleir.main/src/main/java/org/mapleir/Boot.java +++ b/org.mapleir.main/src/main/java/org/mapleir/Boot.java @@ -13,6 +13,8 @@ import org.mapleir.deob.PassGroup; import org.mapleir.deob.PassResult; import org.mapleir.deob.dataflow.LiveDataFlowAnalysisImpl; +import org.mapleir.deob.passes.*; +import org.mapleir.deob.passes.constparam.ConstantExpressionEvaluatorPass; import org.mapleir.deob.passes.rename.ClassRenamerPass; import org.mapleir.deob.util.RenamingHeuristic; import org.mapleir.ir.algorithms.BoissinotDestructor; @@ -26,6 +28,9 @@ import org.topdank.byteio.in.SingleJarDownloader; import java.io.*; +import java.lang.management.ManagementFactory; +import java.net.URI; +import java.net.URL; import java.util.*; import java.util.Map.Entry; import java.util.jar.JarOutputStream; @@ -53,7 +58,7 @@ public static void main(String[] args) throws Exception { // Load input jar // File f = locateRevFile(135); - File f = new File("res/salesforce.jar"); + File f = new File(args[0]); section("Preparing to run on " + f.getAbsolutePath()); SingleJarDownloader dl = new SingleJarDownloader<>(new JarInfo(f)); @@ -64,9 +69,9 @@ public static void main(String[] args) throws Exception { // ApplicationClassSource app = new ApplicationClassSource("test", ClassHelper.parseClasses(CGExample.class)); // app.addLibraries(new InstalledRuntimeClassSource(app)); - File rtjar = new File("res/rt.jar"); - File androidjar = new File("res/android.jar"); - app.addLibraries(rt(app, rtjar), rt(app, androidjar)); + File rtjar = new File(System.getProperty("java.home"), "lib/rt.jar"); + //File androidjar = new File("res/android.jar"); + app.addLibraries(rt(app, rtjar)); section("Initialising context."); @@ -108,7 +113,12 @@ public static void main(String[] args) throws Exception { for(Entry e : cxt.getIRCache().entrySet()) { MethodNode mn = e.getKey(); ControlFlowGraph cfg = e.getValue(); - cfg.verify(); + try { + cfg.verify(); + } catch (Exception ex){ + ex.printStackTrace(); + } + } section("Retranslating SSA IR to standard flavour."); @@ -120,7 +130,11 @@ public static void main(String[] args) throws Exception { // System.out.println(cfg); // CFGUtils.easyDumpCFG(cfg, "pre-destruct"); - cfg.verify(); + try { + cfg.verify(); + } catch (Exception ex){ + ex.printStackTrace(); + } BoissinotDestructor.leaveSSA(cfg); @@ -128,7 +142,11 @@ public static void main(String[] args) throws Exception { LocalsReallocator.realloc(cfg); // CFGUtils.easyDumpCFG(cfg, "post-reaalloc"); // System.out.println(cfg); - cfg.verify(); + try { + cfg.verify(); + } catch (Exception ex){ + ex.printStackTrace(); + } // System.out.println("Rewriting " + mn.getName()); (new ControlFlowGraphDumper(cfg, mn)).dump(); // System.out.println(InsnListUtils.insnListToString(mn.instructions)); @@ -199,22 +217,34 @@ private static void run(AnalysisContext cxt, PassGroup group) { private static IPass[] getTransformationPasses() { RenamingHeuristic heuristic = RenamingHeuristic.RENAME_ALL; return new IPass[] { -// new ConcreteStaticInvocationPass(), + // Const param + + // Rename // new ClassRenamerPass(heuristic), // new MethodRenamerPass(heuristic), // new FieldRenamerPass(), -// new CallgraphPruningPass(), - // new PassGroup("Interprocedural Optimisations") - // .add(new ConstantParameterPass()) - // new LiftConstructorCallsPass(), -// new DemoteRangesPass(), + // Default + + new PassGroup("Interprocedural Optimisations") + .add( + new CallgraphPruningPass(), + new ConcreteStaticInvocationPass(), + new ConstantExpressionReorderPass(), + //new ConstantParameterPass(), + new DeadCodeEliminationPass(), + //new DemoteRangesPass(), // Not done + new DetectIrreducibleFlowPass(), + new LiftConstructorCallsPass() + ), + //new ConstantExpressionEvaluatorPass(), + + - // new ConstantExpressionReorderPass(), // new FieldRSADecryptionPass(), - // new ConstantParameterPass(), -// new ConstantExpressionEvaluatorPass(), -// new DeadCodeEliminationPass() + + + }; } diff --git a/org.mapleir.main/src/main/java/org/mapleir/Boot2.java b/org.mapleir.main/src/main/java/org/mapleir/Boot2.java index 7cbe8f4d..1793658d 100644 --- a/org.mapleir.main/src/main/java/org/mapleir/Boot2.java +++ b/org.mapleir.main/src/main/java/org/mapleir/Boot2.java @@ -51,14 +51,20 @@ public static void main(String[] args) throws Exception { // Load input jar // File f = locateRevFile(135); - File f = new File("res/JetbrainsCrack-4.2-release-enc.jar"); + // Load input jar + // File f = locateRevFile(135); + File f = new File(args[0]); SingleJarDownloader dl = new SingleJarDownloader<>(new JarInfo(f)); dl.download(); String appName = f.getName().substring(0, f.getName().length() - 4); ApplicationClassSource app = new ApplicationClassSource(appName, dl.getJarContents().getClassContents()); +// +// ApplicationClassSource app = new ApplicationClassSource("test", ClassHelper.parseClasses(CGExample.class)); +// app.addLibraries(new InstalledRuntimeClassSource(app)); - File rtjar = new File("res/rt.jar"); + File rtjar = new File(System.getProperty("java.home"), "lib/rt.jar"); + //File androidjar = new File("res/android.jar"); app.addLibraries(rt(app, rtjar)); IRCache irFactory = new IRCache(ControlFlowGraphBuilder::build); diff --git a/org.mapleir.main/src/main/java/org/mapleir/Main.java b/org.mapleir.main/src/main/java/org/mapleir/Main.java new file mode 100644 index 00000000..92c2d48b --- /dev/null +++ b/org.mapleir.main/src/main/java/org/mapleir/Main.java @@ -0,0 +1,8 @@ +package org.mapleir; +/** + * @author Ghast + * @since 27/11/2020 + * mapleir © 2020 + */ +public class Main { +} From 09699a012fa490d426e20e43f5f1bf239b916d92 Mon Sep 17 00:00:00 2001 From: Thibaut Gautier Date: Sat, 28 Nov 2020 22:33:35 +0100 Subject: [PATCH 05/19] Fixed Locals not being properly versioned for the comparation and sort --- .../java/org/mapleir/ir/algorithms/LocalsReallocator.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/org.mapleir.ir/src/main/java/org/mapleir/ir/algorithms/LocalsReallocator.java b/org.mapleir.ir/src/main/java/org/mapleir/ir/algorithms/LocalsReallocator.java index 17eb735b..596ed05c 100644 --- a/org.mapleir.ir/src/main/java/org/mapleir/ir/algorithms/LocalsReallocator.java +++ b/org.mapleir.ir/src/main/java/org/mapleir/ir/algorithms/LocalsReallocator.java @@ -109,7 +109,9 @@ public int compare(Local o1, Local o2) { } else if (!s1 && s2) { return 1; } else { - return o1.compareTo(o2); + VersionedLocal vo1 = o1 instanceof VersionedLocal ? (VersionedLocal) o1 : cfg.getLocals().get(o1.getIndex(), 0); + VersionedLocal vo2 = o2 instanceof VersionedLocal ? (VersionedLocal) o2 : cfg.getLocals().get(o2.getIndex(), 0); + return vo1.compareTo(vo2); } } }); From 12834f9d482d9823d2c8926db040dbaec1b46102 Mon Sep 17 00:00:00 2001 From: Thibaut Gautier Date: Sun, 3 Jan 2021 14:56:01 +0100 Subject: [PATCH 06/19] Updated to ASM 9.0 --- .../org/mapleir/ir/algorithms/BoissinotDestructor.java | 1 + org.mapleir.main/src/main/java/org/mapleir/Boot.java | 4 ++-- org.mapleir.modasm/pom.xml | 8 ++++---- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/org.mapleir.ir/src/main/java/org/mapleir/ir/algorithms/BoissinotDestructor.java b/org.mapleir.ir/src/main/java/org/mapleir/ir/algorithms/BoissinotDestructor.java index 91433590..76c079b4 100644 --- a/org.mapleir.ir/src/main/java/org/mapleir/ir/algorithms/BoissinotDestructor.java +++ b/org.mapleir.ir/src/main/java/org/mapleir/ir/algorithms/BoissinotDestructor.java @@ -274,6 +274,7 @@ private void computeValueInterference() { Expr e = copy.getExpression(); Local b = copy.getVariable().getLocal(); + // Expression has to be a VarExpr if (!copy.isSynthetic() && e.getOpcode() == Opcode.LOCAL_LOAD) { LinkedHashSet vc = values.get(((VarExpr) e).getLocal()); vc.add(b); diff --git a/org.mapleir.main/src/main/java/org/mapleir/Boot.java b/org.mapleir.main/src/main/java/org/mapleir/Boot.java index 46635ed3..d6f122ce 100644 --- a/org.mapleir.main/src/main/java/org/mapleir/Boot.java +++ b/org.mapleir.main/src/main/java/org/mapleir/Boot.java @@ -228,14 +228,14 @@ private static IPass[] getTransformationPasses() { new PassGroup("Interprocedural Optimisations") .add( - new CallgraphPruningPass(), + /*new CallgraphPruningPass(), new ConcreteStaticInvocationPass(), new ConstantExpressionReorderPass(), //new ConstantParameterPass(), new DeadCodeEliminationPass(), //new DemoteRangesPass(), // Not done new DetectIrreducibleFlowPass(), - new LiftConstructorCallsPass() + new LiftConstructorCallsPass()*/ ), //new ConstantExpressionEvaluatorPass(), diff --git a/org.mapleir.modasm/pom.xml b/org.mapleir.modasm/pom.xml index 2c49555f..f8636cb3 100644 --- a/org.mapleir.modasm/pom.xml +++ b/org.mapleir.modasm/pom.xml @@ -20,22 +20,22 @@ org.ow2.asm asm - 7.1 + 9.0 org.ow2.asm asm-tree - 7.1 + 9.0 org.ow2.asm asm-util - 7.1 + 9.0 org.ow2.asm asm-commons - 7.1 + 9.0 From cce128ca4f22e07c2eb17320353988446e763ed3 Mon Sep 17 00:00:00 2001 From: Thibaut Gautier Date: Sun, 24 Jan 2021 13:45:15 +0100 Subject: [PATCH 07/19] Added arguments modifying, stack addition to blocks and other fixes --- .../java/org/mapleir/ir/cfg/BasicBlock.java | 10 ++++++++++ .../ir/cfg/builder/GenerationPass.java | 1 + .../org/mapleir/ir/code/ExpressionStack.java | 19 +++++++++++++++++++ .../expr/invoke/DynamicInvocationExpr.java | 8 ++++++-- .../ir/code/expr/invoke/InvocationExpr.java | 7 +++++++ .../main/java/org/mapleir/asm/ClassNode.java | 14 ++++++++++++++ .../main/java/org/mapleir/asm/MethodNode.java | 7 +++++++ 7 files changed, 64 insertions(+), 2 deletions(-) diff --git a/org.mapleir.ir/src/main/java/org/mapleir/ir/cfg/BasicBlock.java b/org.mapleir.ir/src/main/java/org/mapleir/ir/cfg/BasicBlock.java index ac14c36e..8fc9d42f 100644 --- a/org.mapleir.ir/src/main/java/org/mapleir/ir/cfg/BasicBlock.java +++ b/org.mapleir.ir/src/main/java/org/mapleir/ir/cfg/BasicBlock.java @@ -1,5 +1,6 @@ package org.mapleir.ir.cfg; +import org.mapleir.ir.code.ExpressionStack; import org.mapleir.ir.code.Stmt; import org.mapleir.stdlib.collections.graph.FastGraphVertex; import org.mapleir.stdlib.collections.list.NotifiedList; @@ -22,6 +23,7 @@ public class BasicBlock implements FastGraphVertex, Collection { private int id; public final ControlFlowGraph cfg; private final NotifiedList statements; + private ExpressionStack stack; private int flags = 0; // for debugging purposes. the number of times the label was changed @@ -215,6 +217,14 @@ public void clear() { statements.clear(); } + public ExpressionStack getStack() { + return stack; + } + + public void setStack(ExpressionStack stack) { + this.stack = stack; + } + @Override public Iterator iterator() { return statements.iterator(); diff --git a/org.mapleir.ir/src/main/java/org/mapleir/ir/cfg/builder/GenerationPass.java b/org.mapleir.ir/src/main/java/org/mapleir/ir/cfg/builder/GenerationPass.java index 075a462a..355234a2 100644 --- a/org.mapleir.ir/src/main/java/org/mapleir/ir/cfg/builder/GenerationPass.java +++ b/org.mapleir.ir/src/main/java/org/mapleir/ir/cfg/builder/GenerationPass.java @@ -121,6 +121,7 @@ protected void setInputStack(BasicBlock b, ExpressionStack s) { } inputStacks.put(b, s); + b.setStack(s); } protected ExpressionStack getInputStackFor(BasicBlock b) { diff --git a/org.mapleir.ir/src/main/java/org/mapleir/ir/code/ExpressionStack.java b/org.mapleir.ir/src/main/java/org/mapleir/ir/code/ExpressionStack.java index 6f7260c1..1518c4a3 100644 --- a/org.mapleir.ir/src/main/java/org/mapleir/ir/code/ExpressionStack.java +++ b/org.mapleir.ir/src/main/java/org/mapleir/ir/code/ExpressionStack.java @@ -1,5 +1,8 @@ package org.mapleir.ir.code; +import java.util.Arrays; +import java.util.Objects; + // top(0) -> bottom(size() - 1) public class ExpressionStack { @@ -102,6 +105,22 @@ public int height() { return count; } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof ExpressionStack)) return false; + ExpressionStack that = (ExpressionStack) o; + return size == that.size && + Arrays.equals(stack, that.stack); + } + + @Override + public int hashCode() { + int result = Objects.hash(size); + result = 31 * result + Arrays.hashCode(stack); + return result; + } + @Override public String toString() { StringBuilder sb = new StringBuilder(); diff --git a/org.mapleir.ir/src/main/java/org/mapleir/ir/code/expr/invoke/DynamicInvocationExpr.java b/org.mapleir.ir/src/main/java/org/mapleir/ir/code/expr/invoke/DynamicInvocationExpr.java index 5f2916fa..a78f4559 100644 --- a/org.mapleir.ir/src/main/java/org/mapleir/ir/code/expr/invoke/DynamicInvocationExpr.java +++ b/org.mapleir.ir/src/main/java/org/mapleir/ir/code/expr/invoke/DynamicInvocationExpr.java @@ -40,7 +40,7 @@ public DynamicInvocationExpr(Handle bootstrapMethod, Object[] bootstrapArgs, Str this.bootstrapMethod = bootstrapMethod; this.bootstrapArgs = bootstrapArgs; this.boundName = boundName; - assert(Type.getArgumentTypes(bootstrapDesc).length == args.length); // I hope this tells me when this fucks up, because this is not a matter of if, but when. + assert(Type.getArgumentTypes(bootstrapDesc).length == args.length) : "You fucked up"; // I hope this tells me when this fucks up, because this is not a matter of if, but when. for(int i = 0; i < args.length; i++) { writeAt(args[i], i); @@ -54,7 +54,11 @@ public Handle getBootstrapMethod() { public Object[] getBootstrapArgs() { return bootstrapArgs; } - + + public void setBootstrapArgs(Object[] bootstrapArgs) { + this.bootstrapArgs = bootstrapArgs; + } + public String getBoundName() { return boundName; } diff --git a/org.mapleir.ir/src/main/java/org/mapleir/ir/code/expr/invoke/InvocationExpr.java b/org.mapleir.ir/src/main/java/org/mapleir/ir/code/expr/invoke/InvocationExpr.java index 829aa801..d1aea689 100644 --- a/org.mapleir.ir/src/main/java/org/mapleir/ir/code/expr/invoke/InvocationExpr.java +++ b/org.mapleir.ir/src/main/java/org/mapleir/ir/code/expr/invoke/InvocationExpr.java @@ -207,6 +207,10 @@ public final Expr[] getArgumentExprs() { return args; } + public void setArgumentExprs(Expr[] args) { + this.args = args; + } + // @Override // public Set resolveTargets(InvocationResolver res) { // String owner = getOwner(); @@ -224,6 +228,9 @@ public final Expr[] getArgumentExprs() { // } // } + + + @Override public JavaDesc.DescType getDescType() { return JavaDesc.DescType.METHOD; diff --git a/org.mapleir.modasm/src/main/java/org/mapleir/asm/ClassNode.java b/org.mapleir.modasm/src/main/java/org/mapleir/asm/ClassNode.java index b8038b30..9446caf8 100644 --- a/org.mapleir.modasm/src/main/java/org/mapleir/asm/ClassNode.java +++ b/org.mapleir.modasm/src/main/java/org/mapleir/asm/ClassNode.java @@ -1,6 +1,8 @@ package org.mapleir.asm; import org.mapleir.stdlib.collections.graph.FastGraphVertex; +import org.objectweb.asm.Opcodes; + import java.util.ArrayList; import java.util.List; @@ -54,4 +56,16 @@ public String getDisplayName() { public int getNumericId() { return numericId; } + + public boolean isEnum() { + return (node.access & Opcodes.ACC_ENUM) != 0; + } + + public boolean isStatic() { + return (node.access & Opcodes.ACC_STATIC) != 0; + } + + public boolean isSynthetic() { + return (node.access & Opcodes.ACC_SYNTHETIC) != 0; + } } diff --git a/org.mapleir.modasm/src/main/java/org/mapleir/asm/MethodNode.java b/org.mapleir.modasm/src/main/java/org/mapleir/asm/MethodNode.java index a7a185d3..f92a5fda 100644 --- a/org.mapleir.modasm/src/main/java/org/mapleir/asm/MethodNode.java +++ b/org.mapleir.modasm/src/main/java/org/mapleir/asm/MethodNode.java @@ -3,6 +3,7 @@ import org.mapleir.stdlib.collections.graph.FastGraphVertex; import org.mapleir.stdlib.util.IHasJavaDesc; import org.mapleir.stdlib.util.JavaDesc; +import org.objectweb.asm.Opcodes; public class MethodNode implements FastGraphVertex, IHasJavaDesc { private static int ID_COUNTER = 1; @@ -55,4 +56,10 @@ public JavaDesc.DescType getDescType() { public JavaDesc getJavaDesc() { return new JavaDesc(owner.getName(), getName(), getDesc(), JavaDesc.DescType.METHOD); } + + public boolean isStatic() { + return (node.access & Opcodes.ACC_STATIC) != 0; + } + + } From 436ab510888b15226db5290e24b9bb3a51a0b68b Mon Sep 17 00:00:00 2001 From: Thibaut Gautier Date: Sun, 11 Apr 2021 21:36:22 +0200 Subject: [PATCH 08/19] Slight bug fixes and improvements --- .../java/org/mapleir/app/service/ClassSource.java | 4 ++++ .../mapleir/ir/algorithms/BoissinotDestructor.java | 14 +++++++++----- .../src/main/java/org/mapleir/asm/MethodNode.java | 6 ++++++ 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/org.mapleir.app-services/src/main/java/org/mapleir/app/service/ClassSource.java b/org.mapleir.app-services/src/main/java/org/mapleir/app/service/ClassSource.java index 5c820735..199ffe30 100644 --- a/org.mapleir.app-services/src/main/java/org/mapleir/app/service/ClassSource.java +++ b/org.mapleir.app-services/src/main/java/org/mapleir/app/service/ClassSource.java @@ -71,4 +71,8 @@ public Iterable iterate() { public Iterator iterator() { return nodeMap.values().iterator(); } + + public int size() { + return nodeMap.size(); + } } diff --git a/org.mapleir.ir/src/main/java/org/mapleir/ir/algorithms/BoissinotDestructor.java b/org.mapleir.ir/src/main/java/org/mapleir/ir/algorithms/BoissinotDestructor.java index 76c079b4..dc73c2e6 100644 --- a/org.mapleir.ir/src/main/java/org/mapleir/ir/algorithms/BoissinotDestructor.java +++ b/org.mapleir.ir/src/main/java/org/mapleir/ir/algorithms/BoissinotDestructor.java @@ -901,11 +901,15 @@ public boolean equivalent(CodeUnit s) { private class CongruenceClass extends TreeSet { private static final long serialVersionUID = -4472334406997712498L; - CongruenceClass() { - super((o1, o2) -> { - if (o1 == o2) - return 0; - return ((defuse.defIndex.get(o1) - defuse.defIndex.get(o2))) >> 31 | 1; + protected CongruenceClass() { + super(new Comparator() { + @Override + public int compare(Local o1, Local o2) { + if (o1 == o2) + return 0; + return ((BoissinotDestructor.this.defuse.defIndex.get(o1) - BoissinotDestructor. + this.defuse.defIndex.get(o2))) >> 31 | 1; + } }); } } diff --git a/org.mapleir.modasm/src/main/java/org/mapleir/asm/MethodNode.java b/org.mapleir.modasm/src/main/java/org/mapleir/asm/MethodNode.java index f92a5fda..db81bba5 100644 --- a/org.mapleir.modasm/src/main/java/org/mapleir/asm/MethodNode.java +++ b/org.mapleir.modasm/src/main/java/org/mapleir/asm/MethodNode.java @@ -61,5 +61,11 @@ public boolean isStatic() { return (node.access & Opcodes.ACC_STATIC) != 0; } + public boolean isAbstract() { + return (node.access & Opcodes.ACC_ABSTRACT) != 0; + } + public boolean isNative() { + return (node.access & Opcodes.ACC_NATIVE) != 0; + } } From 7a2d92cc549cbd63f2145daaec45fff17ef2323e Mon Sep 17 00:00:00 2001 From: Thibaut Gautier Date: Tue, 27 Jul 2021 13:29:25 +0300 Subject: [PATCH 09/19] Slight fixes --- org.mapleir.ir/pom.xml | 2 +- org.mapleir.parent/pom.xml | 1 + org.mapleir.topdank-services/pom.xml | 5 +++++ .../commons/classloader/JarClassLoader.java | 12 ++++++------ 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/org.mapleir.ir/pom.xml b/org.mapleir.ir/pom.xml index fb12e4fb..58c24a39 100644 --- a/org.mapleir.ir/pom.xml +++ b/org.mapleir.ir/pom.xml @@ -34,7 +34,7 @@ org.projectlombok lombok - 1.18.12 + 1.18.20 provided diff --git a/org.mapleir.parent/pom.xml b/org.mapleir.parent/pom.xml index 39f132d1..6a04d078 100644 --- a/org.mapleir.parent/pom.xml +++ b/org.mapleir.parent/pom.xml @@ -73,6 +73,7 @@ + ${java.home}/bin/javadoc diff --git a/org.mapleir.topdank-services/pom.xml b/org.mapleir.topdank-services/pom.xml index c7cdfd60..25f68f19 100644 --- a/org.mapleir.topdank-services/pom.xml +++ b/org.mapleir.topdank-services/pom.xml @@ -15,6 +15,11 @@ gson 2.8.5 + + org.danilopianini + urlclassloader-util + 0.1.1 + org.mapleir modasm diff --git a/org.mapleir.topdank-services/src/main/java/org/topdank/byteengineer/commons/classloader/JarClassLoader.java b/org.mapleir.topdank-services/src/main/java/org/topdank/byteengineer/commons/classloader/JarClassLoader.java index e788940a..f61fa42c 100644 --- a/org.mapleir.topdank-services/src/main/java/org/topdank/byteengineer/commons/classloader/JarClassLoader.java +++ b/org.mapleir.topdank-services/src/main/java/org/topdank/byteengineer/commons/classloader/JarClassLoader.java @@ -1,16 +1,16 @@ package org.topdank.byteengineer.commons.classloader; import java.net.URL; +import java.net.URLClassLoader; import java.util.HashMap; import java.util.Map; +import org.danilopianini.urlclassloader.URLClassLoaderUtil; import org.mapleir.asm.ClassNode; import org.topdank.byteengineer.commons.asm.ASMFactory; import org.topdank.byteengineer.commons.asm.DefaultASMFactory; import org.topdank.byteengineer.commons.data.LocateableJarContents; -import sun.misc.URLClassPath; - /** * Specific {@link ClassLoader} for loading things from external JarFiles, caching loaded classes as it goes along.
* @@ -23,7 +23,7 @@ public class JarClassLoader extends ClassLoader { private Map fastNodeCache; private Map> cache; - private URLClassPath ucp; + private ClassLoader ucp; public JarClassLoader(LocateableJarContents contents) { this(contents, null, new DefaultASMFactory()); @@ -51,7 +51,7 @@ public JarClassLoader(LocateableJarContents contents, ClassLoader par cache = new HashMap<>(); fastNodeCache = new HashMap<>(); - ucp = new URLClassPath(new URL[0]); + ucp = new URLClassLoader(new URL[0]); add(contents); StackTraceElement e = creator(false); @@ -76,7 +76,7 @@ private static StackTraceElement creator(boolean cl) { public void add(LocateableJarContents contents) { for (URL url : contents.getJarUrls()) { - ucp.addURL(url); + URLClassLoaderUtil.addLast(url, ucp); } for (ClassNode cn : contents.getClassContents()) { fastNodeCache.put(cn.getName(), cn); @@ -85,7 +85,7 @@ public void add(LocateableJarContents contents) { @Override public URL findResource(String name) { - return ucp.findResource(name, true); + return ucp.getResource(name); } /** From e5869d12b36b29b47c5820dae6f6448774bfbbb8 Mon Sep 17 00:00:00 2001 From: Thibaut Gautier Date: Sat, 2 Oct 2021 19:34:06 +0200 Subject: [PATCH 10/19] Changes --- .../ir/cfg/builder/ControlFlowGraphBuilder.java | 6 ++++++ .../org/mapleir/ir/cfg/builder/GenerationPass.java | 1 + .../ir/code/expr/invoke/DynamicInvocationExpr.java | 6 +++++- .../src/main/java/org/mapleir/ir/locals/Local.java | 10 +++++++++- .../main/java/org/mapleir/ir/locals/LocalsPool.java | 3 +++ 5 files changed, 24 insertions(+), 2 deletions(-) diff --git a/org.mapleir.ir/src/main/java/org/mapleir/ir/cfg/builder/ControlFlowGraphBuilder.java b/org.mapleir.ir/src/main/java/org/mapleir/ir/cfg/builder/ControlFlowGraphBuilder.java index be8a00ac..2ef3461e 100644 --- a/org.mapleir.ir/src/main/java/org/mapleir/ir/cfg/builder/ControlFlowGraphBuilder.java +++ b/org.mapleir.ir/src/main/java/org/mapleir/ir/cfg/builder/ControlFlowGraphBuilder.java @@ -42,6 +42,12 @@ public ControlFlowGraphBuilder(MethodNode method, boolean optimise) { graph = new ControlFlowGraph(new VirtualMethodLocalsPool(), method.getJavaDesc()); } locals = new HashSet<>(); + + // Reserved self reference local + if (!method.isStatic()) { + locals.add(graph.getLocals().get(0, false)); + } + assigns = new NullPermeableHashMap<>(HashSet::new); } diff --git a/org.mapleir.ir/src/main/java/org/mapleir/ir/cfg/builder/GenerationPass.java b/org.mapleir.ir/src/main/java/org/mapleir/ir/cfg/builder/GenerationPass.java index 355234a2..2f06693c 100644 --- a/org.mapleir.ir/src/main/java/org/mapleir/ir/cfg/builder/GenerationPass.java +++ b/org.mapleir.ir/src/main/java/org/mapleir/ir/cfg/builder/GenerationPass.java @@ -1272,6 +1272,7 @@ protected CopyVarStmt copy(VarExpr v, Expr e, BasicBlock b) { protected VarExpr _var_expr(int index, Type type, boolean isStack) { Local l = builder.graph.getLocals().get(index, isStack); + l.setType(type); builder.locals.add(l); return new VarExpr(l, type); } diff --git a/org.mapleir.ir/src/main/java/org/mapleir/ir/code/expr/invoke/DynamicInvocationExpr.java b/org.mapleir.ir/src/main/java/org/mapleir/ir/code/expr/invoke/DynamicInvocationExpr.java index a78f4559..33cc9b5c 100644 --- a/org.mapleir.ir/src/main/java/org/mapleir/ir/code/expr/invoke/DynamicInvocationExpr.java +++ b/org.mapleir.ir/src/main/java/org/mapleir/ir/code/expr/invoke/DynamicInvocationExpr.java @@ -1,5 +1,6 @@ package org.mapleir.ir.code.expr.invoke; +import org.apache.log4j.Logger; import org.mapleir.app.service.InvocationResolver; import org.mapleir.ir.code.CodeUnit; import org.mapleir.ir.code.Expr; @@ -159,7 +160,10 @@ public Set resolveTargets(InvocationResolver res) { case Opcodes.H_INVOKESTATIC: return StaticInvocationExpr.resolveStaticCall(res, boundFunc.getOwner(), boundFunc.getName(), boundFunc.getDesc()); case Opcodes.H_INVOKESPECIAL: - assert(boundFunc.getName().equals("")); + if (!boundFunc.getName().equals("")) { + Logger.getLogger(this.getClass()).warn("Lambda function invocation of type H_INVOKESPECIAL is linking against " + boundFunc.getName()); + } + //assert(boundFunc.getName().equals("")); return VirtualInvocationExpr.resolveSpecialInvocation(res, boundFunc.getOwner(), boundFunc.getDesc()); case Opcodes.H_INVOKEINTERFACE: case Opcodes.H_INVOKEVIRTUAL: diff --git a/org.mapleir.ir/src/main/java/org/mapleir/ir/locals/Local.java b/org.mapleir.ir/src/main/java/org/mapleir/ir/locals/Local.java index 2601aed3..c3cc93e6 100644 --- a/org.mapleir.ir/src/main/java/org/mapleir/ir/locals/Local.java +++ b/org.mapleir.ir/src/main/java/org/mapleir/ir/locals/Local.java @@ -2,8 +2,10 @@ public abstract class Local implements Comparable { +import org.objectweb.asm.Type; + private Type type; private final boolean stack; - private final int index; + private int index; private boolean tempLocal; public Local(int index) { @@ -52,6 +54,12 @@ public boolean isStoredInLocal() { return !isStack() || isTempLocal(); } + public void setIndex(int index) { + this.index = index; + } + public void setType(Type type) { + this.type = type; + } @Override public int compareTo(Local o) { if(stack && !o.stack) { diff --git a/org.mapleir.ir/src/main/java/org/mapleir/ir/locals/LocalsPool.java b/org.mapleir.ir/src/main/java/org/mapleir/ir/locals/LocalsPool.java index a441e51d..6a52f116 100644 --- a/org.mapleir.ir/src/main/java/org/mapleir/ir/locals/LocalsPool.java +++ b/org.mapleir.ir/src/main/java/org/mapleir/ir/locals/LocalsPool.java @@ -65,6 +65,9 @@ public GenericBitSet createBitSet() { public GenericBitSet create() { return createBitSet(); } + public Map getCache() { + return cache; + } // end factory public BasicLocal asSimpleLocal(Local l) { From 479e7dafb637dc1f64d35c7a8e8d710f49398587 Mon Sep 17 00:00:00 2001 From: Thibaut Gautier Date: Fri, 29 Oct 2021 12:59:44 +0200 Subject: [PATCH 11/19] I'm actually retarded --- org.mapleir.ir/src/main/java/org/mapleir/ir/locals/Local.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/org.mapleir.ir/src/main/java/org/mapleir/ir/locals/Local.java b/org.mapleir.ir/src/main/java/org/mapleir/ir/locals/Local.java index c3cc93e6..e955f02e 100644 --- a/org.mapleir.ir/src/main/java/org/mapleir/ir/locals/Local.java +++ b/org.mapleir.ir/src/main/java/org/mapleir/ir/locals/Local.java @@ -1,8 +1,9 @@ package org.mapleir.ir.locals; +import org.objectweb.asm.Type; + public abstract class Local implements Comparable { -import org.objectweb.asm.Type; private Type type; private final boolean stack; private int index; From 05dffb348a056f067ef19ac6167ca84548bbb0ee Mon Sep 17 00:00:00 2001 From: Thibaut Gautier Date: Tue, 2 Nov 2021 01:54:40 +0100 Subject: [PATCH 12/19] Added exception fixer + another change --- .../main/java/org/mapleir/ir/code/Expr.java | 2 +- .../ir/codegen/ControlFlowGraphDumper.java | 8 +++ .../src/main/java/org/mapleir/Boot.java | 1 - .../deob/passes/fixer/ExceptionFixerPass.java | 67 +++++++++++++++++++ 4 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 org.mapleir.main/src/main/java/org/mapleir/deob/passes/fixer/ExceptionFixerPass.java diff --git a/org.mapleir.ir/src/main/java/org/mapleir/ir/code/Expr.java b/org.mapleir.ir/src/main/java/org/mapleir/ir/code/Expr.java index b116b3ad..2d8c279c 100644 --- a/org.mapleir.ir/src/main/java/org/mapleir/ir/code/Expr.java +++ b/org.mapleir.ir/src/main/java/org/mapleir/ir/code/Expr.java @@ -64,7 +64,7 @@ public void unlink() { } } - protected void setParent(CodeUnit parent) { + public void setParent(CodeUnit parent) { this.parent = parent; if(parent != null) { setBlock(parent.getBlock()); diff --git a/org.mapleir.ir/src/main/java/org/mapleir/ir/codegen/ControlFlowGraphDumper.java b/org.mapleir.ir/src/main/java/org/mapleir/ir/codegen/ControlFlowGraphDumper.java index 3c570f59..90d86946 100644 --- a/org.mapleir.ir/src/main/java/org/mapleir/ir/codegen/ControlFlowGraphDumper.java +++ b/org.mapleir.ir/src/main/java/org/mapleir/ir/codegen/ControlFlowGraphDumper.java @@ -1,5 +1,6 @@ package org.mapleir.ir.codegen; +import com.google.common.collect.Streams; import org.mapleir.flowgraph.ExceptionRange; import org.mapleir.flowgraph.edges.FlowEdge; import org.mapleir.flowgraph.edges.FlowEdges; @@ -8,8 +9,13 @@ import org.mapleir.ir.TypeUtils; import org.mapleir.ir.cfg.BasicBlock; import org.mapleir.ir.cfg.ControlFlowGraph; +import org.mapleir.ir.code.Expr; import org.mapleir.ir.code.Stmt; +import org.mapleir.ir.code.expr.CastExpr; +import org.mapleir.ir.code.expr.VarExpr; import org.mapleir.ir.code.stmt.UnconditionalJumpStmt; +import org.mapleir.ir.code.stmt.copy.CopyVarStmt; +import org.mapleir.ir.locals.Local; import org.mapleir.stdlib.collections.graph.*; import org.mapleir.stdlib.collections.graph.algorithms.SimpleDfs; import org.mapleir.stdlib.collections.graph.algorithms.TarjanSCC; @@ -22,6 +28,7 @@ import org.objectweb.asm.tree.TryCatchBlockNode; import java.util.*; +import java.util.stream.Collectors; public class ControlFlowGraphDumper implements BytecodeFrontend { private final ControlFlowGraph cfg; @@ -258,6 +265,7 @@ private void dumpRange(ExceptionRange er) { if (typeSet.size() != 1) { // TODO: find base exception type = TypeUtils.THROWABLE; + System.err.println("[fatal] No compatible exception at " + m + " : " + Arrays.toString(typeSet.toArray())); } else { type = typeSet.iterator().next(); } diff --git a/org.mapleir.main/src/main/java/org/mapleir/Boot.java b/org.mapleir.main/src/main/java/org/mapleir/Boot.java index d6f122ce..2402c98b 100644 --- a/org.mapleir.main/src/main/java/org/mapleir/Boot.java +++ b/org.mapleir.main/src/main/java/org/mapleir/Boot.java @@ -52,7 +52,6 @@ private static LibraryClassSource rt(ApplicationClassSource app, File rtjar) thr } public static void main(String[] args) throws Exception { - sections = new LinkedList<>(); logging = true; diff --git a/org.mapleir.main/src/main/java/org/mapleir/deob/passes/fixer/ExceptionFixerPass.java b/org.mapleir.main/src/main/java/org/mapleir/deob/passes/fixer/ExceptionFixerPass.java new file mode 100644 index 00000000..21284308 --- /dev/null +++ b/org.mapleir.main/src/main/java/org/mapleir/deob/passes/fixer/ExceptionFixerPass.java @@ -0,0 +1,67 @@ +package org.mapleir.deob.passes.fixer; + +import com.google.common.collect.Lists; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; +import org.mapleir.asm.ClassNode; +import org.mapleir.deob.IPass; +import org.mapleir.deob.PassContext; +import org.mapleir.deob.PassResult; +import org.mapleir.flowgraph.ExceptionRange; +import org.mapleir.ir.cfg.BasicBlock; +import org.mapleir.ir.cfg.ControlFlowGraph; +import org.objectweb.asm.Type; + +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; + +public class ExceptionFixerPass implements IPass { + private final Logger logger = LogManager.getLogger(this.getClass()); + + @Override + public PassResult accept(PassContext cxt) { + final AtomicInteger counter = new AtomicInteger(); + + for (ControlFlowGraph value : cxt.getAnalysis().getIRCache().values()) { + for (ExceptionRange range : value.getRanges()) { + if (range.getTypes().size() <= 1) + continue; + + final Stack stack = new Stack<>(); + for (Type type : range.getTypes()) { + final ClassNode classNode = cxt.getAnalysis().getApplication().findClassNode(type.getClassName()); + + final List classNodeList = cxt.getAnalysis().getApplication().getClassTree().getAllParents(classNode); + + if (stack.isEmpty()) { + stack.add(classNode); + stack.addAll(Lists.reverse(classNodeList)); + } else { + final Stack toIterate = new Stack<>(); + toIterate.add(classNode); + toIterate.addAll(Lists.reverse(classNodeList)); + + runner: { + while (!stack.isEmpty()) { + for (ClassNode node : toIterate) { + if (node.equals(stack.peek())) + break runner; + } + + stack.pop(); + } + + logger.fatal("[*] Could not find common exception type between " + Arrays.toString(range.getTypes().toArray())); + } + } + } + + counter.incrementAndGet(); + range.setTypes(new HashSet<>(Collections.singleton(Type.getType(stack.peek().getName())))); + } + } + + logger.info("[*] Successfully fixed" + counter.get() + " exception ranges!"); + return PassResult.with(cxt, this).finished().make(); + } +} From b1b410bf48273ac44a5007a477511d4b7e6acc09 Mon Sep 17 00:00:00 2001 From: Thibaut Gautier Date: Wed, 3 Nov 2021 17:35:28 +0100 Subject: [PATCH 13/19] Added fixes for passes --- .../mapleir/deob/passes/ConstantExpressionReorderPass.java | 2 +- .../org/mapleir/deob/passes/DeadCodeEliminationPass.java | 6 +++--- .../passes/constparam/ConstantExpressionEvaluatorPass.java | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/org.mapleir.main/src/main/java/org/mapleir/deob/passes/ConstantExpressionReorderPass.java b/org.mapleir.main/src/main/java/org/mapleir/deob/passes/ConstantExpressionReorderPass.java index 9cd3168e..65f166cb 100644 --- a/org.mapleir.main/src/main/java/org/mapleir/deob/passes/ConstantExpressionReorderPass.java +++ b/org.mapleir.main/src/main/java/org/mapleir/deob/passes/ConstantExpressionReorderPass.java @@ -35,7 +35,7 @@ public PassResult accept(PassContext pcxt) { return PassResult.with(pcxt, this).finished(delta).make(); } - private int transform(ControlFlowGraph ir) { + public int transform(ControlFlowGraph ir) { int i = 0; for(BasicBlock b : ir.vertices()) { diff --git a/org.mapleir.main/src/main/java/org/mapleir/deob/passes/DeadCodeEliminationPass.java b/org.mapleir.main/src/main/java/org/mapleir/deob/passes/DeadCodeEliminationPass.java index 42376b28..6707d9a3 100644 --- a/org.mapleir.main/src/main/java/org/mapleir/deob/passes/DeadCodeEliminationPass.java +++ b/org.mapleir.main/src/main/java/org/mapleir/deob/passes/DeadCodeEliminationPass.java @@ -28,9 +28,9 @@ import java.util.List; public class DeadCodeEliminationPass implements IPass { - int deadBlocks = 0; - int immediateJumps = 0; - int deadLocals = 0; + public int deadBlocks = 0; + public int immediateJumps = 0; + public int deadLocals = 0; public void process(ControlFlowGraph cfg) { LocalsPool lp = cfg.getLocals(); diff --git a/org.mapleir.main/src/main/java/org/mapleir/deob/passes/constparam/ConstantExpressionEvaluatorPass.java b/org.mapleir.main/src/main/java/org/mapleir/deob/passes/constparam/ConstantExpressionEvaluatorPass.java index ffcdc6bf..bce79dbe 100644 --- a/org.mapleir.main/src/main/java/org/mapleir/deob/passes/constparam/ConstantExpressionEvaluatorPass.java +++ b/org.mapleir.main/src/main/java/org/mapleir/deob/passes/constparam/ConstantExpressionEvaluatorPass.java @@ -78,7 +78,7 @@ public PassResult accept(PassContext pcxt) { return PassResult.with(pcxt, this).finished(exprsEvaluated).make(); } - private void processMethod(MethodNode m, IPConstAnalysisVisitor vis, ControlFlowGraph cfg) { + public void processMethod(MethodNode m, IPConstAnalysisVisitor vis, ControlFlowGraph cfg) { for(BasicBlock b : new HashSet<>(cfg.vertices())) { for(int i=0; i < b.size(); i++) { Stmt stmt = b.get(i); From 8f41205a8027a33f9ba6174737ce0e76bfcf274b Mon Sep 17 00:00:00 2001 From: Thibaut Gautier Date: Wed, 3 Nov 2021 17:42:35 +0100 Subject: [PATCH 14/19] Fixer upper --- .../deob/passes/constparam/ConstantExpressionEvaluatorPass.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.mapleir.main/src/main/java/org/mapleir/deob/passes/constparam/ConstantExpressionEvaluatorPass.java b/org.mapleir.main/src/main/java/org/mapleir/deob/passes/constparam/ConstantExpressionEvaluatorPass.java index bce79dbe..8f73d19b 100644 --- a/org.mapleir.main/src/main/java/org/mapleir/deob/passes/constparam/ConstantExpressionEvaluatorPass.java +++ b/org.mapleir.main/src/main/java/org/mapleir/deob/passes/constparam/ConstantExpressionEvaluatorPass.java @@ -271,7 +271,7 @@ public TaintableSet getValues(ControlFlowGraph cfg, Local l) { /** * Stores information regarding constant parameters encountered during call tracing. */ - private class IPConstAnalysisVisitor implements IPAnalysisVisitor { + public class IPConstAnalysisVisitor implements IPAnalysisVisitor { final AnalysisContext cxt; final Map>> constParams = new HashMap<>(); From d6ad7c95da25f7c2f40aa8d26da295848187dbe9 Mon Sep 17 00:00:00 2001 From: Thibaut Gautier Date: Wed, 3 Nov 2021 17:53:49 +0100 Subject: [PATCH 15/19] The fact I have to make a new release for this makes me want to cry --- .../passes/constparam/ConstantExpressionEvaluatorPass.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/org.mapleir.main/src/main/java/org/mapleir/deob/passes/constparam/ConstantExpressionEvaluatorPass.java b/org.mapleir.main/src/main/java/org/mapleir/deob/passes/constparam/ConstantExpressionEvaluatorPass.java index 8f73d19b..880c6ae4 100644 --- a/org.mapleir.main/src/main/java/org/mapleir/deob/passes/constparam/ConstantExpressionEvaluatorPass.java +++ b/org.mapleir.main/src/main/java/org/mapleir/deob/passes/constparam/ConstantExpressionEvaluatorPass.java @@ -223,7 +223,7 @@ public Boolean evaluateConditional(IPConstAnalysisVisitor vis, ControlFlowGraph /** * Provides values of locals based on constant parameter information from call trace (IPConstAnalysisVisitor) */ - private class SemiConstantLocalValueResolver implements LocalValueResolver { + public static class SemiConstantLocalValueResolver implements LocalValueResolver { private final IPConstAnalysisVisitor vis; @@ -271,7 +271,7 @@ public TaintableSet getValues(ControlFlowGraph cfg, Local l) { /** * Stores information regarding constant parameters encountered during call tracing. */ - public class IPConstAnalysisVisitor implements IPAnalysisVisitor { + public static class IPConstAnalysisVisitor implements IPAnalysisVisitor { final AnalysisContext cxt; final Map>> constParams = new HashMap<>(); From 32693feeaafe7a1f4f80abe199696fb470614e36 Mon Sep 17 00:00:00 2001 From: Thibaut Gautier Date: Sat, 27 Nov 2021 01:22:14 +0100 Subject: [PATCH 16/19] Triple ClassTree performance by adding cache + fixed IR tracer choking itself on invoke dynamics --- .../org/mapleir/app/service/ClassTree.java | 25 ++++++++++++++++--- .../mapleir/deob/interproc/IRCallTracer.java | 12 ++++++++- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/org.mapleir.app-services/src/main/java/org/mapleir/app/service/ClassTree.java b/org.mapleir.app-services/src/main/java/org/mapleir/app/service/ClassTree.java index e316313b..583bce25 100644 --- a/org.mapleir.app-services/src/main/java/org/mapleir/app/service/ClassTree.java +++ b/org.mapleir.app-services/src/main/java/org/mapleir/app/service/ClassTree.java @@ -28,7 +28,10 @@ public class ClassTree extends FastDirectedGraph { private final ApplicationClassSource source; private final ClassNode rootNode; private final boolean allowPhantomClasses; - + + private final Map> parentCache = new HashMap<>(); + private final Map> childCache = new HashMap<>(); + public ClassTree(ApplicationClassSource source) { this(source, ALLOW_PHANTOM_CLASSES); } @@ -101,7 +104,15 @@ public List getAllParents(ClassNode cn) { if(!containsVertex(cn)) { return new ArrayList<>(); } - return SimpleDfs.topoorder(this, cn, false); + + List classNodes = parentCache.get(cn); + + if (classNodes == null) { + classNodes = SimpleDfs.topoorder(this, cn, false); + parentCache.put(cn, classNodes); + } + + return classNodes; } // returns a postorder traversal of the graph starting from cn following edges in opposite direction. @@ -109,7 +120,15 @@ public List getAllChildren(ClassNode cn) { if(!containsVertex(cn)) { return new ArrayList<>(); } - return SimpleDfs.postorder(this, cn, true); + + List classNodes = childCache.get(cn); + + if (classNodes == null) { + classNodes = SimpleDfs.postorder(this, cn, true); + childCache.put(cn, classNodes); + } + + return classNodes; } /** diff --git a/org.mapleir.main/src/main/java/org/mapleir/deob/interproc/IRCallTracer.java b/org.mapleir.main/src/main/java/org/mapleir/deob/interproc/IRCallTracer.java index 405ead37..c1f3bfd6 100644 --- a/org.mapleir.main/src/main/java/org/mapleir/deob/interproc/IRCallTracer.java +++ b/org.mapleir.main/src/main/java/org/mapleir/deob/interproc/IRCallTracer.java @@ -42,10 +42,20 @@ protected void traceImpl(MethodNode m) { } private void traceInvocation(MethodNode m, Invocation invoke) { - Set targets = invoke.resolveTargets(resolver); + Set targets; + + try { + targets = invoke.resolveTargets(resolver); + } catch (Throwable e) { + LOGGER.warn(String.format("can't resolve call to %s.%s %s%s%s", invoke.getOwner(), + invoke.getName(), invoke.getDesc(), invoke.isStatic() ? "(static)" : "", invoke.isDynamic() ? "(dynamic)" : "")); + LOGGER.warn(String.format(" call from %s", m)); + return; + } if (targets.size() != 0) { for (MethodNode vtarg : targets) { + trace(vtarg); processedInvocation(m, vtarg, invoke); } From 9943d772212ee944d822913b20bc3eeea4916887 Mon Sep 17 00:00:00 2001 From: Thibaut Gautier Date: Wed, 5 Jan 2022 01:02:35 +0100 Subject: [PATCH 17/19] Updated Maven naming --- .gitignore | 2 ++ org.mapleir.app-services/pom.xml | 8 ++++---- org.mapleir.dot4j/pom.xml | 4 ++-- org.mapleir.flowgraph/pom.xml | 10 +++++----- org.mapleir.ir.printer/pom.xml | 6 +++--- org.mapleir.ir/pom.xml | 12 ++++++------ org.mapleir.modasm/pom.xml | 4 ++-- org.mapleir.parent/pom.xml | 4 ++-- org.mapleir.property-framework/pom.xml | 3 ++- org.mapleir.service-framework.api/pom.xml | 4 ++-- org.mapleir.service-framework.impl/pom.xml | 4 ++-- org.mapleir.service-util/pom.xml | 4 ++-- org.mapleir.stdlib/pom.xml | 6 +++--- org.mapleir.topdank-services/pom.xml | 6 +++--- pom.xml | 4 ++-- 15 files changed, 42 insertions(+), 39 deletions(-) diff --git a/.gitignore b/.gitignore index da9b6b88..4df10c01 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,8 @@ .idea/* *.iml +# MacOS +*.DS_Store # Maven output */target/* diff --git a/org.mapleir.app-services/pom.xml b/org.mapleir.app-services/pom.xml index c8a60e6f..b041eb18 100644 --- a/org.mapleir.app-services/pom.xml +++ b/org.mapleir.app-services/pom.xml @@ -3,22 +3,22 @@ org.mapleir parent - 0.0.1-ALPHA + 1.0.0-SNAPSHOT ../org.mapleir.parent org.mapleir - app-services + MapleIR-app-services app-services org.mapleir modasm - 0.0.1-ALPHA + 1.0.0-SNAPSHOT org.mapleir topdank-services - 0.0.1-ALPHA + 1.0.0-SNAPSHOT \ No newline at end of file diff --git a/org.mapleir.dot4j/pom.xml b/org.mapleir.dot4j/pom.xml index 533968e5..5f00e3af 100644 --- a/org.mapleir.dot4j/pom.xml +++ b/org.mapleir.dot4j/pom.xml @@ -3,9 +3,9 @@ org.mapleir parent - 0.0.1-ALPHA + 1.0.0-SNAPSHOT ../org.mapleir.parent dot4j - dot4j + MapleIR-dot4j \ No newline at end of file diff --git a/org.mapleir.flowgraph/pom.xml b/org.mapleir.flowgraph/pom.xml index 13e3a264..eb3aa4da 100644 --- a/org.mapleir.flowgraph/pom.xml +++ b/org.mapleir.flowgraph/pom.xml @@ -3,29 +3,29 @@ org.mapleir parent - 0.0.1-ALPHA + 1.0.0-SNAPSHOT ../org.mapleir.parent - flowgraph + MapleIR-flowgraph flowgraph org.mapleir org.mapleir stdlib - 0.0.1-ALPHA + 1.0.0-SNAPSHOT org.mapleir stdlib - 0.0.1-ALPHA + 1.0.0-SNAPSHOT test-jar test org.mapleir modasm - 0.0.1-ALPHA + 1.0.0-SNAPSHOT \ No newline at end of file diff --git a/org.mapleir.ir.printer/pom.xml b/org.mapleir.ir.printer/pom.xml index 298388a9..1a1663e6 100644 --- a/org.mapleir.ir.printer/pom.xml +++ b/org.mapleir.ir.printer/pom.xml @@ -5,19 +5,19 @@ org.mapleir parent - 0.0.1-ALPHA + 1.0.0-SNAPSHOT ../org.mapleir.parent org.mapleir ir.printer - ir.printer + MapleIR-ir.printer org.mapleir ir - 0.0.1-ALPHA + 1.0.0-SNAPSHOT org.mapleir diff --git a/org.mapleir.ir/pom.xml b/org.mapleir.ir/pom.xml index 58c24a39..bb3497d5 100644 --- a/org.mapleir.ir/pom.xml +++ b/org.mapleir.ir/pom.xml @@ -3,33 +3,33 @@ org.mapleir parent - 0.0.1-ALPHA + 1.0.0-SNAPSHOT ../org.mapleir.parent org.mapleir - ir + MapleIR-ir ir org.mapleir stdlib - 0.0.1-ALPHA + 1.0.0-SNAPSHOT org.mapleir modasm - 0.0.1-ALPHA + 1.0.0-SNAPSHOT org.mapleir flowgraph - 0.0.1-ALPHA + 1.0.0-SNAPSHOT org.mapleir app-services - 0.0.1-ALPHA + 1.0.0-SNAPSHOT org.projectlombok diff --git a/org.mapleir.modasm/pom.xml b/org.mapleir.modasm/pom.xml index f8636cb3..d11dc00f 100644 --- a/org.mapleir.modasm/pom.xml +++ b/org.mapleir.modasm/pom.xml @@ -4,13 +4,13 @@ org.mapleir parent - 0.0.1-ALPHA + 1.0.0-SNAPSHOT ../org.mapleir.parent org.mapleir modasm - modasm + MapleIR-modasm org.mapleir diff --git a/org.mapleir.parent/pom.xml b/org.mapleir.parent/pom.xml index 6a04d078..db35175b 100644 --- a/org.mapleir.parent/pom.xml +++ b/org.mapleir.parent/pom.xml @@ -4,10 +4,10 @@ org.mapleir parent - 0.0.1-ALPHA + 1.0.0-SNAPSHOT pom - parent + MapleIR-parent UTF-8 diff --git a/org.mapleir.property-framework/pom.xml b/org.mapleir.property-framework/pom.xml index 644f7d29..62f68bc9 100644 --- a/org.mapleir.property-framework/pom.xml +++ b/org.mapleir.property-framework/pom.xml @@ -3,11 +3,12 @@ org.mapleir property-framework 0.0.1-SNAPSHOT + MapleIR-property-framework org.mapleir parent - 0.0.1-ALPHA + 1.0.0-SNAPSHOT ../org.mapleir.parent \ No newline at end of file diff --git a/org.mapleir.service-framework.api/pom.xml b/org.mapleir.service-framework.api/pom.xml index 90414de3..82895968 100644 --- a/org.mapleir.service-framework.api/pom.xml +++ b/org.mapleir.service-framework.api/pom.xml @@ -3,12 +3,12 @@ org.mapleir service-framework-api 0.0.1-SNAPSHOT - Service provider API + MapleIR-service-provider-api org.mapleir parent - 0.0.1-ALPHA + 1.0.0-SNAPSHOT ../org.mapleir.parent diff --git a/org.mapleir.service-framework.impl/pom.xml b/org.mapleir.service-framework.impl/pom.xml index b1a870b0..360ba8ec 100644 --- a/org.mapleir.service-framework.impl/pom.xml +++ b/org.mapleir.service-framework.impl/pom.xml @@ -3,12 +3,12 @@ org.mapleir service-framework-impl 0.0.1-SNAPSHOT - Service provider impl + MapleIR-service-provider-impl org.mapleir parent - 0.0.1-ALPHA + 1.0.0-SNAPSHOT ../org.mapleir.parent diff --git a/org.mapleir.service-util/pom.xml b/org.mapleir.service-util/pom.xml index 5e1350b5..ea7759f2 100644 --- a/org.mapleir.service-util/pom.xml +++ b/org.mapleir.service-util/pom.xml @@ -3,11 +3,11 @@ org.mapleir service-util 0.0.1-SNAPSHOT - + MapleIR-service-util org.mapleir parent - 0.0.1-ALPHA + 1.0.0-SNAPSHOT ../org.mapleir.parent diff --git a/org.mapleir.stdlib/pom.xml b/org.mapleir.stdlib/pom.xml index 688325af..567ff5b7 100644 --- a/org.mapleir.stdlib/pom.xml +++ b/org.mapleir.stdlib/pom.xml @@ -5,18 +5,18 @@ org.mapleir parent - 0.0.1-ALPHA + 1.0.0-SNAPSHOT ../org.mapleir.parent org.mapleir stdlib - stdlib + MapleIR-stdlib org.mapleir dot4j - 0.0.1-ALPHA + 1.0.0-SNAPSHOT org.mapleir diff --git a/org.mapleir.topdank-services/pom.xml b/org.mapleir.topdank-services/pom.xml index 25f68f19..21c13a79 100644 --- a/org.mapleir.topdank-services/pom.xml +++ b/org.mapleir.topdank-services/pom.xml @@ -3,11 +3,11 @@ org.mapleir parent - 0.0.1-ALPHA + 1.0.0-SNAPSHOT ../org.mapleir.parent org.mapleir - topdank-services + MapleIR-topdank-services topdank-services @@ -23,7 +23,7 @@ org.mapleir modasm - 0.0.1-ALPHA + 1.0.0-SNAPSHOT diff --git a/pom.xml b/pom.xml index 5bc07ed1..2e31191f 100644 --- a/pom.xml +++ b/pom.xml @@ -4,10 +4,10 @@ org.mapleir mapleir - 0.0.1-ALPHA + 1.0.0-SNAPSHOT pom - mapleir + MapleIR-father UTF-8 From ec5fda18e0ba31e84c6f79008caac14731d4e01a Mon Sep 17 00:00:00 2001 From: Thibaut Gautier Date: Wed, 5 Jan 2022 01:02:48 +0100 Subject: [PATCH 18/19] Updated ASM to 9.2 --- org.mapleir.modasm/pom.xml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/org.mapleir.modasm/pom.xml b/org.mapleir.modasm/pom.xml index d11dc00f..7b9fb000 100644 --- a/org.mapleir.modasm/pom.xml +++ b/org.mapleir.modasm/pom.xml @@ -11,31 +11,34 @@ org.mapleir modasm MapleIR-modasm + + 9.2 + org.mapleir stdlib - 0.0.1-ALPHA + 1.0.0-SNAPSHOT org.ow2.asm asm - 9.0 + ${asm.version} org.ow2.asm asm-tree - 9.0 + ${asm.version} org.ow2.asm asm-util - 9.0 + ${asm.version} org.ow2.asm asm-commons - 9.0 + ${asm.version} From f43c1ccd088d763780bfecdce66a8888679a8d03 Mon Sep 17 00:00:00 2001 From: Thibaut Gautier Date: Wed, 5 Jan 2022 01:05:14 +0100 Subject: [PATCH 19/19] Fix ClassTree significant performance issue due to tree grabbing all childs from parents Short description of what happened here. The stack kept adding the parents and the childrens of the popped value from the stack. So naturally it went like this: ClassA -> ClassAParent -> Object -> Proceeds to add EVERY CHILD TO OBJECT AND THEIR CHILDREN TOO The fix? Easy one. Split it into it's own while statement. --- .../org/mapleir/app/service/ClassTree.java | 33 ++++++------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/org.mapleir.app-services/src/main/java/org/mapleir/app/service/ClassTree.java b/org.mapleir.app-services/src/main/java/org/mapleir/app/service/ClassTree.java index 583bce25..8fe1ea1f 100644 --- a/org.mapleir.app-services/src/main/java/org/mapleir/app/service/ClassTree.java +++ b/org.mapleir.app-services/src/main/java/org/mapleir/app/service/ClassTree.java @@ -28,10 +28,7 @@ public class ClassTree extends FastDirectedGraph { private final ApplicationClassSource source; private final ClassNode rootNode; private final boolean allowPhantomClasses; - - private final Map> parentCache = new HashMap<>(); - private final Map> childCache = new HashMap<>(); - + public ClassTree(ApplicationClassSource source) { this(source, ALLOW_PHANTOM_CLASSES); } @@ -104,15 +101,7 @@ public List getAllParents(ClassNode cn) { if(!containsVertex(cn)) { return new ArrayList<>(); } - - List classNodes = parentCache.get(cn); - - if (classNodes == null) { - classNodes = SimpleDfs.topoorder(this, cn, false); - parentCache.put(cn, classNodes); - } - - return classNodes; + return SimpleDfs.topoorder(this, cn, false); } // returns a postorder traversal of the graph starting from cn following edges in opposite direction. @@ -120,15 +109,7 @@ public List getAllChildren(ClassNode cn) { if(!containsVertex(cn)) { return new ArrayList<>(); } - - List classNodes = childCache.get(cn); - - if (classNodes == null) { - classNodes = SimpleDfs.postorder(this, cn, true); - childCache.put(cn, classNodes); - } - - return classNodes; + return SimpleDfs.postorder(this, cn, true); } /** @@ -142,10 +123,16 @@ public Collection getAllBranches(ClassNode cn) { while (!queue.isEmpty()) { ClassNode next = queue.remove(); if (results.add(next) && next != rootNode) { - queue.addAll(getAllParents(next)); queue.addAll(getAllChildren(next)); } } + queue.add(cn); + while (!queue.isEmpty()) { + ClassNode next = queue.remove(); + if (results.add(next) && next != rootNode) { + queue.addAll(getAllParents(next)); + } + } return results; }