Search in sources :

Example 21 with LabelStmt

use of com.googlecode.dex2jar.ir.stmt.LabelStmt in project dex2jar by pxb1988.

the class ExceptionHandlerTrim method transform.

@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public void transform(IrMethod irMethod) {
    List<Trap> trips = irMethod.traps;
    irMethod.traps = new ArrayList();
    LabelAndLocalMapper map = new LabelAndLocalMapper() {

        @Override
        public LabelStmt map(LabelStmt label) {
            return label;
        }
    };
    for (Trap trap : trips) {
        Trap ntrap = trap.clone(map);
        int status = 0;
        for (Stmt p = trap.start.getNext(); p != trap.end; p = p.getNext()) {
            if (!Cfg.notThrow(p)) {
                if (status == 0) {
                    Stmt pre = p.getPre();
                    if (pre == null || pre.st != ST.LABEL) {
                        pre = Stmts.nLabel();
                        irMethod.stmts.insertBefore(p, pre);
                    }
                    ntrap.start = (LabelStmt) pre;
                    status = 1;
                } else if (status == 1) {
                // continue;
                }
            } else if (status == 1) {
                Stmt pre = p.getPre();
                if (pre == null || pre.st != ST.LABEL) {
                    pre = Stmts.nLabel();
                    irMethod.stmts.insertBefore(p, pre);
                }
                ntrap.end = (LabelStmt) pre;
                irMethod.traps.add(ntrap);
                status = 0;
                ntrap = trap.clone(map);
            }
        }
        if (status == 1) {
            ntrap.end = trap.end;
            irMethod.traps.add(ntrap);
            status = 0;
        }
    }
}
Also used : LabelAndLocalMapper(com.googlecode.dex2jar.ir.LabelAndLocalMapper) LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) ArrayList(java.util.ArrayList) Trap(com.googlecode.dex2jar.ir.Trap) LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) Stmt(com.googlecode.dex2jar.ir.stmt.Stmt)

Example 22 with LabelStmt

use of com.googlecode.dex2jar.ir.stmt.LabelStmt in project dex2jar by pxb1988.

the class NewTransformer method makeSureUsedBeforeConstructor.

