充电有喜分析

参考相关应用

  1. 华为市场 -> 充电有喜2.0.1
  2. 网络查找 -> 充电有喜1.0.0 http://www.xz7.com/downinfo/609008.html
  3. 反编译app有个文字漏洞,找到 来福充电宝 https://sj.qq.com/appdetail/com.evenhaexplo.courte

需要解决的问题

  1. 电源插拔注册
  2. 为什么需要悬浮窗权限
  3. 后台弹窗实现
  4. 锁屏显示权限

最后的总结

  1. 在壁纸Fragment中监听电源插拔
  2. 有个后台弹出权限,保证弹出来
  3. android.permission.BIND_NOTIFICATION_LISTENER_SERVICE 有一定程度的保活(弱)
  4. (不在项目中)android-keeplive
  5. AndroidKeepAlive

组件化总结

  1. ARouter
  2. BinderHook(https://github.com/pinggle/binderHook)
    Android插件化原理解析——Hook机制之Binder Hook https://weishu.me/2016/02/16/understand-plugin-framework-binder-hook/

其他相关

  1. DSBridge-Android https://github.com/wendux/DSBridge-Android
  2. ijkplayer播放 ‘tv.danmaku.ijk.media:ijkplayer-java:0.8.8’
  3. stringfog 字符串加密

说明:

  1. 定向分析,只找到了上面的总结相关
  2. 还需要非定向分析(即一个包一个包找,需要花些时间)

步骤

使用apkHelper分析基本信息

在这里插入图片描述
com.dwelliembos.equivo

1. 用jadx和GDA打开apk,分析基本信息

jadx

GDA
在这里插入图片描述

通过frida脚本down下内存中的dex

frida -U -f com.xxx.xxx.xxx -l dupDex.js
在相对应的目录下找到生成的dex

分析监听电源插拔,电量变化

在这里插入图片描述
在这里插入图片描述
追溯到CommonWebFragment
在这里插入图片描述
想找CommonWebFragment出现在哪里,目测应该是通用的一个
找到Activity -> com.luoli.oubin.web.CommonWebAct

问题:

  1. CommonWebAct是什么时候调用的

  2. 作用是什么,UI是否透明

	有注册
  <activity android:name="com.luoli.oubin.web.CommonWebAct" ></activity>

package com.luoli.oubin.web.js.BaseWebInterface;
在这里插入图片描述
CommonWebView

在这里插入图片描述
com.dwelliembos.equivo.oOOO00o
找到一些加载的URL
在这里插入图片描述
o0o000Oo.o0o000Oo.o0OO0O0.o0OO0O0

无意间找到首页

在这里插入图片描述
找到几个网址:
https://bd.chengyudatiaozhan.com/update_frontend_service/index?infoId=8d6bb4fe325e4261ae8f161db4e0c88b
在这里插入图片描述
https://bd.chengyudatiaozhan.com/update_frontend_service/index?infoId=e8287ca4a20d4d1abb247857338b85a8
在这里插入图片描述
用户协议 https://docs.qq.com/doc/DQXB5bFZCQWNPVlZz
隐私协议 https://docs.qq.com/doc/DQVJFQVhDd3dNY1pG

MainActivity

在这里插入图片描述
this.setContentView(0x7f0c0025);
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

多个Fragment

  1. 首页 new o00oooo(),
    在这里插入图片描述
    主页的主内容
    在这里插入图片描述
    在这里插入图片描述
    0x7f0c006

.field public static final fragment_home:I = 0x7F0C0066
在这里插入图片描述
重点在Reclerview

但是,并没有找到CommonWebFragment相关的?

  1. 壁纸 new oOOO00o(),
    在这里插入图片描述

  2. 福气 new oo0o0oO(),

  3. 我的 new o00o0oO0(

回到正题,找到CommonWebFragment

在壁纸Fragment中监听了插拔信息

找到了 com.air.wallpaper.realpage.details.view.real.ChargeWallPaperActivity@e9b63bf

android.permission.BIND_NOTIFICATION_LISTENER_SERVIC

Android 通知监听服务、NotificationListenerService使用方式(详细步骤+源码) 原创
https://blog.51cto.com/u_15117645/5669824

Android NotificationListenerService通知监听服务使用
https://www.jb51.net/article/267863.htm

        <service android:name="com.test.rommatch.service.NotificationService" android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" >
            <intent-filter >
                <action android:name="android.service.notification.NotificationListenerService" ></action>
            </intent-filter>
        </service>

悬浮窗权限

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" ></uses-permission>

Android app打开系统界面设置悬浮窗权限
https://blog.csdn.net/niuba123456/article/details/120197603

不同机型判断悬浮窗权限
android window浮窗 安卓10悬浮窗适配 转载
https://blog.51cto.com/u_16213635/7853449

后台弹出壁纸

  1. 找监听电源插拔ACTION_POWER_CONNECTED

  2. 在这里插入图片描述

  3. 跳转到LazyWallpaperActivity
    在这里插入图片描述

  4. 清单文件中

<activity android:name="com.whiaz.wall.LazyWallpaperActivity" android:launchMode="3" android:screenOrientation="1" android:configChanges="0x000004a0" ></activity>
  1. WallpaperLayoutManager
    自定义的

  2. LazyWallpaperActivity的界面
    在这里插入图片描述

  3. R$layout.activity_wallpaper_details
    在这里插入图片描述

  4. 设置壁纸界面
    在这里插入图片描述

  5. 弹出ChargeWallPaperActivity
    在这里插入图片描述
    应该是组件化策略Arouter
    在这里插入图片描述

  6. 找到Arouter的这个
    在这里插入图片描述

  7. 静态代码跳转的设置壁纸界面, 但弹出框是ChargeActivity。两个不一样。有问题??

  8. LazyWallpaperActivity
    在这里插入图片描述

找保活相关

com.dwelliembos.equivo.App

在v2.0.1中
在这里插入图片描述

解决思路

1. 都需要什么权限

在这里插入图片描述
来福充电宝~~~

找到权限弹窗LazyWxShowPermissionActivity

adb shell dumpsys activity top
在这里插入图片描述

跳转到悬浮窗权限

public interface abstract o000o000	// class@001156 from classes.dex
{

    default static void o0OO0O0(Activity p0,int p1){
       if (Build$VERSION.SDK_INT >= 23) {
          Intent intent = new Intent("android.settings.action.MANAGE_OVERLAY_PERMISSION");
          intent.setData(Uri.parse("package:"+p0.getPackageName()));
          p0.startActivityForResult(intent, p1);
       }
       return;
    }
}

PERMISSION_HAD_GRANTED_BACKGROUND

android 10+从后台启动 Activity 的限制
https://blog.csdn.net/xiaoyantan/article/details/128401740
android 系统权限授权 安卓授权管理
https://blog.51cto.com/u_12228/6575401

在这里插入图片描述

class LazyWxShowPermissionActivity$o0OO0O0 implements oOO0oo00	// class@001123 from classes.dex
{
    final LazyWxShowPermissionActivity o0OO0O0;

    void LazyWxShowPermissionActivity$o0OO0O0(LazyWxShowPermissionActivity p0){
       this.o0OO0O0 = p0;
       super();
    }
    public void o0OO0O0(){
       LazyWxShowPermissionActivity.o0Ooo0(this.o0OO0O0).oOO0oo00.setSelected(false);
       oo0oOO0.oOOOooOO("开启后台弹出权限失败,请重试");
    }
    public void oOO0oo00(){
       ActivityManager systemServic = this.o0OO0O0.getSystemService("activity");
       boolean b = (Build$VERSION.SDK_INT >= 28)? systemServic.isBackgroundRestricted(): true;
       if (oOOo0OO0.o00o0oOO()) {
          LazyWxShowPermissionActivity.o0Ooo0(this.o0OO0O0).oOO0oo00.setSelected(true);
          oOOo0000.o0OO0O0.o0o000Oo("PERMISSION_HAD_GRANTED_BACKGROUND", true);
          return;
       }else if(ooooooO0.o0o0OOoO()){
          LazyWxShowPermissionActivity.o0Ooo0(this.o0OO0O0).oOO0oo00.setSelected(true);
          oOOo0000.o0OO0O0.o0o000Oo("PERMISSION_HAD_GRANTED_BACKGROUND", true);
       }
       if (!b) {
          LazyWxShowPermissionActivity.o0Ooo0(this.o0OO0O0).oOO0oo00.setSelected(true);
          oOOo0000.o0OO0O0.o0o000Oo("PERMISSION_HAD_GRANTED_BACKGROUND", true);
       }else {
          LazyWxShowPermissionActivity.o0Ooo0(this.o0OO0O0).oOO0oo00.setSelected(false);
          ToastUtils.oo00O00o("开启后台弹出权限失败,请重试");
       }
       return;
    }
}

Android 判断后台运行权限是否开启

https://blog.51cto.com/u_16213369/7650688

Android 取消后台运行限制

https://www.jianshu.com/p/1e75b9fb71d2
workmanager

<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />

如何设置壁纸

❌只是一个弹窗,并不是概念上的壁纸功能,所以后台弹窗是很重要的
VideoWallpaperService
com.whiaz.wall.VideoWallpaperService

        <service android:name="com.whiaz.wall.VideoWallpaperService" android:permission="android.permission.BIND_WALLPAPER" >
            <intent-filter >
                <action android:name="android.service.wallpaper.WallpaperService" ></action>
            </intent-filter>
            <meta-data android:name="android.service.wallpaper" android:resource="@xml/wallpaper" ></meta-data>
        </service>

保活库AndroidKeepAlive

https://github.com/fgkeepalive/AndroidKeepAlive

Android进程保活实战经验(已经上线使用)

https://blog.51cto.com/u_16353097/8775791

https://github.com/08carmelo/android-keeplive

https://github.com/08carmelo/android-keeplive

不同的手机有不同的策略

在这里插入图片描述
不断地点进去,都可以找到相应的手机型号
在这里插入图片描述
在这里插入图片描述

锁屏显示弹窗

How to enable ‘show in lock screen’ permission in andriod
https://stackoverflow.com/questions/60478065/how-to-enable-show-in-lock-screen-permission-in-andriod

getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON|
            WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD|
            WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED|
            WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);

public static void goToNotificationSettings(Context context) {
    Intent intent = new Intent();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        intent.setData(Uri.fromParts(SCHEME, context.getPackageName(), null));
    } else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1) {
        intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
        intent.putExtra("app_package", context.getPackageName());
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
        intent.putExtra("app_package", context.getPackageName());
        intent.putExtra("app_uid", context.getApplicationInfo().uid);
    } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {
        intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        intent.setData(Uri.parse("package:" + context.getPackageName()));
    } else {
        return;
    }
    context.startActivity(intent);
}

