Xposed 摘要
验证Xposed模块自身是否被启用
Java反射机制、动态代理(过滤器Filter和拦截器Interceptor)
xposedAPI文档
xposedAPI文档:https://api.xposed.info/reference/packages.html
xposed插件AndroidStudio修改代码运行没变化没生效的问题->android11 (Instant Run已经在AndroidStudio3.5废弃了,改成了ApplyChange)
【精选】解决AndroidStudio修改代码运行没变化没生效的问题-Xposed插件重载_android studio修改代码运行不产生效果_KeepStudya的博客-CSDN博客
xposed插件装载失败-Android10前 (Instant Run)
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
方法对象直接调用的例子
判断一个对象是否是某个类的实例
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 {
// 在方法执行后,你可以在这里添加你的逻辑
}
}
);
当子类重写了父类的方法直接调用父类方法例子
如果加了壳的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]);
}
});
}
});
}
}
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、如何获取调用对象去调用函数,或者新建新建示例去调用方法
hook自定义类及自定义类数组、接口代理等
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路径
/data/user/0/de.robv.android.xposed.installer/conf/modules.list