Analysis of APK from the perspective of Android system (2) - Qualitative analysis of APK installation process

statement

  • From the perspective of Android mobile phone users, installing various APPs is basically a three-way process of "search->download->install" from the application market. For the Android system, this is a big project, because the APK is an "outsider" to the Android system, so problems such as how to install it, support its operation with restrictions, and how to prevent it from doing bad things come.
  • The reason for writing this column is to enable customers to quickly install large .
  • This column will analyze the entire life cycle of APK (installation-run-uninstallation) from the perspective of Android system, including static analysis of APK, PackageManagerService, pm command, PackageInstaller, Installd
  • This code is based on LineageOS 14.1 (Android 7.1.1). It refers to some blogs and books. It is not convenient to list them one by one. It is only for learning and knowledge sharing.

1 Overview

There are several ways to install APP on Android system:

  • Install through the app store client;
  • Open the downloaded apk file directly on the device;
  • Connect to PC via Type-C, use adb install command to install;

Android's package management function is distributed among several system components, and they interact with each other during installation, as shown in the figure:
insert image description here

2 APK package storage location and data location in the Android system

Android distinguishes between system-installed and user-installed applications. System apps can be found in the read-only system partition and cannot be modified or uninstalled on production devices. System apps are thus considered trusted and given more permissions, and some signature checks are relaxed.

  • Most system applications are found in the /system/app/ directory;
  • Privileged applications are stored in the /system/priv-app/ directory, and they can be authorized with signatureOrSystem protection level permissions;
  • The /vendor/app/ directory is a vendor-specific application;
  • The applications installed by users in the /data/app/ directory can be uninstalled or replaced arbitrarily;

Application data directories for system and user installations are created under the /data/data/ directory of the userdata partition. The userdata partition also stores some DEX files (data/dalvik-cache/) optimized for user installed applications, system package database (stored in /data/system/packages.xm/), system database and configuration files.

3 Android system active components involved in the APK installation process (Active Component)

3.1 PackageInstaller system application

  PackageInstaller provides a basic GUI for package management, and when it is passed the VIEW or INSTALL_ACTION action with the URI of the APK file intent, it will process the installation package and pop up a confirmation on the screen showing the permissions required by the application. dialog box. Installing apps using PackageInstaller can only be done after the user has enabled the "Unknown Sources" option in the device's security settings.
  PackageInstaller gets the UID and package name of the application requesting the APK install action, and checks if it is a privileged application (installed in /system/priv-app/ directory). If the requesting application is not privileged, it is considered to be an unknown source.
  If the "Unknown Sources" option is enabled, and the user clicks the "OK" button in the dialog, PackageInstaller will call the PackageManagerService service, which will perform the actual installation process. PackageInstaller's GUI will also prompt when the application is updated or uninstalled.

insert image description hereinsert image description hereinsert image description here

3.2 pm command

  The pm command can perform some functions of the system package manager. The pm install or pm uninstall commands can be used to install or uninstall packages. pm install does not rely on unknown sources system options, and does not pop up a GUI interface, it provides a variety of useful options for testing package installation, which PackageInstaller does not have.

hammerhead:/system/framework # pm
usage: pm path [--user USER_ID] PACKAGE
       pm dump PACKAGE
       pm install [-lrtsfd] [-i PACKAGE] [--user USER_ID] [PATH]
       pm install-create [-lrtsfdp] [-i PACKAGE] [-S BYTES]
               [--install-location 0/1/2]
               [--force-uuid internal|UUID]
       pm install-write [-S BYTES] SESSION_ID SPLIT_NAME [PATH]
       pm install-commit SESSION_ID
       pm install-abandon SESSION_ID
       pm uninstall [-k] [--user USER_ID] PACKAGE
       pm set-installer PACKAGE INSTALLER
       pm move-package PACKAGE [internal|UUID]
       pm move-primary-storage [internal|UUID]
       pm clear [--user USER_ID] PACKAGE
       pm enable [--user USER_ID] PACKAGE_OR_COMPONENT
       pm disable [--user USER_ID] PACKAGE_OR_COMPONENT
       pm disable-user [--user USER_ID] PACKAGE_OR_COMPONENT
       pm disable-until-used [--user USER_ID] PACKAGE_OR_COMPONENT
       pm default-state [--user USER_ID] PACKAGE_OR_COMPONENT
       pm hide [--user USER_ID] PACKAGE_OR_COMPONENT
       pm unhide [--user USER_ID] PACKAGE_OR_COMPONENT
       pm grant [--user USER_ID] PACKAGE PERMISSION
       pm revoke [--user USER_ID] PACKAGE PERMISSION
       pm reset-permissions
       pm set-app-link [--user USER_ID] PACKAGE {
    
    always|ask|never|undefined}
       pm get-app-link [--user USER_ID] PACKAGE
       pm set-install-location [0/auto] [1/internal] [2/external]
       pm get-install-location
       pm set-permission-enforced PERMISSION [true|false]
       pm trim-caches DESIRED_FREE_SPACE [internal|UUID]
       pm create-user [--profileOf USER_ID] [--managed] [--restricted] [--ephemeral] [--guest] USER_NAME
       pm remove-user USER_ID
       pm get-max-users

