xposed方面的备忘录

Xposed 摘要
验证Xposed模块自身是否被启用
Java反射机制、动态代理(过滤器Filter和拦截器Interceptor)

xposedAPI文档

xposedAPI文档:https://api.xposed.info/reference/packages.html

鸿蒙 harmonyos 采用 太极

xposed插件AndroidStudio修改代码运行没变化没生效的问题->android11 (Instant Run已经在AndroidStudio3.5废弃了,改成了ApplyChange)

【精选】解决AndroidStudio修改代码运行没变化没生效的问题-Xposed插件重载_android studio修改代码运行不产生效果_KeepStudya的博客-CSDN博客

image.png

xposed插件装载失败-Android10前 (Instant Run)

image.png

Found Xposed class 'de/robv/android/xposed/XposedBridge', now initializing
03-28 11:23:39.569 I/Xposed ( 1377): Loading modules from /data/app/com.younghare.wechatWebAuto-1/base.apk
03-28 11:23:39.571 I/Xposed ( 1377): Loading class younghare.com.wechatWebAuto.xposed.XMoudleWechatApp
03-28 11:23:39.572 E/Xposed ( 1377): Failed to load class younghare.com.wechatWebAuto.xposed.XMoudleWechatApp
03-28 11:23:39.572 E/Xposed ( 1377): java.lang.ClassNotFoundException: Didn't find class "younghare.com.wechatWebAuto.xposed.XMoudleWechatApp" on path: DexPathList[[zip file "/data/app/com.younghare.wechatWebAuto-1/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]

参考解决办法
Xposed Not Loading my module, ClassNotFoundException

image.png

image.png

方法对象直接调用的例子

image.png

判断一个对象是否是某个类的实例

xposed 实现如下 代码 if (obj instanceof IMsgItem) 其中IMsgItem 不是我们自己的类

        XposedHelpers.findAndHookMethod(
            "com.example.app.SomeClass", // 替换为目标方法所在的完整类名
            lpparam.classLoader,
            "someMethod", // 替换为目标方法的名称
            Object.class, // 替换为目标方法的参数类型
            new XC_MethodHook() {
                @Override
                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                    // 在方法执行前,你可以在这里添加你的逻辑
                    Object obj = param.args[0]; // 假设我们hook的方法有一个参数

                    // 使用反射来检查对象是否是IMsgItem类型的实例
                    Class<?> iMsgItemClass = XposedHelpers.findClass("com.example.app.IMsgItem", lpparam.classLoader); // 替换为IMsgItem的完整类名
                    if (iMsgItemClass.isInstance(obj)) {
                        // 在这里实现你的逻辑
                    }
                }

                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    // 在方法执行后,你可以在这里添加你的逻辑
                }
            }
        );

当子类重写了父类的方法直接调用父类方法例子

image.png
image.png

如果加了壳的APP

直接用jadx打开apk,查看加的是哪种壳,寻找对应的函数,类似attachBaseContext这样的方法。
参考链接:https://www.cnblogs.com/mangM/p/11055384.html

public class EncryptHook implements IXposedHookLoadPackage {

    public void handleLoadPackage(LoadPackageParam loadPackageParam) throws Throwable {
        if (!loadPackageParam.packageName.equals("app包名")) { return; }
        XposedBridge.log("Start hook " + loadPackageParam.packageName);

        XposedHelpers.findAndHookMethod("com.stub.StubApp", loadPackageParam.classLoader,
                 //com.stub.StubApp 加壳的类
                "attachBaseContext", Context.class, new XC_MethodHook() {
                 // attachBaseContext 加壳的方法 
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    super.afterHookedMethod(param);
                    Context context = (Context) param.args[0];
                    ClassLoader classLoader = context.getClassLoader();
                    XposedBridge.log("Enter stubApp");

                    XposedHelpers.findAndHookMethod("com.huijiemanager.utils.t", classLoader,
                        "a", byte[].class, PublicKey.class, new XC_MethodHook() {
                            @Override
                            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                                XposedBridge.log("rsa before params: " + new String(
                                    (byte[]) param.args[0]) + "," + param.args[1]);
                            }
                            @Override
                            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                                XposedBridge.log("rsa after params: " + new String(
                                    (byte[]) param.args[0]) + "," + param.args[1]);
                            }
                        });
                }
            });
    }
}

xposed 的编译

XposedTools: 编译xposed的相关脚本,与工具。
xposedbridge: xposed 框架的java层,
XposedInstaller: xposed 框架的独立apk,用于管理基于xposed的相关插件
Xposed : 修改之后的app_process,用于替代系统的 app_process
android_art: 对art_methods 进行改造后的art,用于替代系统的 art。

Android Studio Xposed模块编写(二)

1、如何Hook静态变量
2、如何Hook构造方法
3、如何Hook复杂参数的方法
4、如何替换函数执行内容
5、如何Hook内部类中的函数
6、如何Hook匿名类的函数
7、如何获取调用对象去调用函数,或者新建新建示例去调用方法

