吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 11100|回复: 65
收起左侧

[Android 原创] [玩转APP之三]绝不杀后台之变态保活(卸载了APP还能运行)

  [复制链接]
陈司机 发表于 2021-1-12 21:05
本帖最后由 陈司机 于 2021-1-13 08:34 编辑

前面文章:
[玩转App之一] 利用ROOT权限或Xposed随意对apk进行保资料降级
[玩转APP之二 ] Xposed对手机App进行安装卸载或升级限制
如需转载,请获得允许。

记得在读高中的时候,那回刚刚安卓系统刚刚火起来,那回手机性能还不够,划开后台列表下面并不是理解后台运行而是写着最近任务四个小字,但是有时候,它又能真的后台运行,去uc浏览器看看网页,回到QQ是不用重新打开的,但很多时候,又需要重新打开,真是个谜。

基础:
每个进程对应一个进程pid,
在linux系统中,在操作系统内核,都会维护一个值oom_adj的值,
这个值会根据系统资源情况,用户当前使用情况进行动态调整。
这个值越低,越不容易被系统杀死,如果足够低,在某种程度可做到与系统进程同生共死,即我要是运行不了,就死机给你看。
安卓基于linux, 也有这样一个值, 但是也有自己的特色,就是由ActivityManagerService(AMS)去维护管理这个值。
听起来,AMS是活动管理器,但是AMS是管理着应用的生杀大权的,我们在手机桌面点击一个图标,如果应用未启动,是会由AMS去启动进程的,这样想起来,AMS管理oom_adj是理所应当的。

怎样查看自己应用的oom_adj呢?我们以咸鱼为例

ps -A | grep com.taobao.idlefish 
cat /proc/pid/oom_adj

我们可以观察发现,
当闲鱼APP在前台的时候,看到oom_adj为0
当我们退到后台,随便打开某其它应用吧,oom_adj一下子掉到6了

我们看下桌面进程com.miui.home吧,发现它是2
所以说,系统进程虽然也在后台,但是它优先级还是挺高的。

再看下更重要的zygote进程,它的oom_adj是-17

假如我们有root权限,能不能直接把值写入内核空间呢,答案是可以的。

echo -1 > /proc/pid/oom_adj

但是,它只能生效那么一会,前面说了,oom_adj是由活动大管家动态调整的,你退一下到后台,大管家会重新给你刷新一下,手机电量不够了,内存不够了,大管家都会给我们的应用重新贴标签。你是重要的,你是不太重要的。请拿着这个oom_adj,内存不够了,先把高的给斩首示众了,告诉广大应用们,手机各项资源是稀缺的,谁不听话老占内存,老占网络又耗电什么又不做点"产出高的事情"或”不可或缺“就该死。

实践
1.在AMS调整oom_adj的过程中,拦截它,改它结果。
2.不断地刷新oom_adj的值,防止被覆盖。
3.研究发现,oom_adj存放在processRecord实例中。

val processRecords = mutableSetOf<Any>()

// 这里我们把闲鱼和加入到保活白名单
val lockPackageList = setOf("com.taobao.idlefish", "com.netease.cloudmusic")
hookAllMethods("com.android.server.am.ActivityManagerService.newProcessRecordLocked") {
        after { m ->
                try {
                        changeAppInfoForLockPackage(m.result, -12) // 弄成-12
                }catch (e:Throwable){
                        Log.e(Tag, "newProcessRecordLocked" + e.stackTraceString)
                }
        }
}

private fun changeAppInfoForLockPackage(processRecord: Any, oomAdjValue:Int) {
        if (processRecord.toString().contains("system")) return
        Log.d(Tag, "!@@ >>>> $processRecord")
        val info = processRecord.get<ApplicationInfo>("info")!!
        val processName = processRecord.get<String>("processName")!!
    // 注意,只保活主进程就够了,其它子进程的优先级自然会被拉起来
        lockPackageList.firstOrNull {  info.packageName == it && processName == it }?.let {
                setAdj(processRecord, oomAdjValue)
                setPersistent(processRecord)
                processRecords.add(processRecord)
        }
        if (!thread.isAlive) thread.start()
}