NOTE: 'pm list' commands have moved! Run 'adb shell cmd package'
  to display the new commands.

pm path: print the path to the .apk of the given PACKAGE.

pm dump: print system state associated with the given PACKAGE.

pm install: install a single legacy package
pm install-create: create an install session
    -l: forward lock application
    -r: replace existing application
    -t: allow test packages
    -i: specify the installer package name
    -s: install application on sdcard
    -f: install application on internal flash
    -d: allow version code downgrade (debuggable packages only)
    -p: partial application install
    -g: grant all runtime permissions
    -S: size in bytes of entire session

pm install-write: write a package into existing session; path may
  be '-' to read from stdin
    -S: size in bytes of package, required for stdin

pm install-commit: perform install of fully staged session
pm install-abandon: abandon session

pm set-installer: set installer package name

pm uninstall: removes a package from the system. Options:
    -k: keep the data and cache directories around after package removal.

pm clear: deletes all data associated with a package.

pm enable, disable, disable-user, disable-until-used, default-state:
  these commands change the enabled state of a given package or
  component (written as "package/class").

pm grant, revoke: these commands either grant or revoke permissions
    to apps. The permissions must be declared as used in the app's
    manifest, be runtime permissions (protection level dangerous),
    and the app targeting SDK greater than Lollipop MR1.

pm reset-permissions: revert all runtime permissions to their default state.

pm get-install-location: returns the current install location.
    0 [auto]: Let system decide the best location
    1 [internal]: Install on internal device storage
    2 [external]: Install on external media

pm set-install-location: changes the default install location.
  NOTE: this is only intended for debugging; using this can cause
  applications to break and other undersireable behavior.
    0 [auto]: Let system decide the best location
    1 [internal]: Install on internal device storage
    2 [external]: Install on external media

pm trim-caches: trim cache files to reach the given free space.

pm create-user: create a new user with the given USER_NAME,
  printing the new user identifier of the user.

pm remove-user: remove the user with the given USER_IDENTIFIER,
  deleting all data associated with that user

3.3 PackageManager/PackageManagerService

  PackageManagerService is the core object in the Android package management infrastructure. It is responsible for parsing APK files, initiating app installation, updating and uninstalling packages, maintaining the package database, and managing permissions.
PackageManagerService also provides several installPackage() methods, which are used to execute the package installation process under different parameter options. The most general method is installPackagewithVerificationAndEncryption(), which allows installation of encrypted APK files and package verification via a verification proxy.

3.4 Installer class

  Although PackageManagerService is a privileged Android system service, it runs in the system service process (system UID) and lacks root permissions. However, because creating, deleting, and changing the owner of application directories requires superuser privileges, PackageManagerService delegates these operations to the installd daemon. The Installer class uses the UNIX Domain Socket /dev/socket/installd to initiate an execution request to the installd daemon process for execution.

3.5 installd daemon process

  The installd daemon is a privileged local daemon that provides application and user directory management functionality to the system package manager. It is also used to start the dexopt command, which is used to generate optimized DEX files for newly installed packages.
  The installd daemon can be accessed through the installd local socket, which is only accessible by processes running under system. The installd daemon, which does not execute as root, makes use of the Linux capabilities CAP_DAC_OVERRIDE and CAP_CHOWN to set the UID and GID of files and directories created by the application. You can refer to this article: Daemon process in Android system - main class service (3): installd

