测试apk-异常管控autostart攻击者开发

1. 目的

基于《软件绿色联盟应用体验标准》中autostart资源的定义,进autostart频繁次数的测试apk。旨在触发手机中异常功耗管控机制。
自启动高耗电提醒

本方案需要2个APP协同工作,具体工作原理:

  1. APP1 作用:负责自杀和被冷启动
  2. APP2 作用:负责定时复活APP1,触发冷启动检测

红线标准:半小时内的频繁冷启动次数检测,阈值20次以上。
策略介绍

2. 测试步骤

H手机和T手机、其他手机进行安装该apk.
所有手机都需要设置应用为白名单。

2.1 手机白名单设置方法:

手机管家->应用启动设置:允许自启动、允许关联启动、允许后台启动

H手机白名单

T手机:手机管家->自启动管理:允许自启动

2.2 运行本apk

只需运行APP2,作用:负责定时复活APP1,触发冷启动检测

保持APP2前台显示。至少等待400秒以上。观察通知栏是否有高耗电提醒

红线标准:半小时内的频繁冷启动次数检测,阈值20次以上。
自启动高耗电提醒

2.3 日志查看

使用命令模拟拔掉USB的技巧,先发如下命令,再插拔一下USB数据线即可
adb shell dumpsys battery unplug

日志关键字:APwTrigger|APwLevelAnalysis|APwActAnalysis|startDeaderApp startForegroundService count=|AutoStartDeaderService onDestroy|AutoStartDeaderService onCreate|AutoStartDeaderService killCount

2022-05-18 17:29:51.633 2614-2978/com.huawei.iaware D/APwTrigger: start bg process:com.sufadi.blockautostart_deader reason:service pid:14604 uid:10160 count:19
2022-05-18 17:29:51.633 2614-2978/com.huawei.iaware I/APwLevelAnalysis: frequently auto start app: com.sufadi.blockautostart_deader count:20 duration:366667 level:2 // 检测到冷启动20次
2022-05-18 17:29:51.634 2614-2978/com.huawei.iaware I/APwActAnalysis: auto start high power app : com.sufadi.blockautostart_deader count:20 totalTime:366667// 高耗电提醒

3. apk 源码

3.1 APP1 负责启动后自杀

3.2.1 UI

app1

3.1.2 核心逻辑

主要都需要设置为前台进程属性,服务的逻辑是收到 APP2 的kill Action 后,延迟5秒执行自杀

package com.sufadi.blockautostart_deader

import android.app.*
import android.content.Context
import android.content.Intent
import android.os.*
import android.util.Log
import com.sufadi.commlib.R

/**
 * adb shell am force-stop com.sufadi.blockautostart
 * adb shell am start-foreground-service -n com.sufadi.blockautostart_deader/com.sufadi.blockautostart_deader.AutoStartDeaderService
 *
 *while true;am force-stop com.sufadi.blockautostart_deader;do sleep 5;am start-foreground-service -n com.sufadi.blockautostart_deader/com.sufadi.blockautostart_deader.AutoStartDeaderService;done;
 */
class AutoStartDeaderService: Service() {

    val TAG = "AutoStartDeaderService"
    val FORGROUND_ID = 0x99

    private var killCount = 0
    var workHandler: WorkHandler?= null


    override fun onBind(p0: Intent?): IBinder? {
        return null
    }

    override fun onCreate() {
        Log.d("AutoStart", "AutoStartDeaderService onCreate")

        val workThread = HandlerThread("work thread")
        workThread.start()

        workHandler = WorkHandler(workThread.looper)

        startMyForeground()
        super.onCreate()
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        if ("kill_app" == intent?.action) {
            killCount = intent.getIntExtra("kill_count", 0)
            Log.d("AutoStart", "AutoStartDeaderService killCount:$killCount")
            if (killCount < 20) {
                workHandler?.removeMessages(1)
                workHandler?.sendEmptyMessageDelayed(1, 5000)
            }
        }
        return super.onStartCommand(intent, flags, startId)
    }

    override fun onDestroy() {
        Log.d("AutoStart", "AutoStartDeaderService onDestroy")
        stopForeground(true)
        super.onDestroy()
    }

    fun killAppProcess() {
       Log.d("AutoStart", "AutoStartDeaderService Kill killAppProcess")
        //注意:不能先杀掉主进程,否则逻辑代码无法继续执行,需先杀掉相关进程最后杀掉主进程
        val mActivityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
        val  mList = mActivityManager.runningAppProcesses
        for (runningAppProcessInfo in mList) {
            if (runningAppProcessInfo.pid != android.os.Process.myPid()) {
                android.os.Process.killProcess(runningAppProcessInfo.pid)
                Log.d("AutoStart", "Kill killAppProcess pid ${runningAppProcessInfo.pid}")
            }
        }
        android.os.Process.killProcess(android.os.Process.myPid())
        System.exit(0)
    }