if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_NOTIFICATION_POLICY) != PackageManager.PERMISSION_GRANTED) {
        goToNotificationSettings(getActivity());
    }
    
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);



创建简单的 widget
https://developer.android.com/develop/ui/views/appwidgets?hl=zh-cn#lockscreen

Android开发艺术探索》第八章笔记.md
https://github.com/francistao/LearningNotes/blob/aa04b68b728a3505077f8d2a1ce931b758367b54/Part5/ReadingNotes/%E3%80%8AAndroid%E5%BC%80%E5%8F%91%E8%89%BA%E6%9C%AF%E6%8E%A2%E7%B4%A2%E3%80%8B%E7%AC%AC%E5%85%AB%E7%AB%A0%E7%AC%94%E8%AE%B0.md?plain=1#L17

监听插入电源

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.util.Log

object ChargingMonitor {
    val TAG = ChargingMonitor::class.simpleName
    private val callbacks = CopyOnWriteArrayList<Callback>()
    private val intentFilter = IntentFilter().apply {
        addAction(Intent.ACTION_POWER_CONNECTED)
        addAction(Intent.ACTION_POWER_DISCONNECTED)
        priority = 1000
    }

    init {
        MyApp.application.registerReceiver(object : BroadcastReceiver {
            override fun onReceive(context: Context, intent: Intent) {
                Log.i(TAG, "ChargingMonitor 有广播到了 action=${intent.action}!")
                if (intent.action == Intent.ACTION_POWER_CONNECTED) {
                    callbacks.forEach { callback -> callback.onCharging(true) }
                } else {
                    callbacks.forEach { callback -> callback.onCharging(false) }
                }
            }
        }, intentFilter)
        Log.i(TAG, "注册监听电源插拔成功!")
    }

