逆向分析第一个鸿蒙OS应用

鸿蒙 2.0 App 到底是什么 ?


「 嗯,已经都几个月没更新博客了。」

Part 1 趣图

9月10日,HDC 2020 正式发布了鸿蒙2.0

第二天的朋友圈我发现了一张「趣图」 – 用 IDA Pro 分别加载的 adbWinApi.dllHdcWinApi.dll 文件

趣图

做逆向的我,引起了好奇心?

Part 2 下载安装IDE

于是我下载了华为为HarmonyOS设计了专门的开发IDE:DevEco Studio (目前只支持Windows10)

当前版本:deveco-studio-2.0.8.203.exe

注:以下简称 DevEco Studio 为 DS

开启界面

安装完成之后 (嗯?和 Android Studio 很像,都是基于IDEA)

主界面

Part 3 对比sdk文件

打开 Huawei Sdk 和 Android SDK 路径 , 在 IDA Pro 下对比 adbWinApi.dllHdcWinApi.dll 文件

咦 ? 还果真一样,华为直接将adb替换为hdc

对比 HdcWinApi.dll 和 adbWinApi.dll 文件

套壳? 是否,这里也就不深究了

Part 4 创建鸿蒙APP

创建一个鸿蒙OS的APP,从模板看目前支持电视、可穿戴设备应用、可穿戴设备(Lite)应用,电视、可穿戴设备应用支持 Java 和 Javascript,可穿戴设备(Lite)应用只支持 Javascript

选择模板

个人比较熟悉Java版本,这里就创建TV的Java模板类型

配置项目

完成创建,以下是项目的大致结构

项目结构

Part 5 从AS看DS项目结构

app\src\main 变成了 entry\src\main

在main下:

AS –> java 、res 、AndroidManifest.xml
DS –> java 、resources、config.json

在java文件夹下「MainAbility.java」

Activity 变成了 Ability

1
2
3
4
5
6
7
8
9
10
11
12
13
package com.xw.hdctest;

import com.xw.hdctest.slice.MainAbilitySlice;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;

public class MainAbility extends Ability {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setMainRoute(MainAbilitySlice.class.getName());
}
}

然后就是 [MainAbilitySlice.java」

Layout 布局变成了 AbilitySlice 相当于动态布局

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
37
38
39
40
41
42
43
44
45
46
package com.xw.hdctest.slice;

import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;

import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.DirectionalLayout.LayoutConfig;
import ohos.agp.components.Text;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.Color;
import ohos.agp.utils.TextAlignment;

public class MainAbilitySlice extends AbilitySlice {

private DirectionalLayout myLayout = new DirectionalLayout(this);

@Override
public void onStart(Intent intent) {
super.onStart(intent);
LayoutConfig config = new LayoutConfig(LayoutConfig.MATCH_PARENT, LayoutConfig.MATCH_PARENT);
myLayout.setLayoutConfig(config);
ShapeElement element = new ShapeElement();
element.setRgbColor(new RgbColor(255, 255, 255));
myLayout.setBackground(element);

Text text = new Text(this);
text.setLayoutConfig(config);
text.setText("Hello World");
text.setTextColor(new Color(0xFF000000));
text.setTextSize(50);
text.setTextAlignment(TextAlignment.CENTER);
myLayout.addComponent(text);
super.setUIContent(myLayout);
}

@Override
public void onActive() {
super.onActive();
}

@Override
public void onForeground(Intent intent) {
super.onForeground(intent);
}
}

定义字符串是在「string.json」文件里(main\resources\base\element下)

1
2
3
4
5
6
7
8
9
10
11
12
{
"string": [
{
"name": "app_name",
"value": "HDCTest"
},
{
"name": "mainability_description",
"value": "hap sample empty page"
}
]
}

app图标是在main\resources\base\media下

AndroidManifest 变成了 「config.json」

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
{
"app": {
"bundleName": "com.xw.hdctest",
"vendor": "xw",
"version": {
"code": 1,
"name": "1.0"
},
"apiVersion": {
"compatible": 3,
"target": 3
}
},
"deviceConfig": {},
"module": {
"package": "com.xw.hdctest",
"name": ".HDCTest",
"reqCapabilities": [
"video_support"
],
"deviceType": [
"tv"
],
"distro": {
"deliveryWithInstall": true,
"moduleName": "entry",
"moduleType": "entry"
},
"abilities": [
{
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home"
]
}
],
"orientation": "landscape",
"formEnabled": false,
"name": "com.xw.hdctest.MainAbility",
"icon": "$media:icon",
"description": "$string:mainability_description",
"label": "HDCTest",
"type": "page",
"launchType": "standard"
}
]
}
}

