Skip to content

Commit e1dfb4e

Browse files
asashourskylot
authored andcommitted
fix: byte to number without cast (skylot#596) (PR skylot#638)
1 parent 031582d commit e1dfb4e

File tree

8 files changed

+88
-28
lines changed

8 files changed

+88
-28
lines changed

jadx-core/src/main/java/jadx/core/dex/instructions/InvokeNode.java

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public InvokeType getInvokeType() {
4646
return type;
4747
}
4848

49+
@Override
4950
public MethodInfo getCallMth() {
5051
return mth;
5152
}

jadx-core/src/main/java/jadx/core/dex/instructions/args/RegisterArg.java

+2
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ void setSVar(@NotNull SSAVar sVar) {
8181
}
8282
}
8383

84+
@Override
8485
public String getName() {
8586
if (isThis()) {
8687
return THIS_ARG_NAME;
@@ -91,6 +92,7 @@ public String getName() {
9192
return sVar.getName();
9293
}
9394

95+
@Override
9496
public void setName(String name) {
9597
if (sVar != null && name != null) {
9698
sVar.setName(name);
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
package jadx.core.dex.visitors.typeinference;
22

3+
import org.jetbrains.annotations.Nullable;
4+
35
import jadx.core.dex.instructions.args.ArgType;
6+
import jadx.core.dex.instructions.args.RegisterArg;
47

58
public interface ITypeBound {
69
BoundEnum getBound();
710

811
ArgType getType();
12+
13+
@Nullable
14+
RegisterArg getArg();
915
}

jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/TypeBoundConst.java

+13
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,22 @@
33
import java.util.Objects;
44

55
import jadx.core.dex.instructions.args.ArgType;
6+
import jadx.core.dex.instructions.args.RegisterArg;
67

78
public final class TypeBoundConst implements ITypeBound {
89
private final BoundEnum bound;
910
private final ArgType type;
11+
private final RegisterArg arg;
12+
1013

1114
public TypeBoundConst(BoundEnum bound, ArgType type) {
15+
this(bound, type, null);
16+
}
17+
18+
public TypeBoundConst(BoundEnum bound, ArgType type, RegisterArg arg) {
1219
this.bound = bound;
1320
this.type = type;
21+
this.arg = arg;
1422
}
1523

1624
@Override
@@ -23,6 +31,11 @@ public ArgType getType() {
2331
return type;
2432
}
2533

34+
@Override
35+
public RegisterArg getArg() {
36+
return arg;
37+
}
38+
2639
@Override
2740
public boolean equals(Object o) {
2841
if (this == o) {

jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/TypeInferenceVisitor.java

+42-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import jadx.core.dex.instructions.InsnType;
2222
import jadx.core.dex.instructions.PhiInsn;
2323
import jadx.core.dex.instructions.args.ArgType;
24+
import jadx.core.dex.instructions.args.CodeVar;
2425
import jadx.core.dex.instructions.args.InsnArg;
2526
import jadx.core.dex.instructions.args.LiteralArg;
2627
import jadx.core.dex.instructions.args.PrimitiveType;
@@ -81,7 +82,11 @@ public void visit(MethodNode mth) {
8182
resolved = false;
8283
}
8384
}
84-
if (!resolved) {
85+
if (resolved) {
86+
for (SSAVar var : new ArrayList<>(mth.getSVars())) {
87+
processIncompatiblePrimitives(mth, var);
88+
}
89+
} else {
8590
for (SSAVar var : new ArrayList<>(mth.getSVars())) {
8691
tryInsertAdditionalInsn(mth, var);
8792
}
@@ -249,7 +254,7 @@ private ITypeBound makeUseBound(RegisterArg regArg) {
249254
if (insn == null) {
250255
return null;
251256
}
252-
return new TypeBoundConst(BoundEnum.USE, regArg.getInitType());
257+
return new TypeBoundConst(BoundEnum.USE, regArg.getInitType(), regArg);
253258
}
254259

255260
private boolean tryPossibleTypes(SSAVar var, ArgType type) {
@@ -375,4 +380,39 @@ private boolean tryWiderObjects(MethodNode mth, SSAVar var) {
375380
}
376381
return false;
377382
}
383+
384+
private void processIncompatiblePrimitives(MethodNode mth, SSAVar var) {
385+
if (var.getAssign().getType() == ArgType.BOOLEAN) {
386+
for (ITypeBound bound : var.getTypeInfo().getBounds()) {
387+
if (bound.getBound() == BoundEnum.USE
388+
&& bound.getType().isPrimitive() && bound.getType() != ArgType.BOOLEAN) {
389+
InsnNode insn = bound.getArg().getParentInsn();
390+
if (insn.getType() == InsnType.CAST) {
391+
continue;
392+
};
393+
394+
IndexInsnNode castNode = new IndexInsnNode(InsnType.CAST, bound.getType(), 1);
395+
castNode.addArg(bound.getArg());
396+
castNode.setResult(InsnArg.reg(bound.getArg().getRegNum(), bound.getType()));
397+
398+
SSAVar newVar = mth.makeNewSVar(castNode.getResult().getRegNum(), castNode.getResult());
399+
CodeVar codeVar = new CodeVar();
400+
codeVar.setType(bound.getType());
401+
newVar.setCodeVar(codeVar);
402+
newVar.getTypeInfo().setType(bound.getType());
403+
404+
for (int i = insn.getArgsCount() - 1; i >= 0; i--) {
405+
if (insn.getArg(i) == bound.getArg()) {
406+
insn.setArg(i, castNode.getResult().duplicate());
407+
break;
408+
}
409+
}
410+
411+
BlockNode blockNode = BlockUtils.getBlockByInsn(mth, insn);
412+
List<InsnNode> insnList = blockNode.getInstructions();
413+
insnList.add(insnList.indexOf(insn), castNode);
414+
}
415+
}
416+
}
417+
}
378418
}

jadx-core/src/test/java/jadx/tests/integration/conditions/TestBooleanToInt2.java jadx-core/src/test/java/jadx/tests/integration/conditions/TestBooleanToInt.java

+4-6
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,24 @@
55

66
import org.junit.jupiter.api.Test;
77

8-
import jadx.NotYetImplemented;
98
import jadx.core.dex.nodes.ClassNode;
109
import jadx.tests.api.SmaliTest;
1110

12-
public class TestBooleanToInt2 extends SmaliTest {
11+
public class TestBooleanToInt extends SmaliTest {
1312

1413
/**
1514
private boolean showConsent;
1615
1716
public void write(int b) {
1817
}
1918
20-
public void writeToParcel(TestBooleanToInt2 testBooleanToInt2) {
21-
testBooleanToInt2.write(this.showConsent ? 1 : 0);
19+
public void writeToParcel(TestBooleanToInt testBooleanToInt) {
20+
testBooleanToInt.write(this.showConsent ? 1 : 0);
2221
}
2322
*/
2423
@Test
25-
@NotYetImplemented
2624
public void test() {
27-
ClassNode cls = getClassNodeFromSmaliWithPath("conditions", "TestBooleanToInt2");
25+
ClassNode cls = getClassNodeFromSmaliWithPath("conditions", "TestBooleanToInt");
2826
String code = cls.getCode().toString();
2927

3028
assertThat(code, containsString("write(this.showConsent ? 1 : 0);"));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
.class public LTestBooleanToInt;
2+
.super Ljava/lang/Object;
3+
4+
.field private showConsent:Z
5+
6+
.method public writeToParcel(LTestBooleanToInt;)V
7+
.locals 0
8+
9+
iget-boolean p1, p0, LTestBooleanToInt;->showConsent:Z
10+
11+
invoke-virtual {p0, p1}, LTestBooleanToInt;->write(I)V
12+
13+
return-void
14+
.end method
15+
16+
.method public write(I)V
17+
.locals 0
18+
19+
return-void
20+
.end method

jadx-core/src/test/smali/conditions/TestBooleanToInt2.smali

-20
This file was deleted.

0 commit comments

Comments
 (0)