我想检测一个APK来计算其回调方法的执行次数(类似于这个SO帖子(。
为此,我想从头开始创建一个静态类(类似于此链接(,以保持计数数字。然后将该类添加到APK中,最后检测回调方法的开头以调用该静态类的方法(类似于此链接(。
我能够用Java应用程序做类似的事情,但我不能为APK做。下面是生成新 SootClass 并将其添加到Scene
的代码部分:
SootClass staticCls = generateClass("StaticCounter");
Scene.v().addClass(staticCls);
Scene.v().addBasicClass("StaticCounter", SootClass.SIGNATURES);
Scene.v().loadNecessaryClasses();
generateClass
改编自这里。但是当我检查修改后的APK时,没有任何StaticCounter
类的迹象。此外,我安装并运行了修改后的APK,并收到此错误:
08-21 14:15:45.936 19917 19917 E AndroidRuntime:
Caused by: java.lang.ClassNotFoundException:
Didn't find class "StaticCounter" on path:
DexPathList[[zip file "/system/framework/org.apache.http.legacy.boot.jar", zip file "/data/app/APKNAME-RdhHiJzxKyyUHh_KCi6RUA==/base.apk"],nativeLibraryDirectories=[/data/app/APKNAME-RdhHiJzxKyyUHh_KCi6RUA==/lib/x86, /system/lib]]
这仅显示生成的类不在APK内。
这个问题有什么解决方案吗?
您可能需要提供它所需的依赖项:
android {
useLibrary "org.apache.http.legacy"
}
它不会构建的原因可能是,StaticCounter
在编译时是未知的 - 因为它可能不应该从应用程序包中引用,而应用程序包不知道它。看看这篇博文,显然来自Soot
作者......驱动程序类可能是成功的关键:
//prefer Android APK files// -src-prec apk
Options.v().set_src_prec(Options.src_prec_apk);
//output as APK, too//-f J
Options.v().set_output_format(Options.output_format_dex);
// resolve the PrintStream and System soot-classes
Scene.v().addBasicClass("java.io.PrintStream", SootClass.SIGNATURES);
Scene.v().addBasicClass("java.lang.System", SootClass.SIGNATURES);
这是整个例子:AndroidInstrument.java
除非已将其标记为应用程序类,否则烟灰不会发出该类。你能试试吗?
我想我找到了为什么应用程序不知道新生成的类,这要归功于Martin Zitler的提示。生成的类必须位于 APK 的包中。烟灰通过查看类的签名来处理类的包。因此,StaticCounter
类必须具有类似
com.example.app.StaticCounter
表示StaticCounter
在包com.example.app
中。
可以使用ProcessManifest
类找到包名称,该类可以在 FlowDroid 中找到:
new ProcessManifest(apkPath).getPackageName();
我简化了工作代码并将其放在这里。它从头开始创建一个新类,并添加一个静态整数字段和一个方法,该字段是调用静态方法的时间,该方法打印此值。然后使用转换包,应用中的每个方法都将调用此静态方法。