Android利用制限アプリの作成:REA分析とポリシーエンジン検証はどこまで異なるのか

Android利用制限アプリは、「このアプリを今許可するか」を判断し、その決定を実際のデバイスに適用するプログラムです。コード構造を理解することと、オペレーティングシステムにその決定を実行させることには、それぞれ異なる検証が必要です。

REAはReverse Engineer Anythingの略で、エージェントがアプリケーションやバイナリの構造と動作を調査するために接続する分析ツールです。REAでクラスや呼び出し関係を見つけたからといって、アプリ制限ポリシーが正しい、必要なAndroid権限を確保した、実際の携帯電話でブロックが維持されると結論付けることはできません。公式REAリポジトリ

公式サイト

この記事では、架空のDemo Controllerと例示アプリを基準に、分析・ポリシー決定・Android実行を区別し、合成エミュレーター試験を設計します。この記事では、APK分析・エミュレーター・実際の携帯電話試験は実行していません。商用アプリのリバースエンジニアリングや複製完了後のレビュー、過去のテスト実績報告として読むべきではありません。

アプリ構造分析・ポリシー決定・デバイス実行を3段階に分離した概念イメージ

AIで生成された概念イメージ。実際のアプリ・携帯電話画面や試験の成功を示すものではありません。

1. APKを分析してわかることから分ける

APKはAndroidアプリを配布するパッケージです。構造を調査すると、アプリにどのようなコンポーネントが宣言されているか、どのようなコードがどのAPIを呼び出しているか、ポリシーを保存したり読み込んだりする場所はどこかなどを調べることができます。これは、調査する実行パスを絞り込む根拠となります。

公式REAのAndroidガイドでは、JADXを介したAPKのマニフェスト、クラス、逆コンパイルされたメソッドと参照の調査について説明しています。REAは分析結果と根拠をエージェントに接続する役割を果たします。逆コンパイルされた説明は検討すべき手がかりであり、実行結果を代替するものではありません。REA Android分析ガイド

架空のDemo Controllerで「ポリシー有効期限を判断する関数」と「Android APIを呼び出す関数」を見つけたと仮定します。その後確認すべき質問は次のとおりです。

  • 分析したAPKは、今検証するビルドと同じか?
  • 発見した関数は、実際の実行パスで呼び出されるか?
  • 呼び出す際に必要な管理権限とプロファイル範囲があるか?
  • 失敗・オフライン・再起動後も同じポリシーが適用されるか?

古いデバッグAPKを分析した場合、その結果は当該成果物の構造に関する根拠です。最新の実装の動作や他のアプリの内部実装まで確認した資料として拡大解釈してはなりません。逆コンパイルで推定した条件は、独自のコードと試験で再度確認する必要があります。

2. ポリシーエンジンと実行アダプターを分離する

ポリシーエンジンは、入力状態を見て許可・制限・保留などの決定を行う部分です。実行アダプターは、その決定をAndroidが提供するAPIや承認されたデバイス管理手段に接続する部分です。

정책·허용 기간·현재 상태
           ↓
정책 엔진: 허용 / 제한 / 확인 대기
           ↓
Android 집행 어댑터: 권한과 적용 범위 확인 → API 호출
           ↓
실제 상태 확인: 대상 앱 진입, 실패 항목, 복구 상태

例示アプリを今制限するという決定が出たことと、例示アプリを実際に起動できなくなったことは、別々の観測です。ポリシーエンジンの単体テストが成功しても、実行APIが拒否されれば、デバイスの状態は期待と異なる可能性があります。

試験記録もこの区分を維持します。

観測 意味 まだ確認していないこと
ポリシー結果が「制限」 当該入力で判断関数が制限を選択 Androidで適用されたか
実行呼び出しが実行された アダプターがAPIを呼び出し 戻り値・失敗・実際のアプリ状態
例示アプリのActivity開始がブロックされた 当該ユーザー・設定で進入制限を観測 他のプロファイル・OS・再起動後の状態
エミュレーターシナリオ通過 当該試験環境の条件を満たす 実際の携帯電話とメーカーの動作

