8

Note: already saw this question

Checking the android app location on Oreo emulator, the APK is still installed at /data/app. However, instead of the following format:

/data/app/<package_name> or optionally /data/app/<package_name>-1 

it's now

/data/app/<package_name>-_-<22 chars base 64>

or

/data/app/<package_name>-<some chars>-<22 chars base 64>

Does anyone know anything about this change? I've tried googling, but 'APK android location base64' combinations will yield a sea of unrelated results (or google will ignore the base64 keyword)

A link to a google blog or github commit would be nice. I'd settle for the AOSP general location if anyone knows that. Ideally, I'd like to know why (the change), as well as how (the base64 is generated).

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
Roy Falk
  • 1,685
  • 3
  • 19
  • 45
  • I'm trying to work out why you would need to know this information. Why would you need to know this? – Tigger Dec 24 '17 at 08:34
  • 1
    Because knowledge is power (https://en.wikipedia.org/wiki/Scientia_potentia_est). Also, because I'm curious and stumbled onto this when poking around Android. It may not have an immediate use, but I, or someone else may have one in the future. – Roy Falk Dec 24 '17 at 08:39
  • I see two possibilities (just guesses): The base64 characters may be related to the app signature or to the local Android user account (multi-user Android system). Are they the same for different apps or are they static for each app? – Robert Dec 24 '17 at 13:38

1 Answers1

11

Since Android Oreo, the install path for APKs has been changed, see: commit or https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r36/services/core/java/com/android/server/pm/PackageManagerService.java

When PackageManagerService is trying to find a right path for installing APKs, it is using getNextCodePath(File targetDir, String packageName) method. Before Android Oreo, the code is:

private File getNextCodePath(File targetDir, String packageName) {
    int suffix = 1;
    File result;
    do {
        result = new File(targetDir, packageName + "-" + suffix);
        suffix++;
    } while (result.exists());
    return result;
}

Since Android Oreo, the code has been changed to:

private File getNextCodePath(File targetDir, String packageName) {
    File result;
    SecureRandom random = new SecureRandom();
    byte[] bytes = new byte[16];
    do {
        random.nextBytes(bytes);
        String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
        result = new File(targetDir, packageName + "-" + suffix);
    } while (result.exists());
    return result;
}
whoopdedoo
  • 2,815
  • 23
  • 46
Zhang quaful
  • 126
  • 2
  • 5
  • Can some one tell me the exact reason for this change? I guess it is for security. But it seems we can make the app sub directory to other non-readable to avoid. – progquester Feb 28 '20 at 04:00
  • 2
    @ProgQuester it's explained in the [commit](https://android.googlesource.com/platform/frameworks/base/+/5e10e8f1b2126f031b976b853c3f150418f3b342) and says: "...This prevents apps (both normal and ephemeral) from learning what applications are installed by checking for the existence of /data/app/com.example.package-1. ..." – scooter Dec 05 '20 at 03:57