那些年的Xposed开发经验记录
把之前写的Xposed相关文章合并到一块,方便查阅
目录
- 多进程App的Hook问题
- XposedHelper中的静态变量
- demo的AndroidManifest.xml的测试核心代码
- 结论
- 限制handleLoadPackage被单个进程多次执行的问题
- 多dex Hook问题
- 为应用增加权限
- 利用Xposed删除权限
- 参考
- Hook框架集锦
- 原始思维导图文件下载
多进程App的Hook问题
以及App中单个方法被多个模块Hook时的Hook代码优先级问题
XposedHelper中的静态变量

demo的AndroidManifest.xml的测试核心代码
<activityandroid:name=".ProcessActivity"android:process=":process"></activity>//私有进程<activityandroid:name=".PublicProcessActivity"android:process="com.publicProcess">//公共进程</activity>
结论
以下"所有进程"都包括应用内创建的私有进程和公共进程
经过测试[测试代码过多就不贴了],得出结论:
1.所有进程的创建都会执行而且会多次执行handleLoadPackage函数;
2.每个进程都会重新创建一个fieldCache,methodCache,constructorCache静态变量;
3.若两个模块Hook了当前App的同一个函数则beforeHookedMethod执行顺序是按Xposed框架私有目录下conf/modules.list的顺序执行的,afterHookedMethod则与beforeHookedMethod执行顺序相反[测试数据是这样的,具体真实情况就不太想探究了,应该90%正确],举个例子:
模块A和模块B同时Hook了应用C的方法D,modules.list中模块A比模块B的顺序靠前,则Hook代码执行顺序为:
A->beforeHookedMethod,B->beforeHookedMethod,D,B->afterHookedMethod,A->afterHookedMethod
4.lpparam.isFirstApplication并不是仅仅在主进程执行handleLoadPackage函数时才会置为true,在所有进程执行该函数时都会置为true[测试数据是这样的,具体真实情况就不太想探究了,应该90%正确];
5.在App的一个进程A中对某函数进行Hook只会影响进程A执行该函数,不会影响该App其它未被Hook的进程执行该函数。
限制handleLoadPackage被单个进程多次执行的问题
/***防止重复执行Hook代码* @param flag 判断标识,针对不同Hook代码分别进行判断* @return 是否已经注入Hook代码*/private boolean isInjecter(String flag) {try {if (TextUtils.isEmpty(flag)) return false;Field methodCacheField = XposedHelpers.class.getDeclaredField("methodCache");methodCacheField.setAccessible(true);HashMap<String, Method> methodCache = (HashMap<String, Method>) methodCacheField.get(null);Method method=XposedHelpers.findMethodBestMatch(Application.class,"onCreate");String key=String.format("%s#%s",flag,method.getName());if (methodCache.containsKey(key)) return true;methodCache.put(key, method);return false;} catch (Throwable e) {e.printStackTrace();}return false;}
在handleLoadPackage做判断
@Keeppublic void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) {if (isInjecter(this.getClass().getName())) {return;}//hook代码
}
多dex Hook问题
//解决多dex问题public static void findHideDex(final OnFindDexListener listener) {XposedBridge.hookAllMethods(ContextWrapper.class, "attachBaseContext", new XC_MethodHook() {public void beforeHookedMethod(MethodHookParam param) {ClassLoader classLoader = ((Context) param.args[0]).getClassLoader();if (classLoader == null) return;if (listener != null) listener.onFind(classLoader);}});XposedBridge.hookAllConstructors(ClassLoader.class, new XC_MethodHook() {public void beforeHookedMethod(MethodHookParam param) {ClassLoader classLoader = (ClassLoader) param.args[0];if (classLoader == null) return;if (listener != null) listener.onFind(classLoader);}});}
public interface OnFindDexListener {void onFind(ClassLoader classLoader);}
为应用增加权限
利用Xposed删除权限
这个已经有人实现了,就是Xposed的作者,我们就先来研究研究他是怎么实现的,先上他的实现代码
public class PackagePermissions extends BroadcastReceiver {private final Object pmSvc;private final Map<String, Object> mPackages;private final Object mSettings;@SuppressWarnings("unchecked")public PackagePermissions(Object pmSvc) {this.pmSvc = pmSvc;this.mPackages = (Map<String, Object>) getObjectField(pmSvc, "mPackages");this.mSettings = getObjectField(pmSvc, "mSettings");}/*这个函数主要hook了 PackageManager 服务(负责系统中Package的管理,应用程序的安装、卸载、信息查询),实现了通过监听我们自己发出的广播,拦截权限授予功能来进行修改apk的权限的*/public static void initHooks() {try {final Class<?> clsPMS = findClass("com.android.server.pm.PackageManagerService", XposedMod.class.getClassLoader());//获取这个PackageManager类//注册监听广播,监听我们的设置更改,以实现立即应用设置findAndHookMethod(clsPMS, "systemReady", new XC_MethodHook() {@Overrideprotected void afterHookedMethod(MethodHookParam param)throws Throwable {Context mContext = (Context) getObjectField(param.thisObject, "mContext");//这个应该是系统的上下文,具体待研究mContext.registerReceiver(new PackagePermissions(param.thisObject),new IntentFilter(Common.MY_PACKAGE_NAME + ".UPDATE_PERMISSIONS"),Common.MY_PACKAGE_NAME + ".BROADCAST_PERMISSION",null);//注册广播}});//拦截PackageManager类中的grantPermissionsLPw函数findAndHookMethod(clsPMS, "grantPermissionsLPw", "android.content.pm.PackageParser$Package", boolean.class,new XC_MethodHook() {@SuppressWarnings("unchecked")@Overrideprotected void beforeHookedMethod(MethodHookParam param) throws Throwable {String pkgName = (String) getObjectField(param.args[0], "packageName");if (!XposedMod.isActive(pkgName) || !XposedMod.prefs.getBoolean(pkgName + Common.PREF_REVOKEPERMS, false))return;Set<String> disabledPermissions = XposedMod.prefs.getStringSet(pkgName + Common.PREF_REVOKELIST, null);if (disabledPermissions == null || disabledPermissions.isEmpty())return;ArrayList<String> origRequestedPermissions = (ArrayList<String>) getObjectField(param.args[0], "requestedPermissions");param.setObjectExtra("orig_requested_permissions", origRequestedPermissions);ArrayList<String> newRequestedPermissions = new ArrayList<String>(origRequestedPermissions.size());for (String perm: origRequestedPermissions) {if (!disabledPermissions.contains(perm))newRequestedPermissions.add(perm);else// you requested those internet permissions? I didn't read that, sorryLog.w(Common.TAG, "Not granting permission " + perm+ " to package " + pkgName+ " because you think it should not have it");}setObjectField(param.args[0], "requestedPermissions", newRequestedPermissions);}@SuppressWarnings("unchecked")@Overrideprotected void afterHookedMethod(MethodHookParam param) throws Throwable {// restore requested permissions if they were modifiedArrayList<String> origRequestedPermissions = (ArrayList<String>) param.getObjectExtra("orig_requested_permissions");if (origRequestedPermissions != null)setObjectField(param.args[0], "requestedPermissions", origRequestedPermissions);}});} catch (Throwable e) {XposedBridge.log(e);}}@Overridepublic void onReceive(Context context, Intent intent) {try {// The app broadcasted a request to update settings for a running app// Validate the action being requestedif (!Common.ACTION_PERMISSIONS.equals(intent.getExtras().getString("action")))return;String pkgName = intent.getExtras().getString("Package");boolean killApp = intent.getExtras().getBoolean("Kill", false);XposedMod.prefs.reload();Object pkgInfo;synchronized (mPackages) {pkgInfo = mPackages.get(pkgName);callMethod(pmSvc, "grantPermissionsLPw", pkgInfo, true);callMethod(mSettings, "writeLPr");}// Apply new permissions if neededif (killApp) {try {ApplicationInfo appInfo = (ApplicationInfo) getObjectField(pkgInfo, "applicationInfo");if (Build.VERSION.SDK_INT <= 18)callMethod(pmSvc, "killApplication", pkgName, appInfo.uid);elsecallMethod(pmSvc, "killApplication", pkgName, appInfo.uid, "apply App Settings");} catch (Throwable t) {XposedBridge.log(t);}}} catch (Throwable t) {XposedBridge.log(t);}}
}
这段代码的地址
参考
1.AppSettingshook权限代码
2.Android5.1.1源码 - 添加应用权限
Hook框架集锦

原始思维导图文件下载
ProcessOn:Android-Hook框架集锦.pos
相关文章:
那些年的Xposed开发经验记录
把之前写的Xposed相关文章合并到一块,方便查阅 目录 多进程App的Hook问题XposedHelper中的静态变量demo的AndroidManifest.xml的测试核心代码结论限制handleLoadPackage被单个进程多次执行的问题 多dex Hook问题为应用增加权限利用Xposed删除权限参考 Hook框架集锦…...
android studio内存分析之Memory profiler的使用
目录 Android Studio中内存分析工具Memory profiler的使用1. 打开Memory Profiler2. 工具使用3. 内存选项说明4. 内存性能分析器概览5. 内存计算方式6. 查看内存分配7. 捕获java/kotlin方式查看内存分配8. 堆转储文件导入和导出 内存性能分析器中的泄漏检测 Android Studio中内…...
Qt下载慢/无法下载解决方式
文章目录 一. Qt在线安装下载二. 安装方式 一. Qt在线安装下载 官网下载:https://www.qt.io/download清华源下载:https://mirrors.tuna.tsinghua.edu.cn/qt/official_releases/online_installers/ 二. 安装方式 进入下载好的目录 在目录栏输入CMD&…...
【UE4 RTS】04-Camera Pan
前言 本篇实现了CameraPawn的旋转功能。 效果 步骤 1. 打开项目设置,添加两个操作映射 2. 打开玩家控制器“RTS_PlayerController_BP”,新建一个浮点型变量,命名为“PanSpeed” 在事件图表中添加如下节点 此时运行游戏可以发现当鼠标移动…...
出现raise NotImplementedError报错
在学习《动手学深度学习》时,实现下面代码时,报出raise NotImplementedError错误。 import collections import torch from d2l import torch as d2l import math from torch import nnclass Seq2SeqEncoder(d2l.Encoder):def __init__(self,vocab_size,…...
第一百二十二天学习记录:C++提高:STL-vector容器(上)(黑马教学视频)
vector基本概念 功能: vector数据结构和数组非常相似,也称为单端数组 vector与普通数组区别: 不同之处在于数组是静态空间,而vector可以动态扩展 动态扩展: 并不是在原空间之后续接新的空间,而是找更大的内…...
《Linux从练气到飞升》No.11 初识操作系统
🕺作者: 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux菜鸟刷题集 😘欢迎关注:👍点赞🙌收藏✍️留言 🏇码字不易,你的👍点赞🙌收藏❤️关注对我真的…...
什么是 XSS 攻击?
概念 XSS 攻击指的是跨站脚本攻击,是一种代码注入攻击。攻击者通过在网站注入恶意脚本,使之在用户的浏览器上运行,从而盗取用户的信息如 cookie 等。 XSS 的本质是因为网站没有对恶意代码进行过滤,与正常的代码混合在一起了&…...
基于Spring Boot的招聘网站的设计与实现(Java+spring boot+MySQL)
获取源码或者论文请私信博主 演示视频: 基于Spring Boot的招聘网站的设计与实现(Javaspring bootMySQL) 使用技术: 前端:html css javascript jQuery ajax thymeleaf 微信小程序 后端:Java springboot框…...
中级课程——CSRF
文章目录 案例原理挖掘 案例 原理 挖掘 挖掘详情 首先就是对目标敏感部位进行抓包分析,比如修改信息、转账、添加信息等等。通常一个数据包HTTP请求头里边都会有一个Referer,这个需要特别去验证。比如放到Burpsuit Repeater里边去测试:去掉…...
面试热题(岛屿数量)
给你一个由 1(陆地)和 0(水)组成的的二维网格,请你计算网格中岛屿的数量。 岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。 此外,你可以假设该网格的四条边均…...
【WebRTC---源码篇】(二十四)GCC获取码率后的分配
RtpTransportControllerSend::PostUpdates 配置码率 GoogCcNetworkController::GetPacingRates pacing_factor_默认2.5。也就是说pacer发送报文的码率是探测码率的2.5倍。 PacerConfig GoogCcNetworkController::GetPacingRates(Timestamp at_time) const {// Pacing rate …...
数据可视化工具LightningChart .NET正式发布v10.5.1——拥有全新的3D新功能
LightningChart.NET完全由GPU加速,并且性能经过优化,可用于实时显示海量数据-超过10亿个数据点。 LightningChart包括广泛的2D,高级3D,Polar,Smith,3D饼/甜甜圈,地理地图和GIS图表以及适用于科学…...
AWS认证SAA-C03每日一题
本题库由云计算狂魔微信公众号分享。 【SAA-C03助理级解决方案架构师认证】A company has a multi-tier application that runs six front-end web servers in an Amazon EC2 Auto Scaling group in a single Availability Zone behind an Application Load Balancer(ALB).A …...
ASP.NET Core MVC -- 将视图添加到 ASP.NET Core MVC 应用
Index页 右键单击“视图”文件夹,然后单击“添加”>>“新文件夹”,并将文件夹命名为“HelloWorld”。 右键单击“Views/HelloWorld”文件夹,然后单击“添加”>“新项”。 在“添加新项 - MvcMovie”对话框中: 在右上…...
基于R做宏基因组结果的PCoA分析
写在前面 因为公司给的PCA结果效果不佳,决定从中重新挑选部分样本进行再分析 步骤 表格结果预处理 在属水平genus参考原本结果已有的PCA图,尽可能挑选距离较远且聚团的样本 选取不同样本属水平的丰度数据,整理成逗号分隔的csv文件 代码…...
8.10 算法刷题【1道题】
8.10 算法刷题 22. 链表中环的入口结点(快慢指针) 22. 链表中环的入口结点(快慢指针) 原题链接 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode(int x) : val(x…...
Apache Maven:从构建到部署,一站式解决方案
目录 一、Maven介绍 1. Maven是什么? 2.Maven的作用? 二、Maven仓库介绍 2.1 库的分类 三、Maven安装与配置 3.1 Maven安装 3.2 Maven环境配置 3.3 仓库配置 四、Eclipse与Maven配置 五、Maven项目测试 5.1 新建Maven项目步骤及注意事项 5.…...
文章四:版本控制策略 - 穿越时光机:Git版本控制进阶技巧
开始本篇文章之前先推荐一个好用的学习工具,AIRIght,借助于AI助手工具,学习事半功倍。欢迎访问:http://airight.fun 概述 版本控制是Git的核心功能,它使得开发者可以记录代码的历史变更,并能够在不同版本…...
爬虫如何应对网站的反爬机制?如何查找user-agent对应的值
import requestsurl https://movie.douban.com/top250 response requests.get(url) # 查看结果 print(response)在requests使用一文中我们有讲到,当状态码不是200时表示爬虫不可用,也就是说我们获取不到网页源代码。但是我们还是可以挣扎一下ÿ…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
基于Springboot+Vue的办公管理系统
角色: 管理员、员工 技术: 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能: 该办公管理系统是一个综合性的企业内部管理平台,旨在提升企业运营效率和员工管理水…...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
webpack面试题
面试题:webpack介绍和简单使用 一、webpack(模块化打包工具)1. webpack是把项目当作一个整体,通过给定的一个主文件,webpack将从这个主文件开始找到你项目当中的所有依赖文件,使用loaders来处理它们&#x…...
