【问题标题】:Log all methods called in an app by Xposed记录 Xposed 在应用程序中调用的所有方法
【发布时间】:2017-03-11 09:55:45
【问题描述】:

正如标题所说,我想使用 xposed 记录应用程序中调用的所有方法,从它开始到我停止它。我只想记录类名、方法名,不想挂钩所有方法。 我尝试此代码,但得到错误 getMethod not found。

findAndHookMethod("java.lang.Class", lpparam.classLoader, "getMethod", String.class, Object.class, new XC_MethodHook()

提前致谢!

【问题讨论】:

  • 挂钩所有应用程序调用的方法几乎是不可能的。如果您要挂钩用于打印日志的方法怎么办?如果您只想查看应用程序中的静态方法列表,您可以使用apktool 反编译 APK 文件。
  • 我不想挂钩所有方法。我只想记录应用程序从开始到停止调用的方法。
  • 可以通过修改AOSP,仍然相关吗?

标签: xposed


【解决方案1】:

没有像您正在搜索的那样的单一解决方案。

挂钩所有方法将记录应用程序从开始到停止调用了哪些方法(有点 - 见下文),但如果(出于某种原因)您不想挂钩所有方法,我唯一能做到的解决方案想到的是修改 java VM 本身(我不建议这样做。)

一种(某种)有效的解决方案

我所做的是首先使用 apktool 反编译我的 apk 并获取所有类中所有方法的名称。 然后我使用 xposed 挂钩到每个类的每个方法,并将当前函数名打印到 dlog。

为什么它只起作用

Xposed 在挂钩方法时都会产生开销。对于 xposed 应用程序的一般用法,它并不多。但是,当您开始挂钩应用程序的每个方法时,开销很快就会变得非常大 - 以至于上述方法适用于小型应用程序,但对于任何大型应用程序,它很快就会导致应用程序挂起然后崩溃。

一种同样有效的替代方法

FRIDA 是一种将 javascript 注入本机应用程序的方法。 Here 他们向您展示了如何记录所有函数调用。虽然在上面的链接中,他们将所有函数调用记录在一段 python 代码中,但同样的代码也适用于 Android。

【讨论】:

  • 谢谢你的回答:)
【解决方案2】:

有一种方法可以记录所有 Java 方法。修改 XposedBridge。

通过XposedBridge.java的方法Xposed hook java方法 "handleHookedMethod(成员方法, int originalMethodId, Object additionalInfoObj, thisObject, Object[] args)"

Log.v(TAG, "className " + method.getClass().getName() + ",methodName " + method.getName());

【讨论】:

  • 导致引用表溢出。
【解决方案3】:

如前所述,由于开销,Xposed 在这种情况下不可行。

最简单的解决方案就是使用 Google 提供的dmtracedump。大多数 x86 Android 映像和模拟器都带有可调试标志 (ro.debuggable),因此您甚至可以将其用于闭源应用程序。

此外,已知其他工具(例如 Emma)也可以与 Android 一起使用,但这些工具可能需要修改源代码。

【讨论】:

  • 是的,我知道这个 traceview,但问题是有时应用程序在我的 stoptracing 调用之前强制关闭,所以没有写入跟踪文件。
  • 这是您的应用还是闭源应用?如果您想要的只是运行的方法/类的名称,那么可以随着时间的推移检索 Emma 代码覆盖率......
  • 这是一个闭源应用程序。艾玛可以用吗?
  • 我只尝试将 Emma 与开源应用程序一起使用,因为它需要向应用程序添加一个类。如果添加了 xposed,它可能适用于闭源应用程序,但我从未尝试过。你看过 startMethodTracingSampling 和 startNativeTracing 吗?第一个允许设置采样间隔,后者在模拟器级别运行并将输出写入标准输出。因此,这两种方法都可能为您提供中间结果。
【解决方案4】:

我找到了解决办法。

请参阅下面的代码 sn-p。

package com.kyunggi.logcalls;

import android.content.pm.*;
import android.util.*;

import dalvik.system.*;
import de.robv.android.xposed.*;
import de.robv.android.xposed.callbacks.XC_LoadPackage.*;

import java.io.*;
import java.lang.reflect.*;
import java.util.*;

import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;

import android.app.*;

public class Main implements IXposedHookLoadPackage {
    private String TAG = "LogCall";

    public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {
        if (!lpparam.packageName.equals("com.android.bluetooth")) {
            Log.i(TAG, "Not: " + lpparam.packageName);
            return;
        }

        Log.i(TAG, "Yes " + lpparam.packageName);
        //Modified https://d3adend.org/blog/?p=589
        ApplicationInfo applicationInfo = AndroidAppHelper.currentApplicationInfo();
        if (applicationInfo.processName.equals("com.android.bluetooth")) {
            Set<String> classes = new HashSet<>();
            DexFile dex;
            try {
                dex = new DexFile(applicationInfo.sourceDir);
                Enumeration entries = dex.entries();
                while (entries.hasMoreElements()) {
                    String entry = (String) entries.nextElement();
                    classes.add(entry);
                }
                dex.close();
            } catch (IOException e) {
                Log.e("HookDetection", e.toString());
            }

            for (String className : classes) {
                boolean obex = false;
                if (className.startsWith("com.android.bluetooth") || (obex = className.startsWith("javax.obex"))) {
                    try {
                        final Class clazz = lpparam.classLoader.loadClass(className);
                        for (final Method method : clazz.getDeclaredMethods()) {
                            if (obex) {
                                if (!Modifier.isPublic(method.getModifiers())) {
                                    continue;    //on javax.obex package, hook only public APIs
                                }
                            }
                            XposedBridge.hookMethod(method, new XC_MethodHook() {
                                final String methodNam = method.getName();
                                final String classNam = clazz.getName();
                                final StringBuilder sb = new StringBuilder("[");
                                final String logstr = "className " + classNam + ",methodName " + methodNam;

                                @Override
                                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                                    //Method method=(Method)param.args[0];
                                    sb.setLength(0);
                                    sb.append(logstr);
                                    //Log.v(TAG,logstr);

                                    for (Object o : param.args) {
                                        String typnam = "";
                                        String value = "null";
                                        if (o != null) {
                                            typnam = o.getClass().getName();
                                            value = o.toString();
                                        }
                                        sb.append(typnam).append(" ").append(value).append(", ");
                                    }
                                    sb.append("]");
                                    Log.v(TAG, sb.toString());
                                }

                            });
                        }
                    } catch (ClassNotFoundException e) {
                        Log.wtf("HookDetection", e.toString());
                    }
                }
            }
        }

        //  ClassLoader rootcl=lpparam.classLoader.getSystemClassLoader();
        //findAndHookMethod("de.robv.android.xposed.XposedBridge", rootcl, "handleHookedMethod", Member.class, int.class, Object.class, Object.class, Object[].class, );
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-04
    • 2013-09-20
    • 1970-01-01
    相关资源
    最近更新 更多