Search in sources :

Example 11 with ClassNode

use of org.mapleir.asm.ClassNode in project maple-ir by LLVM-but-worse.

the class ConstantExpressionEvaluatorPass method accept.

@Override
public PassResult accept(PassContext pcxt) {
    AnalysisContext cxt = pcxt.getAnalysis();
    branchesEvaluated = 0;
    exprsEvaluated = 0;
    IPConstAnalysisVisitor vis = new IPConstAnalysisVisitor(cxt);
    IPAnalysis.create(cxt, vis);
    for (; ; ) {
        int prevExprsEval = exprsEvaluated;
        int prevBranchesEval = branchesEvaluated;
        for (ClassNode cn : cxt.getApplication().iterate()) {
            for (MethodNode m : cn.getMethods()) {
                processMethod(m, vis, cxt.getIRCache().getFor(m));
            }
        }
        if (prevExprsEval == exprsEvaluated && prevBranchesEval == branchesEvaluated) {
            break;
        }
    }
    System.out.printf("  evaluated %d constant expressions.%n", exprsEvaluated);
    System.out.printf("  eliminated %d constant branches.%n", branchesEvaluated);
    return PassResult.with(pcxt, this).finished(exprsEvaluated).make();
}
Also used : ClassNode(org.mapleir.asm.ClassNode) MethodNode(org.mapleir.asm.MethodNode) AnalysisContext(org.mapleir.context.AnalysisContext)

Example 12 with ClassNode

use of org.mapleir.asm.ClassNode in project maple-ir by LLVM-but-worse.

the class MethodRenamerPass method accept.

@Override
public PassResult accept(PassContext pcxt) {
    AnalysisContext cxt = pcxt.getAnalysis();
    ApplicationClassSource source = cxt.getApplication();
    InvocationResolver resolver = cxt.getInvocationResolver();
    Map<MethodNode, String> remapped = new HashMap<>();
    int totalMethods = 0;
    for (ClassNode cn : source.iterate()) {
        totalMethods += cn.getMethods().size();
    }
    int i = RenamingUtil.computeMinimum(totalMethods);
    for (ClassNode cn : source.iterate()) {
        for (MethodNode m : cn.getMethods()) {
            if (!heuristic.shouldRename(m.getName(), m.node.access)) {
                // System.out.println("Heuristic bypass meth " + m.name);
                continue;
            }
            if (remapped.containsKey(m)) {
                continue;
            }
            if (Modifier.isStatic(m.node.access)) {
                if (!m.getName().equals("<clinit>") && !SimpleApplicationContext.isMainMethod(m)) {
                    String newName = RenamingUtil.createName(i++);
                    remapped.put(m, newName);
                }
            } else {
                if (!m.getName().equals("<init>")) {
                    // Set<ClassNode> classes = source.getStructures().dfsTree(m.owner, true, true, true);
                    // Set<MethodNode> methods = getVirtualMethods(cxt, classes, m.name, m.desc);
                    Set<MethodNode> methods = resolver.getHierarchyMethodChain(m.owner, m.getName(), m.node.desc, true);
                    if (canRename(cxt, methods)) {
                        String newName = RenamingUtil.createName(i++);
                        for (MethodNode o : methods) {
                            // Set<MethodNode> s2 = InvocationResolver.getHierarchyMethodChain(cxt, o.owner, o.name, m.desc, true);
                            /*if(!methods.equals(s2)) {
									System.err.printf("m: %s%n", m);
									System.err.printf("o: %s%n", o);
									System.err.println("this ms::");
									for(MethodNode s : methods) {
										System.err.printf("   %s%n", s);
									}
									System.err.println("o ms::");
									for(MethodNode s : s2) {
										System.err.printf("   %s%n", s);
									}
									throw new IllegalStateException();
								}*/
                            /*if(remapped.containsKey(o)) {
									System.err.printf("m: %s%n", m);
									System.err.printf("o: %s%n", o);
									System.err.println("this ms::");
									for(MethodNode s : methods) {
										System.err.printf("   %s%n", s);
									}
									System.err.println("o ms::");
									for(MethodNode s : InvocationResolver.getHierarchyMethodChain(cxt, o.owner, o.name, m.desc, true)) {
										System.err.printf("   %s%n", s);
									}
									System.err.println(" o debugset::");
									for(MethodNode s : debugMap.get(o)) {
										System.err.printf("   %s%n", s);
									}
									System.err.printf("on: %s%n", remapped.get(o));
									System.err.printf("nn: %s%n", newName);
									throw new IllegalStateException();
								}*/
                            remapped.put(o, newName);
                        }
                    /*for(MethodNode hm : methods) {
								debugMap.put(hm, methods);
							}*/
                    } else {
                        System.out.println("  can't rename: " + methods);
                    }
                }
            }
        }
    }
    rename(cxt, remapped, true);
    System.out.printf("  Remapped %d/%d methods.%n", remapped.size(), totalMethods);
    return PassResult.with(pcxt, this).finished().make();
}
Also used : ClassNode(org.mapleir.asm.ClassNode) ApplicationClassSource(org.mapleir.app.service.ApplicationClassSource) MethodNode(org.mapleir.asm.MethodNode) HashMap(java.util.HashMap) InvocationResolver(org.mapleir.app.service.InvocationResolver) AnalysisContext(org.mapleir.context.AnalysisContext)

