Skip to content

Commit

Permalink
Support the case where the array is defined by an assignment from
Browse files Browse the repository at this point in the history
another array.
  • Loading branch information
jpstotz committed May 27, 2024
1 parent 581a6e7 commit 9036ad6
Showing 1 changed file with 47 additions and 23 deletions.
70 changes: 47 additions & 23 deletions src/main/java/soot/dexpler/DexFillArrayDataTransformer.java
Original file line number Diff line number Diff line change
Expand Up @@ -91,30 +91,8 @@ protected void internalTransform(final Body body, String phaseName, Map<String,
ArrayRef leftArray = (ArrayRef) left;

Local l = (Local) leftArray.getBase();
List<Unit> assDefs = defs.getDefsOfAt(l, ass);
List<Type> arrayTypes = new LinkedList<>();
for (Unit d : assDefs) {
if (d instanceof AssignStmt) {
AssignStmt arrayAssign = (AssignStmt) d;
Value source = arrayAssign.getRightOp();
if (source instanceof NewArrayExpr) {
NewArrayExpr newArray = (NewArrayExpr) source;
arrayTypes.add(newArray.getBaseType());
continue;
}
if (source instanceof InvokeExpr) {
InvokeExpr invExpr = (InvokeExpr) source;
Type aType = invExpr.getMethodRef().getReturnType();
if (!(aType instanceof ArrayType)) {
throw new InternalError("Failed to identify the array type. The identified method invocation "
+ "does not return an array type. Invocation: " + invExpr.getMethodRef());
}
arrayTypes.add(((ArrayType) aType).getArrayElementType());
continue;
}
throw new InternalError("Unsupported array definition statement: " + d);
}
}
checkArrayDefinitions(l, ass, defs, arrayTypes);
if (arrayTypes.isEmpty()) {
throw new InternalError("Failed to determine the array type ");
}
Expand All @@ -135,4 +113,50 @@ protected void internalTransform(final Body body, String phaseName, Map<String,
}
}

/**
* Check the all available definitions of the current array to detect the array type and thus the type of the data loaded
* by the array-fill-data instruction.
*
* @param l
* local the array we are interested in is saved in
* @param u
* unit we start our search
* @param defs
* @param arrayTypes
* result list containing the discovered array type(s)
*/
private void checkArrayDefinitions(Local l, Unit u, LocalDefs defs, List<Type> arrayTypes) {
List<Unit> assDefs = defs.getDefsOfAt(l, u);
for (Unit d : assDefs) {
if (d instanceof AssignStmt) {
AssignStmt arrayAssign = (AssignStmt) d;
Value source = arrayAssign.getRightOp();
if (source instanceof NewArrayExpr) {
// array is assigned from a newly created array
NewArrayExpr newArray = (NewArrayExpr) source;
arrayTypes.add(newArray.getBaseType());
continue;
}
if (source instanceof InvokeExpr) {
// array is assigned from the return value of a function
InvokeExpr invExpr = (InvokeExpr) source;
Type aType = invExpr.getMethodRef().getReturnType();
if (!(aType instanceof ArrayType)) {
throw new InternalError("Failed to identify the array type. The identified method invocation "
+ "does not return an array type. Invocation: " + invExpr.getMethodRef());
}
arrayTypes.add(((ArrayType) aType).getArrayElementType());
continue;
}
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;
}
throw new InternalError("Unsupported array definition statement: " + d);
}
}

}
}

0 comments on commit 9036ad6

Please sign in to comment.