基于xposed框架hook使用

目录

创建测试项目

创建xposed模块

新增默认带Empty Activity的Module

在Module下的build.gradle文件添加依赖包

在Module下的AndroidManifest.xml文件添加xposed相关meta标签,用于框架识别

添加hook类,继承IXposedHookLoadPackage实现hook方法

 在模块下的src/assets/xposed_init(没有则新建)文件添加完整的hook类名

 安装xposed模块

hook测试app 

对于加壳的情况 

第一次hook 

 第二次hook

 其他示例

目标代码 

 hook模块

总结

参考 


Xposed:https://github.com/rovo89/Xposed
Xposed Installer:[OFFICIAL] Xposed for Lollipop/Marshmallow/Nougat/Oreo [v90-beta3, 2018/01/29] | XDA Forums
api文档:Xposed Framework API
Maven包:https://mvnrepository.com/artifact/de.robv.android.xposed/api

注:安装原生xposed框架需root,若无法root可以考虑使用virtualXposed
https://github.com/android-hacker/VirtualXposed

创建测试项目

为了便于实践,我们直接创建一个名为test的Empty Activity项目即可。
接着在MainActivity.java中,新增一个Log方法,我们后面用xposed框架来hook这个方法。

package com.example.test;


import androidx.appcompat.app.AppCompatActivity;


import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;


import java.util.Random;


public class MainActivity extends AppCompatActivity {
    private static final String TAG = "xposedText";
    private TextView tv_hook;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv_hook = (TextView) findViewById(R.id.tv_hook);
        tv_hook.setText("快来hook我");
        Log("init", new Random().nextInt(100));
    }


    public void Log(String msg, int code) {
        Log.i(TAG, "Log: " + msg + code);
    }
}

创建xposed模块

新增默认带Empty Activity的Module

在Module下的build.gradle文件添加依赖包

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])


    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
    //xposed依赖包

    compileOnly 'de.robv.android.xposed:api:82'
}

然后sync,如果比较慢建议科学·上网。

在Module下的AndroidManifest.xml文件添加xposed相关meta标签,用于框架识别

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.xposed">


    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <!--模块申明,true表示申明为xposed模块-->
        <meta-data
            android:name="xposedmodule"
            android:value="true" />


        <!--模块说明,一般为模块的功能描述-->
        <meta-data
            android:name="xposeddescription"
            android:value="这个模块是用来劫持登录的" />


        <!--模块兼容版本-->
        <meta-data
            android:name="xposedminversion"
            android:value="54" />

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />


                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>


</manifest>

添加hook类,继承IXposedHookLoadPackage实现hook方法

package com.example.xposed;


import android.content.Context;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;


import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;


public class HookLog implements IXposedHookLoadPackage {
    private static final String TAG = "XposedHook";
    private Context hookContext = null;


    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) {


        //过滤非目标包
        if (lpparam == null) {
            return;
        }
        Log.e(TAG, "Load app packageName:" + lpparam.packageName);
        //目标app的包名,既目标apk的AndroidManifest.xml文件manifest标签中的package属性值
        if (!"com.example.test".equals(lpparam.packageName)) {
            return;
        }


        //获取context,用于Toast提示
        XposedHelpers.findAndHookMethod(
                //填写目标方法所在的完整类名
                "android.content.ContextWrapper",
                //默认classLoader
                lpparam.classLoader,
                //目标方法
                "getApplicationContext",
                // Hook回调
                new XC_MethodHook() {
                    protected void afterHookedMethod(MethodHookParam param) {
                        if (hookContext != null)
                            return;
                        hookContext = (Context) param.getResult();
                        Log.i(TAG + "hookContext", hookContext.getPackageCodePath());
                    }
                }
        );


        //进行hook
        XposedHelpers.findAndHookMethod(
                //填写目标方法所在的完整类名
                "com.example.test.MainActivity",
                //默认classLoader
                lpparam.classLoader,
                //目标方法
                "Log",
                //方法参数,有几个写几个
                String.class,
                // 注意,要做到与目标方法参数对应,这里不能用Integer.class。
                int.class,
                // Hook回调
                new XC_MethodHook() {


                    @Override
                    protected void beforeHookedMethod(MethodHookParam param) throws Exception {
                        Log.i(TAG, "劫持开始");
                        String msg = (String) param.args[0];
                        int code = (int) param.args[1];
                        Log.i(TAG, "原code:" + code);
                        Toast.makeText(hookContext, "原code:" + code, Toast.LENGTH_LONG).show();
                        //修改方法参数,设为54,这样就不随机了。
                        param.args[1] = 54;
                        TextView tv = (TextView) XposedHelpers.findField(param.thisObject.getClass(), "tv_hook").get(param.thisObject);
                        tv.setText("随机数被我固定为54了");
                    }


                    protected void afterHookedMethod(MethodHookParam param) {
                        Log.i(TAG, "劫持结束");
                    }
                }
        );


    }
}

 在模块下的src/assets/xposed_init(没有则新建)文件添加完整的hook类名

