use of com.googlecode.dex2jar.ir.expr.Constant in project dex2jar by pxb1988.
the class ZeroTransformer method transformReportChanged.
@Override
public boolean transformReportChanged(IrMethod method) {
boolean changed = false;
List<AssignStmt> assignStmtList = new ArrayList<>();
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.CONSTANT) {
Constant cst = (Constant) as.getOp2();
Object value = cst.value;
if (value instanceof Number && !((value instanceof Long) || (value instanceof Double))) {
int v = ((Number) value).intValue();
if (v == 0 || v == 1) {
assignStmtList.add(as);
}
}
}
}
}
if (assignStmtList.size() == 0) {
return false;
}
List<LabelStmt> phiLabels = method.phiLabels;
if (phiLabels != null) {
for (AssignStmt as : assignStmtList) {
Local local = (Local) as.getOp1();
boolean first = true;
for (LabelStmt labelStmt : phiLabels) {
for (AssignStmt phi : labelStmt.phis) {
Value[] vs = phi.getOp2().getOps();
for (int i = 0; i < vs.length; i++) {
Value v = vs[i];
if (v == local) {
if (first) {
first = false;
} else {
Local nLocal = Exprs.nLocal(-1);
method.locals.add(nLocal);
changed = true;
method.stmts.insertBefore(as, Stmts.nAssign(nLocal, as.getOp2().clone()));
vs[i] = nLocal;
}
}
}
}
}
}
}
return changed;
}
use of com.googlecode.dex2jar.ir.expr.Constant in project dex2jar by pxb1988.
the class ArrayNullPointerTransformer method tryAdd.
private boolean tryAdd(Value value, List<Value> values) {
if (!arrayNPE(value)) {
values.add(value);
return true;
} else {
switch(value.et) {
case E0:
values.add(value);
break;
case E1:
E1Expr e1 = (E1Expr) value;
if (e1.op == null || e1.op.trim() == null) {
return false;
}
tryAdd(e1.op.trim(), values);
break;
case E2:
E2Expr e2 = (E2Expr) value;
if (e2.vt == VT.ARRAY && e2.op1.trim().vt == VT.CONSTANT) {
Constant cst = (Constant) e2.op1.trim();
if (cst.value.equals(Integer.valueOf(0))) {
tryAdd(e2.op2.trim(), values);
return false;
}
}
if (tryAdd(e2.op1.trim(), values)) {
tryAdd(e2.op2.trim(), values);
}
case En:
for (Value vb : ((EnExpr) value).ops) {
if (!tryAdd(vb.trim(), values)) {
break;
}
}
}
}
return false;
}
use of com.googlecode.dex2jar.ir.expr.Constant in project dex2jar by pxb1988.
the class JimpleTransformer method convertExpr.
private Value convertExpr(Value x, boolean keep, N tmp) {
switch(x.et) {
case E0:
if (!keep) {
switch(x.vt) {
case CONSTANT:
Constant cst = (Constant) x;
if (cst.value instanceof String || cst.value instanceof Constant.Type || cst.value.getClass().isArray()) {
return tmp.newAssign(x);
}
break;
case NEW:
case STATIC_FIELD:
return tmp.newAssign(x);
default:
}
}
break;
case E1:
x.setOp(convertExpr(x.getOp(), false, tmp));
if (!keep) {
return tmp.newAssign(x);
}
break;
case E2:
x.setOp1(convertExpr(x.getOp1(), false, tmp));
x.setOp2(convertExpr(x.getOp2(), false, tmp));
if (!keep) {
return tmp.newAssign(x);
}
break;
case En:
Value[] ops = x.getOps();
for (int i = 0; i < ops.length; i++) {
ops[i] = convertExpr(ops[i], false, tmp);
}
if (!keep) {
return tmp.newAssign(x);
}
break;
}
return x;
}
use of com.googlecode.dex2jar.ir.expr.Constant in project dex2jar by pxb1988.
the class NpeTransformer method replace.
private void replace(final IrMethod m, final Stmt p) {
StmtTraveler traveler = new StmtTraveler() {
@Override
public Value travel(Value op) {
switch(op.vt) {
case INVOKE_VIRTUAL:
case INVOKE_SPECIAL:
case INVOKE_INTERFACE:
{
Value[] ops = op.getOps();
if (isNull(ops[0])) {
for (int i = 1; i < ops.length; i++) {
travel(ops[i]);
}
throw NPE;
}
}
break;
case ARRAY:
{
if (isNull(op.getOp1())) {
travel(op.getOp2());
throw NPE;
}
}
break;
case FIELD:
{
if (isNull(op.getOp())) {
throw NPE;
}
}
break;
case IDIV:
if (op.getOp2().vt == Value.VT.CONSTANT) {
Constant constant = (Constant) op.getOp2();
if (((Number) constant.value).intValue() == 0) {
travel(op.getOp1());
throw DIVE;
}
}
break;
case LDIV:
if (op.getOp2().vt == Value.VT.CONSTANT) {
Constant constant = (Constant) op.getOp2();
if (((Number) constant.value).longValue() == 0) {
travel(op.getOp1());
throw DIVE;
}
}
break;
case NEW_ARRAY:
if (op.getOp().vt == Value.VT.CONSTANT) {
Constant constant = (Constant) op.getOp();
if (((Number) constant.value).intValue() < 0) {
throw NEGATIVE_ARRAY_SIZE;
}
}
break;
case NEW_MUTI_ARRAY:
for (Value size : op.getOps()) {
if (size.vt == Value.VT.CONSTANT) {
Constant constant = (Constant) size;
if (((Number) constant.value).intValue() < 0) {
throw NEGATIVE_ARRAY_SIZE;
} else {
travel(size);
}
}
}
break;
default:
}
Value sop = super.travel(op);
if (sop.vt == Value.VT.LOCAL || sop.vt == Value.VT.CONSTANT) {
return sop;
} else {
Local local = new Local();
m.locals.add(local);
m.stmts.insertBefore(p, Stmts.nAssign(local, sop));
return local;
}
}
};
try {
switch(p.et) {
case E0:
// impossible
break;
case E1:
traveler.travel(p.getOp());
break;
case E2:
if (p.st == Stmt.ST.ASSIGN) {
switch(p.getOp1().vt) {
case ARRAY:
traveler.travel(p.getOp1().getOp1());
traveler.travel(p.getOp1().getOp2());
traveler.travel(p.getOp2());
break;
case FIELD:
traveler.travel(p.getOp1().getOp());
traveler.travel(p.getOp2());
break;
case STATIC_FIELD:
case LOCAL:
traveler.travel(p.getOp2());
break;
default:
}
} else if (p.st == Stmt.ST.FILL_ARRAY_DATA) {
if (isNull(p.getOp1())) {
throw NPE;
} else {
traveler.travel(p.getOp1());
}
}
break;
case En:
}
} catch (MustThrowException e) {
if (e == NPE) {
m.stmts.insertBefore(p, Stmts.nThrow(Exprs.nInvokeNew(new Value[0], new String[0], "Ljava/lang/NullPointerException;")));
} else if (e == DIVE) {
m.stmts.insertBefore(p, Stmts.nThrow(Exprs.nInvokeNew(new Value[] { Exprs.nString("divide by zero") }, new String[] { "Ljava/lang/String;" }, "Ljava/lang/ArithmeticException;")));
} else if (e == NEGATIVE_ARRAY_SIZE) {
m.stmts.insertBefore(p, Stmts.nThrow(Exprs.nInvokeNew(new Value[0], new String[0], "Ljava/lang/NegativeArraySizeException;")));
}
}
}
use of com.googlecode.dex2jar.ir.expr.Constant in project dex2jar by pxb1988.
the class NpeTransformer method transformReportChanged.
@Override
public boolean transformReportChanged(IrMethod method) {
boolean changed = false;
if (method.locals.size() == 0) {
return false;
}
StmtSearcher st = new StmtSearcher() {
@Override
public void travel(Stmt stmt) {
if (stmt.st == Stmt.ST.FILL_ARRAY_DATA) {
if (isNull(stmt.getOp1())) {
throw NPE;
}
}
super.travel(stmt);
}
@Override
public void travel(Value op) {
switch(op.vt) {
case INVOKE_VIRTUAL:
case INVOKE_SPECIAL:
case INVOKE_INTERFACE:
{
if (isNull(op.getOps()[0])) {
throw NPE;
}
}
break;
case ARRAY:
{
if (isNull(op.getOp1())) {
throw NPE;
}
}
break;
case FIELD:
{
if (isNull(op.getOp())) {
throw NPE;
}
}
break;
case IDIV:
if (op.getOp2().vt == Value.VT.CONSTANT) {
Constant constant = (Constant) op.getOp2();
if (((Number) constant.value).intValue() == 0) {
throw DIVE;
}
}
break;
case LDIV:
if (op.getOp2().vt == Value.VT.CONSTANT) {
Constant constant = (Constant) op.getOp2();
if (((Number) constant.value).longValue() == 0) {
throw DIVE;
}
}
break;
case NEW_ARRAY:
if (op.getOp().vt == Value.VT.CONSTANT) {
Constant constant = (Constant) op.getOp();
if (((Number) constant.value).intValue() < 0) {
throw NEGATIVE_ARRAY_SIZE;
}
}
break;
case NEW_MUTI_ARRAY:
for (Value size : op.getOps()) {
if (size.vt == Value.VT.CONSTANT) {
Constant constant = (Constant) size;
if (((Number) constant.value).intValue() < 0) {
throw NEGATIVE_ARRAY_SIZE;
}
}
}
break;
default:
}
}
};
for (Stmt p = method.stmts.getFirst(); p != null; ) {
try {
st.travel(p);
p = p.getNext();
} catch (MustThrowException e) {
replace(method, p);
Stmt q = p.getNext();
method.stmts.remove(p);
changed = true;
p = q;
}
}
return changed;
}
Aggregations