Commit 4fb6ada5 authored by Skylot's avatar Skylot

core: fix type inference for phi nodes

parent ab924faa
...@@ -12,7 +12,12 @@ import jadx.core.utils.exceptions.JadxException; ...@@ -12,7 +12,12 @@ import jadx.core.utils.exceptions.JadxException;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class EliminatePhiNodes extends AbstractVisitor { public class EliminatePhiNodes extends AbstractVisitor {
private static final Logger LOG = LoggerFactory.getLogger(EliminatePhiNodes.class);
@Override @Override
public void visit(MethodNode mth) throws JadxException { public void visit(MethodNode mth) throws JadxException {
if (mth.isNoCode()) { if (mth.isNoCode()) {
...@@ -29,13 +34,20 @@ public class EliminatePhiNodes extends AbstractVisitor { ...@@ -29,13 +34,20 @@ public class EliminatePhiNodes extends AbstractVisitor {
} }
List<PhiInsn> list = phiList.getList(); List<PhiInsn> list = phiList.getList();
for (PhiInsn phiInsn : list) { for (PhiInsn phiInsn : list) {
for (Iterator<InsnNode> iterator = block.getInstructions().iterator(); iterator.hasNext(); ) { removeInsn(mth, block, phiInsn);
InsnNode insn = iterator.next(); }
if (insn == phiInsn) { }
iterator.remove(); }
}
} 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; ...@@ -3,6 +3,7 @@ package jadx.core.dex.visitors.typeinference;
import jadx.core.dex.info.MethodInfo; import jadx.core.dex.info.MethodInfo;
import jadx.core.dex.instructions.IndexInsnNode; import jadx.core.dex.instructions.IndexInsnNode;
import jadx.core.dex.instructions.InvokeNode; 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.ArgType;
import jadx.core.dex.instructions.args.InsnArg; import jadx.core.dex.instructions.args.InsnArg;
import jadx.core.dex.instructions.args.LiteralArg; import jadx.core.dex.instructions.args.LiteralArg;
...@@ -94,6 +95,21 @@ public class PostTypeInference { ...@@ -94,6 +95,21 @@ public class PostTypeInference {
return true; 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: default:
break; break;
} }
......
package jadx.core.dex.visitors.typeinference; package jadx.core.dex.visitors.typeinference;
import jadx.core.dex.attributes.AFlag;
import jadx.core.dex.instructions.PhiInsn; import jadx.core.dex.instructions.PhiInsn;
import jadx.core.dex.instructions.args.ArgType; import jadx.core.dex.instructions.args.ArgType;
import jadx.core.dex.instructions.args.InsnArg; import jadx.core.dex.instructions.args.InsnArg;
...@@ -9,7 +8,6 @@ import jadx.core.dex.instructions.args.SSAVar; ...@@ -9,7 +8,6 @@ import jadx.core.dex.instructions.args.SSAVar;
import jadx.core.dex.nodes.MethodNode; import jadx.core.dex.nodes.MethodNode;
import jadx.core.dex.visitors.AbstractVisitor; import jadx.core.dex.visitors.AbstractVisitor;
import jadx.core.utils.exceptions.JadxException; import jadx.core.utils.exceptions.JadxException;
import jadx.core.utils.exceptions.JadxRuntimeException;
import java.util.List; import java.util.List;
...@@ -43,7 +41,7 @@ public class TypeInference extends AbstractVisitor { ...@@ -43,7 +41,7 @@ public class TypeInference extends AbstractVisitor {
} }
} }
private ArgType processType(SSAVar var) { private static ArgType processType(SSAVar var) {
RegisterArg assign = var.getAssign(); RegisterArg assign = var.getAssign();
List<RegisterArg> useList = var.getUseList(); List<RegisterArg> useList = var.getUseList();
if (assign != null if (assign != null
...@@ -58,17 +56,15 @@ public class TypeInference extends AbstractVisitor { ...@@ -58,17 +56,15 @@ public class TypeInference extends AbstractVisitor {
} }
for (RegisterArg arg : useList) { for (RegisterArg arg : useList) {
ArgType useType = arg.getType(); ArgType useType = arg.getType();
if (useType.isTypeKnown()) { ArgType newType = ArgType.merge(type, useType);
type = ArgType.merge(type, useType); if (newType != null) {
} type = newType;
if (arg.getParentInsn().contains(AFlag.INCONSISTENT_CODE)) {
throw new JadxRuntimeException("not removed arg");
} }
} }
return type; return type;
} }
private void processPhiNode(PhiInsn phi) { private static void processPhiNode(PhiInsn phi) {
ArgType type = phi.getResult().getType(); ArgType type = phi.getResult().getType();
if (!type.isTypeKnown()) { if (!type.isTypeKnown()) {
for (InsnArg arg : phi.getArguments()) { for (InsnArg arg : phi.getArguments()) {
...@@ -86,7 +82,7 @@ public class TypeInference extends AbstractVisitor { ...@@ -86,7 +82,7 @@ public class TypeInference extends AbstractVisitor {
} }
} }
private String processVarName(SSAVar var) { private static String processVarName(SSAVar var) {
String name = null; String name = null;
if (var.getAssign() != null) { if (var.getAssign() != null) {
name = var.getAssign().getName(); name = var.getAssign().getName();
......
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);
}
}
.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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment