2

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

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

提前致谢!

4

4 回答 4

4

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

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

(某种)有效的解决方案

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

为什么它只起作用

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

一种同样有效的替代方案

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

于 2017-03-14T16:36:50.500 回答
2

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

Xposed hook java方法通过XposedBridge.java的方法“handleHookedMethod(Member method, int originalMethodId, Object additionalInfoObj, thisObject, Object[] args)”

Log.v(TAG, "className " + method.getClass().getName() + ",methodName " + method.getName());
于 2017-03-23T03:45:14.003 回答
1

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

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

此外,众所周知, Emma等其他工具也可以与 Android 一起使用,但这些工具可能需要修改源代码。

于 2017-03-16T14:20:51.127 回答
1

我找到了解决方案。

请参阅下面的代码片段。

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, );
    }
}
于 2018-10-19T13:42:10.703 回答