winscope怎么实现user版本上导出方案设计探讨-千里马android framework车载车机手机系统开发

2023-09-12 11:27:42

背景

在马哥给讲解怎么用winscope来分析各种闪黑,黑屏等问题后,很多买课的同学都开始使用这个工具用于实际公司的项目了,但是很多同学又开始发现有一个问题,那就发现在user版本的手机设备上发现无法抓取相关的winscope,哪怕可以抓取也发现没办法导出来分析。这个问题在群里求助马哥,这边今天就给出相关的一些解决方案。
相关winscope深入使用解决闪黑等请看我的b站视频或者付费视频,可以直接看视频联系我
https://www.bilibili.com/video/BV14M411M7Pu/

1、user手机上网页获取winscope失败

winscope在user手机上的效果如下:

在这里插入图片描述可以看出一直是显示个error,但是具体是啥原因error呢?
从服务端的python程序输出日日志看看:
在这里插入图片描述

明显看到其实服务端也只是去执行相关的adb shell命令,只不过这个命令需要有su root这样高级别的权限。自然在user手机上是没有的

2、手机上可以抓取,但是无权限获取文件

快捷按钮可以去setting中放开
在这里插入图片描述

抓取完成后有相关的trace文件:
在这里插入图片描述

可以看到trace文件被导出到了 data/misc/wmtrace文件夹,那么尝试取出
发现有如下权限问题
在这里插入图片描述

可以看出这个wmtrace文件夹压根没有权限哈,自然无法取出

3、尝试探索解决办法

使用bugreoport命令:

test@test:~$ adb bugreport
/data/user_de/0/com.android.shell/files/bugreports/bugreport-crosshatch-SP1A.210812.016.C1-2022-06-28-12-21-13.zip: 1 file pulled. 27.7 MB/s (11790205 bytes in 0.406s)
test@test:~$ adb pull /data/user_de/0/com.android.shell/files/bugreports/bugreport-crosshatch-SP1A.210812.016.C1-2022-06-28-12-21-13.zip 
/data/user_de/0/com.android.shell/files/bugreports/bugreport-crosshatch-SP1A.210812.016.C1-2022-06-28-12-21-13.zip: 1 file pulled. 27.7 MB/s (11790205 bytes in 0.406s)

看看这个bugreport命令导出的相关文件:
在这里插入图片描述

发现FS文件夹下面有个data的文件夹,还有misc,因为本身misc根本adb shell是没有权限可以查看的,看着是不是很有希望。。
在这里插入图片描述
但是情况却如下:
在这里插入图片描述
只有recovery相关,没有看到wmtrace相关文件夹

但是明明就是/data/misc/wmtrace路径,为啥没有导出呢?
需要知道这个原因就必须要看源码了
首先需要了解点bugreport其实本质上也最多只能有shell权限,因为也属于adb shell拉起的进程,
但是为啥它可以导出data/misc/下面相关文件夹

为了解密这个我们可以来看看相关源码
frameworks/native/cmds/bugreport/bugreport.cpp

int main() {
    fprintf(stderr,
            "=============================================================================\n");
    fprintf(stderr, "WARNING: Flat (text file, non-zipped) bugreports are deprecated.\n");
    fprintf(stderr, "WARNING: Please generate zipped bugreports instead.\n");
    fprintf(stderr, "WARNING: On the host use: adb bugreport filename.zip\n");
    fprintf(stderr, "WARNING: On the device use: bugreportz\n");
    fprintf(stderr, "WARNING: bugreportz will output the filename to use with adb pull.\n");
    fprintf(stderr,
            "=============================================================================\n\n\n");

    return 0;
}

可以看出的这里其实bugreport已经是一个空壳了,真正还是bugreportz在起作用
看看bugreportz的相关命令:
frameworks/native/cmds/bugreportz/main.cpp