3.6 MountService

  MountService is used to mount detachable external storage (SD card and other peripheral storage), and can also be used to mount OBB files (opaque binary blob), which are often used as extension files of applications. MountService is also used to initiate device encryption and change encryption passwords.
  The MountService service also manages a secure container (secure container), which is used to store application files so that non-system applications cannot be accessed. The secure container is encrypted and is used to implement a DRM mechanism called forward locking. Forward locks are mainly used for installations of paid apps to ensure that their APK files cannot be easily copied and redistributed.

3.7 The vold daemon

  vold is the Android storage management daemon. Although MountService contains most of the storage management API, because it runs as the system user, it lacks permissions to mount/unmount disks. These privileged operations are performed by the vold daemon, which runs as the root user.
vold exposes a local socket through UNIX Domain Socket /dev/socket/vold, which can only be accessed by root and mount group members. Because the supplementary GID of the system_server process (of which the MountService service is a child thread) contains mount (GID 1009), MountService is allowed to access the vold command socket. In addition to mounting and unmounting storage, vold can also create and format filesystems and manage secure containers. You can refer to this article: Daemon process in Android system - service in core class (4): vold

3.8 MediaContainerService

  The MediaContainerService service copies the APK files to their final installation location, or to an encrypted container, and allows the PackageManagerService to access the files on removable storage. Use the DownloadManager service to obtain APK files remotely (or through the application market), and download files can be accessed through the contentprovider interface of the DownloadManager service. The PackageManager grants the MediaContainerService process temporary permissions to the downloaded APK. If the APK file is encrypted, the MediaContainerService process first decrypts it. If an encrypted container is required, the MediaContainerService delegates the encrypted container to MountService, which then copies the protected parts of the APK (including code and assets) into a newly created container. Files that do not need to be protected are directly copied to the file system.

3.9 AppDirObserver

  AppDirobserver is a component used to detect the changes of APK files in the application directory, and then call the corresponding PackageManagerService method according to the event type. When an APK file is added to the system, AppDirobserver starts a package scanner to install or update the app. When the APK file is removed, AppDirobserver starts the uninstall process, which deletes the app entry in the app directory and the system package database.

  • The directories monitored on the svstem partition are /system/framework/ (holding the framework resource package famework-resapk), /system/app/ and /system/priv-app (system package);
  • The directory monitored on the vendor partition is /vendor/app;
  • The directories monitored on the userdata partition are /data/app/ and /data/app-private/, where the /data/app-private directory contains temporary files generated during the APK decryption process;

4 Qualitative analysis of an APK installation process

4.1 Parsing and Validating Packages

  Opening an APK file triggers the launch of the "application/vnd.android.package-archive" handler, which is usually the PackageInstallerActivity component of the PackageInstaller system application.

        <activity android:name=".PackageInstallerActivity"
                android:configChanges="orientation|keyboardHidden|screenSize"
                android:excludeFromRecents="true">
            <intent-filter android:priority="1">
                <action android:name="android.intent.action.VIEW" />
                <action android:name="android.intent.action.INSTALL_PACKAGE" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:scheme="file" />
                <data android:scheme="content" />
                <data android:mimeType="application/vnd.android.package-archive" />
            </intent-filter>
            <intent-filter android:priority="1">
                <action android:name="android.intent.action.INSTALL_PACKAGE" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:scheme="file" />
                <data android:scheme="package" />
                <data android:scheme="content" />
            </intent-filter>
            <intent-filter android:priority="1">
                <action android:name="android.content.pm.action.CONFIRM_PERMISSIONS" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

  The PackageInstallerActivity component first checks if the app is trusted (apps from "unknown sources" are not considered). If not trusted, and Settings.Global.INSTALL_NON_MARKET_APPS is set to false (true if the "Unknown sources" checkbox is checked), then a warning box will pop up and the installation process will be terminated.
  If installation is allowed, PackageInstallerActivity parses the APK file and extracts information and package signature from the AndroidManifest.xml file. The integrity of the APK file is automatically verified when the signing certificate is extracted for each entry using java.util.jar.JarFile and related classes. System apps are implicitly trusted and only verify the integrity of the AndroidManifest.xml file when parsing the APK file. For applications that are not system images, all entries need to be verified, such as user-installed applications or update packages for system applications.
  The AndroidMamifest.xml file hash value calculation is also part of the APK parsing process and will be passed to subsequent installation steps. This value will be used to verify that the APK file has not been deleted between the user clicking OK and the APK copy process starting. replace.