com.example.xposed.HookLog
用于提示XposedBridge加载哪一个类。

 安装xposed模块

安装完成之后,Xposed Installer下就会出现我们开发的模块了

 打勾启用,然后软重启手机

hook测试app 

接着我们直接运行测试app,xposed将启用我们写好的模块进行hook 

 最终我们拦截了参数,使其固定为54,并且改写了tv_hook的值

对于加壳的情况 

若需目标app加壳,我们就不能直接findAndHookMethod了,因为真正app代码是在壳内动态加载的,所以要经过两次hook。
我们以360的壳为例 

第一次hook 

需要分析壳代码实际加载app的方法,然后注入获取到真正的ClassLoader 

        XposedHelpers.findAndHookMethod(
                "com.stub.StubApp",
                lpparam.classLoader,
                "attachBaseContext",
                Context.class,
                // Hook回调
                new XC_MethodHook() {


                    @Override
                    protected void beforeHookedMethod(MethodHookParam param) throws Exception {
                        Log.e(TAG, "劫持开始");
                    }


                    protected void afterHookedMethod(MethodHookParam param) {
                        //获取到Context对象,通过这个对象来获取classloader
                        Context context = (Context) param.args[0];
                        //获取classloader,之后hook加固后的就使用这个classloader
                        ClassLoader realClassLoader = context.getClassLoader();
                        //下面就是将classloader修改成壳的classloader就可以成功的hook了
                        realXposedHook(realClassLoader);
                        Log.e(TAG, "劫持结束");
                    }
                }
        );

 第二次hook

取到真正的ClassLoader,我们就可以愉快的hook了 

    private void realXposedHook(final ClassLoader classLoader) {
        //固定格式
        XposedHelpers.findAndHookMethod(
                "com.target.class",
                classLoader,
                "targetMethod",
                // Hook回调
                new XC_MethodHook() {


                    @Override
                    protected void beforeHookedMethod(MethodHookParam param) throws Exception {
                        Log.e(TAG, "real劫持开始");
                    }


                    protected void afterHookedMethod(MethodHookParam param) {
                        Log.e(TAG, "real劫持结束");
                    }
                }
        );
    }

 其他示例

目标代码 

abstract class Animal{
    int anonymoutInt = 500;
    public abstract void eatFunc(String value);
}


public class HookDemo {
    private String Tag = "HookDemo";
    private static  int staticInt = 100;
    public  int publicInt = 200;
    private int privateInt = 300;


    public HookDemo(){
        this("NOHook");
        Log.d(Tag, "HookDemo() was called|||");
    }


    private HookDemo(String str){
        Log.d(Tag, "HookDemo(String str) was called|||" + str);
    }


    public void hookDemoTest(){
        Log.d(Tag, "staticInt = " + staticInt);
        Log.d(Tag, "PublicInt = " + publicInt);
        Log.d(Tag, "privateInt = " + privateInt);
        publicFunc("NOHook");
        Log.d(Tag, "PublicInt = " + publicInt);
        Log.d(Tag, "privateInt = " + privateInt);
        privateFunc("NOHook");
        staticPrivateFunc("NOHook");


        String[][] str = new String[1][2];
        Map map = new HashMap<String, String>();
        map.put("key", "value");
        ArrayList arrayList = new ArrayList();
        arrayList.add("listValue");
        complexParameterFunc("NOHook", str, map, arrayList);


        repleaceFunc();
        anonymousInner(new Animal() {
            @Override
            public void eatFunc(String value) {
                Log.d(Tag, "eatFunc(String value)  was called|||" + value);
                Log.d(Tag, "anonymoutInt =  " + anonymoutInt);
            }
        }, "NOHook");


        InnerClass innerClass = new InnerClass();
        innerClass.InnerFunc("NOHook");
    }