int main(int argc, char* argv[]) {
  //省略

    // TODO: code below was copy-and-pasted from bugreport.cpp (except by the
    // timeout value);
    // should be reused instead.

    // Start the dumpstatez service.
    //启动相关的 dumpstate服务
    if (stream_data) {
        property_set("ctl.start", "dumpstate");
    } else {
        property_set("ctl.start", "dumpstatez");
    }

    // Socket will not be available until service starts.
    int s = -1;
    for (int i = 0; i < 20; i++) {
    //与dumpstate进行本地socket跨进程通讯
            s = socket_local_client("dumpstate", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
        if (s >= 0) break;
        // Try again in 1 second.
        sleep(1);
    }


    int ret;
    //socket接受相关的数据进行处理
    if (stream_data) {
        ret = bugreportz_stream(s);
    } else {
        ret = bugreportz(s, show_progress);
    }
    return ret;
}

总结如下图所示:
在这里插入图片描述

验证方式:

在执行bugreport命令时候:

test@test:~/aosp/frameworks/native/cmds$ adb bugreport
[  5%] generating bugreport-crosshatch-SP1A.210812.016.C1-2022-06-28-13-02-19.zip

开另一个在终端进行adb shell查看一下阿dumpstate服务是啥权限:

crosshatch:/ $ ps -A | grep dump                                                                        
root         16137     1 10878140  5172 0                   0 S dumpstate

明显看到是一个root权限的进程

4、原因寻找及解决办法

上面已经分析了bugreport的原理,实际是借助dumpstate来实现获取高权限root的,那么问题来了,为啥wmtrace相关文件夹呢?这个问题就得看dumpstate相关源码了:

frameworks/native/cmds/dumpstate/dumpstate.cpp
看到了如下的代码:


#define PSTORE_LAST_KMSG "/sys/fs/pstore/console-ramoops"
#define ALT_PSTORE_LAST_KMSG "/sys/fs/pstore/console-ramoops-0"
#define BLK_DEV_SYS_DIR "/sys/block"

#define RECOVERY_DIR "/cache/recovery"
#define RECOVERY_DATA_DIR "/data/misc/recovery"
#define UPDATE_ENGINE_LOG_DIR "/data/misc/update_engine_log"
#define LOGPERSIST_DATA_DIR "/data/misc/logd"
#define PREREBOOT_DATA_DIR "/data/misc/prereboot"
#define PROFILE_DATA_DIR_CUR "/data/misc/profiles/cur"
#define PROFILE_DATA_DIR_REF "/data/misc/profiles/ref"
#define XFRM_STAT_PROC_FILE "/proc/net/xfrm_stat"
#define WLUTIL "/vendor/xbin/wlutil"
#define WMTRACE_DATA_DIR "/data/misc/wmtrace"
#define OTA_METADATA_DIR "/metadata/ota"
#define SNAPSHOTCTL_LOG_DIR "/data/misc/snapshotctl_log"
#define LINKERCONFIG_DIR "/linkerconfig"
#define PACKAGE_DEX_USE_LIST "/data/system/package-dex-usage.list"
#define SYSTEM_TRACE_SNAPSHOT "/data/misc/perfetto-traces/bugreport/systrace.pftrace"
#define CGROUPFS_DIR "/sys/fs/cgroup"

可以看到有列出一个个的data相关目录,有RECOVERY_DATA_DIR和WMTRACE_DATA_DIR,这里重点看看WMTRACE_DATA_DIR为啥没有被导出看看是否有相关的限制条件:

看到了如下的代码,这里有一个条件就是!PropertiesHelper::IsUserBuild()
即只有在非user手机才可以导出WMTRACE_DATA_DIR目录


    /* Add window and surface trace files. */
    if (!PropertiesHelper::IsUserBuild()) {
        ds.AddDir(WMTRACE_DATA_DIR, false);
    }

修改方案探索:
1、直接删除 if (!PropertiesHelper::IsUserBuild()) 条件(比较暴力不安全)

   //if (!PropertiesHelper::IsUserBuild()) {
        ds.AddDir(WMTRACE_DATA_DIR, false);
  //  }

2、可以加一个或条件,加入自己的暗门(建议这种),比如自己也搞一个prop,可以通过adb shell改变的prop

   if (!PropertiesHelper::IsUserBuild() || isEnableProp()) {
        ds.AddDir(WMTRACE_DATA_DIR, false);
    }
更多推荐

探索AIGC人工智能(Midjourney篇)(四)

文章目录Midjourney模特换装Midjourney制作APP图标Midjourney网页设计Midjourney如何生成IP盲盒Midjourney设计儿童节海报Midjourney制作商用矢量插画Midjourney设计徽章Midjourney图片融合Midjourney后缀参数Midjourney模特换装关键

基于 Vue 和 SpringBoot 的医院门诊预约挂号系统源代码+数据库

基于Vue和SpringBoot的医院门诊预约挂号系统完整代码下载地址:基于Vue和SpringBoot的医院门诊预约挂号系统源代码+数据库软件简介本软件是《基于Vue的医院门诊预约挂号管理系统》,主要包含数据中心、科室医生模块、预约挂号模块、医院时政这四大模块。预约挂号系统采用了基于角色的访问控制,角色和菜单关联,一

Flask-[实现websocket]-(2): flask-socketio文档学习

一、简单项目的构建flask_websocket|---static|---js|---jquery-3.7.0.min.js|---socket.io_4.3.1.js|---templates|---home|---group_chat.html|---index.html|---app.py1.1、python环

驱动开发-字符设备的内部实现

1、字符设备驱动内部的注册过程对register_chrdev内部的实现过程分析,注册字符驱动的过程有以下几步1、分配structcdev对象空间2、初始化structcdev对象3、注册cdev对象以上三步完成了字符设备驱动的注册2、structcdev结构体分析只要有一个驱动存在于系统内核中,就会存在一个struc

[ESP32 IDF+Vscode]蓝牙配网后采用上传温湿度数据至阿里云(MQTT协议)

阿里云平台的设置参考文章:http://t.csdn.cn/RzLGqhttp://t.csdn.cn/RzLGqBlufi配网1.简介BluFi是一款基于蓝牙通道的Wi-Fi网络配置功能,适用于ESP32。它通过安全协议将Wi-Fi配置和证书传输到ESP32,然后ESP32可基于这些信息连接到AP或建立SoftAP。

Node.js 20.6支持.env配置文件,加入C++垃圾回收函式库Oilpan

在最新版本20.6.0中,Node.js现在内置了对.env文件的支持。现在,您可以将环境变量从.env文件加载到process.envNode.js应用程序中,完全无依赖。加载.env文件现在非常简单:node--env-file.env什么是.env?.env文件用于配置将存在于正在运行的应用程序中的环境变量。这个

浅谈STL|STL函数对象篇

一.函数对象概念概念:·重载函数调用操作符的类,其对象常称为函数对象·函数对象使用重载的()时,行为类似函数调用,也叫仿函数本质:函数对象(仿函数)是一个类,不是一个函数特点函数对象在使用时,可以像普通函数那样调用,可以有参数,可以有返回值;函数对象超出普通函数的概念,函数对象可以有自己的状态;函数对象可以作为参数传递

SD系列——图像高清化算法方法

图像高清化算法方法文章目录图像高清化算法方法一、通过Extras选项卡执行放大算法二、通过SDupscale脚本增强细节三、txt2img页面下的HiresFix四、扩展插件UltimateSDupscale+ControlNetTile参数调整单用UltimateSDUpscale小结五、TiledDiffusion

基于springboot大学生租房系统springboot10

大家好✌!我是CZ淡陌。一名专注以理论为基础实战为主的技术博主,将再这里为大家分享优质的实战项目,本人在Java毕业设计领域有多年的经验,陆续会更新更多优质的Java实战项目,希望你能有所收获,少走一些弯路,向着优秀程序员前行!🍅更多优质项目👇🏻👇🏻可点击下方获取🍅文章底部或评论区获取🍅Java项目精品实

数据结构——堆

堆文章目录堆1.什么是堆2.堆的两个特性3.父子节点下标之间的关系4.堆的实现4.1堆的插入HeapPush4.1.1向上调整算法AdjustUp:4.1.2AdjustUp代码实现(以大堆为例)4.1.3HeapPush实现4.1.4时间复杂度4.2堆的删除HeapPop4.2.1向下调整算法AdjustDown4.

基于Docker的JMeter分布式压测实战讲解

一个JMeter实例可能无法产生足够的负载来对你的应用程序进行压力测试。如本网站所示,一个JMeter实例将能够控制许多其他的远程JMeter实例,并对你的应用程序产生更大的负载。JMeter使用JavaRMI[远程方法调用]来与分布式网络中的对象进行交互。JMeter主站和从站的通信如下图所示:我们需要为每个Slav

热文推荐