4.2 Accept permissions and start the installation process

  After the APK is parsed, PackageInstallerActivity will display the relevant information and required permissions of the application in a dialog box (this is authorized at installation time, but it is authorized at runtime after Android 6). If the user confirms the installation, PackageInstallerActivity forwards the APK file and its manifest digest to InstallAppProgress, which then starts the actual package installation process. The manifest summary includes installation metadata, such as reference URL, installation package name and initial UID. InstallAppProgress then passes the APK URI and installation metadata to the installPackagewithVerificationAndEncryption() method of PackageManagerService to start the installation process. Then it just waits for the installation process to complete and handles any errors.
  The installation method first verifies whether the caller has the INSTALL_PACKAGES permission, which is at the sigmature protection level, and the system application has this permission by default.

4.3 Copy to application directory

  If the APK file is not encrypted, no authentication is required and the next step is to copy it to the application's directory (/data/app). To copy a file, PackageManagerService first creates a temporary file (with vmdl prefix and tmp extension) in the application directory and then delegates to MediaContainerService to do the copying. Files are usually not copied directly, as it may need to be decrypted, or because a forward lock is required, an encrypted container is created for it. Because MediaContainerServices encapsulate these tasks, PackageManagerService does not need to know about its internal implementation.
  When the APK file is successfully copied, any native libraries it contains are extracted to a designated app directory under the system native library directory (/data/app-lib). Next, both the temporary APK file and the library directory are renamed to their final package-name-based names, for example:

hammerhead:/data/app # ls
com.jay.example.gpsdemo-1
hammerhead:/data/app # cd com.jay.example.gpsdemo-1/
hammerhead:/data/app/com.jay.example.gpsdemo-1 # ls
base.apk  lib  oat

Finally, the permissions of the APK file are set to 0644, and its SELinux environment is also set.

4.4 Packet Scanning

  The next step is to trigger package scanning by calling the scanPackageLI() method of PackageManagerService. (If the installation process is stopped before the scan, it will eventually be picked up again by the AppDirobserver instance monitoring the /data/app/ directory, which will trigger another package scan.) For a newly installed
  application, the package manager First create a PackageSettings structure, which includes: package name, code path, individual resource paths (if the package is forward-locked), and a path to a native library. It then assigns a UID to the new package and stores it in the configuration structure. Once the new app has a UID, its data directory can be created.

4.5 Create a data directory

  Because the PackageManagerService does not have sufficient permissions to create and set ownership of the app directory, it sends the installd daemon an install command that includes parameters such as the package name, UID, GID, and seinfo label (for SELinux), thereby converting the directory to Creation actions are delegated to the installd daemon. Then, the installd daemon creates the data directory of the package (for example, when installing the com.jay.example.gpsdemo package, its data directory is /data/dala/com.jay.example.gpsdemo/), the shared native library directory (/data /app-lib/com.jay.example.gpsdemo/), local library record (/data/data/com.jay.example.gpsdemo/lib/). Then, it sets the permissions of the package directory to 0751, and in the native library directory, creates a symbolic link to the app's native library. Finally, set the SELinux environment of the package directory and switch its owner to the UID and GID that the app was assigned.
  When all necessary directories are created, control is returned to PackageManagerService, which then extracts all native libraries into the application's native library directory and creates symbols in /data/data/com.jay.example.gpsdemo/lib/ Link.

4.6 generate odex

  The next step is to generate odex (optimized DEX) files for the application code. This is done by sending the dexopt command to the installd daemon, also by the installd daemon. Next, the installd daemon forks a dexopt process, which creates odex files in the /data/dalvik-cache/ directory. If the ART virtual machine is used on an Android device, the installd daemon uses the dex2oat command to generate native code.

4.7 File and directory structure

Taking "Xianyu app" as an example, the content of the /data/data/com.taobao.idlefish directory after being installed on the LineageOS 14.1 Nexus 5 mobile phone:

