【问题标题】:Can Xposed log current method name?Xposed 可以记录当前方法名吗?
【发布时间】:2016-08-29 16:11:15
【问题描述】:

我想测试一个应用程序,但它太大而无法通过静态方法进行。

我开始用谷歌搜索。我发现了一个有趣的工具,叫做 Xposed Framework。

我阅读了很多文档/示例。但我找不到关于获取应用程序方法名称的主题。

我的目的是在我按下应用程序中的按钮时记录当前方法名称。调用方法时会发送哪些参数?

有关详细信息,我要测试的应用程序是聊天应用程序。我想检查它是否安全使用?开发人员声称该应用程序使用了等等等等加密,这是真的吗?是真正的端到端加密吗?

根据应用程序的庞大,我需要一些工具来帮助我分析这一点。当我发送消息时,会调用哪些方法?连同什么值一起发送?

【问题讨论】:

  • 应用程序是你的吗?
  • 这不是我的。但它是一个开源的。
  • 如果它是开源的,直接修改它比用 Xposed 挂钩更容易。无论如何,您需要知道如何进行 Java 和 Android 开发。

标签: android hook xposed-framework xposed


【解决方案1】:

如果它是开源的,您可以轻松地在源代码中插入一些日志并重新编译。一些代码覆盖工具允许您记录执行的方法,但我不确定参数(例如EMMA coverage)。

如果它是闭源的,那么你可以用 Xposed 来做,但它有一些挑战。 Xposed 允许你挂钩 Java 方法,如果它是开源的,你可以查找你想要拦截的特定方法并打印它们的参数。如果是闭源的,可以随时通过apktool反编译app查看方法名。

查看Xposed tutorial 以了解如何注册挂钩。假设您创建了扩展 XC_MethodHook 的类,以下方法应该可以处理原始参数:

@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {

    String threadname = Thread.currentThread().getName();
    String d = _dateFormat.format(new Date());
    Class<?> cls = param.this.getClass();

    //Extend XC_MethodHook to receive the mthName in the constructor
    //and store it as a static field.

    Log.v("MethodInvocation", "[A][" + d + "]"
            + "[" + cls.getName() + "."
            + mthName 
            + "(" + args(param) + ")" + " = " + result(param)
            + "]" + " [" + threadname + "]");
}

public boolean shouldPrintContent(Object o) {
    if (o.getClass().isPrimitive()
        || o.getClass().getName().contains("java.lang"))
            return true;
    return false;
}

public String args(MethodHookParam param) {
    String args = "";
    int counter = 0;
    if (param != null) {
        for (Object o : param.args) {
            if (counter > 0)
                args += ",";

            // argument can be null
            if (o == null) {
                args += "null";


            } else { // if it is an object lets print its type and content.
                args += printclean(o.getClass().getName());

                if (shouldPrintContent(o)) {

                    args += ":" + printclean(o.toString());
                } else
                    args += ":nonPrimitiveOrJavaLang";
            }
            counter++;
        }
    }
    return args;
}

//avoid identation chars in strings
public String printclean(String str) {
    char[] res = str.toCharArray();
    for (int i = 0; i < str.length(); i++) {
        if (res[i] == '\n' || res[i] == '\r' || res[i] == '\t'
                || res[i] == '[' || res[i] == ']') {
            res[i] = '*';
        }
    }
    return String.valueOf(res);
}

public String result(MethodHookParam param) {
    String res = "";
    Object retobj = param.getResult();
    if (retobj == null) {
        res += "null";
    } else {
        res += printclean(retobj.getClass().getName());

        if (shouldPrintContent(retobj)) {
            res += printclean(retobj.toString());
        } else
            res += "(nonPrimitiveOrJavaLang)";
    }

    return res;
}

请注意,打印任何对象都不是小事。在这里,我只打印了已知类型,如原语或其他 java.lang 对象。更复杂的对象(包括集合)您可以尝试使用 Gson 来表示它们,但这也有一些限制(例如,不能经常处理引用循环)。

最后,请注意您要挂钩的方法,因为经常调用的挂钩和日志记录方法会影响应用的性能。

祝你好运!

【讨论】:

  • 非常感谢。我试试看
【解决方案2】:

一个新的Xposed module called Inspeckage 做了(在许多其他有用的检查中)你想做的事情:你可以用它来挂钩任何方法和视图,甚至改变它的输入和输出。

【讨论】:

    猜你喜欢
    • 2011-11-09
    • 1970-01-01
    • 2014-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多