Example 13 with ClassNode

use of org.mapleir.asm.ClassNode in project maple-ir by LLVM-but-worse.

the class MethodRenamerPass method rename.

public static void rename(AnalysisContext cxt, Map<MethodNode, String> remapped, boolean warn) {
    ApplicationClassSource source = cxt.getApplication();
    InvocationResolver resolver = cxt.getInvocationResolver();
    for (ClassNode cn : source.iterate()) {
        {
            if (cn.node.outerMethod != null) {
                // ClassNode owner = tree.getClass(cn.node.outerClass);
                System.out.println("Outer: " + cn.node.outerClass + "." + cn.node.outerMethod + " " + cn.node.outerMethodDesc);
                cn.node.outerClass = null;
                cn.node.outerMethod = null;
                cn.node.outerMethodDesc = null;
            // System.out.println(owner.name);
            // do {
            // for(MethodNode m : owner.methods) {
            // System.out.println(m);
            // if(m.name.equals(cn.outerMethod) && m.desc.equals(cn.outerMethodDesc)) {
            // System.out.println("m: " + m);
            // }
            // }
            // owner = tree.getClass(owner.superName);
            // System.out.println(cn.superName);
            // System.out.println(owner);
            // } while(owner != null);
            }
        }
        Set<Expr> visited = new HashSet<>();
        for (MethodNode m : cn.getMethods()) {
            ControlFlowGraph cfg = cxt.getIRCache().getFor(m);
            for (BasicBlock b : cfg.vertices()) {
                for (Stmt stmt : b) {
                    for (Expr e : stmt.enumerateOnlyChildren()) {
                        if (e.getOpcode() == Opcode.INVOKE) {
                            InvocationExpr invoke = (InvocationExpr) e;
                            if (invoke.isDynamic())
                                throw new UnsupportedOperationException();
                            if (visited.contains(invoke)) {
                                throw new RuntimeException(invoke.toString());
                            }
                            visited.add(invoke);
                            if (invoke.getOwner().startsWith("[")) {
                                System.err.println("  ignore array object invoke: " + invoke + ", owner: " + invoke.getOwner());
                                continue;
                            }
                            if (invoke.isStatic()) {
                                MethodNode site = resolver.resolveStaticCall(invoke.getOwner(), invoke.getName(), invoke.getDesc());
                                if (site != null) {
                                    if (remapped.containsKey(site)) {
                                        invoke.setName(remapped.get(site));
                                    } else {
                                        if (warn && mustMark(source, invoke.getOwner())) {
                                            System.err.println("  invalid site(s): " + invoke);
                                        }
                                    }
                                } else {
                                    if (mustMark(source, invoke.getOwner())) {
                                        System.err.printf("  can't resolve(s) %s ; %s.%s %s%n", invoke, invoke.getOwner(), invoke.getName(), invoke.getDesc());
                                        if (invoke.getOwner().equals("hey")) {
                                            for (MethodNode mm : cxt.getApplication().findClassNode(invoke.getOwner()).getMethods()) {
                                                System.out.println(mm);
                                            }
                                            throw new UnsupportedOperationException();
                                        }
                                    }
                                }
                            } else {
                                // Set<MethodNode> sites = resolver.resolveVirtualCalls(invoke.getOwner(), invoke.getName(), invoke.getDesc());
                                // Set<ClassNode> classes = source.getStructures().dfsTree(cn, true, true, true);
                                // Set<MethodNode> sites = getVirtualMethods(cxt, classes, invoke.getName(), invoke.getDesc());
                                Set<MethodNode> sites = resolver.getHierarchyMethodChain(source.findClassNode(invoke.getOwner()), invoke.getName(), invoke.getDesc(), true);
                                if (sites.size() > 0) {
                                    /* all of the sites must be linked by the same name,
										 * so we can use any to find the new name. */
                                    boolean anyContains = false;
                                    boolean allContains = true;
                                    for (MethodNode s : sites) {
                                        anyContains |= remapped.containsKey(s);
                                        allContains &= remapped.containsKey(s);
                                    }
                                    if (anyContains && !allContains) {
                                        System.err.println("mismatch: ");
                                        // System.err.println(classes);
                                        System.err.println(sites);
                                        throw new RuntimeException();
                                    }
                                    MethodNode site = sites.iterator().next();
                                    if (remapped.containsKey(site)) {
                                        invoke.setName(remapped.get(site));
                                    } else {
                                        if (warn && !site.getName().equals("<init>") && canRename(cxt, sites)) {
                                            System.err.println("  invalid site(v): " + invoke + ", " + sites);
                                        }
                                    }
                                } else {
                                    if (mustMark(source, invoke.getOwner())) {
                                        System.err.println("  can't resolve(v) " + invoke + ", owner: " + invoke.getOwner() + " desc " + invoke.getDesc());
                                    // System.err.println("  classes: " + classes);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    /* Rename the methods after as we need to resolve
		 * them using the old names during the invocation 
		 * analysis above. */
    for (Entry<MethodNode, String> e : remapped.entrySet()) {
        // System.out.printf("%s -> %s%n", e.getKey(), e.getValue());
        e.getKey().node.name = e.getValue();
    }
}
Also used : ClassNode(org.mapleir.asm.ClassNode) BasicBlock(org.mapleir.ir.cfg.BasicBlock) Stmt(org.mapleir.ir.code.Stmt) ApplicationClassSource(org.mapleir.app.service.ApplicationClassSource) InvocationExpr(org.mapleir.ir.code.expr.invoke.InvocationExpr) Expr(org.mapleir.ir.code.Expr) MethodNode(org.mapleir.asm.MethodNode) ControlFlowGraph(org.mapleir.ir.cfg.ControlFlowGraph) InvocationResolver(org.mapleir.app.service.InvocationResolver) InvocationExpr(org.mapleir.ir.code.expr.invoke.InvocationExpr) HashSet(java.util.HashSet)

Example 14 with ClassNode

use of org.mapleir.asm.ClassNode in project maple-ir by LLVM-but-worse.

the class ReflectiveFunctorFactory method makeBase.

private MethodNode makeBase(String name, String desc) {
    ClassNode owner = new ClassNode();
    owner.node.version = Opcodes.V1_7;
    owner.node.name = name;
    owner.node.superName = "java/lang/Object";
    owner.node.access = Opcodes.ACC_PUBLIC;
    MethodNode m = new MethodNode(new org.objectweb.asm.tree.MethodNode(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "eval", desc, null, null), owner);
    owner.addMethod(m);
    return m;
}
Also used : ClassNode(org.mapleir.asm.ClassNode) MethodNode(org.mapleir.asm.MethodNode)

Example 15 with ClassNode

use of org.mapleir.asm.ClassNode in project maple-ir by LLVM-but-worse.

the class ReflectiveFunctorFactory method buildBridge.

private <T> EvaluationFunctor<T> buildBridge(MethodNode m) {
    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
    ClassNode owner = m.owner;
    owner.node.accept(cw);
    byte[] bytes = cw.toByteArray();
    Class<?> clazz = classLoader.make(owner.getName(), bytes);
    for (Method method : clazz.getDeclaredMethods()) {
        if (method.getName().equals("eval")) {
            EvaluationFunctor<T> f = new ReflectiveFunctor<>(method);
            cache.put(owner.getName(), f);
            return f;
        }
    }
    throw new UnsupportedOperationException();
}
Also used : ClassNode(org.mapleir.asm.ClassNode) Method(java.lang.reflect.Method) ClassWriter(org.objectweb.asm.ClassWriter)

Aggregations

ClassNode (org.mapleir.asm.ClassNode)45 MethodNode (org.mapleir.asm.MethodNode)24 ControlFlowGraph (org.mapleir.ir.cfg.ControlFlowGraph)16 AnalysisContext (org.mapleir.context.AnalysisContext)13 ApplicationClassSource (org.mapleir.app.service.ApplicationClassSource)11 JarInfo (org.topdank.byteengineer.commons.data.JarInfo)11 SingleJarDownloader (org.topdank.byteio.in.SingleJarDownloader)11 IRCache (org.mapleir.context.IRCache)8 ControlFlowGraphBuilder (org.mapleir.ir.cfg.builder.ControlFlowGraphBuilder)8 SimpleApplicationContext (org.mapleir.app.client.SimpleApplicationContext)7 LibraryClassSource (org.mapleir.app.service.LibraryClassSource)7 BasicAnalysisContext (org.mapleir.context.BasicAnalysisContext)7 IPass (org.mapleir.deob.IPass)7 PassGroup (org.mapleir.deob.PassGroup)7 LiveDataFlowAnalysisImpl (org.mapleir.deob.dataflow.LiveDataFlowAnalysisImpl)7 ControlFlowGraphDumper (org.mapleir.ir.codegen.ControlFlowGraphDumper)7 BasicBlock (org.mapleir.ir.cfg.BasicBlock)6 JarOutputStream (java.util.jar.JarOutputStream)5 Expr (org.mapleir.ir.code.Expr)5 Stmt (org.mapleir.ir.code.Stmt)5