计算来自 classes.dex 的 api 次调用

count number of api calls from classes.dex

我想知道是否可以通过解析 classes.dex 文件来计算 API 被调用的次数。我知道调用所有 API 的方法,但想知道是否有一种方法可以在没有 运行 应用程序的情况下获取调用 api 的次数,只需通过解析classes.dex。这些信息是否存储在 dex 文件中?

我快速查看了 dex 文件格式,但找不到该信息。

Ex : 如果在 class1 和 class2 和 class3 中使用了一次 substring() ,我应该能够得到 substring 已被调用 3 次的信息。

无法仅通过解析代码来判断 API 调用了多少次。比如foo()被调用了多少次?:

public static void bar(int x) {
    for ( int i = 0; i < x; i++ ) {
        foo();
    }
}

如果只看源码,答案是一次,但如果分析语义,答案是x

如果你只想知道一个API调用在源代码中存在的次数,你可以很容易地得到。

  1. 使用 baksmali 获取Smali代码的dex文件。

  2. Grep(或确认)您想要的 API 调用的 Smali。 SmsManager.sendTextMessage() 的示例正则表达式是:

    "invoke[^,]+, Landroid/telephony/SmsManager;->sendTextMessage\(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/app/PendingIntent;Landroid/app/PendingIntent;\)V"
    
  3. 计算您找到该行的次数。类似于:

    grep api_call_pattern . | wc -l
    

这只能被视为实际 API 调用计数的粗略代表。如果您想要更准确的东西,则必须进行符号分析。不幸的是,据我所知,没有您可以使用的交钥匙解决方案。