@@ -13,6 +13,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import jadx.core.Consts;
|
||||
import jadx.core.deobf.NameMapper;
|
||||
import jadx.core.dex.attributes.AFlag;
|
||||
import jadx.core.dex.attributes.AType;
|
||||
import jadx.core.dex.attributes.nodes.FieldReplaceAttr;
|
||||
@@ -888,6 +889,13 @@ public class InsnGen {
|
||||
&& lit2 != Short.MAX_VALUE && lit2 != Short.MIN_VALUE) {
|
||||
code.add("(short) ");
|
||||
}
|
||||
} else if (first.getType() == ArgType.CHAR) {
|
||||
long lit1 = ((LiteralArg) first).getLiteral();
|
||||
long lit2 = ((LiteralArg) second).getLiteral();
|
||||
if (!NameMapper.isPrintableChar((char) (lit1))
|
||||
&& !NameMapper.isPrintableChar((char) (lit2))) {
|
||||
code.add("(char) ");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package jadx.core.dex.visitors;
|
||||
|
||||
import static jadx.core.utils.BlockUtils.replaceInsn;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
@@ -18,6 +20,8 @@ import jadx.core.dex.instructions.ConstClassNode;
|
||||
import jadx.core.dex.instructions.ConstStringNode;
|
||||
import jadx.core.dex.instructions.FillArrayNode;
|
||||
import jadx.core.dex.instructions.FilledNewArrayNode;
|
||||
import jadx.core.dex.instructions.IfNode;
|
||||
import jadx.core.dex.instructions.IfOp;
|
||||
import jadx.core.dex.instructions.IndexInsnNode;
|
||||
import jadx.core.dex.instructions.InsnType;
|
||||
import jadx.core.dex.instructions.NewArrayNode;
|
||||
@@ -29,11 +33,13 @@ import jadx.core.dex.instructions.args.NamedArg;
|
||||
import jadx.core.dex.instructions.args.RegisterArg;
|
||||
import jadx.core.dex.instructions.args.SSAVar;
|
||||
import jadx.core.dex.instructions.mods.ConstructorInsn;
|
||||
import jadx.core.dex.instructions.mods.TernaryInsn;
|
||||
import jadx.core.dex.nodes.BlockNode;
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
import jadx.core.dex.nodes.FieldNode;
|
||||
import jadx.core.dex.nodes.InsnNode;
|
||||
import jadx.core.dex.nodes.MethodNode;
|
||||
import jadx.core.dex.regions.conditions.IfCondition;
|
||||
import jadx.core.dex.trycatch.ExcHandlerAttr;
|
||||
import jadx.core.dex.trycatch.ExceptionHandler;
|
||||
import jadx.core.dex.visitors.shrink.CodeShrinkVisitor;
|
||||
@@ -42,8 +48,6 @@ import jadx.core.utils.InsnRemover;
|
||||
import jadx.core.utils.InsnUtils;
|
||||
import jadx.core.utils.exceptions.JadxRuntimeException;
|
||||
|
||||
import static jadx.core.utils.BlockUtils.replaceInsn;
|
||||
|
||||
/**
|
||||
* Visitor for modify method instructions
|
||||
* (remove, replace, process exception handlers)
|
||||
@@ -155,6 +159,23 @@ public class ModVisitor extends AbstractVisitor {
|
||||
}
|
||||
break;
|
||||
|
||||
case CAST:
|
||||
// replace boolean to (byte/char/short/long/double/float) cast with ternary
|
||||
if (insn.getArg(0).getType() == ArgType.BOOLEAN) {
|
||||
ArgType type = insn.getResult().getType();
|
||||
if (type.isPrimitive()) {
|
||||
IfNode ifNode = new IfNode(IfOp.EQ, -1, insn.getArg(0), LiteralArg.TRUE);
|
||||
IfCondition condition = IfCondition.fromIfNode(ifNode);
|
||||
InsnArg zero = new LiteralArg(0, type);
|
||||
InsnArg one = new LiteralArg(
|
||||
type == ArgType.DOUBLE ? Double.doubleToLongBits(1) :
|
||||
type == ArgType.FLOAT ? Float.floatToIntBits(1) : 1, type);
|
||||
TernaryInsn ternary = new TernaryInsn(condition, insn.getResult(), one, zero);
|
||||
replaceInsn(block, i, ternary);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package jadx.tests.integration.conditions;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
import jadx.tests.api.SmaliTest;
|
||||
|
||||
public class TestBooleanToByte extends SmaliTest {
|
||||
|
||||
/**
|
||||
private boolean showConsent;
|
||||
|
||||
public void write(byte b) {
|
||||
}
|
||||
|
||||
public void writeToParcel(TestBooleanToByte testBooleanToByte) {
|
||||
testBooleanToByte.write(this.showConsent ? (byte) 1 : 0);
|
||||
}
|
||||
*/
|
||||
@Test
|
||||
public void test() {
|
||||
ClassNode cls = getClassNodeFromSmaliWithPath("conditions", "TestBooleanToByte");
|
||||
String code = cls.getCode().toString();
|
||||
|
||||
assertThat(code, containsString("write(this.showConsent ? (byte) 1 : 0);"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package jadx.tests.integration.conditions;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
import jadx.tests.api.SmaliTest;
|
||||
|
||||
public class TestBooleanToChar extends SmaliTest {
|
||||
|
||||
/**
|
||||
private boolean showConsent;
|
||||
|
||||
public void write(char b) {
|
||||
}
|
||||
|
||||
public void writeToParcel(TestBooleanToChar testBooleanToChar) {
|
||||
testBooleanToChar.write(this.showConsent ? (char) 1 : 0);
|
||||
}
|
||||
*/
|
||||
@Test
|
||||
public void test() {
|
||||
ClassNode cls = getClassNodeFromSmaliWithPath("conditions", "TestBooleanToChar");
|
||||
String code = cls.getCode().toString();
|
||||
|
||||
assertThat(code, containsString("write(this.showConsent ? (char) 1 : 0);"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package jadx.tests.integration.conditions;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
import jadx.tests.api.SmaliTest;
|
||||
|
||||
public class TestBooleanToDouble extends SmaliTest {
|
||||
|
||||
/**
|
||||
private boolean showConsent;
|
||||
|
||||
public void write(double d) {
|
||||
}
|
||||
|
||||
public void writeToParcel(TestBooleanToDouble testBooleanToDouble) {
|
||||
testBooleanToDouble.write(this.showConsent ? 1 : 0);
|
||||
}
|
||||
*/
|
||||
@Test
|
||||
public void test() {
|
||||
ClassNode cls = getClassNodeFromSmaliWithPath("conditions", "TestBooleanToDouble");
|
||||
String code = cls.getCode().toString();
|
||||
|
||||
assertThat(code, containsString("write(this.showConsent ? 1.0d : 0.0d);"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package jadx.tests.integration.conditions;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
import jadx.tests.api.SmaliTest;
|
||||
|
||||
public class TestBooleanToFloat extends SmaliTest {
|
||||
|
||||
/**
|
||||
private boolean showConsent;
|
||||
|
||||
public void write(float f) {
|
||||
}
|
||||
|
||||
public void writeToParcel(TestBooleanToFloat testBooleanToFloat) {
|
||||
testBooleanToFloat.write(this.showConsent ? 1 : 0);
|
||||
}
|
||||
*/
|
||||
@Test
|
||||
public void test() {
|
||||
ClassNode cls = getClassNodeFromSmaliWithPath("conditions", "TestBooleanToFloat");
|
||||
String code = cls.getCode().toString();
|
||||
|
||||
assertThat(code, containsString("write(this.showConsent ? 1.0f : 0.0f);"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package jadx.tests.integration.conditions;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
import jadx.tests.api.SmaliTest;
|
||||
|
||||
public class TestBooleanToLong extends SmaliTest {
|
||||
|
||||
/**
|
||||
private boolean showConsent;
|
||||
|
||||
public void write(long j) {
|
||||
}
|
||||
|
||||
public void writeToParcel(TestBooleanToLong testBooleanToLong) {
|
||||
testBooleanToLong.write(this.showConsent ? 1 : 0);
|
||||
}
|
||||
*/
|
||||
@Test
|
||||
public void test() {
|
||||
ClassNode cls = getClassNodeFromSmaliWithPath("conditions", "TestBooleanToLong");
|
||||
String code = cls.getCode().toString();
|
||||
|
||||
assertThat(code, containsString("write(this.showConsent ? 1 : 0);"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package jadx.tests.integration.conditions;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
import jadx.tests.api.SmaliTest;
|
||||
|
||||
public class TestBooleanToShort extends SmaliTest {
|
||||
|
||||
/**
|
||||
private boolean showConsent;
|
||||
|
||||
public void write(short b) {
|
||||
}
|
||||
|
||||
public void writeToParcel(TestBooleanToShort testBooleanToShort) {
|
||||
testBooleanToShort.write(this.showConsent ? (short) 1 : 0);
|
||||
}
|
||||
*/
|
||||
@Test
|
||||
public void test() {
|
||||
ClassNode cls = getClassNodeFromSmaliWithPath("conditions", "TestBooleanToShort");
|
||||
String code = cls.getCode().toString();
|
||||
|
||||
assertThat(code, containsString("write(this.showConsent ? (short) 1 : 0);"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
.class public LTestBooleanToByte;
|
||||
.super Ljava/lang/Object;
|
||||
|
||||
.field private showConsent:Z
|
||||
|
||||
.method public writeToParcel(LTestBooleanToByte;)V
|
||||
.locals 0
|
||||
|
||||
iget-boolean p1, p0, LTestBooleanToByte;->showConsent:Z
|
||||
|
||||
int-to-byte p1, p1
|
||||
|
||||
invoke-virtual {p0, p1}, LTestBooleanToByte;->write(B)V
|
||||
|
||||
return-void
|
||||
.end method
|
||||
|
||||
.method public write(B)V
|
||||
.locals 0
|
||||
|
||||
return-void
|
||||
.end method
|
||||
@@ -0,0 +1,22 @@
|
||||
.class public LTestBooleanToChar;
|
||||
.super Ljava/lang/Object;
|
||||
|
||||
.field private showConsent:Z
|
||||
|
||||
.method public writeToParcel(LTestBooleanToChar;)V
|
||||
.locals 0
|
||||
|
||||
iget-boolean p1, p0, LTestBooleanToChar;->showConsent:Z
|
||||
|
||||
int-to-char p1, p1
|
||||
|
||||
invoke-virtual {p0, p1}, LTestBooleanToChar;->write(C)V
|
||||
|
||||
return-void
|
||||
.end method
|
||||
|
||||
.method public write(C)V
|
||||
.locals 0
|
||||
|
||||
return-void
|
||||
.end method
|
||||
@@ -0,0 +1,22 @@
|
||||
.class public LTestBooleanToDouble;
|
||||
.super Ljava/lang/Object;
|
||||
|
||||
.field private showConsent:Z
|
||||
|
||||
.method public writeToParcel(LTestBooleanToDouble;)V
|
||||
.locals 0
|
||||
|
||||
iget-boolean p1, p0, LTestBooleanToDouble;->showConsent:Z
|
||||
|
||||
int-to-double p1, p1
|
||||
|
||||
invoke-virtual {p0, p1}, LTestBooleanToDouble;->write(D)V
|
||||
|
||||
return-void
|
||||
.end method
|
||||
|
||||
.method public write(D)V
|
||||
.locals 0
|
||||
|
||||
return-void
|
||||
.end method
|
||||
@@ -0,0 +1,22 @@
|
||||
.class public LTestBooleanToFloat;
|
||||
.super Ljava/lang/Object;
|
||||
|
||||
.field private showConsent:Z
|
||||
|
||||
.method public writeToParcel(LTestBooleanToFloat;)V
|
||||
.locals 0
|
||||
|
||||
iget-boolean p1, p0, LTestBooleanToFloat;->showConsent:Z
|
||||
|
||||
int-to-float p1, p1
|
||||
|
||||
invoke-virtual {p0, p1}, LTestBooleanToFloat;->write(F)V
|
||||
|
||||
return-void
|
||||
.end method
|
||||
|
||||
.method public write(F)V
|
||||
.locals 0
|
||||
|
||||
return-void
|
||||
.end method
|
||||
@@ -0,0 +1,22 @@
|
||||
.class public LTestBooleanToLong;
|
||||
.super Ljava/lang/Object;
|
||||
|
||||
.field private showConsent:Z
|
||||
|
||||
.method public writeToParcel(LTestBooleanToLong;)V
|
||||
.locals 0
|
||||
|
||||
iget-boolean p1, p0, LTestBooleanToLong;->showConsent:Z
|
||||
|
||||
int-to-long p1, p1
|
||||
|
||||
invoke-virtual {p0, p1}, LTestBooleanToLong;->write(J)V
|
||||
|
||||
return-void
|
||||
.end method
|
||||
|
||||
.method public write(J)V
|
||||
.locals 0
|
||||
|
||||
return-void
|
||||
.end method
|
||||
@@ -0,0 +1,22 @@
|
||||
.class public LTestBooleanToShort;
|
||||
.super Ljava/lang/Object;
|
||||
|
||||
.field private showConsent:Z
|
||||
|
||||
.method public writeToParcel(LTestBooleanToShort;)V
|
||||
.locals 0
|
||||
|
||||
iget-boolean p1, p0, LTestBooleanToShort;->showConsent:Z
|
||||
|
||||
int-to-short p1, p1
|
||||
|
||||
invoke-virtual {p0, p1}, LTestBooleanToShort;->write(S)V
|
||||
|
||||
return-void
|
||||
.end method
|
||||
|
||||
.method public write(S)V
|
||||
.locals 0
|
||||
|
||||
return-void
|
||||
.end method
|
||||
Reference in New Issue
Block a user