正如标题所说,我想使用xposed来记录应用程序中调用的所有方法,直到我停止它为止。我只想记录类名,方法名,不想挂钩所有方法。 我尝试了这段代码,但是找不到错误的getMethod。
findAndHookMethod("java.lang.Class", lpparam.classLoader, "getMethod", String.class, Object.class, new XC_MethodHook()
提前致谢!
答案 0 :(得分:4)
没有像你似乎在寻找的一行解决方案。
挂钩所有方法将记录app从哪个方法调用它从开始直到停止(排序 - 见下文),但如果(由于某种原因)你不想挂钩所有方法,我唯一的解决方案想到的是修改java VM本身(不是我推荐的。)
(某种程度)有效的解决方案
我所做的是首先使用apktool来反编译我的apk并获取所有类中所有方法的名称。 然后我使用xposed挂钩到每个类的每个方法,并将当前函数名称打印到dlog。
为什么它只是有效的
只要挂钩方法,Xposed就会有开销。对于xposed apps的一般用法,它并不多。但是当你开始挂钩应用程序的每一个方法时,开销很快变得非常大 - 以至于上述方法适用于小型应用程序,对于任何大型应用程序,它很快就会导致应用程序挂起然后崩溃。
另一种可以分类的方法
FRIDA是一种向本机应用注入javascript的方法。 Here他们会告诉你如何记录所有函数调用。在上面的链接中,他们在一段python代码中记录所有函数调用,相同的代码也适用于Android。
答案 1 :(得分:1)
有一种方法可以记录所有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());
答案 2 :(得分:0)
如前所述,由于其开销,Xposed不是这种情况下的方法。
最简单的解决方案就是使用Google提供的dmtracedump。大多数x86 Android图像和模拟器都带有debuggable标志(ro.debuggable),因此您甚至可以将它用于闭源应用程序。
此外,已知其他工具(例如Emma)也适用于Android,但这些工具可能需要修改源代码。
答案 3 :(得分:0)
我找到了解决方法。
请参见下面的代码段。
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, );
}
}