    public void publicFunc(String value){
        Log.d(Tag, "publicFunc(String value) was called|||" + value);
    }


    private void privateFunc(String value){
        Log.d(Tag, "privateFunc(String value) was called|||" + value);
    }


    static private void staticPrivateFunc(String value){
        Log.d("HookDemo", "staticPrivateFunc(Strin value) was called|||" + value);
    }


    private void complexParameterFunc(String value, String[][] str, Map<String,String> map, ArrayList arrayList)
    {
        Log.d("HookDemo", "complexParameter(Strin value) was called|||" + value);
    }


    private void repleaceFunc(){
        Log.d(Tag, "repleaceFunc will be replace|||");
    }


    public void anonymousInner(Animal dog, String value){
        Log.d(Tag, "anonymousInner was called|||" + value);
        dog.eatFunc("NOHook");
    }


    private void hideFunc(String value){
        Log.d(Tag, "hideFunc was called|||" + value);
    }


    class InnerClass{
        public int innerPublicInt = 10;
        private int innerPrivateInt = 20;
        public InnerClass(){
            Log.d(Tag, "InnerClass constructed func was called");
        }
        public void InnerFunc(String value){
            Log.d(Tag, "InnerFunc(String value) was called|||" + value);
            Log.d(Tag, "innerPublicInt = " + innerPublicInt);
            Log.d(Tag, "innerPrivateInt = " + innerPrivateInt);
        }
    }
}

 hook模块

public class XposedHook implements IXposedHookLoadPackage {


    @Override
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
        if (loadPackageParam.packageName.equals("com.example.xposedhooktarget")) {
            final Class<?> clazz = XposedHelpers.findClass("com.example.xposedhooktarget.HookDemo", loadPackageParam.classLoader);
            //getClassInfo(clazz);


            //不需要获取类对象,即可直接修改类中的私有静态变量staticInt
            XposedHelpers.setStaticIntField(clazz, "staticInt", 99);


            //Hook无参构造函数,啥也不干。。。。
            XposedHelpers.findAndHookConstructor(clazz, new XC_MethodHook() {
                @Override
                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                    XposedBridge.log("Haha, HookDemo constructed was hooked" );
                    //大坑,此时对象还没有建立,即不能获取对象,也不能修改非静态变量的值
                    //XposedHelpers.setIntField(param.thisObject, "publicInt", 199);
                    //XposedHelpers.setIntField(param.thisObject, "privateInt", 299);
                }
            });