このような分離は、実装を評価する際にも役立ちます。ポリシー条件が間違っていたのか、権限がなかったのか、適用失敗を見落としたのか、デバイス状態の確認が不十分だったのかをそれぞれ調査できます。

REA構造分析、ポリシー決定、Android権限に基づく実行、実際のデバイス状態確認はそれぞれ異なる証拠を要求する

図:分析・判断・実行・観測段階の区分。公式文書に基づいて再構成されており、この記事で実行した開発・試験結果ではありません。公式根拠1

公式根拠2

3. DevicePolicyManagerはどのアプリにも同じ権限を与えるわけではない

DevicePolicyManagerはAndroidのデバイス管理ポリシーAPIです。例えば、setPackagesSuspended()は当該ユーザーのパッケージを停止状態に設定する機能であり、デバイス所有者・プロファイル所有者または指定された委任範囲のような呼び出し条件があります。一般アプリがメソッド名を知っているという理由だけでその権限を得るわけではありません。DevicePolicyManager公式API)

ここで、デバイス所有者(device owner)とプロファイル所有者(profile owner)はAndroidの管理役割です。プロファイル所有者の管理範囲を個人領域まで全て制御する権限と解釈してはなりません。呼び出そうとするAPIの現在のユーザー・管理役割・委任条件を確認する必要があります。

公式文書によると、停止されたパッケージはActivityを開始できないなどの制限を受けますが、一部の必須アプリは停止できません。また、APIは要求された状態に設定されなかったパッケージのリストを返します。「呼び出した」というログだけを残すのではなく、失敗リストと対象の実際の状態を一緒に確認する必要があります。

アプリ制限と全ての実行プロセス・サービスの強制終了も同じ意味でまとめません。どのような進入と動作を阻止するのかをまず定義することで、試験が正確になります。この記事の「アプリブロック」試験は、例示アプリのActivity進入を含む明示された条件で設計します。

管理役割を作成するプロビジョニングも別途の手順です。Androidの管理プロビジョニングは、ユーザーに管理の意味を知らせ、デバイスまたは管理プロファイルの所有者を設定する流れです。デバイス所有者設定には初期設定状態のような前提もあるため、既存の個人デバイスに一般権限を追加する作業のように説明することはできません。Android管理デバイスプロビジョニング

実験では、初期化可能な専用エミュレーターの管理条件をまず記録します。この原稿作成中には、実際のデバイスを初期化したり管理者として登録したりしていません。権限条件と適法な管理範囲が確認されていない状態で実行を試験することは推奨しません。

4. 「時間が終わった」を2種類の時計で検査する

仮想の例で、一度許可したアプリを一定時間後に再度制限すると仮定します。カレンダーの時刻と経過時間は互いに異なる基準です。

Androidのウォールクロック、つまり日付と時刻はユーザーが変更したり補正されたりする可能性があります。SystemClock.elapsedRealtime()は起動以降の経過時間を示し、深いスリープ時間も含む単調増加時計です。システム日付を過去に戻す試験と、経過時間基準の許可期間試験を区別する根拠となります。Android SystemClock

単調増加時計を使用したからといって、再起動問題まで自動的に解決されるわけではありません。起動を基準とする値は、以前の起動の値とそのまま比較することはできません。ポリシーバージョン、保存した許可状態、再起動後の復旧条件と再確認方法を別途設計する必要があります。

オフライン終了も、サーバーから終了命令を受けなければ動作しないのか、ローカルに保存したポリシーで終了を判断するのかを分けて考えます。サーバーと接続されていない間にポリシーの有効期限切れ・更新・取り消し情報をどれだけ信頼するか、確認できないときにどのような状態を維持するかは、設計者が定めるべき条件です。

著者の推奨は、制限対象アプリの未確認の許可を無期限に延長しないように仕様を定めつつ、管理画面と必要な緊急機能を維持する復旧経路も合わせて設計することです。これは、全ての機能を無条件にブロックするという公式Androidルールではなく、今回検証した完成実装でもありません。

5. 合成エミュレーターでは正常対照と失敗注入を一緒に準備する

下記の表は、今後実施する試験設計です。この作成作業で実行した結果ではありません。例示アプリとDemo Controllerのみをインストールした専用エミュレーターを使用し、Androidバージョン・管理役割・ユーザー・ビルド識別を試験条件として固定します。