hammerhead:/data/app/com.taobao.idlefish-1 # ls -al
total 118768
drwxr-xr-x 4 system system       4096 2023-06-12 12:28 .
drwxrwx--x 5 system system       4096 2023-06-12 12:29 ..
-rw-r--r-- 1 system system  121598101 2023-06-12 12:28 base.apk
drwxr-xr-x 3 system system       4096 2023-06-12 12:28 lib
drwxrwx--x 3 system install      4096 2023-06-12 12:28 oat

hammerhead:/data/app/com.taobao.idlefish-1/oat/arm # ls -al
total 71956
drwxrwx--x 2 system install       4096 2023-06-12 12:28 .
drwxrwx--x 3 system install       4096 2023-06-12 12:28 ..
-rw-r--r-- 1 system u0_a29999 73666984 2023-06-12 12:28 base.odex

hammerhead:/data/data/com.taobao.idlefish # ls -al
total 92
drwx------  22 u0_a68 u0_a68 4096 2023-06-12 12:30 .
drwxrwx--x 101 system system 4096 2023-06-12 12:29 ..
drwxrwx--x   6 u0_a68 u0_a68 4096 2023-06-12 12:29 app_SGLib
drwxrwx--x   2 u0_a68 u0_a68 4096 2023-06-12 12:29 app_accs
drwxrwx--x   2 u0_a68 u0_a68 4096 2023-06-12 12:29 app_cyclone
drwxrwx--x   3 u0_a68 u0_a68 4096 2023-06-12 12:29 app_efs
drwxrwx--x   2 u0_a68 u0_a68 4096 2023-06-12 12:29 app_flutter
drwxrwx--x   3 u0_a68 u0_a68 4096 2023-06-12 12:29 app_local_libs
drwxrwx--x   2 u0_a68 u0_a68 4096 2023-06-12 12:29 app_patrons
drwxrwx--x   2 u0_a68 u0_a68 4096 2023-06-12 12:29 app_sslcache
drwxrwx--x   2 u0_a68 u0_a68 4096 2023-06-12 12:29 app_textures
drwxrwx--x   5 u0_a68 u0_a68 4096 2023-06-12 12:29 app_tombstone
drwx------   2 u0_a68 u0_a68 4096 2023-06-12 12:30 app_u4_webview
drwxrwx--x   5 u0_a68 u0_a68 4096 2023-06-12 12:30 app_ucmsdk
drwx------   3 u0_a68 u0_a68 4096 2023-06-12 12:29 app_webview
drwxrwx--x   5 u0_a68 u0_a68 4096 2023-06-12 12:30 app_wpksdk
drwxrwx--x   7 u0_a68 u0_a68 4096 2023-06-12 12:29 app_zcache
drwxrwx--x   4 u0_a68 u0_a68 4096 2023-06-12 12:30 cache
drwxrwx--x   3 u0_a68 u0_a68 4096 2023-06-12 12:29 code_cache
drwxrwx--x   2 u0_a68 u0_a68 4096 2023-06-12 12:29 databases
drwxrwx--x  27 u0_a68 u0_a68 4096 2023-06-12 12:29 files
lrwxrwxrwx   1 root   root     39 2023-06-12 12:29 lib -> /data/app/com.taobao.idlefish-1/lib/arm
drwxrwx--x   2 u0_a68 u0_a68 4096 2023-06-12 12:30 shared_prefs

Description of each file:

  • base.apk is the APK file;
  • The lib directory is the decompressed native library files, which belong to the system user and are globally readable;
  • In the oat directory is the odex file, the owner is set to system, and all groups are set to u0_a29999, which includes all device users who install the application. This allows all users to share the same odex file, thus avoiding creating a separate copy of the file for each user, reducing disk usage on multi-user supported devices.
  • The application's data directory /data/data/com.taobao.idlefish and its subdirectories belong to a specific Linux user, which is defined by the combination of the device user ID (u0, if it is a single-user device) and appID (a68) where the application is installed Then it becomes u0_a68.

4.8 Add new installation package to packages.xml

