Android最强进程保活黑科技实现原理解密及方法

2023-11-08

启动Service:

mRemote.transact(transactCode, mServiceData, null, 1);

在 native 层进行 binder 通信

在Java层做进程复活的工作,这个方式是比较低效的,最好的方式是在 native 层使用纯 C/C++来复活进程。方案有两个。

其一,维术大佬给出的方案是利用libbinder.so, 利用Android提供的C++接口,跟ActivityManagerService通信,以唤醒新进程。

  1. Java 层创建 Parcel (含 Intent),拿到 Parcel 对象的 mNativePtr(native peer),传到 Native 层。
  2. native 层直接把 mNativePtr 强转为结构体指针。
  3. fork 子进程,建立管道,准备传输 parcel 数据。
  4. 子进程读管道,拿到二进制流,重组为 parcel。

其二,Gityuan大佬则认为使用 ioctl 直接给 binder 驱动发送数据以唤醒进程,才是更高效的做法。然而,这个方法,大佬们并没有提供思路。

那么今天,我们就来实现这两种在 native 层进行 Binder 调用的骚操作。

方式一 利用 libbinder.so 与 ActivityManagerService 通信

上面在Java层复活进程一节中,是向ActivityManagerService发送特定的封装了Intent的Parcel包来实现唤醒进程。而在native层,没有Intent这个类。所以就需要在Java层创建好Intent,然后写到Parcel里,再传到Native层。

Parcel mServiceData = Parcel.obtain();
mServiceData.writeInterfaceToken(“android.app.IActivityManager”);
mServiceData.writeStrongBinder(null);
mServiceData.writeInt(1);
intent.writeToParcel(mServiceData, 0);
mServiceData.writeString(null); // resolvedType
mServiceData.writeInt(0);
mServiceData.writeString(context.getPackageName()); // callingPackage
mServiceData.writeInt(0);

