core: fix type inference for phi nodes
This commit is contained in:
@@ -12,7 +12,12 @@ import jadx.core.utils.exceptions.JadxException;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class EliminatePhiNodes extends AbstractVisitor {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(EliminatePhiNodes.class);
|
||||
|
||||
@Override
|
||||
public void visit(MethodNode mth) throws JadxException {
|
||||
if (mth.isNoCode()) {
|
||||
@@ -29,13 +34,20 @@ public class EliminatePhiNodes extends AbstractVisitor {
|
||||
}
|
||||
List<PhiInsn> list = phiList.getList();
|
||||
for (PhiInsn phiInsn : list) {
|
||||
for (Iterator<InsnNode> iterator = block.getInstructions().iterator(); iterator.hasNext(); ) {
|
||||
InsnNode insn = iterator.next();
|
||||
if (insn == phiInsn) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
removeInsn(mth, block, phiInsn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void removeInsn(MethodNode mth, BlockNode block, PhiInsn phiInsn) {
|
||||
Iterator<InsnNode> it = block.getInstructions().iterator();
|
||||
while (it.hasNext()) {
|
||||
InsnNode insn = it.next();
|
||||
if (insn == phiInsn) {
|
||||
it.remove();
|
||||
return;
|
||||
}
|
||||
}
|
||||
LOG.warn("Phi node not removed: {}, mth: {}", phiInsn, mth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package jadx.core.dex.visitors.typeinference;
|
||||
import jadx.core.dex.info.MethodInfo;
|
||||
import jadx.core.dex.instructions.IndexInsnNode;
|
||||
import jadx.core.dex.instructions.InvokeNode;
|
||||
import jadx.core.dex.instructions.PhiInsn;
|
||||
import jadx.core.dex.instructions.args.ArgType;
|
||||
import jadx.core.dex.instructions.args.InsnArg;
|
||||
import jadx.core.dex.instructions.args.LiteralArg;
|
||||
@@ -94,6 +95,21 @@ public class PostTypeInference {
|
||||
return true;
|
||||
}
|
||||
|
||||
case PHI: {
|
||||
PhiInsn phi = (PhiInsn) insn;
|
||||
SSAVar resultSVar = phi.getResult().getSVar();
|
||||
if (resultSVar != null && !resultSVar.getType().isTypeKnown()) {
|
||||
for (InsnArg arg : phi.getArguments()) {
|
||||
ArgType argType = arg.getType();
|
||||
if (argType.isTypeKnown()) {
|
||||
resultSVar.setType(argType);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package jadx.core.dex.visitors.typeinference;
|
||||
|
||||
import jadx.core.dex.attributes.AFlag;
|
||||
import jadx.core.dex.instructions.PhiInsn;
|
||||
import jadx.core.dex.instructions.args.ArgType;
|
||||
import jadx.core.dex.instructions.args.InsnArg;
|
||||
@@ -9,7 +8,6 @@ import jadx.core.dex.instructions.args.SSAVar;
|
||||
import jadx.core.dex.nodes.MethodNode;
|
||||
import jadx.core.dex.visitors.AbstractVisitor;
|
||||
import jadx.core.utils.exceptions.JadxException;
|
||||
import jadx.core.utils.exceptions.JadxRuntimeException;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -43,7 +41,7 @@ public class TypeInference extends AbstractVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
private ArgType processType(SSAVar var) {
|
||||
private static ArgType processType(SSAVar var) {
|
||||
RegisterArg assign = var.getAssign();
|
||||
List<RegisterArg> useList = var.getUseList();
|
||||
if (assign != null
|
||||
@@ -58,17 +56,15 @@ public class TypeInference extends AbstractVisitor {
|
||||
}
|
||||
for (RegisterArg arg : useList) {
|
||||
ArgType useType = arg.getType();
|
||||
if (useType.isTypeKnown()) {
|
||||
type = ArgType.merge(type, useType);
|
||||
}
|
||||
if (arg.getParentInsn().contains(AFlag.INCONSISTENT_CODE)) {
|
||||
throw new JadxRuntimeException("not removed arg");
|
||||
ArgType newType = ArgType.merge(type, useType);
|
||||
if (newType != null) {
|
||||
type = newType;
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
private void processPhiNode(PhiInsn phi) {
|
||||
private static void processPhiNode(PhiInsn phi) {
|
||||
ArgType type = phi.getResult().getType();
|
||||
if (!type.isTypeKnown()) {
|
||||
for (InsnArg arg : phi.getArguments()) {
|
||||
@@ -86,7 +82,7 @@ public class TypeInference extends AbstractVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
private String processVarName(SSAVar var) {
|
||||
private static String processVarName(SSAVar var) {
|
||||
String name = null;
|
||||
if (var.getAssign() != null) {
|
||||
name = var.getAssign().getName();
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package jadx.tests.smali;
|
||||
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
import jadx.tests.api.SmaliTest;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestN21 extends SmaliTest {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
ClassNode cls = getClassNodeFromSmali("TestN21");
|
||||
String code = cls.getCode().toString();
|
||||
System.out.println(code);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
.class public LTestN21;
|
||||
.super Ljava/lang/Object;
|
||||
|
||||
.method private static test([BI)I
|
||||
.locals 5
|
||||
|
||||
const/4 v1, 0x0
|
||||
|
||||
const/16 v0, 0xe
|
||||
|
||||
aget-byte v0, p0, v0
|
||||
|
||||
shl-int/lit8 v0, v0, 0x10
|
||||
|
||||
move v2, v1
|
||||
|
||||
:goto_0
|
||||
if-nez v2, :cond_1
|
||||
|
||||
const/4 v2, 0x3
|
||||
|
||||
and-int/lit16 v3, p1, 0xff
|
||||
|
||||
:try_start_0
|
||||
aget-byte v3, p0, v3
|
||||
|
||||
and-int/lit16 v3, v3, 0xff
|
||||
|
||||
shr-int/lit8 v4, p1, 0x8
|
||||
|
||||
and-int/lit16 v4, v4, 0xff
|
||||
|
||||
aget-byte v4, p0, v4
|
||||
|
||||
and-int/lit16 v4, v4, 0xff
|
||||
|
||||
shl-int/lit8 v4, v4, 0x8
|
||||
|
||||
or-int/2addr v3, v4
|
||||
|
||||
shr-int/lit8 v4, p1, 0x10
|
||||
|
||||
and-int/lit16 v4, v4, 0xff
|
||||
|
||||
aget-byte v4, p0, v4
|
||||
|
||||
and-int/lit16 v4, v4, 0xff
|
||||
|
||||
shl-int/lit8 v4, v4, 0x10
|
||||
|
||||
or-int/2addr v3, v4
|
||||
|
||||
shr-int/lit8 v4, p1, 0x18
|
||||
|
||||
and-int/lit16 v4, v4, 0xff
|
||||
|
||||
aget-byte v0, p0, v4
|
||||
:try_end_0
|
||||
.catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_1
|
||||
|
||||
shl-int/lit8 v0, v0, 0x18
|
||||
|
||||
or-int/2addr v0, v3
|
||||
|
||||
:cond_0
|
||||
:goto_1
|
||||
return v0
|
||||
|
||||
:catch_0
|
||||
move-exception v2
|
||||
|
||||
:cond_1
|
||||
if-nez v1, :cond_0
|
||||
|
||||
const/4 v1, 0x2
|
||||
|
||||
and-int/lit8 v2, p1, 0x7f
|
||||
|
||||
:try_start_1
|
||||
aget-byte v0, p0, v2
|
||||
:try_end_1
|
||||
.catch Ljava/lang/Exception; {:try_start_1 .. :try_end_1} :catch_0
|
||||
|
||||
shr-int/lit8 v0, v0, 0x8
|
||||
|
||||
goto :goto_1
|
||||
|
||||
:catch_1
|
||||
move-exception v3
|
||||
|
||||
goto :goto_0
|
||||
.end method
|
||||
|
||||
Reference in New Issue
Block a user