Search in sources :

Example 1 with InvocationResolver

use of org.mapleir.app.service.InvocationResolver in project maple-ir by LLVM-but-worse.

the class ConcreteStaticInvocationPass method accept.

@Override
public int accept(AnalysisContext cxt, IPass prev, List<IPass> completed) {
    int fixed = 0;
    InvocationResolver resolver = cxt.getInvocationResolver();
    for (ClassNode cn : cxt.getApplication().iterate()) {
        for (MethodNode mn : cn.methods) {
            ControlFlowGraph cfg = cxt.getIRCache().getFor(mn);
            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.isStatic()) {
                                MethodNode invoked = resolver.resolveStaticCall(invoke.getOwner(), invoke.getName(), invoke.getDesc());
                                if (invoked != null) {
                                    if (!invoked.owner.name.equals(invoke.getOwner())) {
                                        invoke.setOwner(invoked.owner.name);
                                        fixed++;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    System.out.printf("  corrected %d dodgy static calls.%n", fixed);
    return fixed;
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) MethodNode(org.objectweb.asm.tree.MethodNode) InvocationExpr(org.mapleir.ir.code.expr.invoke.InvocationExpr) Expr(org.mapleir.ir.code.Expr) ControlFlowGraph(org.mapleir.ir.cfg.ControlFlowGraph) InvocationResolver(org.mapleir.app.service.InvocationResolver) BasicBlock(org.mapleir.ir.cfg.BasicBlock) InvocationExpr(org.mapleir.ir.code.expr.invoke.InvocationExpr) Stmt(org.mapleir.ir.code.Stmt)

Example 2 with InvocationResolver

use of org.mapleir.app.service.InvocationResolver in project maple-ir by LLVM-but-worse.

the class MethodRenamerPass method accept.

@Override
public int accept(AnalysisContext cxt, IPass prev, List<IPass> completed) {
    ApplicationClassSource source = cxt.getApplication();
    InvocationResolver resolver = cxt.getInvocationResolver();
    Map<MethodNode, String> remapped = new HashMap<>();
    int totalMethods = 0;
    for (ClassNode cn : source.iterate()) {
        totalMethods += cn.methods.size();
    }
    int i = RenamingUtil.computeMinimum(totalMethods);
    for (ClassNode cn : source.iterate()) {
        for (MethodNode m : cn.methods) {
            if (!heuristic.shouldRename(m.name, m.access)) {
                // System.out.println("Heuristic bypass meth " + m.name);
                continue;
            }
            if (remapped.containsKey(m)) {
                continue;
            }
            if (Modifier.isStatic(m.access)) {
                if (!m.name.equals("<clinit>") && !SimpleApplicationContext.isMainMethod(m)) {
                    String newName = RenamingUtil.createName(i++);
                    remapped.put(m, newName);
                }
            } else {
                if (!m.name.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.name, m.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 remapped.size();
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) ApplicationClassSource(org.mapleir.app.service.ApplicationClassSource) MethodNode(org.objectweb.asm.tree.MethodNode) HashMap(java.util.HashMap) InvocationResolver(org.mapleir.app.service.InvocationResolver)

Example 3 with InvocationResolver

use of org.mapleir.app.service.InvocationResolver 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.outerMethod != null) {
                // ClassNode owner = tree.getClass(cn.outerClass);
                System.out.println("Outer: " + cn.outerClass + "." + cn.outerMethod + " " + cn.outerMethodDesc);
                cn.outerClass = null;
                cn.outerMethod = null;
                cn.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.methods) {
            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 (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()).methods) {
                                                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.name.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);
                                    }
                                }
                            }
                        } else if (e.getOpcode() == Opcode.DYNAMIC_INVOKE) {
                            throw new UnsupportedOperationException();
                        }
                    }
                }
            }
        }
    }
    /* 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().name = e.getValue();
    }
}
Also used : ClassNode(org.objectweb.asm.tree.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.objectweb.asm.tree.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 4 with InvocationResolver

use of org.mapleir.app.service.InvocationResolver in project maple-ir by LLVM-but-worse.

the class ConstantParameterPass method accept.

@Override
public int accept(AnalysisContext cxt, IPass prev, List<IPass> completed) {
    Map<MethodNode, Set<MethodNode>> chainMap = new HashMap<>();
    for (MethodNode mn : cxt.getIRCache().getActiveMethods()) {
        makeUpChain(cxt, mn, chainMap);
    }
    InvocationResolver resolver = cxt.getInvocationResolver();
    Map<MethodNode, List<Set<Object>>> rawConstantParameters = new HashMap<>();
    Map<MethodNode, boolean[]> chainedNonConstant = new HashMap<>();
    Map<MethodNode, boolean[]> specificNonConstant = new HashMap<>();
    IPAnalysisVisitor vis = new IPAnalysisVisitor() {

        @Override
        public void postVisitMethod(IPAnalysis analysis, MethodNode m) {
            int pCount = Type.getArgumentTypes(m.desc).length;
            /* init map entries */
            if (!chainedNonConstant.containsKey(m)) {
                for (MethodNode assoc : chainMap.get(m)) {
                    boolean[] arr = new boolean[pCount];
                    chainedNonConstant.put(assoc, arr);
                }
                for (MethodNode assoc : chainMap.get(m)) {
                    boolean[] arr = new boolean[pCount];
                    specificNonConstant.put(assoc, arr);
                }
            }
            if (Modifier.isStatic(m.access)) {
                if (!rawConstantParameters.containsKey(m)) {
                    List<Set<Object>> l = new ArrayList<>(pCount);
                    rawConstantParameters.put(m, l);
                    for (int i = 0; i < pCount; i++) {
                        l.add(new HashSet<>());
                    }
                }
            } else {
                // TODO: cache
                for (MethodNode site : resolver.resolveVirtualCalls(m, true)) {
                    if (!rawConstantParameters.containsKey(site)) {
                        List<Set<Object>> l = new ArrayList<>(pCount);
                        rawConstantParameters.put(site, l);
                        for (int i = 0; i < pCount; i++) {
                            l.add(new HashSet<>());
                        }
                    }
                }
            }
        }

        @Override
        public void postProcessedInvocation(IPAnalysis analysis, MethodNode caller, MethodNode callee, Invocation call) {
            Expr[] params = call.getParameterExprs();
            for (int i = 0; i < params.length; i++) {
                Expr e = params[i];
                if (e.getOpcode() == Opcode.CONST_LOAD) {
                    if (Modifier.isStatic(callee.access)) {
                        rawConstantParameters.get(callee).get(i).add(((ConstantExpr) e).getConstant());
                    } else {
                        /* only chain callsites *can* have this input */
                        for (MethodNode site : resolver.resolveVirtualCalls(callee, true)) {
                            rawConstantParameters.get(site).get(i).add(((ConstantExpr) e).getConstant());
                        }
                    }
                } else {
                    /* whole branch tainted */
                    for (MethodNode associated : chainMap.get(callee)) {
                        chainedNonConstant.get(associated)[i] = true;
                    }
                    /* callsites tainted */
                    if (Modifier.isStatic(callee.access)) {
                        specificNonConstant.get(callee)[i] = true;
                    } else {
                        /* only chain callsites *can* have this input */
                        for (MethodNode site : resolver.resolveVirtualCalls(callee, true)) {
                            specificNonConstant.get(site)[i] = true;
                        }
                    }
                }
            }
        }
    };
    IPAnalysis constAnalysis = IPAnalysis.create(cxt, vis);
    // ApplicationClassSource app = cxt.getApplication();
    // ClassTree structures = app.getStructures();
    /* remove all calls to library methods since we can't
		 * handle them. */
    /*Iterator<Entry<MethodNode, List<Set<Object>>>> it = rawConstantParameters.entrySet().iterator();
		while(it.hasNext()) {
			Entry<MethodNode, List<Set<Object>>> en = it.next();
			
			MethodNode m = en.getKey();

			if(app.isLibraryClass(m.owner.name)) {
				it.remove();
				continue;
			}
			
			// TODO: MUST BE CONVERTED TO ACCOUNT FOR DIRECT SUPERS, NOT ALL
			superFor: for(ClassNode cn : structures.getAllParents(m.owner)) {
				if(app.isLibraryClass(cn.name)) {
					for(MethodNode m1 : cn.methods) {
						if(resolver.areMethodsCongruent(m1, m, Modifier.isStatic(m.access))) {
							it.remove();
							break superFor;
						}
					}
				}
			}
		}*/
    /* aggregate constant parameters indices with their chained
		 * methods such that the map contains only constant parameter
		 * indices that we can actually remove while keeping a valid chain.
		 * 
		 * We do this as we can have methods from different branches that
		 * are cousin-related but have different constant parameter values.
		 * In these cases we can still inline the constants (different constants)
		 * and change the descriptions, keeping the chain. */
    Map<MethodNode, boolean[]> filteredConstantParameters = new HashMap<>();
    for (Entry<MethodNode, List<Set<Object>>> en : rawConstantParameters.entrySet()) {
        MethodNode m = en.getKey();
        List<Set<Object>> objParams = en.getValue();
        boolean[] tainted = chainedNonConstant.get(m);
        if (filteredConstantParameters.containsKey(m)) {
            /* note: if this method is contained in the
				 * map all of it's cousin-reachable methods
				 * must also be and furthermore the dead map
				 * for the entire chain is the same array. 
				 * 
				 * we need to now merge the current dead map
				 * with the one specifically for this method.*/
            boolean[] thisDeadMap = makeDeadMap(objParams, tainted);
            boolean[] prevDeadMap = filteredConstantParameters.get(m);
            if (thisDeadMap.length != prevDeadMap.length) {
                throw new IllegalStateException(String.format("m: %s, chain:%s, %d:%d", m, chainMap.get(m), thisDeadMap.length, prevDeadMap.length));
            }
            /* each dead map contains true values for an
				 * index if that index is a constant parameter. */
            for (int i = 0; i < prevDeadMap.length; i++) {
                prevDeadMap[i] &= thisDeadMap[i];
            }
        } else {
            boolean[] deadParams = makeDeadMap(objParams, tainted);
            for (MethodNode chm : chainMap.get(m)) {
                filteredConstantParameters.put(chm, deadParams);
            }
        }
        ControlFlowGraph cfg = cxt.getIRCache().getFor(m);
        // boolean b = false;
        boolean[] specificTaint = specificNonConstant.get(m);
        for (int i = 0; i < objParams.size(); i++) {
            Set<Object> set = objParams.get(i);
            if (!specificTaint[i] && set.size() == 1) {
                inlineConstant(cfg, constAnalysis.getLocalIndex(m, i), set.iterator().next());
            }
        }
    }
    Map<MethodNode, String> remap = new HashMap<>();
    Set<MethodNode> toRemove = new HashSet<>();
    Set<Set<MethodNode>> mustRename = new HashSet<>();
    for (Entry<MethodNode, boolean[]> en : filteredConstantParameters.entrySet()) {
        MethodNode m = en.getKey();
        if (!remap.containsKey(m) && !toRemove.contains(m)) {
            boolean[] deadMap = en.getValue();
            boolean notSame = false;
            for (boolean b : deadMap) {
                notSame |= b;
            }
            if (!notSame) {
                /* eliminate all branches (same congruence class) */
                for (MethodNode n : chainMap.get(m)) {
                    toRemove.add(n);
                }
                continue;
            }
            Type[] params = Type.getArgumentTypes(m.desc);
            Type ret = Type.getReturnType(m.desc);
            String desc = buildDesc(params, ret, deadMap);
            Set<MethodNode> conflicts = new HashSet<>();
            for (MethodNode chm : chainMap.get(m)) {
                remap.put(chm, desc);
                if (Modifier.isStatic(m.access)) {
                    MethodNode mm = resolver.resolveStaticCall(chm.owner.name, chm.name, desc);
                    if (mm != null) {
                        conflicts.add(mm);
                    }
                } else {
                    if (chm.name.equals("<init>")) {
                        conflicts.addAll(resolver.resolveVirtualCalls(chm.owner.name, "<init>", desc, false));
                    } else {
                        conflicts.addAll(resolver.getHierarchyMethodChain(m.owner, m.name, desc, true));
                    }
                }
            }
            if (conflicts.size() > 0) {
                Set<MethodNode> chain = chainMap.get(m);
                /* rename the smallest conflict set */
                // if(chain.size() < conflicts.size()) {
                // 
                // } else {
                // mustRename.add(conflicts);
                // }
                mustRename.add(chain);
            }
        }
    }
    remap.keySet().removeAll(toRemove);
    int k = RenamingUtil.numeric("aaaaa");
    Map<MethodNode, String> methodNameRemap = new HashMap<>();
    for (Set<MethodNode> set : mustRename) {
        // MethodNode first = set.iterator().next();
        // String newName = "rename_" + first.name;
        String newName = RenamingUtil.createName(k++);
        System.out.printf(" renaming %s to %s%n", set, newName);
        System.out.println("   recom " + computeChain(cxt, set.iterator().next()));
        Set<MethodNode> s2 = new HashSet<>();
        for (MethodNode m : set) {
            s2.addAll(chainMap.get(m));
        }
        if (!s2.equals(set)) {
            System.err.println(set);
            System.err.println(s2);
            throw new IllegalStateException();
        }
        for (MethodNode m : set) {
            methodNameRemap.put(m, newName);
        }
    }
    if (mustRename.size() > 0) {
        MethodRenamerPass.rename(cxt, methodNameRemap, false);
    }
    Set<MethodNode> visitedMethods = new HashSet<>();
    Set<Expr> visitedExprs = new HashSet<>();
    int killedTotal = 0;
    for (; ; ) {
        int killedBeforePass = killedTotal;
        for (Entry<MethodNode, String> en : remap.entrySet()) {
            MethodNode key = en.getKey();
            String newDesc = en.getValue();
            if (!visitedMethods.contains(key)) {
                Set<MethodNode> chain = chainMap.get(key);
                /*for(MethodNode n : chain) {
						if(visitedMethods.contains(n)) {
							throw new IllegalStateException(String.format("Invalid transistivityr: %s in %s but not %s", n, chain, key));
						}
					}*/
                boolean[] dead = filteredConstantParameters.get(key);
                for (MethodNode n : chain) {
                    n.desc = newDesc;
                    /* boolean[] dead = filteredConstantParameters.get(n);
						boolean[] deadM = filteredConstantParameters.get(key);
						
						if(!Arrays.equals(dead, deadM)) {
							throw new IllegalStateException(String.format("neq: %s vs %s for %s and %s", Arrays.toString(dead), Arrays.toString(deadM), n, key));
						} */
                    demoteDeadParamters(constAnalysis, cxt.getIRCache().getFor(n), n, dead);
                    for (Invocation call : constAnalysis.getCallsTo(n)) {
                        /* since the callgrapher finds all
							 * the methods in a hierarchy and considers
							 * it as a single invocation, a certain
							 * invocation may be considered multiple times. */
                        if (visitedExprs.contains(call)) {
                            continue;
                        }
                        /* the invocationexpr method desc is changed implicitly
							 * when the new expression is created in patchCall() */
                        visitedExprs.add(call);
                        patchCall(newDesc, call, dead);
                        killedTotal += chain.size();
                    }
                }
                visitedMethods.addAll(chain);
            }
        }
        if (killedBeforePass == killedTotal) {
            break;
        }
    }
    System.out.printf("  removed %d constant parameters.%n", killedTotal);
    return killedTotal;
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) Invocation(org.mapleir.ir.code.expr.invoke.Invocation) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) MethodNode(org.objectweb.asm.tree.MethodNode) ArrayList(java.util.ArrayList) List(java.util.List) HashSet(java.util.HashSet) IPAnalysisVisitor(org.mapleir.deob.interproc.IPAnalysisVisitor) Type(org.objectweb.asm.Type) ConstantExpr(org.mapleir.ir.code.expr.ConstantExpr) InitialisedObjectExpr(org.mapleir.ir.code.expr.invoke.InitialisedObjectExpr) InvocationExpr(org.mapleir.ir.code.expr.invoke.InvocationExpr) VarExpr(org.mapleir.ir.code.expr.VarExpr) Expr(org.mapleir.ir.code.Expr) ControlFlowGraph(org.mapleir.ir.cfg.ControlFlowGraph) InvocationResolver(org.mapleir.app.service.InvocationResolver) IPAnalysis(org.mapleir.deob.interproc.IPAnalysis)

