本文博客地址:https://blog.csdn.net/QQ1084283172/article/details/80954759
在进行Android程序的逆向分析的时候,经常需要Android程序的静态分析和动态调试的结合,尤其是对一些加固后的Android类方法被调用的确认,需要Hook java类方法打印java类方法的调用堆栈。有幸在网上看到了这篇文章《XPosed暴力列举Package下所有的方法调用》,按照作者的思路和代码进行了验证和尝试,发现效果并不明显而且不好用,对多dex的Android应用支持不好,因此在此基础上调整了一下思路,简单的写了份xposed Hook代码,如下:
package com.xposed.enumeratorClassHook;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XC_MethodHook.MethodHookParam;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
public class Module implements IXposedHookLoadPackage {
static String strClassName =
"";
@Override
public void handleLoadPackage(LoadPackageParam lpparam)
throws Throwable {
String strPackageName =
"com.guji.loveparty";
if (lpparam.packageName.equals(strPackageName)) {
XposedBridge.log(
"Loaded App:" + lpparam.packageName);
findAndHookMethod(ClassLoader.class,
"loadClass", String.class,
new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param)
throws Throwable {
if (param.hasThrowable()) {
return;
}
Class<?> clazz = (Class<?>) param.getResult();
String strClazz = clazz.getName();
XposedBridge.log(
"LoadClass : "+strClazz);
if (!strClazz.startsWith(
"android.")
&& !strClazz.startsWith(
".system")
&& !strClazz.startsWith(
"java.")
&& !strClazz.startsWith(
"org.")
&& !strClazz.contains(
"umeng.")
&& !strClazz.contains(
"com.google")
&& !strClazz.contains(
".alipay")
&& !strClazz.contains(
".netease")
&& !strClazz.contains(
".alibaba")
&& !strClazz.contains(
".pgyersdk")
&& !strClazz.contains(
".daohen")
&& !strClazz.contains(
".bugly")
&& !strClazz.contains(
"mini")
&& !strClazz.contains(
"xposed")) {
synchronized (
this.getClass()) {
strClassName = strClazz;
Method[] m = clazz.getDeclaredMethods();
for (
int i =
0; i < m.length; i++) {
if (!Modifier.isAbstract(m[i].getModifiers())
&& !Modifier.isNative(m[i].getModifiers())
&& !Modifier.isInterface(m[i].getModifiers())
) {
XposedBridge.hookMethod(m[i],
new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param)
throws Throwable {
XposedBridge.log(
"HOOKED METHOD: "+strClassName+
"-"+param.method.toString());
}
});
}
}
}
}
}
});
}
}
public void dumpClass(Class<?> actions) {
XposedBridge.log(
"Dump class " + actions.getName());
XposedBridge.log(
"Methods");
Method[] m = actions.getDeclaredMethods();
for (
int i =
0; i < m.length; i++) {
XposedBridge.log(m[i].toString());
}
XposedBridge.log(
"Fields");
Field[] f = actions.getDeclaredFields();
for (
int j =
0; j < f.length; j++) {
XposedBridge.log(f[j].toString());
}
XposedBridge.log(
"Classes");
Class<?>[] c = actions.getDeclaredClasses();
for (
int k =
0; k < c.length; k++) {
XposedBridge.log(c[k].toString());
}
}
}
/**
* Look up a method and place a hook on it. The last argument must be the callback for the hook.
* @see #findMethodExact(Class, String, Object...)
*/
/** @see #findAndHookMethod(Class, String, Object...) */
/**
* Loads the class with the specified name. Invoking this method is
* equivalent to calling {@code loadClass(className, false)}.
* <p>
* <strong>Note:</strong> In the Android reference implementation, the
* second parameter of {@link #loadClass(String, boolean)} is ignored
* anyway.
* </p>
*
* @return the {@code Class} object.
* @param className
* the name of the class to look for.
* @throws ClassNotFoundException
* if the class can not be found.
*/
Xposed Hook处理Android应用打印Log日志的结果截图: