LSposed hook(学习分享)
Xposed模块编写
参考:
https://www.52pojie.cn/thread-1740944-1-1.html
https://www.52pojie.cn/thread-1748081-1-1.html
环境配置
电脑端准备
1.官网下载相关jar包
https://github.com/bywhat/XposedBridgeApi/blob/main/XposedBridgeAPI-82.jar
2.将jar包导入到android工程中
- 项目下创建libs目录,将jar包导入
- 配置gradle,直接在
build.gradle
的dependencies
下添加即可
compileOnly(files("libs/XposedBridgeAPI-82.jar"))
3.配置项目
- 在
AndroidManifest.xml
下的application添加下面元数据
<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/Theme.Test" >
<meta-data android:name="xposedmodule"
android:value="true" />
<meta-data android:name="xposeddescription"
android:value="My test xposed" />
<meta-data android:name="xposedminversion"
android:value="82" />
<!-- 根据版本号 -->
</application>
- 在
main
目录下添加assets/xposed_init
文件,文件中写入口类名
com.example.xposed.MyXposed
4.在配置好的类中愉快的hook
public class MyXposed implements IXposedHookLoadPackage {
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
XposedBridge.log("MytagIs:" + loadPackageParam.packageName);
}
}
手机端
1.用Magisk Root手机并在设置中开启zygisk
2.下载Lsposed
https://github.com/LSPosed/LSPosed
3.在Magisk 模块安装Lsposed zygisk版的发行压缩包
Xposed
类的路径
外部类:com.zj.wuaipojie.Demo
内部类:com.zj.wuaipojie.Demo$inner
hook函数
用回调函数XC_MethodHook来修改传入参数和返回值
常规函数
XposedHelpers.findAndHookMethod("com.zj.wuaipojie.Demo", loadPackageParam.classLoader, "a", "java.lang.String", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
//获取参数
Log.d("zj2595", param.args[0].toString());
//设置传入参数
param.args[0] = "hook普通参数";
Log.d("zj2595", param.args[0].toString());
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
//获取返回值
Log.d("zj2595", param.getResult().toString());
//设置返回值
param.setResult("我hook普通返回");
}
});
hook复杂/自定义方法
Class<?> clazz = loadPackageParam.classLoader.loadClass("com.zj.wuaipojie.Demo");
XposedBridge.hookAllMethods(clazz, "complexParameterFunc", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Log.d("zj2595", param.args[0].toString());
param.args[0] = "hook复杂参数";
Log.d("zj2595", param.args[0].toString());
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Log.d("zj2595", param.getResult().toString());
param.setResult("我hook复杂返回");
}
});
用回调函数XC_MethodReplacement来替换该函数
替换函数
Class<?> clazz = loadPackageParam.classLoader.loadClass("com.zj.wuaipojie.Demo");
XposedBridge.hookAllMethods(clazz, "repleaceFunc", new XC_MethodReplacement() {
@Override
protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
Log.d("zj2595", "我将函数替换了");
return null;
}
});
加固后函数
构造函数
通过签名区分
XposedBridge.hookAllConstructors(clazz, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Constructor<?> constructor = (Constructor<?>) param.method;
Class<?>[] parameterTypes = constructor.getParameterTypes();
Log.d("zj2595", "构造" + Arrays.toString(parameterTypes));
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
}
});
直接hook特定函数
XposedHelpers.findAndHookConstructor("com.zj.wuaipojie.Demo", loadPackageParam.classLoader, "java.lang.String", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Log.d("zj2595", "hook str构造函数");
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
}
});
XposedHelpers.findAndHookConstructor("com.zj.wuaipojie.Demo", loadPackageParam.classLoader, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Log.d("zj2595", "hook 空参构造函数");
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
}
});
Dex
hook变量
静态成员变量
final Class<?> clazz = loadPackageParam.classLoader.loadClass("com.zj.wuaipojie.Demo");
//获取静态成员变量
Log.i("zj2595", (String) XposedHelpers.getStaticObjectField(clazz, "staticField"));
//设置静态成员变量
XposedHelpers.setStaticObjectField(clazz, "staticField", "hook_static");
普通成员变量
要在构造函数运行后获取修改
final Class<?> clazz = loadPackageParam.classLoader.loadClass("com.zj.wuaipojie.Demo");
XposedBridge.hookAllConstructors(clazz, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
//获取成员变量
Log.d("zj2595", String.valueOf(XposedHelpers.getIntField(param.thisObject, "publicInt")));
//设置成员变量
XposedHelpers.setIntField(param.thisObject,"publicInt", 999);
}
});
方法调用
成员方法
final Class<?> clazz = loadPackageParam.classLoader.loadClass("com.zj.wuaipojie.Demo");
XposedHelpers.callMethod(clazz.newInstance(), "refl");
静态方法
final Class<?> clazz = loadPackageParam.classLoader.loadClass("com.zj.wuaipojie.Demo");
XposedHelpers.callStaticMethod(clazz.newInstance(), "staticrefl");
Xposed应用
遍历类下的所有方法
XposedHelpers.findAndHookMethod(ClassLoader.class, "loadClass", String.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Class<?> clazz = (Class<?>) param.getResult();
if(clazz.getName().contains("com.zj.wuaipojie")){
Method[] methods = clazz.getDeclaredMethods();
for(Method method : methods){
//排除抽象,本地,接口方法
if(!Modifier.isAbstract(method.getModifiers()) &&
!Modifier.isNative(method.getModifiers()) &&
!Modifier.isInterface(method.getModifiers())){
XposedBridge.hookMethod(method, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Log.d("zj2595", method.toString());
}
});
}
}
}
}
});
字符串赋值定位
XposedBridge.hookAllMethods(TextView.class, "setText", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
PrintStack();
}
});
//打印堆栈
private void PrintStack(){
Throwable ex = new Throwable();
StackTraceElement[] stacktrace = ex.getStackTrace();
for(StackTraceElement stack : stacktrace){
Log.d("zj2595", "line:" + stack.getLineNumber() + " class:" + stack.getClassName() + " method:" + stack.getMethodName() + " file:" + stack.getFileName() );
}
}
点击事件监听
XposedHelpers.findAndHookMethod(View.class, "setOnClickListener", View.OnClickListener.class,new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Class<?> clazz = param.args[0].getClass();
if(clazz != null){
XposedHelpers.findAndHookMethod(clazz, "onClick", View.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
View view = (View)param.args[0];
Log.i("zj2595", String.format("Buttonid:0x%x",view.getId()));
}
});
}
}
});
修改布局
XposedHelpers.findAndHookMethod("com.zj.wuaipojie.ui.ChallengeSixth", loadPackageParam.classLoader, "onCreate", "android.os.Bundle", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
View view = (View)XposedHelpers.callMethod(param.thisObject, "findViewById", 0x7f0800de);
view.setVisibility(View.GONE);
}
});
LSposed hook(学习分享)的更多相关文章
- ElasticSearch 5学习(7)——分布式集群学习分享2
前面主要学习了ElasticSearch分布式集群的存储过程中集群.节点和分片的知识(ElasticSearch 5学习(6)--分布式集群学习分享1),下面主要分享应对故障的一些实践. 应对故障 前 ...
- ElasticSearch 5学习(6)——分布式集群学习分享1
在使用中我们把文档存入ElasticSearch,但是如果能够了解ElasticSearch内部是如何存储的,将会对我们学习ElasticSearch有很清晰的认识.本文中的所使用的ElasticSe ...
- MySQL学习分享--Thread pool实现
基于<MySQL学习分享--Thread pool>对Thread pool架构设计的详细了解,本文主要对Thread pool的实现进行分析,并根据Mariadb和Percona提供的开 ...
- JavaScript Shell学习分享
目录 JavaScript Shell学习分享 简介 安装 使用原因 小结 JavaScript Shell学习分享 简介 JavaScript Shell是由Mozilla提供的综合JavaScri ...
- python 学习分享-paramiko模块
paramiko模块学习分享 paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接.paramiko支持Linux, Solaris, BS ...
- 有关JSOUP学习分享(一)
其实现在用JSOUP爬虫的也不多了,但是由于最近换公司,做数据爬虫需要用到,就看了下,感觉还是挺好用的,原理什么的感觉和weblogic也差不到哪里去,废话少说,这里就简单的分享下最近接触的干货. J ...
- Swagger框架学习分享
Swagger框架学习分享 转至元数据结尾 Created and last modified by 刘新宇 大约1分钟曾经 pageId=162045803#page-metadata-start& ...
- Flink 从0到1学习—— 分享四本 Flink 国外的书和二十多篇 Paper 论文
前言 之前也分享了不少自己的文章,但是对于 Flink 来说,还是有不少新入门的朋友,这里给大家分享点 Flink 相关的资料(国外数据 pdf 和流处理相关的 Paper),期望可以帮你更好的理解 ...
- [torch] pytorch hook学习
pytorch hook学习 register_hook import torch x = torch.Tensor([0,1,2,3]).requires_grad_() y = torch.Ten ...
- python paramiko模块学习分享
python paramiko模块学习分享 paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接.paramiko支持Linux, Sola ...
随机推荐
- Q:CRON表达式,Linux和Java的不同写法
CRON表达式是一个字符串,包含五个到七个由空格分隔的字段(每种软件不一样),表示一组时间,通常作为执行某个程序的时间表. 调度精度: Linux的cron调度精度为分钟级别,最小粒度为分钟,而Jav ...
- Linux mint的hadoop安装方法
参考网址http://www.powerxing.com/install-hadoop/ 1.创建hadoop账户 这条命令创建了可以登陆的 hadoop 用户,并使用 /bin/bash 作为 sh ...
- 源码方式本地化部署deepseek和量化
前置条件 1.python环境,安装教程:https://www.python.org/downloads/2.wsl环境(Windows系统),安装教程:https://learn.microsof ...
- kubsphere应用系列(三)-创建手动流水线
准备工作 1.1 创建凭证 1.2 添加代码仓库 第一步创建流水线 第二步配置流水线 1.1选择CI/CD模板 1.2删除多余阶段 1.3 配置git仓库信息 1.4配置docker仓库信 ...
- Spark - [03] RDD概述
RDD,分布式数据集,是Spark中最基本的数据抽象. 一.什么是RDD RDD(Resilient Distributed Dataset)叫做分布式数据集,是 Spark 中最基本的数据抽象. 代 ...
- ES - 概述
前言 Q1:ElasticSearch 是什么? 为什么要学习? ElasticSearch 是一个分布式.可扩展.实时的搜索和分析引擎,基于 Lucene 构建.它可以用于全文搜索.结构化搜索.分析 ...
- Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
在众多开源项目中,高颜值.功能强大且部署简单的项目往往更能俘获开发者的心.然而,实际部署 Web 应用时,面对数据库.缓存.消息队列等复杂的依赖关系,常常令人头疼.Docker 的开源为我们普及了容器 ...
- ADO.NET中SQL绑定变量方式总结
最近在项目上遇到几个问题,关于ADO.NET中SQL绑定变量 总结一下,分享给大家. 1. 使用 SqlParameter(推荐方式,防止 SQL 注入) ADO.NET 提供 SqlParamete ...
- mongodb查询某个字段数据
如下 db.集合名.find( {}, {需要查询的字段:1, _id:0} ) 例如 db.userInfo.find({}, {'created_at':1, _id: 0}) 默认会显示 _id ...
- docker搭建本地仓库
环境准备: 服务器:9.134.130.35 私有仓库服务器,运行registry容器 客户端:9.208.244.175 测试客户端,用于上传.下载镜像文件 测试搭建本地仓库 mkdir /dock ...