The next step is to add the package to the system package database. An entry for a newly installed package would look like this:

    <package name="com.taobao.idlefish" codePath="/data/app/com.taobao.idlefish-1" nativeLibraryPath="/data/app/com.taobao.idlefish-1/lib" primaryCpuAbi="armeabi-v7a" publicFlags="945307204" privateFlags="0" ft="188addc6838" it="188addd6079" ut="188addd6079" version="330" userId="10068" installer="com.android.packageinstaller">
        <sigs count="1">
            <cert index="6" key="3082023b308201a4a003020102020456e7ce5f300d06092a864886f70d01010505003061310e300c060355040613056368696e61310b3009060355040813027a6a310b300906035504071302687a3110300e060355040a1307616c69626162613110300e060355040b1307616c69626162613111300f0603550403130869646c65666973683020170d3136303331353038353730335a180f32313136303232303038353730335a3061310e300c060355040613056368696e61310b3009060355040813027a6a310b300906035504071302687a3110300e060355040a1307616c69626162613110300e060355040b1307616c69626162613111300f0603550403130869646c656669736830819f300d06092a864886f70d010101050003818d003081890281810089253f9181dae9888669b5dfc0fefb91f9630c575f93cc70c8c20be4af7b1714d3f5d5870c59b73d78481ac29e49fffc49a4a2b441fca387ebeeea2bcb2c71590429d901412d633d5eb445529cb57077a78a2b0d46fbf8c12b3c79aa22952c6ab22b80737c43404a5949d83f18720760ee4d191adb93ee9003ed2da9b5bb1a930203010001300d06092a864886f70d0101050500038181000ea193fcb0de60ed6d4a76d957a6f2bf00f5103ab31714149745b9583924cd1b84afa35e36c2a283327448565ebce36c8b4c1daa31fdf7b46ee2c099195e971730eeb0a42f531e80714ac99dcf3aec31406bd18fd445158f8b638dc82787dc14a8840a9134878947ad4ae7eaec1925dbd06c98cc11ceaf60557f7cd088f373ef" />
        </sigs>
        <perms>
            <item name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" granted="true" flags="0" />
            <item name="com.taobao.idlefish.push.permission.MESSAGE" granted="true" flags="0" />
            <item name="android.permission.USE_CREDENTIALS" granted="true" flags="0" />
            <item name="android.permission.MODIFY_AUDIO_SETTINGS" granted="true" flags="0" />
            <item name="android.permission.MANAGE_ACCOUNTS" granted="true" flags="0" />
            <item name="android.permission.NFC" granted="true" flags="0" />
            <item name="android.permission.CHANGE_NETWORK_STATE" granted="true" flags="0" />
            <item name="android.permission.RECEIVE_BOOT_COMPLETED" granted="true" flags="0" />
            <item name="android.permission.BLUETOOTH" granted="true" flags="0" />
            <item name="android.permission.CHANGE_WIFI_MULTICAST_STATE" granted="true" flags="0" />
            <item name="android.permission.GET_TASKS" granted="true" flags="0" />
            <item name="android.permission.AUTHENTICATE_ACCOUNTS" granted="true" flags="0" />
            <item name="android.permission.INTERNET" granted="true" flags="0" />
            <item name="android.permission.REORDER_TASKS" granted="true" flags="0" />
            <item name="com.android.browser.permission.READ_HISTORY_BOOKMARKS" granted="true" flags="0" />
            <item name="android.permission.BLUETOOTH_ADMIN" granted="true" flags="0" />
            <item name="com.taobao.idlefish.permission.C2D_MESSAGE" granted="true" flags="0" />
            <item name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" granted="true" flags="0" />
            <item name="android.permission.BROADCAST_STICKY" granted="true" flags="0" />
            <item name="android.permission.CHANGE_WIFI_STATE" granted="true" flags="0" />
            <item name="android.permission.FLASHLIGHT" granted="true" flags="0" />
            <item name="android.permission.ACCESS_NETWORK_STATE" granted="true" flags="0" />
            <item name="android.permission.USE_FINGERPRINT" granted="true" flags="0" />
            <item name="com.taobao.idlefish.permission.MIPUSH_RECEIVE" granted="true" flags="0" />
            <item name="com.taobao.idlefish.permission.PUSH_PROVIDER" granted="true" flags="0" />
            <item name="com.taobao.idlefish.permission.PROCESS_PUSH_MSG" granted="true" flags="0" />
            <item name="android.permission.VIBRATE" granted="true" flags="0" />
            <item name="android.permission.ACCESS_WIFI_STATE" granted="true" flags="0" />
            <item name="android.permission.REQUEST_INSTALL_PACKAGES" granted="true" flags="0" />
            <item name="com.android.launcher.permission.INSTALL_SHORTCUT" granted="true" flags="0" />
            <item name="android.permission.WAKE_LOCK" granted="true" flags="0" />
        </perms>
        <proper-signing-keyset identifier="7" />
    </package>
  • The <sigs> element contains the package signing certificate (usually only one) as a DER-encoded hexadecimal string, or in the case of multiple apps signed by the same certificate, a reference to the first occurrence of the certificate;
  • The <perms> element contains the permissions granted to the application;
  • <signing-keyset> is a reference to the set that holds the application signing key, which includes all public keys (not certificates) that sign files inside the APK.

