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


    背景

    在马哥给讲解怎么用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)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    看看这个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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    可以看出的这里其实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;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

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

    验证方式:

    在执行bugreport命令时候:

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

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

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

    明显看到是一个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"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    可以看到有列出一个个的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
    • 2
    • 3
    • 4
    • 5
    • 6

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

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

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

       if (!PropertiesHelper::IsUserBuild() || isEnableProp()) {
            ds.AddDir(WMTRACE_DATA_DIR, false);
        }
    
    • 1
    • 2
    • 3
  • 相关阅读:
    C++ IO流_数据的旅行之路
    P2763 试题库问题
    学习笔记——BSGS
    线性代数(七) 矩阵分析
    Android View体系
    代码随想录|300.最长递增子序列,674. 最长连续递增序列,718. 最长重复子数组(非常不理解了)
    数据归一化的常见方法
    FPGA模块——IIC协议(读写PCF8591)
    C# 在Winform实时显示文件版本
    5. web信息收集(OWASP实战训练)
  • 原文地址:https://blog.csdn.net/learnframework/article/details/132823800