利用反射对修饰符为final的成员变量进行修改


hook自定义类及自定义类数组、接口代理等

image.png
 static String ContactServiceClass = "com.tencent.wework.foundation.logic.ContactService";

    /**
     * 应该是二维码的图片,需要传入回调
     * @param classLoader
     */
    private static void printContactService_GenerateCode(ClassLoader classLoader) {


        try {
            //com.tencent.wework.foundation.model.pb
            //Lcom/tencent/mm/compatible/util/CodeInfo
            //public void GenerateCode(CodeInfo[] codeInfoArr, ICommonStringCallback iCommonStringCallback)
            //.method public GenerateCode([Lcom/tencent/wework/foundation/model/pb/Contact$CodeInfo;Lcom/tencent/wework/foundation/callback/ICommonStringCallback;)V
            Class<?> cls_CodeInfo = classLoader.loadClass("com.tencent.wework.foundation.model.pb.Contact$CodeInfo");
            Object array_cls_CodeInfo = Array.newInstance(cls_CodeInfo,0);

            //Array.netInstance(类名,0).getClass();就可以得到了。

            Class<?> cls_interface_ICommonStringCallback = classLoader.loadClass("com.tencent.wework.foundation.callback.ICommonStringCallback");

            String MethodName_GenerateCode = "GenerateCode";
            XposedHelpers.findAndHookMethod(ContactServiceClass, classLoader  //网络队列
                    , MethodName_GenerateCode
                    ,array_cls_CodeInfo.getClass()//cls_CodeInfo
                    ,cls_interface_ICommonStringCallback

                    , new XC_MethodHook() {
                        @Override
                        protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                            super.beforeHookedMethod(param);
                            Log.i(TAG,"fdfd看看");



                        }
                    });

            //.method public GetMyQRCodeImage(ZLcom/tencent/wework/foundation/callback/IGetCorpAdminInfoCallback;)V
            //public void GetMyQRCodeImage(boolean z, IGetCorpAdminInfoCallback iGetCorpAdminInfoCallback)

            Class<?> cls_interface_IGetCorpAdminInfoCallback = classLoader.loadClass("com.tencent.wework.foundation.callback.IGetCorpAdminInfoCallback");
            String MethodName_GetMyQRCodeImage = "GetMyQRCodeImage";
            XposedHelpers.findAndHookMethod(ContactServiceClass, classLoader  //网络队列
                    , MethodName_GetMyQRCodeImage
                    ,boolean.class
                    ,cls_interface_IGetCorpAdminInfoCallback

                    , new XC_MethodHook() {
                        @Override
                        protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                            super.beforeHookedMethod(param);
                            Log.i(TAG,"fdfd看看");



                        }
                    });

            //.class Lcom/tencent/wework/friends/controller/FriendsShareWxCardActicity$8;
            //.method public onResult(I[B)V
            //public void onResult(int i, byte[] bArr)



            XposedHelpers.findAndHookMethod("com.tencent.wework.friends.controller.FriendsShareWxCardActicity$8", classLoader  //网络队列
                    , "onResult"
                    ,int.class
                    ,byte[].class

                    , new XC_MethodHook() {
                        @Override
                        protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                            super.beforeHookedMethod(param);
                            Log.i(TAG,"fdfd看看");



                        }
                    });
        } catch (ClassNotFoundException e) {

            e.printStackTrace();
        }


    }

hook自定义类及new自定义类数组


    public void sendGroupTextMsg(long[] rids, String txt, Object messageObj, final ICommonStringCallback callback) {
        try {
            Object createGroupMsgReqObj = buildCreateGroupMsgReq(rids, txt);
            Object conversationService = ConversationWrapper.getInstance().getConversationService(classLoader);
            Class messageNanoClz = XposedHelpers.findClass("com.google.protobuf.nano.MessageNano", classLoader);

            byte[] createGroupMsgReqBytes = (byte[]) XposedHelpers.callStaticMethod(messageNanoClz, "toByteArray", new Class[]{messageNanoClz}, new Object[]{createGroupMsgReqObj});

            Class<?> callbackClz = XposedHelpers.findClass(WeWorkID.inter_ICommonStringLongCallback, classLoader);
            InvocationHandler invocationHandler = new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    MyXPoseHelper.printLogE("群发成功");
                    int i = (int) args[0];
                    String str = (String) args[1];
                    callback.onResult(i,str);

                    return null;
                }
            };
            //3.0.16 = public void SendMassMessage(byte[] bArr, Message message, ICommonStringLongCallback iCommonStringLongCallback)
            //3.1.6  = public void SendMassMessage(byte[] bArr, Message[] messageArr, ICommonStringLongCallback iCommonStringLongCallback)

            if (WeWorkID.Wework_vc_cur == WeWorkID.Wework_vc_3_0_16){
                XposedHelpers.callMethod(conversationService,"SendMassMessage",createGroupMsgReqBytes,messageObj, Proxy.newProxyInstance(classLoader,new Class[]{callbackClz},invocationHandler));

            }else {
                //创建目标数组对象
                Object[] obj_messageClz_arr = (Object[]) Array.newInstance(messageObj.getClass(),1);

                //创建临时数组对象
                Object[] obj_messageClz_arr_tmp = {messageObj};
                //临时数组内容copy到目标数组
                System.arraycopy(obj_messageClz_arr_tmp,0,obj_messageClz_arr,0,1);



                //3.1.6  = public void SendMassMessage(byte[] bArr, Message[] messageArr, ICommonStringLongCallback iCommonStringLongCallback)
                XposedHelpers.callMethod(conversationService,"SendMassMessage",createGroupMsgReqBytes,obj_messageClz_arr, Proxy.newProxyInstance(classLoader,new Class[]{callbackClz},invocationHandler));

            }


        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
    }

