OpenHarmony开发者论坛

标题: 反编译DevEcoStudio分析设备截屏实现原理的逆向过程 [打印本页]

作者: westinyang    时间: 2023-10-28 09:52
标题: 反编译DevEcoStudio分析设备截屏实现原理的逆向过程
[md]> 声明:本文中提到的反编译、逆向分析相关技术或思路,仅供学习交流,个人认为这些分享没有任何破坏性,只会对正向开发会产生积极的影响!

# 序言

> 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\`
  ![](data/attachment/forum/202310/28/095052n33h632tzhp2if0a.png "1.png")
- 放眼望去,`ohos-` 开头的jar只有这些,那既然在界面上设备截屏按钮属于日志视图,那十有八九就是 `ohos_hilog-3.1.0.500.jar` 这个jar包了
- 然后使用的 `jadx` 打开反编译这个jar文件
- 在源码中搜索 `screen`、`capture` 等关键字逐一查看并分析
- 刚才的猜测运气很好,最终在这里定位到了如下代码:`com.huawei.ohos.log.core.device.OpenHarmonyDevice` 类中的 `screenCapture` 以及 `getVirtualFile` 这两个关键的方法

```java
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
- 至此,便得出了我在之前技术分享中所提到的如下截屏命令

```shell
hdc shell "snapshot_display -f /data/0.jpeg"
hdc file recv /data/0.jpeg
```

# 持续关注

- OHOS Dev:[https://gitee.com/ohos-dev](https://gitee.com/ohos-dev) `OpenHarmony开源项目组织,为OpenHarmony的未来而创建,Peace & Love`
- BiliBili:[https://space.bilibili.com/74433635](https://space.bilibili.com/74433635) `投稿OpenHarmony探索研究、应用开发和相关技术教程`
[/md]




欢迎光临 OpenHarmony开发者论坛 (https://forums.openharmony.cn/) Powered by Discuz! X3.5