Flutter製アプリのAndroidManifest.xmlや難読化について調べた

Sep 20, 2020 18:00 · 1693 words · 4 minute read flutter android

1年ほど前にFlutter製アプリのデータについて調べました。

Flutter入門。サンプルアプリ作成とアプリデータの調査

前回はDebugビルドした場合のデータのみを調べていたのですが、今回はDebugビルドとReleaseビルドのデータを比較してみました。

目次

環境

  • macOS 10.15.6

インストール

Android Studio

今回はJetBrains Toolbox Appを使って、最新のAndroid Studioをインストールしました。

JetBrains Toolbox App

JetBrains Toolbox Appを使うメリットは、kakakakakkuさんのこちらの記事がとてもわかり易いです。

JetBrains プロダクトを管理するプロダクト「JetBrains Toolbox App」

Flutter SDK 1.20.4

前回Ubuntuにインストールしたのと同じ手順でMac版のFlutter SDKをインストールします。

Flutter入門。Ubuntuの開発環境を準備した

サンプルアプリ作成

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アプリのセキュア設計・セキュアコーディングガイド」と照らし合わせつつ、調べていこうと思います。

Androidアプリのセキュア設計・セキュアコーディングガイド

tweet Share