// 这个设置小了就能逍遥自在,无论怎么吃内存吃电也不会被大管家斩首示众
fun setAdj(processRecord: Any, value: Int) {
        processRecord.set<Int>("maxAdj", value)
}

// 设置了这个就能得永生,不小心死了也能被大管家复活
fun setPersistent(processRecord: Any) {
        if (Build.VERSION.SDK_INT < 29) {
                processRecord.set<Boolean>("persistent", true)
        }

        if (Build.VERSION.SDK_INT >= 29) {
                processRecord.call("setPersistent", true)
        }
}

效果
1.退到后台打开各种其它app,  尽情消耗内存,或者直接后台点停止运行,目标应用依然纹丝不动,打开后仍是上次的界面。
2.卸载网易云音乐,歌曲仍在播放,为什么卸载了还能运行,因为卸载前已经把有用的东东放内存了。一般路人甲应用卸载了,大管家会认为你不需要它了,会给它结束掉,但是要是被为重要应用,是不会被杀的。
3.kill -9 才能杀死,因为不属于AMS大管家管理

除了直接修改oom_adj的指,还有方法可以间接修改噢。
就是找一个应用程序开放的服务,在系统进程使用bindService把应用绑住,应用也能拿上免死卡。

原理写得不多,网上也有,我只给最关键的中间过程,大家有啥想聊的我再补充上。互相学习。

参考资料
Android系统进程优先级策略-ADJ

免费评分

参与人数 14威望 +1 吾爱币 +33 热心值 +12 收起 理由
ssdbmm + 1 + 1 谢谢@Thanks!
qtfreet00 + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
Nikke + 1 + 1 我很赞同!
fengbolee + 1 + 1 用心讨论,共获提升!
LukeThisGuy + 1 + 1 热心回复!
cka890712 + 1 + 1 用心讨论,共获提升!
KylinYang + 1 + 1 我很赞同!
坦然 + 1 + 1 用心讨论,共获提升!
左爷 + 1 鼓励转贴优秀软件安全工具和文档!
Lucifer_BW + 1 + 1 热心回复!
a501839212 + 1 + 1 用心讨论,共获提升!
易请惜 + 1 + 1 用心讨论,共获提升!
blackblock + 1 + 1 dalao牛逼!
zhang颈鹿 + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

slamdunk 发表于 2021-1-13 14:09
那请问楼主,不知道楼主有没有测试过,最新的miui12,系统资源被miui一些程序占用严重,官方发布会说的可以卸载,其实也只是隐藏,并且用一些目前的杀后台的软件,强制结束比如说相机等偶尔使用,不用常驻后台的应用,但是强制结束后,还是会唤醒,就是因为楼主所说的优先级的原因吗?有什么解决方式呢?
zzy大头鬼 发表于 2021-2-21 11:41
你好楼主,有几个问题想要请教:
1.光是hook newProcessRecordLocked方法应该不行吧?文章中也说了,在更新oom_adj时也会覆盖掉在newProcessRecordLocked方法中设置的值。
2.newProcessRecordLocked方法和updateOomAdjLocked这些方法都是final定义的,没办法复写,要如何hook?
3.api 29以后,新增了一个OomAdjuster类,该类是final类型,updateOomAdjLocked方法放到了此类。而newProcessRecordLocked方法放到了ProcessList类中,这时候该如何Hook?
xuexiba 发表于 2021-1-12 21:21
MSLOS 发表于 2021-1-12 21:23
我还以为是不用框架不用root实现结果是我想多了
 楼主| 陈司机 发表于 2021-1-12 21:42
MSLOS 发表于 2021-1-12 21:23
我还以为是不用框架不用root实现结果是我想多了

哈哈,你要自信,不用root不用框架那就得改系统了。要是能玩,大厂不早玩了。
bigdawn 发表于 2021-1-12 21:47
进来学习新技能。
km852753951 发表于 2021-1-12 22:55
牛啤啊大哥 学习了
m80571182 发表于 2021-1-12 23:00
学习学习,楼主威武
黑色魔方 发表于 2021-1-12 23:22
不错,学习了
Boyfri_End 发表于 2021-1-12 23:34
之前还不知道ps命令里面可以看活动优先级!
归海踏歌 发表于 2021-1-12 23:45
流啤 学习了
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 14:00

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表