soot-oss / soot

Soot - A Java optimization framework
GNU Lesser General Public License v2.1
2.89k stars 710 forks source link

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

Closed jpstotz closed 6 months ago

jpstotz commented 6 months ago

The previous FillArrayDataInstruction which converts DEX instructions to Jimpl instructions had two major problems:

  1. The array type detection was only recognizing new-array instructions, not array that are created as a return value of a function
  2. For detecting the array type it used a simple algorithm that inspected the DEX instructions before the fill-array-data instruction, not considering (conditional) branches of the control flow. This caused two problems:
  3. If the array type could not be detected a warning was logged and the fill-array-data instruction completely ignored
  4. If multiple array were defined in a method with non-linear control flow the wrong array-new instruction could be assigned to the fill-array-data instruction causing various problems in the command itself or in a later phase.

The FillArrayDataInstruction implementation provided by this PR splits processing of fill-array-data instructions into two phases:

  1. Command transforming to Jimple instructions, as the array type is not known the elements are stored as UntypedConstant
  2. In the second phase the new DexFillArrayDataTransformer checks AssignStatements that assign an UntypedConstant to an array element. It recovers the array data types and applies it to each value.

Note: The time to execute DexFillArrayDataTransformer.v().transform(jBody); was chosen as it is the latest possible point in time to execute it. The next transformer TypeAssigner.v().transform(jBody); can not handle UntypedConstant and thus throws an exception if it encounters one.

In a test the new implementation was used to process ~350 recent Android apps.