    fun init() = Unit

    fun addCallback(callback: Callback) {
        callbacks.add(callback)
    }

    fun removeCallback(callback: Callback) {
        callbacks.remove(callback)
    }

    interface Callback {
        fun onCharging(isCharging: Boolean)
    }
}

AndroidManifest.xml文件中的权限可以一一分析

    <uses-permission android:name="android.permission.INTERNET" ></uses-permission>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" ></uses-permission>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" ></uses-permission>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" ></uses-permission>
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" ></uses-permission>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" ></uses-permission>
    <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" ></uses-permission>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" ></uses-permission>
    <uses-permission android:name="android.permission.READ_PHONE_STATE" ></uses-permission>
    <uses-permission android:name="android.permission.GET_TASKS" ></uses-permission>
    <uses-permission android:name="android.permission.WAKE_LOCK" ></uses-permission>
    <uses-permission android:name="android.permission.SET_WALLPAPER" ></uses-permission>
    <uses-permission android:name="android.permission.SET_WALLPAPER_HINTS" ></uses-permission>
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" ></uses-permission>
    <uses-permission android:name="android.permission.REORDER_TASKS" ></uses-permission>
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" ></uses-permission>
    <uses-permission android:name="android.permission.READ_SETTINGS" ></uses-permission>
    <uses-permission android:name="android.permission.WRITE_SETTINGS" ></uses-permission>
    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" ></uses-permission>
    <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" ></uses-permission>
    <uses-permission android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" ></uses-permission>
    <uses-permission android:name="oppo.permission.OPPO_COMPONENT_SAFE" ></uses-permission>
    <uses-permission android:name="com.huawei.permission.external_app_settings.USE_COMPONENT" ></uses-permission>

MessengerUtils.java

https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/src/main/java/com/blankj/utilcode/util/MessengerUtils.java

很多使用的方法
https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/README-CN.md

额外分析

在这里插入图片描述

资料

多个dex文件合成方法

https://zhuanlan.zhihu.com/p/681385679
在这里插入图片描述

光环助手

com.sensorsdata.analytics.android.sdk.remote.SensorsDataRemoteManagerDebug

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

赵健zj

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

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

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

打赏作者

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

抵扣说明:

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

余额充值