試験 合成条件 観測する結果
正常対照 許可ポリシーと必要な権限が準備されている 例示アプリ進入可能、過剰制限なし
アプリ制限 ポリシーエンジンが制限を決定 API失敗項目と例示アプリ進入状態が一致
権限不足 管理役割または範囲がない条件 適用失敗を制限成功として記録しない
オフライン終了 接続なしで許可期間が終了 仕様通りにローカル決定・実行、未確認延長の有無を確認
時計を過去に移動 合成環境のウォールクロック変更 経過時間ポリシーがカレンダー移動だけで延長されないか
再起動復旧 保存状態がある専用エミュレーターを再起動 ポリシー・権限・実行状態の再評価と復旧順序
ロック・スリープ ロック・アイドル後、再度アプリ進入 定めた時間許容誤差と復旧状態
新規インストール・ポリシー変更 例示アプリ再インストールまたはポリシーバージョン変更 以前の状態を誤って再利用しないか

判定には正常対照が必要です。例示アプリが元々インストールされていなかったり、実行自体が故障した状態をブロック成功と数えてはなりません。ポリシーを変更する前に進入が可能だったか、ポリシー適用後に期待した理由で制限されたかを連結して確認します。

画面に「制限中」と表示されたキャプチャ1枚も十分な証拠ではありません。判断結果、API失敗リスト、実際の例示アプリ動作と起動・オフライン前後の状態を一緒に読む必要があります。保存したポリシーのバージョンと試験ビルドが異なる場合、その結果を1つの検証としてまとめません。

再起動試験では、ロック解除前後のデータアクセスと復旧順序も明示します。実際のアプリには予約・バックグラウンド実行・ストレージ・デバイス管理の条件が共に作用するため、単一のPython判断関数の結果をAndroid全体の実行結果に置き換えて表現しません。

失敗判定と復旧完了条件まで試験表に入れる

試験1件には、ビルド識別、Androidバージョンとユーザー、管理役割、ポリシーバージョン、期待結果、API失敗リスト、実際のActivity進入結果を一緒に残すように設計します。アプリ画面の「制限」表示とAPI呼び出しの有無だけを残すと、権限拒否や一部パッケージの失敗を見落とす可能性があります。setPackagesSuspended()の失敗リストを期待したポリシー結果と照合し、例示アプリが実際に進入可能かも別途確認する方式です。Androidパッケージ停止API)

復旧シナリオには、制限解除要求後に例示アプリを再起動できるか、管理画面と必要な緊急機能が維持されるか、再起動後にポリシーバージョンと権限を再確認するかを含みます。このリストは今後実行する試験の設計です。まだ実行していないため、通過数や成功率を付けません。

時間試験では、時計の種類だけでなく、期待した終了時点と許容誤差も事前に定めます。経過時間は過ぎていても、実際の実行時点は予約・バックグラウンド実行条件の影響を受ける可能性があるため、elapsedRealtime()を使用したという事実一つで正確な時刻のブロック成功を宣言しません。その結果はエミュレーターと実機でそれぞれ観測する必要があります。

6. エミュレーター結果と実機結果は別途リストに残す

エミュレーターは条件を繰り返し、失敗を注入するのに有用ですが、メーカー別の電力管理、OSアップデート、実際のデバイスのロック・設定と使用パターンまで全てを代表するわけではありません。実際の携帯電話検証には、別途の許可された機器、管理範囲と復旧計画が必要です。

この記事では、公式REAとAndroid文書を確認し、上記の試験の判定基準を作成しました。REA・JADX実行、APK確保・分析、AndroidポリシーAPI呼び出し、エミュレーターと実機試験は実施していません。実際の実装結果は、ビルド・管理条件・実行範囲と共に別途の検証記録として評価する必要があります。

独立した利用制限実装の状態を見る際には、3つの質問が残ります。どのような成果物を分析したのか、どのようなポリシー入力を検証したのか、どのAndroid権限とデバイス条件で実行を確認したのか。この3つを分離することで、分析ツールの成果とアプリの実際の制限機能を同じ成功表示でまとめずに判断できます。


Comments

コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です