Skip to content

Commit

Permalink
Support non-0 and non-1 integer boolean's in dex
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcMil committed Oct 20, 2024
1 parent 1fcdf46 commit 4bae98c
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 4 deletions.
52 changes: 49 additions & 3 deletions src/main/java/soot/dexpler/DexBody.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@

import soot.ArrayType;
import soot.Body;
import soot.BooleanConstant;
import soot.BooleanType;
import soot.DoubleType;
import soot.FloatType;
import soot.IntType;
Expand Down Expand Up @@ -118,6 +120,7 @@
import soot.jimple.FloatConstant;
import soot.jimple.IfStmt;
import soot.jimple.IntConstant;
import soot.jimple.InvokeExpr;
import soot.jimple.Jimple;
import soot.jimple.JimpleBody;
import soot.jimple.LongConstant;
Expand Down Expand Up @@ -841,6 +844,20 @@ protected boolean allowConversion(Type ancestor, Type child) {
}
return super.allowConversion(ancestor, child);
}

public Type promote(Type tlow, Type thigh) {
if (thigh instanceof BooleanType) {
if (tlow instanceof IntegerType) {
//Well... in Android's dex code, 0 = false and everything else is true
//While the compiler should never generate such code, there can be found code like this in the wild.
//And Android accepts it!
//Thus, we allow the type promotion and then correct the boolean constants
return thigh;
}
}
return super.promote(tlow, thigh);

}
};

}
Expand Down Expand Up @@ -1053,13 +1070,32 @@ public Value visit(Value op, Type useType, Stmt stmt, boolean checkOnly) {
for (Unit u : jBody.getUnits()) {

if (u instanceof AssignStmt) {
AssignStmt ass = (AssignStmt) u;
if (ass.getRightOp() instanceof CastExpr) {
CastExpr c = (CastExpr) ass.getRightOp();
final AssignStmt ass = (AssignStmt) u;
final Value rop = ass.getRightOp();
if (rop instanceof CastExpr) {
CastExpr c = (CastExpr) rop;
if (c.getType() instanceof NullType) {
ass.setRightOp(nullConstant);
}
}
if (rop instanceof IntConstant) {
if (ass.getLeftOp().getType() instanceof BooleanType) {
ass.setRightOp(fixBooleanConstant((IntConstant) rop));
}
}

}
Stmt s = (Stmt) u;
if (s.containsInvokeExpr()) {
InvokeExpr inv = s.getInvokeExpr();
for (int p = 0; p < inv.getArgCount(); p++) {
if (inv.getMethodRef().getParameterType(p) instanceof BooleanType) {
Value arg = inv.getArg(p);
if (arg instanceof IntConstant) {
inv.setArg(p, fixBooleanConstant((IntConstant) arg));
}
}
}
}
if (u instanceof DefinitionStmt) {
DefinitionStmt def = (DefinitionStmt) u;
Expand Down Expand Up @@ -1108,6 +1144,16 @@ public Value visit(Value op, Type useType, Stmt stmt, boolean checkOnly) {
return jBody;
}

/**
* In Dex, every int is a valid boolean.
* 0 = false and everything else = true.
* @param arg
* @return
*/
private static BooleanConstant fixBooleanConstant(IntConstant arg) {
return BooleanConstant.v(arg.value != 0);
}

/**
* For non-object array instructions, we know from the bytecode already what the types are, or at least we can reduce it to
* two possibilities (int/float or float/double).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public TypePromotionUseVisitor(JimpleBody jb, Typing tg) {
this.typingChanged = false;
}

private Type promote(Type tlow, Type thigh) {
public Type promote(Type tlow, Type thigh) {
if (tlow instanceof Integer1Type) {
if (thigh instanceof IntType) {
return Integer127Type.v();
Expand Down

0 comments on commit 4bae98c

Please sign in to comment.