Multi_window_Functionality_.../AudioOutput.java

98 lines
3.7 KiB
Java

package AudioChecker;
import soot.*;
import soot.jimple.*;
import soot.options.Options;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
public class AudioOutput {
private final static String androidJAR = "D:\\Android\\Android SDK\\platforms";; // Android 平台库路径
private final static String appApk = "C:\\Users\\32082\\Desktop\\soot\\soot-android-static-analysis-master\\apk\\Audio\\飞书.apk"; // APK
// 文件路径
public static void main(String[] args) {
// Soot 配置
Options.v().set_src_prec(Options.src_prec_apk);
Options.v().set_android_jars(androidJAR); // 确保指向正确的 Android 平台库
Options.v().set_process_dir(Collections.singletonList(appApk));
Options.v().set_allow_phantom_refs(true); // 允许幻影引用,对于找不到的类
Options.v().set_output_format(Options.output_format_jimple);
Scene.v().loadNecessaryClasses();
// 遍历所有类
for (SootClass sootClass : Scene.v().getApplicationClasses()) {
for (SootMethod method : sootClass.getMethods()) {
if (method.isConcrete()) {
Body body = method.retrieveActiveBody();
analyzeMethod(body);
}
}
}
}
private static void analyzeMethod(Body body) {
boolean audioFocusLossCaseFound = false;
for (Unit unit : body.getUnits()) {
// 查找 switch(focusChange) 语句
// System.out.println("We got it!");
if (unit instanceof TableSwitchStmt) {
TableSwitchStmt switchStmt = (TableSwitchStmt) unit;
Value switchKey = switchStmt.getKey();
List<ValueBox> useBoxes = switchKey.getUseBoxes();
System.out.println("We got switch!");
if (useBoxes.stream().anyMatch(box -> box.getValue().toString().equals("focusChange"))) {
System.out.println("We got focusChange!");
List<Unit> targets = switchStmt.getTargets();
// 检查是否有 case AudioManager.AUDIOFOCUS_LOSS
for (Unit target : targets) {
if (target.toString().contains("AudioManager.AUDIOFOCUS_LOSS")) {
System.out.println("We got AudioManager.AUDIOFOCUS_LOSS!");
analyzeMediaPlayerCalls(target, body.getUnits());
break; // 找到后退出循环
}
}
}
}
}
}
private static void analyzeMediaPlayerCalls(Unit caseStartPoint, PatchingChain<Unit> units) {
boolean pauseOrStopCalled = false;
Unit currentUnit = caseStartPoint;
// 遍历 case 代码块
while (currentUnit != null) {
if (currentUnit instanceof InvokeStmt) {
InvokeStmt invokeStmt = (InvokeStmt) currentUnit;
InvokeExpr invokeExpr = invokeStmt.getInvokeExpr();
if (invokeExpr instanceof InstanceInvokeExpr) {
InstanceInvokeExpr instanceInvokeExpr = (InstanceInvokeExpr) invokeExpr;
SootMethod method = instanceInvokeExpr.getMethod();
if (isMediaPlayerPauseOrStopMethod(method)) {
System.out.println("Found MediaPlayer call to " + method.getName() + " in method: "
+ ((Body) caseStartPoint).getMethod());
pauseOrStopCalled = true;
break; // 找到之后跳出循环
}
}
}
// 移动到下一个单元
currentUnit = units.getSuccOf(currentUnit);
}
if (!pauseOrStopCalled) {
System.out.println("No MediaPlayer pause or stop call found in AudioManager.AUDIOFOCUS_LOSS case");
}
}
private static boolean isMediaPlayerPauseOrStopMethod(SootMethod method) {
return method.getDeclaringClass().getName().equals("android.media.MediaPlayer")
&& (method.getName().equals("pause") || method.getName().equals("stop"));
}
}