4.9 Package properties

  The root element <package> contains the core attributes of each package, such as: installation location and version number, etc. The main package properties are shown in the table below. The information in each package entry can be obtained through the getPackageInfo(String packageName, int flags) method of the android.content.pm.PackageManager SDK class. This method will return an instance of PackageInfo, which encapsulates each entry in packages.xml valid properties of . It also contains information about components, permissions, and attributes defined in the manifest file.

Attributes illustrate
name Package names
codePath The full path to where the package is located
resourcePath The full path to the public part of the bundle (main resource bundle and manifest file). Lock apps for forwarding
nativeLibraryPath The full path of the directory where the native library is stored
flags Application related flags
ft APK file timestamp (UNIX millisecond time, System.currentTimeMillis())
it Time when the application was first installed (UNIX milliseconds)
ut The time (in UNIX milliseconds) when the last update was applied
version The version number of the package, specified by the versionCode attribute in the application's manifest file
userId The application's kernel UID
installer The name of the application that installed the app
sharedUserId The shared user ID of the package, specified by the sharedUserId attribute in the manifest file

4.10 Update components and permissions

  After creating the packages.xml entries, the PackageManagerService scans for all Android components defined in the new application's manifest and adds them to its internally loaded in-memory component registry. Next, any permission groups and permissions declared by the app are scanned and added to the permissions registry. Finally, modify the package database (package entries and any new permissions) saved on disk, and then PackageManagerService sends ACTION_PACKAGE_ADDED to notify other components that a new application has been added.

5 Install encrypted APK

5.1 Generate encrypted APK

  Encrypted APK files can be encrypted using the enc OpenSSL command. As follows. The AES encryption algorithm in CBC mode is used here, the key length is 128-bit, and the initial vector IV is the same as the key.

openssl enc -aes-128-cbc -K 000102030405060708090A0BOCODOEOF -iv 000102030405060708090A0BOCOD0E0F -in test-app.apk -out test-app-enc.apk

5.2 Install encrypted APK

adb install [-l] [-r] [-s] [--algo <algorithm name> --key <hex-encoded key> --iv <hex-encoded iv>] <file>

  The --algo, --key, and --iv parameters in this command allow the encryption algorithm, key, and initialization vector (IV) to be specified, respectively.

Install encrypted APKs by passing the encryption algorithm, key, and IV to the adb install command:

adb instal1 --algo 'AES/CBC/PKCS5Padding' --key 0001020340596070809ABBCODEEEF --iv 000102030405060708090AOBOCODOEOF test-app-enc.apk

  As shown in the output of Success, the APK installation process did not encounter any errors. The actual APK file is copied to the /data/app directory, and comparing its hash to the encrypted APK reveals that they are actually different files. Its hash happens to be the same as the unencrypted APK hash, so when the APK is installed, it is decrypted using the provided encryption parameters (algorithm, key, and IV).

6 pack verification

  When the package verification function is enabled, the APK will be scanned by the verifier before installation. When the verifier thinks that the APK may be harmful, the system will pop up a warning box or interrupt the installation process. Authentication is turned on by default on supported devices, but requires the user's permission on first use. App verification can be turned on or off through the "Verify Apps" option in the system settings page.

Guess you like

Origin blog.csdn.net/Xiaoma_Pedro/article/details/131158760