            //Hook有参构造函数,修改参数
            XposedHelpers.findAndHookConstructor(clazz, String.class,  new XC_MethodHook() {
                @Override
                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                    param.args[0] = "Haha, HookDemo(str) are hooked";
                }
            });


            //Hook有参构造函数,修改参数------不能使用XC_MethodReplacement()替换构造函数内容,
            //XposedHelpers.findAndHookConstructor(clazz, String.class, new XC_MethodReplacement() {
            //    @Override
            //    protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
            //        Log.d("HookDemo" , "HookDemo(str) was replace");
            //    }
            //});


            //Hook公有方法publicFunc,
            // 1、修改参数
            // 2、修改下publicInt和privateInt的值
            // 3、再顺便调用一下隐藏函数hideFunc
            //XposedHelpers.findAndHookMethod("com.example.xposedhooktarget.HookDemo", clazz.getClassLoader(), "publicFunc", String.class, new XC_MethodHook()
            XposedHelpers.findAndHookMethod(clazz, "publicFunc", String.class, new XC_MethodHook() {
                @Override
                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                    param.args[0] = "Haha, publicFunc are hooked";
                    XposedHelpers.setIntField(param.thisObject, "publicInt", 199);
                    XposedHelpers.setIntField(param.thisObject, "privateInt", 299);
                    // 让hook的对象本身去执行流程
                    Method md = clazz.getDeclaredMethod("hideFunc", String.class);
                    md.setAccessible(true);
                    //md.invoke(param.thisObject, "Haha, hideFunc was hooked");
                    XposedHelpers.callMethod(param.thisObject, "hideFunc", "Haha, hideFunc was hooked");


                    //实例化对象,然后再调用HideFunc方法
                    //Constructor constructor = clazz.getConstructor();
                    //XposedHelpers.callMethod(constructor.newInstance(), "hideFunc", "Haha, hideFunc was hooked");
                }
            });


            //Hook私有方法privateFunc,修改参数
            //XposedHelpers.findAndHookMethod("com.example.xposedhooktarget.HookDemo", clazz.getClassLoader(), "privateFunc", String.class, new XC_MethodHook()
            XposedHelpers.findAndHookMethod(clazz, "privateFunc", String.class, new XC_MethodHook() {
                @Override
                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                    param.args[0] = "Haha, privateFunc are hooked";
                }
            });


            //Hook私有静态方法staticPrivateFunc, 修改参数
            XposedHelpers.findAndHookMethod(clazz, "staticPrivateFunc", String.class, new XC_MethodHook() {
                @Override
                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                    param.args[0] = "Haha, staticPrivateFunc are hooked";
                }
            });


            //Hook复杂参数函数complexParameterFunc
            Class fclass1 = XposedHelpers.findClass("java.util.Map", loadPackageParam.classLoader);
            Class fclass2 = XposedHelpers.findClass("java.util.ArrayList", loadPackageParam.classLoader);
            XposedHelpers.findAndHookMethod(clazz, "complexParameterFunc", String.class,
                    "[[Ljava.lang.String;", fclass1, fclass2, new XC_MethodHook() {
                        @Override
                        protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                            param.args[0] = "Haha, complexParameterFunc are hooked";
                        }
                    });


            //Hook私有方法repleaceFunc, 替换打印内容
            XposedHelpers.findAndHookMethod(clazz, "repleaceFunc", new XC_MethodReplacement() {
                @Override
                protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
                    Log.d("HookDemo", "Haha, repleaceFunc are replaced");
                    return null;
                }
            });
            //Hook方法, anonymousInner, 参数是抽象类,先加载所需要的类即可
            Class animalClazz  = loadPackageParam.classLoader.loadClass("com.example.xposedhooktarget.Animal");
            XposedHelpers.findAndHookMethod(clazz, "anonymousInner", animalClazz, String.class, new XC_MethodHook() {
                @Override
                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                    XposedBridge.log("HookDemo This is test");
                    param.args[1] = "Haha, anonymousInner are hooked";
                }
            });


            //Hook匿名类的eatFunc方法,修改参数,顺便修改类中的anonymoutInt变量
            XposedHelpers.findAndHookMethod("com.example.xposedhooktarget.HookDemo$1", clazz.getClassLoader(),
                    "eatFunc", String.class, new XC_MethodHook() {
                        @Override
                        protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                            param.args[0] = "Haha, eatFunc are hooked";
                            XposedHelpers.setIntField(param.thisObject, "anonymoutInt", 499);
                        }
                    });


            //hook内部类的构造方法失败,且会导致hook内部类的InnerFunc方法也失败,原因不明