Example 5 with InvocationResolver

use of org.mapleir.app.service.InvocationResolver in project maple-ir by LLVM-but-worse.

the class FieldRenamerPass method accept.

@Override
public int accept(AnalysisContext cxt, IPass prev, List<IPass> completed) {
    Map<FieldNode, String> remapped = new HashMap<>();
    // int totalFields = 0;
    // int i = RenamingUtil.computeMinimum(totalFields);
    ApplicationClassSource source = cxt.getApplication();
    int i = RenamingUtil.numeric("aaaaa");
    for (ClassNode cn : source.iterate()) {
        // totalFields += cn.fields.size();
        for (FieldNode fn : cn.fields) {
            remapped.put(fn, RenamingUtil.createName(i++));
        }
    }
    InvocationResolver resolver = cxt.getInvocationResolver();
    for (ClassNode cn : source.iterate()) {
        for (MethodNode m : cn.methods) {
            ControlFlowGraph cfg = cxt.getIRCache().getFor(m);
            for (BasicBlock b : cfg.vertices()) {
                for (Stmt stmt : b) {
                    if (stmt.getOpcode() == Opcode.FIELD_STORE) {
                        FieldStoreStmt fs = (FieldStoreStmt) stmt;
                        FieldNode f = resolver.findField(fs.getOwner(), fs.getName(), fs.getDesc(), fs.getInstanceExpression() == null);
                        if (f != null) {
                            if (remapped.containsKey(f)) {
                                fs.setName(remapped.get(f));
                            } else if (mustMark(source, f.owner.name)) {
                                System.err.println("  no remap for " + f + ", owner: " + f.owner.name);
                            }
                        } else {
                            if (mustMark(source, fs.getOwner())) {
                                System.err.println("  can't resolve field(set): " + fs.getOwner() + "." + fs.getName() + " " + fs.getDesc() + ", " + (fs.getInstanceExpression() == null));
                            }
                        }
                    }
                    for (Expr e : stmt.enumerateOnlyChildren()) {
                        if (e.getOpcode() == Opcode.FIELD_LOAD) {
                            FieldLoadExpr fl = (FieldLoadExpr) e;
                            FieldNode f = resolver.findField(fl.getOwner(), fl.getName(), fl.getDesc(), fl.getInstanceExpression() == null);
                            if (f != null) {
                                if (remapped.containsKey(f)) {
                                    fl.setName(remapped.get(f));
                                } else if (mustMark(source, f.owner.name)) {
                                    System.err.println("  no remap for " + f + ", owner: " + f.owner.name);
                                }
                            } else {
                                if (mustMark(source, fl.getOwner())) {
                                    System.err.println("  can't resolve field(get): " + fl.getOwner() + "." + fl.getName() + " " + fl.getDesc() + ", " + (fl.getInstanceExpression() == null));
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    for (Entry<FieldNode, String> e : remapped.entrySet()) {
        e.getKey().name = e.getValue();
    }
    System.out.printf("  Renamed %d fields.%n", remapped.size());
    return remapped.size();
}
Also used : FieldStoreStmt(org.mapleir.ir.code.stmt.FieldStoreStmt) ClassNode(org.objectweb.asm.tree.ClassNode) FieldLoadExpr(org.mapleir.ir.code.expr.FieldLoadExpr) FieldNode(org.objectweb.asm.tree.FieldNode) HashMap(java.util.HashMap) BasicBlock(org.mapleir.ir.cfg.BasicBlock) FieldStoreStmt(org.mapleir.ir.code.stmt.FieldStoreStmt) Stmt(org.mapleir.ir.code.Stmt) ApplicationClassSource(org.mapleir.app.service.ApplicationClassSource) MethodNode(org.objectweb.asm.tree.MethodNode) Expr(org.mapleir.ir.code.Expr) FieldLoadExpr(org.mapleir.ir.code.expr.FieldLoadExpr) ControlFlowGraph(org.mapleir.ir.cfg.ControlFlowGraph) InvocationResolver(org.mapleir.app.service.InvocationResolver)

Aggregations

InvocationResolver (org.mapleir.app.service.InvocationResolver)5 MethodNode (org.objectweb.asm.tree.MethodNode)5 ControlFlowGraph (org.mapleir.ir.cfg.ControlFlowGraph)4 Expr (org.mapleir.ir.code.Expr)4 ClassNode (org.objectweb.asm.tree.ClassNode)4 HashMap (java.util.HashMap)3 ApplicationClassSource (org.mapleir.app.service.ApplicationClassSource)3 BasicBlock (org.mapleir.ir.cfg.BasicBlock)3 Stmt (org.mapleir.ir.code.Stmt)3 InvocationExpr (org.mapleir.ir.code.expr.invoke.InvocationExpr)3 HashSet (java.util.HashSet)2 ArrayList (java.util.ArrayList)1 List (java.util.List)1 Set (java.util.Set)1 IPAnalysis (org.mapleir.deob.interproc.IPAnalysis)1 IPAnalysisVisitor (org.mapleir.deob.interproc.IPAnalysisVisitor)1 ConstantExpr (org.mapleir.ir.code.expr.ConstantExpr)1 FieldLoadExpr (org.mapleir.ir.code.expr.FieldLoadExpr)1 VarExpr (org.mapleir.ir.code.expr.VarExpr)1 InitialisedObjectExpr (org.mapleir.ir.code.expr.invoke.InitialisedObjectExpr)1