分类 安卓开发 下的文章

安卓开发时的突发奇想

前言

由于搬家到了新的屋子,新的屋子客厅里有个电视,有一天与好友聊到如何利用起这个电视,好友提到他那边有一个闲置的Unifi Plus Box,来自于办理TM家宽的附带产品,历经几日之奔波,这个电视盒子最终到了我手上。

加注

感谢某位网友提供的关键数据,这个分析流程在基于Android12的新版Unifi Plus Box(创维HP43A)也可用,但有可能会被其自带的远控更新设置后变为不可用状态,请恢复出厂设置后再尝试。

特殊

到手后,发现其采用的是Amlogic S905L3B的SoC,有4核心A53,主频为1.8Ghz,2GB的运行内存和16GB的闪存,Android版本为9,在大多数电视盒子中都属于较高配置。
首先尝试执行系统更新,没想到居然接收到了更新到Android 10的大版本更新,对于我这种熟悉中国电视和电视盒子市场的人来说是颇为惊讶的,从来没有在这类型的设备上看到过有Android大版本更新。执行更新之后,发现了更多奇妙,于是则开始了以下的流程。

开发者选项密码?

正常情况下,如果想对这个盒子深挖,首要就是要打开USB调试,不管是无线还是有线调试。
然而当我尝试以正常方式打开开发者选项时,其弹出了一个与AOSP完全不同的密码输入界面。
UTVCK_Password1
当然目前是不知道实际的密码是什么的,其为什么会有个密码也不是很明确,也无法进行后续的分析了。

获取系统包

UTVCK_GetBFg
后来一天与另一位朋友闲聊,他跟我说他逆向了Google的OTA分发系统的API,问我有没有需求来测试一下,我就想到这个盒子系统更新时候的界面十分原生,其内置的阉割版本Google Play商店也可以下载到AIDA64来获取到当前软件版本的编译指纹,于是我就把编译指纹发给了这位朋友,于是得到了以下结果。

{
    "code": 200,
    "message": "success",
    "data": {
        "title": "New software version is now available. ",
        "url": "https://android.googleapis.com/packages/ota-api/package/xxxxxxxxxxxxxxxxxxxxxx.zip",
        "size": "803.6 MB",
        "size_num": 842585223,
        "fail": "Upgrade failed!",
        "inst": "Upgrade successfully!",
        "desc": "<b>A new software update is available.</b> <br>1. Fix issue Error code 01999 of unifi tv application <br> 2. Update Android TV security patch<br> <br><b>Note: The update may take up to 10 minutes to complete. You will not be able to use the TV during the update. Thank you for your patience.</b> <br>"
    }
}

(请私信我以取得完整链接以作他用)
成功拿到了完整的系统更新包!!

逆向TvSettings

首先我们打开获取到的ZIP包,依据个人经验,这类密码一般存在于系统设置之本体。
UTVCK_InsideOfPkg
所以首先从SYSTEM分区镜像中找到TvSettings的apk
UTVCK_GetTvSettings
找到之后,我们需要一个特征来找到这个密码部分
尝试在密码输入框内胡乱输入,其输出了一个有“Password is error!!”的Toast信息,我们就以此入手
UTVCK_PasswordErr
在Jadx中以字符串搜索Password is error这个字符串,很快得到了有效回应
UTVCK_JadxSearchStr
打开这个代码段后,得益于Jadx强大的反编译能力,我们看到了非常清晰的程序逻辑,查看这些判断语句,很容易就得到了密码。
UTVCK_JadxDecompiled
输入进密码输入框,开发者选项成功被启用!
UTVCK_DevSettingsPass

USB调试密码?

但是当尝试打开USB调试时,其又出现了跟前面一样密码输入框,输入上一个判定中得到的密码,又一次提示密码错误。
尝试找到了开发者模式中USB调试开关的逻辑,发现了一个额外的source判定
UTVCK_JadxFindAnotherSource
再混合前面所提到的逻辑语句得到的字符串密码,成功打开了USB调试!
UTVCK_ADBAuthPass

后记

以上则为这个电视盒子如何打开开发者选项和USB调试的办法了
其实历经以上分析,发现这个盒子还有个很特别的点,其几乎用了可谓是”围追堵截“的办法来屏蔽Netflix,关于这个事情如何解决,请等待我的后续更新了!