//            XposedHelpers.findAndHookConstructor(clazz1, new XC_MethodHook() {
//                        @Override
//                        protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
//                            XposedBridge.log("Haha, InnerClass constructed was hooked" );
//                        }
//                    });


            //Hook内部类InnerClass的InnerFunc方法,修改参数,顺便修改类中的innerPublicInt和innerPrivateInt变量
            final Class<?> clazz1 = XposedHelpers.findClass("com.example.xposedhooktarget.HookDemo$InnerClass", loadPackageParam.classLoader);
            XposedHelpers.findAndHookMethod(clazz1, "InnerFunc", String.class, new XC_MethodHook() {
                        @Override
                        protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                            param.args[0] = "Haha, InnerFunc was hooked";
                            XposedHelpers.setIntField(param.thisObject, "innerPublicInt", 9);
                            XposedHelpers.setIntField(param.thisObject, "innerPrivateInt", 19);
                        }
                    });
        }
    }


    private void getClassInfo(Class clazz) {
        //getFields()与getDeclaredFields()区别:getFields()只能访问类中声明为公有的字段,私有的字段它无法访问,
        //能访问从其它类继承来的公有方法.getDeclaredFields()能访问类中所有的字段,与public,private,protect无关,
        //不能访问从其它类继承来的方法
        //getMethods()与getDeclaredMethods()区别:getMethods()只能访问类中声明为公有的方法,私有的方法它无法访问,
        //能访问从其它类继承来的公有方法.getDeclaredFields()能访问类中所有的字段,与public,private,protect无关,
        //不能访问从其它类继承来的方法
        //getConstructors()与getDeclaredConstructors()区别:getConstructors()只能访问类中声明为public的构造函数
        //getDeclaredConstructors()能访问类中所有的构造函数,与public,private,protect无关


        //XposedHelpers.setStaticObjectField(clazz,"sMoney",110);
        //Field sMoney = clazz.getDeclaredField("sMoney");
        //sMoney.setAccessible(true);
        Field[] fs;
        Method[] md;
        Constructor[] cl;
        fs = clazz.getFields();
        for (int i = 0; i < fs.length; i++) {
            XposedBridge.log("HookDemo getFiled: " + Modifier.toString(fs[i].getModifiers()) + " " +
                    fs[i].getType().getName() + " " + fs[i].getName());
        }
        fs = clazz.getDeclaredFields();
        for (int i = 0; i < fs.length; i++) {
            XposedBridge.log("HookDemo getDeclaredFields: " + Modifier.toString(fs[i].getModifiers()) + " " +
                    fs[i].getType().getName() + " " + fs[i].getName());
        }
        md = clazz.getMethods();
        for (int i = 0; i < md.length; i++) {
            Class<?> returnType = md[i].getReturnType();
            XposedBridge.log("HookDemo getMethods: " + Modifier.toString(md[i].getModifiers()) + " " +
                    returnType.getName() + " " + md[i].getName());
            //获取参数
            //Class<?> para[] = md[i].getParameterTypes();
            //for (int j = 0; j < para.length; ++j) {
            //System.out.print(para[j].getName() + " " + "arg" + j);
            //if (j < para.length - 1) {
            //    System.out.print(",");
            //}
            //}
        }
        md = clazz.getDeclaredMethods();
        for (int i = 0; i < md.length; i++) {
            Class<?> returnType = md[i].getReturnType();
            XposedBridge.log("HookDemo getDeclaredMethods: " + Modifier.toString(md[i].getModifiers()) + " " +
                    returnType.getName() + " " + md[i].getName());
        }
        cl = clazz.getConstructors();
        for (int i = 0; i < cl.length; i++) {
            XposedBridge.log("HookDemo getConstructors: " + Modifier.toString(cl[i].getModifiers()) + " " +
                    md[i].getName());
        }
        cl = clazz.getDeclaredConstructors();
        for (int i = 0; i < cl.length; i++) {
            XposedBridge.log("HookDemo getDeclaredConstructors: " + Modifier.toString(cl[i].getModifiers()) + " " +
                    md[i].getName());
        }
    }
}

总结

1、hook的难点在于逆向分析,花的时间比较多。
2、理论上可以基于xposed做任何事。
3、若目标app改版升级什么的,需要重新适配,很麻烦。

demo地址:
链接:百度网盘 请输入提取码 密码:bvww 

参考 

https://github.com/rovo89/XposedBridge/wiki/Development-tutorial
Android Studio Xposed模块编写(二) - Gordon0918 - 博客园

