那些年的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时表示爬虫不可用,也就是说我们获取不到网页源代码。但是我们还是可以挣扎一下ÿ…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...
安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...
(一)单例模式
一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...
