Skip to content

EA Desktop

erri120 edited this page Jan 18, 2023 · 14 revisions

EA is deprecating Origin and replacing it with EA Desktop. In doing so, they changed how information is stored, and the previous method used by Origin does not work anymore. Instead of storing files as plain HTTP queries, EA has decided to encrypt their files. I went ahead and broke this encryption and will explain how you can do the same (it's very easy).

Note: this is not the only way of finding games installed with EA Desktop. Check the section Alternatives for more information.

Breaking the Encryption

Overview

Let's start by talking about the encrypted file itself. It is located at C:\ProgramData\EA Desktop\530c11479fe252fc5aabc24935b9776d4900eb3ba58fdc271e0d6229413ad40e\IS and you can grab my encrypted file from GitHub. I will be using CyberChef to walk you through everything.

Here is a simple Hexdump of the first 240 bytes:

Hexdump of the first 240 bytes

As you can see, the input contains some hash at the beginning and then an encrypted section. As a side note: the Shannon Entropy is a good measure to identify if the input is structured or unstructured:

Visualization of the Shannon Scale on the input

The section after the hash in the input file has a Shannon Entropy of 7.965, which suggests it's either encrypted or compressed.

The input is encrypted using AES with a key size of 256 bits in the Cipher Block Chaining (CBC) mode that requires an Initialization Vector (IV) of 128 bits. You can use this CyberChef link to see the decryption in action:

Screenshot of CyberChef that shows the input fully decrypted

Key and IV generation

graph TD
    allUsersGenericId & IS --> allUsersGenericIdIS[allUsersGenericId + IS]
    hardwareInfo[Hardware Information] --> |SHA1| hardwareInfoHash[Hardware Info Hash]
    allUsersGenericIdIS & hardwareInfoHash --> combine[allUsersGenericId + IS + Hardware Info Hash] --> |SHA3 256| KEY
    allUsersGenericIdIS --> |SHA3 256| IV

This flowchart displays the process of generating the Key and IV. As you can see, the key is unique for each user and the IV is not unique. Let's start with the IV (CyberChef):

IV = SHA3_256("allUsersGenericId" + "IS") = 84efc4b836119c20419398c3f3f2bcef6fc52f9d86c6e4e8756aec5a8279e492

The IV is just the SHA3 256 hash of allUsersGenericIdIS. This is the same for every user. The key is a bit more complicated. It is made up of unique hardware information gathered from the WMI and the Windows API:

  • Win32_BaseBoard Manufacturer
  • Win32_BaseBoard SerialNumber
  • Win32_BIOS Manufacturer
  • Win32_BIOS SerialNumber
  • hex string of the Serial Number obtained from GetVolumeInformationW for the C:\ drive
  • Win32_VideoController PNPDeviceId
  • Win32_Processor Manufacturer
  • Win32_Processor ProcessorId
  • Win32_Processor Name

If you want to try this out yourself, you can get the WMI values by using the wmic tool:

wmic PATH Win32_BaseBoard get Manufacturer

All values are then joined together with ; as a separator into one long string and then hashed using SHA1:

var sb = new StringBuilder();

sb.Append(baseBoardManufacturer);
sb.Append(';');
sb.Append(baseBoardSerialNumber);
sb.Append(';');
sb.Append(biosManufacturer);
sb.Append(';');
sb.Append(biosSerialNumber);
sb.Append(';');
sb.Append(volumeSerialNumber);
sb.Append(';');
sb.Append(videoControllerDeviceId);
sb.Append(';');
sb.Append(processorManufacturer);
sb.Append(';');
sb.Append(processorId);
sb.Append(';');
sb.Append(processorName);
sb.Append(';');

var hardwareInfoString = sb.ToString();

As an example, this is my output (CyberChef):

ASRock;                      ;American Megatrends Inc.;To Be Filled By O.E.M.;7CB7433E;PCI\VEN_10DE&DEV_2486&SUBSYS_147A10DE&REV_A1\4&2283F625&0&0019;AuthenticAMD;178BFBFF00A20F10;AMD Ryzen 7 5800X 8-Core Processor             ;

The final key is then the SHA3 256 hash of the combination of allUsersGenericId + IS + the SHA1 hardware info hash (CyberChef):

SHA1(hardwareInfo) = "a2a0ad25aa3556c035b34ea63863794e54ad5b53"

SHA3_256("allUsersGenericId" + "IS" + "a2a0ad25aa3556c035b34ea63863794e54ad5b53") = 01b42f0e7e3b32e7c4251bc38fa2ae2edb8dc26498e5b73e2a92ac9e8ffcb4f4

Since the Key is derived from hardware information, the key will be different, if you change your CPU, GPU, Motherboard or your C:\ drive, and you can't decrypt the file anymore.

Decrypted File

Once you have decrypted the file, you will find that it's just JSON:

{
    "installInfos": [
        {
            "baseInstallPath": "",
            "baseSlug": "plants-vs-zombies-garden-warfare-2",
            "contentManifestLaunchers": "",
            "detailedState": {
                "installPhase": 0,
                "installReason": 0,
                "installStatus": 0,
                "previousInstallStatus": 0
            },
            "dlcSubPath": "",
            "executableCheck": "[]",
            "installCheck": "[HKEY_LOCAL_MACHINE\\SOFTWARE\\PopCap\\Plants vs Zombies GW2\\Install Dir]gw2.main_win64_retail.exe",
            "installedLocale": "en_US",
            "installedVersion": "",
            "localInstallProperties": {
                "launchers": [],
                "localManifestVersion": {
                    "build": 0,
                    "major": 0,
                    "minor": 0,
                    "rev": 0
                },
                "useGameVersionFromManifest": false
            },
            "localUninstallProperties": {
                "uninstallCommand": "",
                "uninstallParameters": ""
            },
            "softwareId": "Origin.SFT.50.0000345"
        },
        {
            "baseInstallPath": "E:\\SteamLibrary\\steamapps\\common\\Titanfall2\\",
            "baseSlug": "titanfall-2",
            "contentManifestLaunchers": "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Respawn\\Titanfall2\\Install Dir]Titanfall2.exe[HKEY_LOCAL_MACHINE\\SOFTWARE\\Respawn\\Titanfall2\\Install Dir]Titanfall2_trial.exe",
            "detailedState": {
                "installPhase": 0,
                "installReason": 0,
                "installStatus": 5,
                "previousInstallStatus": 0
            },
            "dlcSubPath": "",
            "executableCheck": "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Respawn\\Titanfall2\\Install Dir]Titanfall2.exe",
            "installCheck": "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Respawn\\Titanfall2\\Install Dir]Titanfall2.exe",
            "installedLocale": "en_US",
            "installedVersion": "1.0.1.3",
            "localInstallProperties": {
                "launchers": [
                    {
                        "cmdArgs": "",
                        "exePath": "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Respawn\\Titanfall2\\Install Dir]Titanfall2.exe",
                        "executeElevated": false,
                        "isTimedTrial": false,
                        "requires64BitOs": true
                    },
                    {
                        "cmdArgs": "",
                        "exePath": "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Respawn\\Titanfall2\\Install Dir]Titanfall2_trial.exe",
                        "executeElevated": false,
                        "isTimedTrial": true,
                        "requires64BitOs": true
                    }
                ],
                "localManifestVersion": {
                    "build": 1,
                    "major": 1,
                    "minor": 0,
                    "rev": 3
                },
                "useGameVersionFromManifest": true
            },
            "localUninstallProperties": {
                "uninstallCommand": "",
                "uninstallParameters": ""
            },
            "softwareId": "Origin.SFT.50.0000532"
        },
        {
            "baseInstallPath": "M:\\Games\\new EA App is shit\\Apex\\",
            "baseSlug": "apex-legends",
            "contentManifestLaunchers": "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Respawn\\Apex\\Install Dir]EasyAntiCheat_launcher.exe",
            "detailedState": {
                "installPhase": 2,
                "installReason": 1,
                "installStatus": 3,
                "previousInstallStatus": 2
            },
            "dlcSubPath": "",
            "executableCheck": "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Respawn\\Apex\\Install Dir]EasyAntiCheat_launcher.exe",
            "installCheck": "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Respawn\\Apex\\Install Dir]__Installer\\installerdata.xml",
            "installedLocale": "en_US",
            "installedVersion": "1.1.0.7",
            "localInstallProperties": {
                "launchers": [
                    {
                        "cmdArgs": "",
                        "exePath": "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Respawn\\Apex\\Install Dir]EasyAntiCheat_launcher.exe",
                        "executeElevated": false,
                        "isTimedTrial": false,
                        "requires64BitOs": true
                    }
                ],
                "localManifestVersion": {
                    "build": 0,
                    "major": 1,
                    "minor": 1,
                    "rev": 7
                },
                "useGameVersionFromManifest": true
            },
            "localUninstallProperties": {
                "uninstallCommand": "C:\\Program Files\\Common Files\\EAInstaller\\Apex\\Cleanup.exe",
                "uninstallParameters": "uninstall_game -autologging"
            },
            "softwareId": "Origin.SFT.50.0000848"
        },
        {
            "baseInstallPath": "M:\\SteamLibrary\\steamapps\\common\\Need for Speed Heat\\",
            "baseSlug": "need-for-speed-heat",
            "contentManifestLaunchers": "[HKEY_LOCAL_MACHINE\\SOFTWARE\\EA Games\\Need for Speed Heat\\Install Dir]NeedForSpeedHeatTrial.exe[HKEY_LOCAL_MACHINE\\SOFTWARE\\EA Games\\Need for Speed Heat\\Install Dir]NeedForSpeedHeat.exe",
            "detailedState": {
                "installPhase": 0,
                "installReason": 0,
                "installStatus": 5,
                "previousInstallStatus": 0
            },
            "dlcSubPath": "",
            "executableCheck": "[HKEY_LOCAL_MACHINE\\SOFTWARE\\EA Games\\Need For Speed Heat\\Install Dir]NeedForSpeedHeat.exe",
            "installCheck": "[HKEY_LOCAL_MACHINE\\SOFTWARE\\EA Games\\Need For Speed Heat\\Install Dir]NeedForSpeedHeat.exe",
            "installedLocale": "en_US",
            "installedVersion": "1.0.60.7041",
            "localInstallProperties": {
                "launchers": [
                    {
                        "cmdArgs": "",
                        "exePath": "[HKEY_LOCAL_MACHINE\\SOFTWARE\\EA Games\\Need for Speed Heat\\Install Dir]NeedForSpeedHeatTrial.exe",
                        "executeElevated": false,
                        "isTimedTrial": true,
                        "requires64BitOs": true
                    },
                    {
                        "cmdArgs": "",
                        "exePath": "[HKEY_LOCAL_MACHINE\\SOFTWARE\\EA Games\\Need for Speed Heat\\Install Dir]NeedForSpeedHeat.exe",
                        "executeElevated": false,
                        "isTimedTrial": false,
                        "requires64BitOs": true
                    }
                ],
                "localManifestVersion": {
                    "build": 60,
                    "major": 1,
                    "minor": 0,
                    "rev": 7041
                },
                "useGameVersionFromManifest": true
            },
            "localUninstallProperties": {
                "uninstallCommand": "",
                "uninstallParameters": ""
            },
            "softwareId": "Origin.SFT.50.0001079"
        },
        {
            "baseInstallPath": "",
            "baseSlug": "need-for-speed-hot-pursuit-remastered",
            "contentManifestLaunchers": "",
            "detailedState": {
                "installPhase": 0,
                "installReason": 0,
                "installStatus": 0,
                "previousInstallStatus": 0
            },
            "dlcSubPath": "",
            "executableCheck": "[]",
            "installCheck": "[HKEY_LOCAL_MACHINE\\SOFTWARE\\EA Games\\Need For Speed Hot Pursuit Remastered\\Install Dir]NFS11Remastered.exe",
            "installedLocale": "en_US",
            "installedVersion": "",
            "localInstallProperties": {
                "launchers": [],
                "localManifestVersion": {
                    "build": 0,
                    "major": 0,
                    "minor": 0,
                    "rev": 0
                },
                "useGameVersionFromManifest": false
            },
            "localUninstallProperties": {
                "uninstallCommand": "",
                "uninstallParameters": ""
            },
            "softwareId": "Origin.SFT.50.0001232"
        }
    ],
    "schema": {
        "version": 21
    }
}

Note: Looking at some other decrypted files, I think they contain every single item you own. This includes DLCs and Add-ons, as well as games that are not installed.

Alternatives

If you don't want to decrypt the file, there are alternatives:

1: Use the registry

Maybe you don't want to find every single game, or you only need a known amount of games. In this case, you can just use the registry key from the installerdata.xml file. Every EA game has a folder called __Installer which contains an installerdata.xml file which can give you the correct registry key:

<?xml version='1.0' encoding='utf-8'?>
<DiPManifest version="4.0">
  <runtime>
    <launcher uid="1-1">
      <filePath>[HKEY_LOCAL_MACHINE\SOFTWARE\Respawn\Apex\Install Dir]EasyAntiCheat_launcher.exe</filePath>
    </launcher>
  </runtime>
</DiPManifest>

In this case, you have to open the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Respawn\Apex and extract the value Install Dir.

2: Use the EA servers

EA actually provides an API you can use. The issue is that you have to use the API and authenticate with it. I suggest looking at the Playnite code, for reference.