98 lines
3.7 KiB
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"));
|
|
}
|
|
} |