查看[Parcel的源码](()可以看到,Parcel类有一个mNativePtr变量:

private long mNativePtr; // used by native code
// android4.4 mNativePtr是int类型

可以通过反射得到这个变量:

private static long getNativePtr(Parcel parcel) {
try {
Field ptrField = parcel.getClass().getDeclaredField(“mNativePtr”);
ptrField.setAccessible(true);
return (long) ptrField.get(parcel);
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}

这个变量对应了C++中[Parcel类](()的地址,因此可以强转得到Parcel指针:

Parcel *parcel = (Parcel *) parcel_ptr;

然而,NDK中并没有提供binder这个模块,我们只能从Android源码中扒到binder相关的源码,再编译出libbinder.so。腾讯TIM应该就是魔改了binder相关的源码。

提取libbinder.so

为了避免libbinder的版本兼容问题,这里我们可以采用一个更简单的方式,拿到binder相关的头文件,再从系统中拿到libbinder.so,当然binder模块还依赖了其它的几个so,要一起拿到,不然编译的时候会报链接错误。

adb pull /system/lib/libbinder.so ./
adb pull /system/lib/libcutils.so ./
adb pull /system/lib/libc.so ./
adb pull /system/lib/libutils.so ./
复制代码

如果需要不同SDK版本,不同架构的系统so库,可以在 [Google Factory Images](() 网页里找到适合的版本,下载相应的固件,然后解包system.img(需要在windows或linux中操作),提取出目标so。

binder_libs
├── ar

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android最强进程保活黑科技实现原理解密及方法 的相关文章

随机推荐

  • ChatGPT/GPT4开源“平替”汇总

    寻找那些ChatGPT GPT4开源 平替 们 ChatGPT爆火出圈 国内很多高校 研究机构和企业都发出类似ChatGPT的发布计划 ChatGPT没有开源 复现难度极大 即使到现在GPT3的完全能力也没有任何一个单位或者企业进行了复现
  • openvswitch--OpenFlow 流表设置

    流规则组成 每条流规则由一系列字段组成 分为基本字段 条件字段和动作字段三部分 基本字段包括生效时间duration sec 所属表项table id 优先级priority 处理的数据包数n packets 空闲超时时间idle time
  • Windows 8 Metro Stype App 学习笔记(五)--文件操作

    Windows 8 Metro Style App中文件操作都包含在Windows Storage命名空间中 其中包括StorageFolder StorageFile FileIO等类库 文件对象用StorageFile实现 文件头用St
  • 001 Python数据可视化之折线图

    话说 人是视觉的动物 本文从可视化入手来展现数据 试想一场景 某制造业工厂的CEO想了解两种成品的次品数及次品率 进而进行下一步决策 对于应用 excel在一定程度上可满足 如下图 对于开发 Python 1 2 作为受众度高的语言 3 在
  • AI实战:docker中用TensorBroad可视化模型训练过程

    前言 TensorBoard是TensorFlow自带的一个强大的可视化工具 目前支持7种可视化 Scalars Images Audio Graphs Distributions Histograms 和 Embeddings 主要功能如
  • 在C++中 char 到底是什么类型?

    在C 中 char 是一个用来表示字符的整数数据类型 它通常占据一个字节 8位 用于存储单个字符的ASCII码或其他字符编码的值 char 类型可以用于表示字符 比如字母 数字 标点符号等 每个字符在计算机内部都有一个对应的整数值 这个值可
  • 机器学习--使用朴素贝叶斯进行垃圾邮件分类

    一 学习背景 垃圾邮件的问题一直困扰着人们 传统的垃圾邮件分类的方法主要有 关键词法 和 校验码法 等 然而这两种方法效果并不理想 其中 如果使用的是 关键词 法 垃圾邮件中如果这个关键词被拆开则可能识别不了 比如 中奖 如果被拆成 中 奖
  • 学习Vue3第一天

    一 Vue简介 Vue是一款用于构建用户界面的 JavaScript 框架 它基于标准 HTML CSS 和 JavaScript 构建 并提供了一套声明式的 组件化的编程模型 帮助你高效地开发用户界面 无论是简单还是复杂的界面 Vue 都
  • Linux中的NFS共享

    1 NFS服务介绍 1 1什么是NFS服务 一 NFS工作原理 1 什么是NFS服务器 NFS就是Network File System的缩写 它最大的功能就是可以通过网络 让不同的机器 不同的操作系统可以共享彼此的文件 NFS服务器可以让
  • tr linux中文,linux中的tr用法详解

    tr命令可以对来自标准输入的字符进行替换 压缩和删除 它可以将一组字符成另一组字符 经常用来编写优美的单行命令 作用很强大 tr 选项 参数 c或 complerment 取代所有不属于第一字符集的字符 d或 delete 删除所有属于第一
  • Vysor 1.7.6 chrome 插件破解

    在你的Chrome扩展文件里面 找到 名为uglify js的文件 我的文件地址 C Users jin AppData Local Google Chrome User Data Default Extensions gidgenkbba
  • 数据库------DML操作

    DML的操作 数据操纵语言 指的是对表中的数据的增 删和改操作 添加数据 insert into 不推荐 方式一 insert into
  • python文字游戏源代码求年纪_Python实现猜年龄游戏代码实例

    1 在猜年龄的基础上编写登录 注册方法 并且把猜年龄游戏分函数处理 如 2 登录函数 3 注册函数 4 猜年龄函数 5 选择奖品函数 代码如下 import json real age 18 prize list 好迪洗发水 绿箭侠 小猪佩
  • 数据挖掘简介及模型介绍(一)

    1 简介 大数据时代正在唤醒企业通过利用客户数据获得竞争优势的机会 数据的广泛使用性和高度复杂性让仅使用传统决策技术来盈利变成不可能 这些传统方法主要使用电子表格 数据库查询和其它商业智能工具 另外 人们对从大数据中提取的有用信息和知识方法
  • CDH 是什么

    CDH 是由 Cloudera 公司构建 的Hadoop 稳定发行版 一 痛点 一个产品的出现肯定是为了解决用户的痛点 在大数据领域 我们这些使用Hadoop Hive Hbase等的开发者来说就是其用户 如果使用原生的ApacheHado
  • 【vue】安装vue3.X版本脚手架(图形化界面版)

    安装脚手架之前需要电脑已安装node与npm 首先按住 shift 鼠标右键 按下 在此处打开命令行窗口 进入命令行窗口 或者 win R 键 输入cmd 进入命令行窗口 输入 node v 与 npm v 查看有无安装node与npm 没
  • java JDK 环境配置教程

    最近在学习java 下面将window10系统为例配置Java JDK环境 1 右键单击此电脑进入属性 2 在打开的界面中选择高级系统设置 3 在系统属性中选中高级 之后点击环境变量 4 将安装的jdk路径复制 5 点击新建系统变量 6 将
  • 两个变量数据交换的方法

    这里给出了3个方法用来交换两个变量数据 1 最常见的创建一个临时变量来交换两个变量的数据 int a 1 b 2 int temp temp a a b b temp 这样就能通过创建的临时变量temp将变量a和b中的值进行交换 2 要是觉
  • node 报错 throw er; // Unhandled 'error' event 解决办法

    node 报错 Starting child process with node web js events js 183 throw er Unhandled error event Error listen EADDRINUSE 800
  • Android最强进程保活黑科技实现原理解密及方法

    启动Service mRemote transact transactCode mServiceData null 1 在 native 层进行 binder 通信 在Java层做进程复活的工作 这个方式是比较低效的 最好的方式是在 nat