Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix array type detection on fill-array-data DEX instructions - fixes #1806 #2084

Merged
merged 3 commits into from
May 27, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
requested changes
  • Loading branch information
jpstotz committed May 27, 2024
commit c5165e03fe1ec4c257a84538c4fcf93ba583654d
26 changes: 15 additions & 11 deletions src/main/java/soot/dexpler/DexFillArrayDataTransformer.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@
public class DexFillArrayDataTransformer extends BodyTransformer {
private static final Logger logger = LoggerFactory.getLogger(DexFillArrayDataTransformer.class);

private static final int MAX_RECURSION_DEPTH = 5;

public static DexFillArrayDataTransformer v() {
return new DexFillArrayDataTransformer();
}
Expand All @@ -92,7 +94,7 @@ protected void internalTransform(final Body body, String phaseName, Map<String,

Local l = (Local) leftArray.getBase();
List<Type> arrayTypes = new LinkedList<>();
checkArrayDefinitions(l, ass, defs, arrayTypes);
checkArrayDefinitions(l, ass, defs, arrayTypes, MAX_RECURSION_DEPTH);
if (arrayTypes.isEmpty()) {
throw new InternalError("Failed to determine the array type ");
}
Expand Down Expand Up @@ -124,8 +126,14 @@ protected void internalTransform(final Body body, String phaseName, Map<String,
* @param defs
* @param arrayTypes
* result list containing the discovered array type(s)
* @param maxDepth
*/
private void checkArrayDefinitions(Local l, Unit u, LocalDefs defs, List<Type> arrayTypes) {
private void checkArrayDefinitions(Local l, Unit u, LocalDefs defs, List<Type> arrayTypes, int maxDepth) {
if (maxDepth <= 0) {
// Avoid infinite recursion
logger.warn("Recursion depth limit reached - aborting");
return;
}
List<Unit> assDefs = defs.getDefsOfAt(l, u);
for (Unit d : assDefs) {
if (d instanceof AssignStmt) {
Expand All @@ -135,9 +143,7 @@ private void checkArrayDefinitions(Local l, Unit u, LocalDefs defs, List<Type> a
// array is assigned from a newly created array
NewArrayExpr newArray = (NewArrayExpr) source;
arrayTypes.add(newArray.getBaseType());
continue;
}
if (source instanceof InvokeExpr) {
} else if (source instanceof InvokeExpr) {
// array is assigned from the return value of a function
InvokeExpr invExpr = (InvokeExpr) source;
Type aType = invExpr.getMethodRef().getReturnType();
Expand All @@ -146,15 +152,13 @@ private void checkArrayDefinitions(Local l, Unit u, LocalDefs defs, List<Type> a
+ "does not return an array type. Invocation: " + invExpr.getMethodRef());
}
arrayTypes.add(((ArrayType) aType).getArrayElementType());
continue;
}
if (source instanceof Local) {
} else if (source instanceof Local) {
// our array is defined by an assignment from another array => check the definition of that other array.
Local newLocal = (Local) source; // local of the "other array"
checkArrayDefinitions(newLocal, d, defs, arrayTypes);
continue;
checkArrayDefinitions(newLocal, d, defs, arrayTypes, maxDepth - 1);
} else {
throw new InternalError("Unsupported array definition statement: " + d);
}
throw new InternalError("Unsupported array definition statement: " + d);
}
}

Expand Down
Loading