Flutter製アプリのAndroidManifest.xmlや難読化について調べた
Sep 20, 2020 18:00 · 1691 words · 4 minute read
1年ほど前にFlutter製アプリのデータについて調べました。
前回はDebugビルドした場合のデータのみを調べていたのですが、今回はDebugビルドとReleaseビルドのデータを比較してみました。
目次
環境
- macOS 10.15.6
インストール
Android Studio
今回はJetBrains Toolbox Appを使って、最新のAndroid Studioをインストールしました。
JetBrains Toolbox Appを使うメリットは、kakakakakkuさんのこちらの記事がとてもわかり易いです。
JetBrains プロダクトを管理するプロダクト「JetBrains Toolbox App」
Flutter SDK 1.20.4
前回Ubuntuにインストールしたのと同じ手順でMac版のFlutter SDKをインストールします。
サンプルアプリ作成
New Flutter Projectからサンプルサプリを作成します。
アプリデータを調べる
DebugビルドとReleaseビルドで作成されたアプリデータを比較しました。いくつか気になった点を挙げていきます。
Debugビルド
AndroidManifest.xml
Releaseビルドとの大きな違いは、「uses-permission android:name=“android.permission.INTERNET”」の権限がついていることと、「android:debuggable=“true” 」でデバッグ機能が有効になっている点でしょうか。
<?xml version="1.0" encoding="utf-8" standalone="no"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" android:compileSdkVersion="28" android:compileSdkVersionCodename="9" package="com.example.flutter_app" platformBuildVersionCode="28" platformBuildVersionName="9">
<uses-permission android:name="android.permission.INTERNET"/>
<application android:appComponentFactory="androidx.core.app.CoreComponentFactory" android:debuggable="true" android:icon="@mipmap/ic_launcher" android:label="flutter_app" android:name="io.flutter.app.FlutterApplication">
<activity android:configChanges="density|fontScale|keyboard|keyboardHidden|layoutDirection|locale|orientation|screenLayout|screenSize|smallestScreenSize|uiMode" android:hardwareAccelerated="true" android:launchMode="singleTop" android:name="com.example.flutter_app.MainActivity" android:theme="@style/LaunchTheme" android:windowSoftInputMode="adjustResize">
<meta-data android:name="io.flutter.embedding.android.NormalTheme" android:resource="@style/NormalTheme"/>
<meta-data android:name="io.flutter.embedding.android.SplashScreenDrawable" android:resource="@drawable/launch_background"/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<meta-data android:name="flutterEmbedding" android:value="2"/>
</application>
</manifest>
ソースコード
MainActivity.java
package com.example.flutter_app;
import io.flutter.embedding.android.FlutterActivity;
import kotlin.Metadata;
@Metadata(bv = {1, 0, 3}, d1 = {"XXXXXXXXXX"}, d2 = {"Lcom/example/flutter_app/MainActivity;", "Lio/flutter/embedding/android/FlutterActivity;", "()V", "app_debug"}, k = 1, mv = {1, 1, 15})
/* compiled from: MainActivity.kt */
public final class MainActivity extends FlutterActivity {
}
このソースコードにはmain.dartで実装した処理は記載されていません。
main.dartで実装されているアプリの処理は、android端末内の「/data/data/{package name}/code_cache/flutter_appLJTKVI/flutter_app/lib/main.dart.incremental.dill」に記載されていました。
ホットリロード機能が有効になっている場合、Android Studioでソースコードが保存されると、Android端末内のmain.dart.incremental.dillが更新され、端末上で実行されているアプリに反映されるようです。
Rleaseビルド
AndroidManifest.xml
デバッグ時に存在していた下記の内容が無くなっていました。
- uses-permission android:name=“android.permission.INTERNET”
- android:debuggable=“true”
<?xml version="1.0" encoding="utf-8" standalone="no"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" android:compileSdkVersion="28" android:compileSdkVersionCodename="9" package="com.example.flutter_app" platformBuildVersionCode="28" platformBuildVersionName="9">
<application android:appComponentFactory="androidx.core.app.CoreComponentFactory" android:icon="@mipmap/ic_launcher" android:label="flutter_app" android:name="io.flutter.app.FlutterApplication">
<activity android:configChanges="density|fontScale|keyboard|keyboardHidden|layoutDirection|locale|orientation|screenLayout|screenSize|smallestScreenSize|uiMode" android:hardwareAccelerated="true" android:launchMode="singleTop" android:name="com.example.flutter_app.MainActivity" android:theme="@style/LaunchTheme" android:windowSoftInputMode="adjustResize">
<meta-data android:name="io.flutter.embedding.android.NormalTheme" android:resource="@style/NormalTheme"/>
<meta-data android:name="io.flutter.embedding.android.SplashScreenDrawable" android:resource="@drawable/launch_background"/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<meta-data android:name="flutterEmbedding" android:value="2"/>
</application>
</manifest>
ソースコード
MainActivity.java
package com.example.flutter_app;
import io.flutter.embedding.android.FlutterActivity;
import kotlin.Metadata;
@Metadata(bv = {1, 0, 3}, d1 = {"XXXXXXXXXX"}, d2 = {"Lcom/example/flutter_app/MainActivity;", "Lio/flutter/embedding/android/FlutterActivity;", "()V", "app_release"}, k = 1, mv = {1, 1, 15})
/* compiled from: MainActivity.kt */
public final class MainActivity extends FlutterActivity {
}
デバッグビルドの場合と同様に、javaの中にはmain.dartで実装した処理は含まれていません。
リリースビルドの場合はandroid端末内の「/data/data/{package name}/app_flutter/flutter_assets/kernel_blob.bin」にmain.dartの内容が含まれていました。
ソースコードの難読化
kernel_blob.binに記載された処理は難読化されていませんでした。実際にアプリをリリースする場合を想定すると、処理の内容は難読化しておきたいところです。
Flutter製のアプリの難読化については、下記の公式ドキュメントに記載されています。
Obfuscating Dart code (flutter.dev)
Obfuscating Dart Code (github.com)
最後に
1年ぶりにFlutter製アプリについて調査をしました。
今回は調査しませんでしたが、端末内データの扱いや、他のアプリと連携する方法も気になるところです。「Androidアプリのセキュア設計・セキュアコーディングガイド」と照らし合わせつつ、調べていこうと思います。