void makeSureUsedBeforeConstructor(IrMethod method, final Map<Local, TObject> init, final int size) {
    Cfg.createCFG(method);
    Cfg.dfs(method.stmts, new Cfg.FrameVisitor<Vx[]>() {

        boolean keepFrame = false;

        Vx[] tmp = new Vx[size];

        StmtTraveler stmtTraveler = new StmtTraveler() {

            Stmt current;

            @Override
            public Stmt travel(Stmt stmt) {
                this.current = stmt;
                if (stmt.et == ET.E2) {
                    if (stmt.getOp1().vt == LOCAL) {
                        Local op1 = (Local) stmt.getOp1();
                        if (stmt.getOp2().vt == LOCAL) {
                            Local op2 = (Local) stmt.getOp2();
                            tmp[op1._ls_index] = tmp[op2._ls_index];
                            return stmt;
                        } else if (stmt.getOp2().vt == NEW) {
                            tmp[op1._ls_index] = new Vx(init.get(op1), false);
                            return stmt;
                        } else {
                            travel(stmt.getOp2());
                            tmp[op1._ls_index] = IGNORED;
                            return stmt;
                        }
                    }
                }
                if (stmt.st == LABEL) {
                    LabelStmt labelStmt = (LabelStmt) stmt;
                    if (labelStmt.phis != null) {
                        for (AssignStmt phi : labelStmt.phis) {
                            Local local = (Local) phi.getOp1();
                            tmp[local._ls_index] = IGNORED;
                        }
                    }
                    return stmt;
                }
                return super.travel(stmt);
            }

            @Override
            public Value travel(Value op) {
                if (op.vt == INVOKE_SPECIAL) {
                    if (op.getOps().length >= 1) {
                        InvokeExpr ie = (InvokeExpr) op;
                        if ("<init>".equals(ie.name)) {
                            Value thiz = op.getOps()[0];
                            if (thiz.vt == LOCAL) {
                                Local local = (Local) thiz;
                                Vx vx = tmp[local._ls_index];
                                TObject object = vx.obj;
                                if (object != null) {
                                    if (object.invokeStmt != null) {
                                        object.useBeforeInit = true;
                                    } else {
                                        vx.init = true;
                                        object.invokeStmt = current;
                                        for (int i = 0; i < tmp.length; i++) {
                                            Vx s = tmp[i];
                                            if (s != null && s.obj == object) {
                                                tmp[i] = IGNORED;
                                            }
                                        }
                                        keepFrame = true;
                                    }
                                }
                            }
                        }
                    }
                }
                op = super.travel(op);
                if (op.vt == LOCAL) {
                    use((Local) op);
                }
                return op;
            }
        };

        @Override
        public Vx[] merge(Vx[] srcFrame, Vx[] distFrame, Stmt src, Stmt dist) {
            if (distFrame == null) {
                distFrame = new Vx[size];
                System.arraycopy(srcFrame, 0, distFrame, 0, size);
            } else {
                for (int i = 0; i < size; i++) {
                    Vx s = srcFrame[i];
                    Vx d = distFrame[i];
                    if (s != null) {
                        if (d == null) {
                            distFrame[i] = s;
                        } else {
                            if (s != d) {
                                TObject obj = s.obj;
                                if (obj != null) {
                                    obj.useBeforeInit = true;
                                }
                                obj = d.obj;
                                if (obj != null) {
                                    obj.useBeforeInit = true;
                                }
                            }
                        }
                    }
                }
            }
            if (dist.st == LABEL) {
                List<AssignStmt> phis = ((LabelStmt) dist).phis;
                if (phis != null && phis.size() > 0) {
                    for (AssignStmt phi : phis) {
                        for (Value value : phi.getOp2().getOps()) {
                            Local local = (Local) value;
                            int i = local._ls_index;
                            Vx s = srcFrame[i];
                            Vx d = distFrame[i];
                            if (d != null) {
                                if (!d.init) {
                                    TObject obj = d.obj;
                                    if (obj != null) {
                                        obj.useBeforeInit = true;
                                    }
                                }
                            } else if (s != null) {
                                if (!s.init) {
                                    TObject obj = s.obj;
                                    if (obj != null) {
                                        obj.useBeforeInit = true;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return distFrame;
        }

        @Override
        public Vx[] initFirstFrame(Stmt first) {
            return new Vx[size];
        }

        @Override
        public Vx[] exec(Vx[] frame, Stmt stmt) {
            keepFrame = false;
            System.arraycopy(frame, 0, tmp, 0, size);
            stmtTraveler.travel(stmt);
            if (stmt._cfg_froms.size() > 1) {
                keepFrame = true;
            }
            if (!keepFrame) {
                stmt.frame = null;
            }
            return tmp;
        }

        void use(Local local) {
            Vx vx = tmp[local._ls_index];
            if (!vx.init) {
                TObject object = vx.obj;
                if (object != null) {
                    object.useBeforeInit = true;
                }
                tmp[local._ls_index] = IGNORED;
            }
        }
    });
    for (Iterator<Map.Entry<Local, TObject>> iterator = init.entrySet().iterator(); iterator.hasNext(); ) {
        Map.Entry<Local, TObject> e = iterator.next();
        boolean keep = true;
        TObject obj = e.getValue();
        if (obj.useBeforeInit) {
            keep = false;
        }
        if (obj.invokeStmt == null) {
            keep = false;
        }
        if (!keep) {
            iterator.remove();
        }
    }
}
Also used : LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Stmt(com.googlecode.dex2jar.ir.stmt.Stmt) StmtTraveler(com.googlecode.dex2jar.ir.StmtTraveler)

Example 23 with LabelStmt

use of com.googlecode.dex2jar.ir.stmt.LabelStmt in project dex2jar by pxb1988.

the class RemoveConstantFromSSA method transformReportChanged.

@Override
public boolean transformReportChanged(IrMethod method) {
    boolean changed = false;
    List<AssignStmt> assignStmtList = new ArrayList<>();
    Map<Local, Object> cstMap = new HashMap<>();
    for (Stmt p = method.stmts.getFirst(); p != null; p = p.getNext()) {
        if (p.st == Stmt.ST.ASSIGN) {
            AssignStmt as = (AssignStmt) p;
            if (as.getOp1().vt == Value.VT.LOCAL) {
                if (as.getOp2().vt == Value.VT.CONSTANT) {
                    assignStmtList.add(as);
                    cstMap.put((Local) as.getOp1(), ((Constant) as.getOp2()).value);
                } else if (as.getOp2().vt == Value.VT.LOCAL) {
                    cstMap.put((Local) as.getOp1(), as.getOp2());
                }
            }
        }
    }
    if (assignStmtList.size() == 0) {
        return false;
    }
    RemoveLocalFromSSA.fixReplace(cstMap);
    final Map<Local, Value> toReplace = new HashMap<>();
    Set<Value> usedInPhi = new HashSet<>();
    List<LabelStmt> phiLabels = method.phiLabels;
    if (phiLabels != null) {
        boolean loopAgain = true;
        while (loopAgain) {
            loopAgain = false;
            usedInPhi.clear();
            for (Iterator<LabelStmt> it = phiLabels.iterator(); it.hasNext(); ) {
                LabelStmt labelStmt = it.next();
                if (labelStmt.phis != null) {
                    for (Iterator<AssignStmt> it2 = labelStmt.phis.iterator(); it2.hasNext(); ) {
                        AssignStmt phi = it2.next();
                        Value[] vs = phi.getOp2().getOps();
                        Object sameCst = null;
                        boolean allEqual = true;
                        for (Value p : vs) {
                            Object cst = cstMap.get(p);
                            if (cst == null) {
                                allEqual = false;
                                break;
                            }
                            if (sameCst == null) {
                                sameCst = cst;
                            } else if (!sameCst.equals(cst)) {
                                allEqual = false;
                                break;
                            }
                        }
                        if (allEqual) {
                            // all are same constant
                            cstMap.put((Local) phi.getOp1(), sameCst);
                            if (sameCst instanceof Local) {
                                phi.setOp2((Value) sameCst);
                            } else {
                                phi.setOp2(Exprs.nConstant(sameCst));
                                assignStmtList.add(phi);
                            }
                            it2.remove();
                            method.stmts.insertAfter(labelStmt, phi);
                            changed = true;
                            // loop again
                            loopAgain = true;
                        } else {
                            usedInPhi.addAll(Arrays.asList(phi.getOp2().getOps()));
                        }
                    }
                    if (labelStmt.phis.size() == 0) {
                        it.remove();
                    }
                }
            }
        }
    }
    for (Iterator<AssignStmt> it = assignStmtList.iterator(); it.hasNext(); ) {
        AssignStmt as = it.next();
        if (!usedInPhi.contains(as.getOp1())) {
            it.remove();
            method.stmts.remove(as);
            method.locals.remove(as.getOp1());
            changed = true;
        }
        toReplace.put((Local) as.getOp1(), as.getOp2());
    }
    Cfg.travelMod(method.stmts, new Cfg.TravelCallBack() {

        @Override
        public Value onAssign(Local v, AssignStmt as) {
            return v;
        }

        @Override
        public Value onUse(Local v) {
            Value n = toReplace.get(v);
            return n == null ? v : n.clone();
        }
    }, false);
    return changed;
}
Also used : LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) HashMap(java.util.HashMap) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) ArrayList(java.util.ArrayList) Local(com.googlecode.dex2jar.ir.expr.Local) LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Stmt(com.googlecode.dex2jar.ir.stmt.Stmt) Value(com.googlecode.dex2jar.ir.expr.Value) HashSet(java.util.HashSet)

Example 24 with LabelStmt

use of com.googlecode.dex2jar.ir.stmt.LabelStmt in project dex2jar by pxb1988.

the class RemoveLocalFromSSA method collectPhiObjects.

private Map<Local, PhiObject> collectPhiObjects(List<LabelStmt> phiLabels) {
    Map<Local, PhiObject> phis;
    phis = new HashMap<>();
    for (LabelStmt labelStmt : phiLabels) {
        for (AssignStmt as : labelStmt.phis) {
            Local local = (Local) as.getOp1();
            PhiObject child = getOrCreate(phis, local);
            child.isInitByPhi = true;
            for (Value op : as.getOp2().getOps()) {
                if (op == local) {
                    continue;
                }
                PhiObject parent = getOrCreate(phis, (Local) op);
                linkPhiObject(parent, child);
            }
        }
    }
    return phis;
}
Also used : LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Value(com.googlecode.dex2jar.ir.expr.Value) Local(com.googlecode.dex2jar.ir.expr.Local)

Example 25 with LabelStmt

use of com.googlecode.dex2jar.ir.stmt.LabelStmt in project dex2jar by pxb1988.

the class RemoveLocalFromSSA method transformReportChanged.

@Override
public boolean transformReportChanged(IrMethod method) {
    boolean irChanged = false;
    List<AssignStmt> assignStmtList = new ArrayList<>();
    List<LabelStmt> phiLabels = method.phiLabels;
    for (Stmt p = method.stmts.getFirst(); p != null; p = p.getNext()) {
        if (p.st == Stmt.ST.ASSIGN) {
            AssignStmt as = (AssignStmt) p;
            if (as.getOp1().vt == Value.VT.LOCAL && as.getOp2().vt == Value.VT.LOCAL) {
                assignStmtList.add(as);
            }
        }
    }
    final Map<Local, Local> toReplace = new HashMap<>();
    Set<Value> set = new HashSet<>();
    boolean changed = true;
    while (changed) {
        changed = false;
        if (removeLoopFromPhi(phiLabels, toReplace)) {
            fixReplace(toReplace);
            replacePhi(phiLabels, toReplace, set);
        }
        while (simplePhi(phiLabels, toReplace, set)) {
            // remove a = phi(b)
            fixReplace(toReplace);
            replacePhi(phiLabels, toReplace, set);
        }
        while (simpleAssign(phiLabels, assignStmtList, toReplace, method.stmts)) {
            // remove a=b
            fixReplace(toReplace);
            replaceAssign(assignStmtList, toReplace);
            changed = true;
            irChanged = true;
        }
        replacePhi(phiLabels, toReplace, set);
    }
    for (Local local : toReplace.keySet()) {
        method.locals.remove(local);
        irChanged = true;
    }
    if (toReplace.size() > 0) {
        Cfg.travelMod(method.stmts, new Cfg.TravelCallBack() {

            @Override
            public Value onAssign(Local v, AssignStmt as) {
                return v;
            }

            @Override
            public Value onUse(Local v) {
                Local n = toReplace.get(v);
                return n == null ? v : n;
            }
        }, true);
    }
    return irChanged;
}
Also used : LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Local(com.googlecode.dex2jar.ir.expr.Local) LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Stmt(com.googlecode.dex2jar.ir.stmt.Stmt) Value(com.googlecode.dex2jar.ir.expr.Value)

Aggregations

LabelStmt (com.googlecode.dex2jar.ir.stmt.LabelStmt)39 Local (com.googlecode.dex2jar.ir.expr.Local)26 Stmt (com.googlecode.dex2jar.ir.stmt.Stmt)22 AssignStmt (com.googlecode.dex2jar.ir.stmt.AssignStmt)17 Test (org.junit.Test)14 Value (com.googlecode.dex2jar.ir.expr.Value)8 ArrayList (java.util.ArrayList)7 Trap (com.googlecode.dex2jar.ir.Trap)4 JumpStmt (com.googlecode.dex2jar.ir.stmt.JumpStmt)4 StmtList (com.googlecode.dex2jar.ir.stmt.StmtList)4 List (java.util.List)3 StmtTraveler (com.googlecode.dex2jar.ir.StmtTraveler)2 PhiExpr (com.googlecode.dex2jar.ir.expr.PhiExpr)2 Cfg (com.googlecode.dex2jar.ir.ts.Cfg)2 HashSet (java.util.HashSet)2 IR2JConverter (com.googlecode.d2j.converter.IR2JConverter)1 DexFileNode (com.googlecode.d2j.node.DexFileNode)1 DexMethodNode (com.googlecode.d2j.node.DexMethodNode)1 IrMethod (com.googlecode.dex2jar.ir.IrMethod)1 LabelAndLocalMapper (com.googlecode.dex2jar.ir.LabelAndLocalMapper)1