From b004967677a6667ad5b06af3b04612c628276c29 Mon Sep 17 00:00:00 2001 From: Bob Pan Date: Sun, 31 Oct 2021 03:32:55 +0800 Subject: [PATCH] fix ClassCastException NewTransformer#findInvokeExpr attempts to cast InvokePolymorphicExpr to InvokeExpr under certain inputs, which causes a ClassCastException. this patch is similar with https://github.com/pxb1988/dex2jar/pull/486/commits/9c6cde4f598f8a59ff1d54d197284be0efc1fa69 https://github.com/pxb1988/dex2jar/pull/486/commits/9c0db1d636d7291bcf9e0265c132c6a4bccd0706 --- .../googlecode/dex2jar/ir/stmt/VoidInvokeStmt.java | 3 ++- .../googlecode/dex2jar/ir/ts/NewTransformer.java | 12 ++++++++---- .../dex2jar/ir/ts/VoidInvokeTransformer.java | 14 ++++---------- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/dex-ir/src/main/java/com/googlecode/dex2jar/ir/stmt/VoidInvokeStmt.java b/dex-ir/src/main/java/com/googlecode/dex2jar/ir/stmt/VoidInvokeStmt.java index 01aa6a1e9..85b08cea2 100644 --- a/dex-ir/src/main/java/com/googlecode/dex2jar/ir/stmt/VoidInvokeStmt.java +++ b/dex-ir/src/main/java/com/googlecode/dex2jar/ir/stmt/VoidInvokeStmt.java @@ -21,7 +21,8 @@ import com.googlecode.dex2jar.ir.stmt.Stmt.E1Stmt; /** - * Represent a void-return Invoke + * Represent a void-expr: the expr result is ignored. + * possible op type: AbstractInvokeExpr, FieldExpr, or others * * @see ST#VOID_INVOKE * diff --git a/dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/NewTransformer.java b/dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/NewTransformer.java index 86e698894..64087741e 100644 --- a/dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/NewTransformer.java +++ b/dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/NewTransformer.java @@ -95,7 +95,7 @@ void replaceAST(IrMethod method) { for (Iterator it = method.stmts.iterator(); it.hasNext(); ) { Stmt p = it.next(); - InvokeExpr ie = findInvokeExpr(p, null); + InvokeExpr ie = findInvokeExpr(p); if (ie != null) { if ("".equals(ie.getName()) && "V".equals(ie.getRet())) { @@ -153,7 +153,7 @@ void replace0(IrMethod method, Map init, int size) { } } } - InvokeExpr ie = findInvokeExpr(obj.invokeStmt, null); + InvokeExpr ie = findInvokeExpr(obj.invokeStmt); Value[] orgOps = ie.getOps(); Value[] nOps = Arrays.copyOfRange(orgOps, 1, orgOps.length); InvokeExpr invokeNew = Exprs.nInvokeNew(nOps, ie.getArgs(), ie.getOwner()); @@ -352,13 +352,17 @@ void use(Local local) { } } - InvokeExpr findInvokeExpr(Stmt p, InvokeExpr ie) { + InvokeExpr findInvokeExpr(Stmt p) { + InvokeExpr ie = null; if (p.st == ASSIGN) { if (p.getOp2().vt == INVOKE_SPECIAL) { ie = (InvokeExpr) p.getOp2(); } } else if (p.st == VOID_INVOKE) { - ie = (InvokeExpr) p.getOp(); + Value op = p.getOp(); + if (op instanceof InvokeExpr) { + ie = (InvokeExpr) op; + } } return ie; } diff --git a/dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/VoidInvokeTransformer.java b/dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/VoidInvokeTransformer.java index 4fc6c8fd2..80fce6d29 100644 --- a/dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/VoidInvokeTransformer.java +++ b/dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/VoidInvokeTransformer.java @@ -17,6 +17,7 @@ package com.googlecode.dex2jar.ir.ts; import com.googlecode.dex2jar.ir.IrMethod; +import com.googlecode.dex2jar.ir.expr.AbstractInvokeExpr; import com.googlecode.dex2jar.ir.expr.Local; import com.googlecode.dex2jar.ir.expr.Value; import com.googlecode.dex2jar.ir.stmt.Stmt; @@ -49,20 +50,13 @@ public boolean transformReportChanged(IrMethod method) { if (p.st == Stmt.ST.ASSIGN && p.getOp1().vt == Value.VT.LOCAL) { Local left = (Local) p.getOp1(); if (reads[left._ls_index] == 0) { - switch (p.getOp2().vt) { - case INVOKE_INTERFACE: - case INVOKE_NEW: - case INVOKE_SPECIAL: - case INVOKE_STATIC: - case INVOKE_VIRTUAL: + Value op2 = p.getOp2(); + if (op2 instanceof AbstractInvokeExpr) { method.locals.remove(left); - Stmt nVoidInvoke = Stmts.nVoidInvoke(p.getOp2()); + Stmt nVoidInvoke = Stmts.nVoidInvoke(op2); method.stmts.replace(p, nVoidInvoke); p = nVoidInvoke; changed = true; - break; - default: - break; } } }