去年年底,借着一些关系联系到了小米电视的PM,直接反馈了一些问题之后,小米给我手头这个18年底就断更的机器更新了最终版本的更新,把大部分Bug和缺憾都做了补全,我很是满意。
但是发现从老版本更新到新版本之后,系统原生的设置不见了。还好老版本当中没有odex化系统App,所以可以直接拿出来安装后补全。不知道其他用户有没有需求,所以在此随便记录一下。
测试版本: 4A 32" matrix Android6.0.1 MIUITV1.3.89

过程

1.安装Settings.apk和Starter.apk
2.于我的应用界面会出现以下图标的APP
MITVSettings_Starter
3.点选即可打开设置主页面
MITVSettings_AOSP1
MITVSettings_AOSP2
也可以通过快速点按版本号来打开完整版的开发者选项
MITVSettings_AOSP3

下载

Settings.apk
Starter.apk

介绍
这是我自己开发的一个电视桌面
有基本的APP打开功能,时间显示功能,隐藏应用功能
运存占用很低,实测RT2984+1GB运行内存也可以流畅运行

开源相关
原来准备开源的,但是因为硬盘事故(乱折腾黑果格了盘),所以没源码了,抱歉

包信息
包名:com.linus.atvhome
Android SDK版本需求:≥4.0.3(IceCreamSandwich)
包大小:>1.5MB

截图
截自我的小米电视4A 32"/Android 6.0.1
ATVHome1
ATVHome2
ATVHome3

下载
正常版本下载
360加固版本下载

更新日志

版本号更新时间更新日志
1.0.12021/05/24360加固测试
更换新签名
1.0.12018/08/28修复应用详情调用崩溃问题
1.0.02018/08/20首次发布

N在ConnectivityManager方面的API变动很大。其中在移动流量部分多了个流量节省程序(不是Chrome里面那个经Google服务器中转的那个,那个国内没法用)
可以在设置下,流量使用情况里面可以开启或关闭这个功能。开启后(默认是允许后台数据),会有一个AppList,让你选择不限制数据使用的APP。如果想要关闭后台数据,可以在流量使用情况里开关后台数据。
那今天就来谈谈InWall环境下,开启DataSaver后后台流量以及推送的处理
开始有些特别处理,比如在流量节省程序开之后,关了后台数据,后台就无法连接网络,这时我们就需要启动界面时请求开启,intent需要设置一个data也就是所在程序的包名

   intent=new Intent(Settings.ACTION_IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS);
        Uri uri = Uri.parse("package:com.demo.napi.DataSaver"); intent.setData(uri); startActivity(intent);

写接收器来监听流量节省开关事件。以下是我的测试结果。

        class MyReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.d("MainActivity","onReceive "+ intent.getAction());
            ConnectivityManager manager = (ConnectivityManager) context.getSystemService(CONNECTIVITY_SERVICE);
            boolean isNetworkMetered =  manager.isActiveNetworkMetered();
            Log.d("MainActivity","isNetworkMetered = "+ isNetworkMetered);
            if(isNetworkMetered){
                Log.d("MainActivity","getRestrictBackgroundStatus = "+ manager.getRestrictBackgroundStatus());
                switch (manager.getRestrictBackgroundStatus()){
                    case ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED:
                        //关闭了流量节省,流量不限制。
                        break;
                    case ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED:
                        //开启了流量节省或者流量节省开启的状态下允许后台数据由关到开。这时服务里后台运行的流量不可以使用,假如程序不是活动,甚至数据也不可以使用。
                        break;
                    case ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED:
                        //流量节省开启的状态下,不限制后台数据开启了,这时流量可以使用,即使程序切到后台,活动变为虚,数据也可以使用。
                        break;
                }
            }
        }
    }

再注册一下接收器

    registerReceiver(DataSaverReceiver(),
             newIntentFilter(ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED));

自己尝试了下,觉得不难理解,觉得如果利用好,这个api在国内一样能有大用处,不过。。。某些国内主流软件还在使用4.0的API(不不不,我不是针对各大Bank),普及起来,难度很大啊!