• Development
  • I made a new feature that spoofs media DRM id

I created a custom system service that provides a single function to generate a unique media DRM ID per user per app—similar to how the Android ID functions. Here’s how it works:

  • The function retrieves the Android ID of the calling user and the package name.
  • It concatenates these two strings and computes a SHA-256 hash.
  • From the resulting hash, it extracts the first 32 characters.
  • The getPropertyByteArray function of MediaDrm is modified to call this custom function, convert the resulting string into a byte array, and return this spoofed value instead of the original one.

This approach ensures that each user/profile receives a consistent but unique media DRM ID for each app. If the Android ID or package name changes, the DRM ID updates accordingly; otherwise, it remains stable for that user/app combination.

Demo Video
I prepared a demo video to illustrate the functionality:

  • In the first part, you can see the Owner, Demo1, and Demo2 profiles using the pre-installed “devcheck” app, each showing a different DRM ID.
  • In the later parts (Demo4 and Demo5), I installed the same app from the internet to demonstrate that the modification works with both pre-installed and non-altered apps.
  • Finally, the video shows that after removing and reinstalling the app, the DRM ID remains consistent (as long as the Android ID and package name are unchanged), which is the expected behavior.

Tell me what you think about it in the comments.

    dj5 Tell me what you think about it in the comments.

    You are leaking the user ID and package name to the remote server. I doubt the actual Media DRM functionality does that. This would mean the remote server can now detect if you are using an unofficial client app instead of the official one, and can detect which of your user profiles you are running the app in. Plain hashing is not enough to conceal this, since both user ID and package name are really low entropy, so it can be brute-force searched.

    You need to add a (possibly persistent) high entropy random string too as input to the hashing to conceal this. Unless I misremember, there are specific ways to do that that are provably secure.

    • dj5 replied to this.

      dj5

      It sounded to me like you do:

      MediaDrmID = SHA256(userid + package_name)

      I was pointing out that this leaks a lot of information MediaDRM IDs usually don't. Especially if userid always is 0, 1, 2, .. and package_name is any of the known clients for that service, it would be easy for the remote end to calculate all possible hashes, and thus being able to detect userid and package_name, essentially reversing the hash.

      I instead suggested you do something like this to prevent that, essentially salting the hashes:

      MediaDrmID = SHA256(random_persistent_key + userid + package_name)

      But I didn't know ANDROID_ID was a thing. If that one already has high enough entropy, that might be enough. Seems unclear from the documentation I found whether it even is random at all though, but I guess you know.

      • dj5 replied to this.

        ryrona

        I'm not sure which server you're referring to? The app developer already knows the package name because they created the app, and they also have access to a lot of information about your phone. All the details shown in the video—such as the phone model for example—are all available to any app without requiring any permissions. My focus was solely on modifying the DRM ID that remains constant, which allows any app to identify you.

          dj5 I'm not sure which server you're referring to?

          MediaDRM is used to deliver encrypted video or audio data to prevent unauthorized copying or saving of that video or audio data. For example NetFlix would use it so people cannot copy their movies. My understanding is that the app that fetches the MediaDRM ID sends this to whatever server that is supposed to send video or audio data (e.g NetFlix server in my example), so that that server can attest the security level provided by the MediaDRM implementation of your device, and can learn about the encryption key to encrypt media with. This is the server I mean. Of course they cannot send any media data at all to your device if you provide a faked MediaDRM ID, but this is more to prevent other apps from abusing this MediaDRM functionality to uniquely fingerprint you. The MediaDRM ID is still sent to a server owned by that app for fingerprinting purposes in that case.

          They do not need to know which user profile you are running the app in, yet, maybe you are now leaking that information to them. Likewise, if they still permit access to their service if you supply a fake MediaDRM ID, which is likely if they only use it for fingerprinting but do not verify it, you don't want to leak the package name either, since maybe you are using an unofficial client, not the official one provided by the service, and you don't want them to know about that.

          That was my thinking.

          2 months later

          This is

          dj5
          This is amazing. So many ppl have been trying to do this to ensure privacy and help prevent apps from tracking you. As far as I know this was the last major identifier that apps were still able to use in graphene to directly and consistently monitor users.

          How exactly did you do this? Is there a guide that someone, like me, can follow to duplicate this?