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;
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;
}
......
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();
......
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