    inner class WorkHandler(looper: Looper): Handler() {

        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            stopForeground(true)
            killAppProcess()
        }
    }

    private fun startMyForeground() {
        Log.d(TAG, "startMyForeground show notification")
        Log.d(TAG, "PhoneDataService startMyForeground sdk :" + android.os.Build.VERSION.SDK_INT)
        val nb = Notification.Builder(this)

        if (android.os.Build.VERSION.SDK_INT >= 26) {
            val CHANNEL_ONE_ID = "channel_id_foreground"
            val CHANNEL_ONE_NAME = "Channel One"
            var notificationChannel: NotificationChannel? = null

            notificationChannel = NotificationChannel(
                CHANNEL_ONE_ID,
                CHANNEL_ONE_NAME, NotificationManager.IMPORTANCE_LOW
            )

            nb.setChannelId(CHANNEL_ONE_ID)

            val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            manager.createNotificationChannel(notificationChannel)
        }

        nb.setSmallIcon(R.mipmap.ic_launcher)
        nb.setContentTitle(getString(R.string.notification_title))
        nb.setContentText(getString(R.string.notification_Content))

        try {
            startForeground(FORGROUND_ID, nb.build())
        } catch (e: Exception) {
            e.printStackTrace()
        }

    }
}

3.2 APP2 负责定时复活APP1,触发冷启动检测

3.2.1 UI

APP2

package com.sufadi.blockautostart_doctor

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.sufadi.commlib.services.ForegroundService

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        startService(Intent(this, AutoStartDoctorService::class.java))
    }
}

3.2.2 核心逻辑

主要都需要设置为前台进程属性,服务的逻辑:每个20秒定时通过startService的方式启动 APP1

package com.sufadi.blockautostart_doctor

import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.content.Context
import android.content.Intent
import android.os.*
import android.util.Log
import com.sufadi.commlib.R

class AutoStartDoctorService : Service(){

    val TAG = "AutoStartDoctorService"
    val FORGROUND_ID = 0x77

    var workHandler: WorkHandler?= null
    var count = 0

    override fun onBind(p0: Intent?): IBinder? {
        return null
    }

    override fun onCreate() {
        super.onCreate()

        val workThread = HandlerThread("work thread")
        workThread.start()

        workHandler = WorkHandler(workThread.looper)
        workHandler?.removeMessages(1)
        workHandler?.sendEmptyMessageDelayed(1, 20000)

        startMyForeground()
    }

    override fun onDestroy() {
        super.onDestroy()
        stopForeground(true)
    }

    inner class WorkHandler(looper: Looper): Handler() {

        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            startDeaderApp()
            workHandler?.removeMessages(1)
            workHandler?.sendEmptyMessageDelayed(1, 20000)
        }
    }

    /**
     * adb shell am force-stop com.sufadi.blockautostart
     * adb shell am start-foreground-service -n com.sufadi.blockautostart_deader/com.sufadi.blockautostart_deader.AutoStartDeaderService
     * while true;am force-stop com.sufadi.blockautostart_deader;do sleep 5;am start-foreground-service -n com.sufadi.blockautostart_deader/com.sufadi.blockautostart_deader.AutoStartDeaderService;done;
     * adb shell am start -n com.sufadi.blockautostart_deader/com.sufadi.blockautostart_deader.MainActivity
     */
    fun startDeaderApp() {
        count++
        Log.d("AutoStart", "startDeaderApp startForegroundService count=$count")
        val intent = Intent()
        intent.setClassName("com.sufadi.blockautostart_deader", "com.sufadi.blockautostart_deader.AutoStartDeaderService")
        if (count > 400) {
            count = 0
        } else if(count > 20) {
            intent.action = "startDeaderApp"
        } else {
            intent.action = "kill_app"
            intent.putExtra("kill_count", count)
        }
        startForegroundService(intent)
    }

    private fun startMyForeground() {
        Log.d(TAG, "startMyForeground show notification")
        Log.d(TAG, "PhoneDataService startMyForeground sdk :" + android.os.Build.VERSION.SDK_INT)
        val nb = Notification.Builder(this)

        if (android.os.Build.VERSION.SDK_INT >= 26) {
            val CHANNEL_ONE_ID = "channel_id_foreground"
            val CHANNEL_ONE_NAME = "Channel One"
            var notificationChannel: NotificationChannel? = null

            notificationChannel = NotificationChannel(
                CHANNEL_ONE_ID,
                CHANNEL_ONE_NAME, NotificationManager.IMPORTANCE_LOW
            )

            nb.setChannelId(CHANNEL_ONE_ID)

            val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            manager.createNotificationChannel(notificationChannel)
        }

        nb.setSmallIcon(R.mipmap.ic_launcher)
        nb.setContentTitle(getString(R.string.notification_title))
        nb.setContentText(getString(R.string.notification_Content))

        try {
            startForeground(FORGROUND_ID, nb.build())
        } catch (e: Exception) {
            e.printStackTrace()
        }

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

法迪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值