[经验分享] 反编译DevEcoStudio分析设备截屏实现原理的逆向过程 原创

westinyang 显示全部楼层 发表于 2023-10-28 09:52:47

声明:本文中提到的反编译、逆向分析相关技术或思路,仅供学习交流,个人认为这些分享没有任何破坏性,只会对正向开发会产生积极的影响!

序言

OpenHarmony生态的发展,除了设备开发、应用开发之外,其实还应该有一些方向,比如:与之相关的电脑软件、工具集,甚至是未来的安全研究等等

在往期的技术分享中,我提到过OpenHarmony设备截屏的一些方法,研究之初就是为了想要找到如何使用命令行进行截图,并开发一些相关的软件工具,这篇文章就是来详细讲下是如何一步步探索、尝试、分析以及得出结论的过程,我希望在之前给出解决方案的同时,再分享下具体的分析过程,希望能给带给你一些解决的问题的思路和灵感~

分析推测

  • 首先,DevEcoStudio是可以识别已连接的安卓设备的,我们知道,打开DevEcoStudio,依次点击 下方日志 - 左侧设备截屏图标 即可截屏。
  • 当连接安卓设备时,点击设备截屏,大概率是调用的 screencap 这个 shell 命令,因为安卓用shell截屏就是这个命令,官方文档中也是有详细的说明。
  • 当连接OpenHarmony设备时,也可以截屏,但是OpenHarmony设备肯定不会有 screencap 命令,那它既然也可以截屏,很有可能就是DevEcoStudio的插件源码中会根据设备类型做判断,最终调用不同的shell命令去截屏。
  • 由于OpenHarmony官方文档中并没有提到设备截屏相关shell命令,那怎么办呢?总不能止步于此吧?
  • 经过不懈的努力还是找到了一些“蛛丝马迹”,顺藤摸瓜找到了具体的实现方法

逆向过程

  • 我们先找到DevEcoStudio插件目录下OpenHarmony相关插件的lib目录 C:\Program Files\Huawei\DevEco Studio\plugins\openharmony\lib\
  • 放眼望去,ohos- 开头的jar只有这些,那既然在界面上设备截屏按钮属于日志视图,那十有八九就是 ohos_hilog-3.1.0.500.jar 这个jar包了
  • 然后使用的 jadx 打开反编译这个jar文件
  • 在源码中搜索 screencapture 等关键字逐一查看并分析
  • 刚才的猜测运气很好,最终在这里定位到了如下代码:com.huawei.ohos.log.core.device.OpenHarmonyDevice 类中的 screenCapture 以及 getVirtualFile 这两个关键的方法
public void screenCapture(Project project) {
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
    String timeStamp = simpleDateFormat.format(new Date());
    String path = PathManager.getTempPath();
    VirtualFile virtualFile = getVirtualFile(HdcCmdList.JPEG, path, timeStamp);
    if (virtualFile == null) {
        virtualFile = getVirtualFile(HdcCmdList.PNG, path, timeStamp);
    }
    if (virtualFile != null) {
        virtualFile.refresh(false, false);
        FileEditorManager.getInstance(project).openFile(virtualFile, true);
        return;
    }
    LOGGER.warn("An error occurred when saving images or displaying screenshots");
}

private VirtualFile getVirtualFile(String picFormat, String path, String timeStamp) {
    String screenshotName = "Screenshot_" + timeStamp + picFormat;
    String receiveFile = "file recv /data/" + screenshotName + " " + path;
    this.device.getClient().sendSyncShellCommand("snapshot_display -f /data/" + screenshotName, (int) DataConstants.WAIT_TIME);
    this.device.getClient().sendSyncCommand(receiveFile, (int) DataConstants.WAIT_TIME);
    return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(path, screenshotName));
}
  • 很明显,在 screenCapture 方法中,先通过格式化当前时间生成截屏的文件名
  • 然后再调用 getVirtualFile 方法进行设备截屏
  • 其中用到的关键shell命令就是这个 snapshot_display
  • 暂且我们可以理解为这个就是OpenHarmony中对应安卓中的截屏shell命令screencap
  • 至此,便得出了我在之前技术分享中所提到的如下截屏命令
hdc shell "snapshot_display -f /data/0.jpeg"
hdc file recv /data/0.jpeg

持续关注

©著作权归作者所有,转载或内容合作请联系作者

您尚未登录,无法参与评论,登录后可以:
参与开源共建问题交流
认同或收藏高质量问答
获取积分成为开源共建先驱

Copyright   ©2023  OpenHarmony开发者论坛  京ICP备2020036654号-3 |技术支持 Discuz!

返回顶部