我不怕千万人阻挡,只怕自己投降。 

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 如果你想通过 Xposed 框架对 ActivityThread.class 中的 currentActivityThread 方法对应的 ArtMethod 对象的 hotness_count_ 字段进行 hook,您需要在 Xposed 框架中编写一个模块,并通过 XposedBridge API 进行 hook。您需要在 Xposed 模块中通过 XposedHelpers.findAndHookMethod() 方法获取 currentActivityThread 方法,然后使用 XposedBridge.hookMethod() 方法对其进行 hook。在 hook 方法中,您可以通过反射获取 hotness_count_ 字段的值,并对其进行修改。 注意:在修改系统层代码(如 Android framework)的 hotness_count_ 字段时,请谨慎操作,以免造成系统不稳定。 ### 回答2: 想要通过Xposed框架hook安卓ActivityThread.class中的currentActivityThread方法对应的ArtMethod对象中的hotness_count_字段值,需要先了解一些相关知识。 Xposed框架是一款用于修改安卓系统的框架,它通过hook技术来实现对安卓应用的改造和扩展。在使用Xposed框架时,首先需要安装Xposed框架并激活,然后编写相应的模块来实现hook。 要hook ActivityThread.class中的currentActivityThread方法,可以通过Xposed的findAndHookMethod方法来实现。首先,我们在模块的初始化方法中使用该方法对currentActivityThread方法进行hook。在hook的回调函数中,我们可以获取到当前执行的ArtMethod对象。 要获取ArtMethod对象中的hotness_count_字段值,可以使用Java的反射机制来实现。首先,通过反射获取到ArtMethod类的声明,然后再通过反射获取到hotness_count_字段,并获取该字段的值。 具体代码如下: ```java import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XposedHelpers; public class MyXposedModule { public void initZygote() { XposedHelpers.findAndHookMethod("android.app.ActivityThread", null, "currentActivityThread", new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { // 获取当前执行的ArtMethod对象 Object currentActivityThread = param.getResult(); // 获取ArtMethod类 Class<?> artMethodClass = XposedHelpers.findClass("java.lang.reflect.ArtMethod", currentActivityThread.getClass().getClassLoader()); // 获取hotness_count_字段 Object hotnessCount = XposedHelpers.getObjectField(currentActivityThread, "hotness_count_"); // 打印hotness_count_字段值 if (hotnessCount != null) { int hotnessCountValue = (int) hotnessCount; Log.d("MyXposedModule", "hotness_count_: " + hotnessCountValue); } } }); } } ``` 以上代码实现了对currentActivityThread方法的hook,获取到ArtMethod对象后再获取其中的hotness_count_字段并进行打印。 需要注意的是,Xposed框架使用可能需要root权限,并且不同版本的安卓系统以及应用可能会有一些差异,可能需要根据实际情况进行相应的修改。 ### 回答3: 要想通过Xposed框架hook安卓ActivityThread.class中的currentActivityThread()方法对应的ArtMethod对象中的hotness_count_字段值,需要按照以下步骤进行: 首先,使用Xposed框架创建一个模块,在模块的init方法中进行hook操作。可以使用findAndHookMethod函数来hook currentActivityThread()方法。代码如下所示: ```java public class MyXposedModule implements IXposedHookLoadPackage { @Override public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable { if (!lpparam.packageName.equals("com.android.systemui")) { return; } // 当加载的包是 com.android.systemui 时进行hook操作 XposedHelpers.findAndHookMethod("android.app.ActivityThread", lpparam.classLoader, "currentActivityThread", new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { // 获取 currentActivityThread 方法的返回值(即 ActivityThread 对象) Object activityThreadObj = param.getResult(); // 获取 ActivityThread 类中的 mHotcness_count 字段 Field hotnessField = activityThreadObj.getClass().getDeclaredField("mHotness_count"); hotnessField.setAccessible(true); // 修改 mHotness_count 的值为你想要的值 hotnessField.setInt(activityThreadObj, 100); } }); } } ``` 上述代码中,我们通过hook currentActivityThread()方法获取了ActivityThread对象,并通过反射获取到该对象的mHotness_count字段,并将其值修改为100。 接下来,使用Android Studio或其他工具进行编译和打包,得到一个Xposed模块的apk文件。 最后,将生成的apk文件安装到Android设备上,并使用Xposed框架将该模块激活即可。当目标应用启动时,Xposed框架会自动调用我们编写的hook代码,从而成功修改ArtMethod对象中的hotness_count_字段值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值