遍历获取自定义数组变量


            //分析拦截到的返回记录  public final void onResult(int i, Message[] messageArr)
            String impl_IGetHistoryMessageCallback ="oce$53";

            Object array_clz_model_message = Array.newInstance(clz_model_message,0);

            XposedHelpers.findAndHookMethod(impl_IGetHistoryMessageCallback, classLoader, "onResult", int.class, array_clz_model_message.getClass(), new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    super.afterHookedMethod(param);
                    int i_tmp = (int) param.args[0];
                    if (param.args[1]!=null){

                        Log.i("GetHistoryMessage_result","messages.size="+Array.getLength(param.args[1]) );
                        int length = Array.getLength(param.args[1]);
                        Object[] message_arr = new Object[length];
                        for (int i = 0; i < message_arr.length; i++) {
                            message_arr[i] = Array.get(param.args[1], i);

                            Object obj_message_mInfo = XposedHelpers.getObjectField(message_arr[i],"mInfo");
                            long msgId = XposedHelpers.getLongField(obj_message_mInfo,"id");
                            Log.i("GetHistoryMessage_result","messages.size="+Array.getLength(param.args[1]) +"; msgId+"+msgId +";msgremoteId ="+msgremoteId);

                        }
                    }

                }


            });

遍历获取自定义数组变量-方式2



            String json = "[{\"albumtype\":2,\"picId\":3,\"cachedSize\":4},{\"albumtype\":2,\"picId\":2,\"cachedSize\":4},{\"albumtype\":2,\"picId\":1,\"cachedSize\":4}]";


            CorpProduct.AlbumMetaInfo[] albumMetaInfos = GsonUtil.gson.fromJson(json,CorpProduct.AlbumMetaInfo[].class);
            Class<?> cls_AlbumMetaInfo = XposedHelpers.findClass("com.tencent.wework.foundation.model.pb.ProductAlbum.AlbumMetaInfo", classLoader);

            //Object[] obj_arr_AlbumMetaInfo = null;   //todo 构造 ProductAlbum.AlbumMetaInfo[]

            //Object[] obj_arr_AlbumMetaInfo = new Object[albumMetaInfos.length];
            Object obj_arr_AlbumMetaInfo = Array.newInstance(cls_AlbumMetaInfo,albumMetaInfos.length);


            //Object array_clz_ProductAlbum$AlbumMetaInfo = Array.newInstance(clz_ProductAlbum$AlbumMetaInfo,0);


            for (int i = 0; i < albumMetaInfos.length; i++) {
                Object obj_AlbumMetaInfo = cls_AlbumMetaInfo.newInstance();
                XposedHelpers.setIntField(obj_AlbumMetaInfo,"albumtype",albumMetaInfos[i].albumtype);
                XposedHelpers.setIntField(obj_AlbumMetaInfo,"cachedSize",albumMetaInfos[i].cachedSize);
                XposedHelpers.setLongField(obj_AlbumMetaInfo,"picId",albumMetaInfos[i].picId);
                //obj_arr_AlbumMetaInfo[i] = obj_AlbumMetaInfo;;

                Array.set(obj_arr_AlbumMetaInfo,i,obj_AlbumMetaInfo);


            }

使用带参数的构造方法


        try {
            
            Constructor ct_ConversationID =XposedHelpers.findClass("com.tencent.wework.msg.api.ConversationID", classLoader).getDeclaredConstructor(long.class);
            ct_ConversationID.setAccessible(true);
            Object obj_ConversationID =ct_ConversationID.newInstance(localId);

 
        } catch (Exception e) {
            e.printStackTrace();
        }

有的手机安装xposed插件需要手动点击的解决办法

修改下面文件中的apk路径

image.png
/data/user/0/de.robv.android.xposed.installer/conf/modules.list
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,552评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,666评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,519评论 0 334
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,180评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,205评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,344评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,781评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,449评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,635评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,467评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,515评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,217评论 3 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,775评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,851评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,084评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,637评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,204评论 2 341

推荐阅读更多精彩内容