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 ...
随机推荐
- FLink参数pipeline.operator-chaining介绍
1.当使用flink提交一个任务,没有给算子设置并行度情况下,默认所有算子会chain在一起,整个DAG图只会显示一个算子,虽然有利于数据传输,提高程序性能,但是无法看到数据的输入和疏忽,业绩反压相关 ...
- .Net对接Java接口加密不通过?
前言 相信又不少小伙伴在对接第三方接口时遇到过这种情况:参数.排序.加密方式都按照接口文档进行处理了,可就是签名不通过,然后开始怀疑是不是参数漏了?参与加密的参数不对?还是加密方式有问题?最后一顿 ...
- flutter-构造方法给数组list默认空值
1 class NewstStyle extends StatelessWidget { 2 final List<DkCenterUpload> upload; 3 const News ...
- keil优化等级说明 keil code optimization
其中 0级(Constan folding)的优化包括: a.常数折叠:只要有可能,编译器就执行将表达式化为常数数字的计算,其中包括运行地址的计算. b. 简单访问优化:对8051系统的内部数据和位地 ...
- Ansible - [11] Roles
前言 Q1:什么是Roles 在实际生产环境中,会编写大量的playbook文件来实现不同的功能.而且,每个playbook还可能会调用其他文件(变量文件),对于海量的.无规律的文件,管理是个问题.A ...
- 【Python】读取写入INI文件
最近,写个abaqus的python脚本,需要输入的item比较多,而且也有一些不经常修改但又可能要修改的option.如果都用abaqus的getinput()和getinputs()函数,那输入的 ...
- wxpython-窗体关闭
` def close(self, event): wx.Exit() `
- 14 个 Linux 下 CPU 监控工具
01. top top是最常用的查看系统资源使用情况的工具,包括CPU.内存等等资源. 这里主要关注CPU资源. 1.1 /proc/loadavg load average取自/proc/loada ...
- Delphi 检测鼠标键盘多久没有活动
function GetInputAwayTime():DWORD; var lpi:TLastInputInfo; begin lpi.cbSize := sizeof(lpi); GetLastI ...
- String类的三种常见构造方法
1.根据构造方法创建字符串对象 1.public String() 创建一个空字符串,里面不包含任何内容 2.public String(char[] chs) 创建一个字符数组,将其拼接成字符串对象 ...