同样也还是有两个build.gradle文件

entry 下 build.gradle

1
2
3
4
5
6
7
8
9
10
11
12
13
apply plugin: 'com.huawei.ohos.hap'
ohos {
compileSdkVersion 3
defaultConfig {
compatibleSdkVersion 3
}

}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
testCompile'junit:junit:4.12'
}

root 下 build.gradle

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
37
// Top-level build file where you can add configuration options common to all sub-projects/modules.
apply plugin: 'com.huawei.ohos.app'

ohos {
compileSdkVersion 3
defaultConfig {
compatibleSdkVersion 3
}
}

buildscript {
repositories {
maven {
url 'https://mirrors.huaweicloud.com/repository/maven/'
}
maven {
url 'https://developer.huawei.com/repo/'
}
jcenter()
}
dependencies {
classpath 'com.huawei.ohos:hap:2.0.0.6'

}
}

allprojects {
repositories {
maven {
url 'https://mirrors.huaweicloud.com/repository/maven/'
}
maven {
url 'https://developer.huawei.com/repo/'
}
jcenter()
}
}

part 6 编译和运行

编译文件有三种方式:Build APP(s) / Build Debug Hap(s) / Build Release Hap(s)

编译文件类型

Build App(s) : 首先需要配置签名

1
2
3
4
5
6
FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':validateReleaseAppSigning'.
> Signing configs can't be empty when build APP.
Please configure 'release' signingConfigs in File -> Project Structure -> Project -> Signing Configs.

创建签名, Android Studio签名要keystore,格式是jks. 而华为的DevEco Studio中,成了p12格式

创建签名文件

配置p12、crt、p7b(需要到官网申请证书和Profile)文件,文章这里没有就暂时忽略

配置签名文件

生成的编译文件,这里只有Build Debug Hap(s) / Build Release Hap(s) 两种情况

和AS生成apk的结构相似,这里鸿蒙生成的app是以.hap为文件类型的app

生成编译文件

运行DevEco -> HVD Manager (模拟器),需要注册成华为开发者,然后授权成功,创建并连接到远程真机测试

创建模拟器运行

登录成功显示的远程设备

创建的远程TV设备

运行项目到远程TV设备

part 7 分析hap文件

以output下生成的entry-debug-unsigned.hap为例

用压缩软件打开,查看hap包里的内容

hap文件结构

既有 dex 又有 apk , 然后我们再来打开apk文件看看

apk文件结构

嗯? 下面我们用jadx-gui分别打开hap文件和hap里面的dex文件看一看

jadx打开hap文件的结构

jad打开apk文件的结构

MainAbilityShellActivity中唯一处引用到了Android包下的Bundle

可能是为了更好的兼容Android吧 ?

这里顺便再来看看一些系统目录文件结构吧

部分系统目录文件结构

part 8 结语

HarmonyOS的应用软件包以APP Pack(Application Package)形式发布,它是由一个或多个HAP(HarmonyOS Ability Package)以及描述每个HAP属性的pack.info组成。HAP是Ability的部署包,HarmonyOS应用代码围绕Ability组件展开。

一个HAP是由代码、资源、第三方库及应用配置文件组成的模块包,可分为entry和feature两种模块类型,如图所示。

  • entry: 应用的主模块。一个APP中,对于同一设备类型必须有且只有一个entry类型的HAP,可独立安装运行。
  • feature: 应用的动态特性模块。一个APP可以包含一个或多个feature类型的HAP,也可以不含。只有包含Ability的HAP才能够独立运行。

HAP是Ability的部署包,HarmonyOS应用代码围绕Ability组件展开,它是由一个或多个Ability组成。Ability分为两种类型:FA(Feature Ability)和PA(Particle Ability)。FA/PA是应用的基本组成单元,能够实现特定的业务功能。FA有UI界面,而PA无UI界面。

APP逻辑视图

本文简单的对鸿蒙APP进行简单入门分析,也算不上是对APP的逆向。感谢阅读,有什么想说的欢迎在下面留言,下期再见。

Google Developer Summit
0%