Monday, May 20, 2024

Android 14 - Battery Usage and App Usage Events

Moin! :-)

What is this post about?


I've switched my test device from Android 13 to Android 14 - finally - and so I have a lot of new stuff to look into.  I've done some analysis on the battery_usage_v9 database. It was introduced with Android 14.

On Android 12 and 13 there also seems to exist an older version of this database - battery_usage_v4 - Kevin Pagano (stark4n6) wrote a blog post about it and an ALEAPP parser in 2021. His blogpost can be found here.



What type of data to expect?


Like Kevin Pagano already wrote in his post - the data in this databases seems to correlate with the Android Battery Usage and Battery Settings Screens in the Android UI.
Can be found under Settings - Battery in Android and shows something like in the following screen shots to see.


Figure 1: Settings Services - Battery


You can get information on the current battery charging and health status and you can get information on the apps that used the battery, in foreground and in background.
So at least this information should also be in the battery_usage_v9 database.

Okay, let's start digging into the database and its data.

Test device and tested version


Test devices: Fairphone 3 and Fairphone 4
OS: Android 14


The tables


Table: BatteryState

This table already existed in the battery_usage_v4 database. But now it has a different structure. Here is a short overview:

  • mid  - just an iterating id for this table
  • uid  - the uid of the app
  • userId - the id of the user the app is running for (e.g. 0 for default user)
  • packageName - name of the package (e.g. com.android.settings)
  • timestamp - Timestamp event was written in epoch - this only happen every hour by the system
  • consumerType - int value - I have the values 1 and 3 - but I don't know what they mean.
  • isFullChargeCycleStart - Zero or One - in the UI it is said, that only the apps since the last full charge are shown - I guess that this field hold the value if the app shall be shown in UI or not. Double check required.
  • batteryInformation - No idea what this is - Sample data in it: 
CgYIYRACGAIQABi9sscTIg1FdXJvcGUvQmVybGluOhFHb29nbGUgUGxheSBTdG9yZVEAAAAAAAAA
AFkQG44jJZ9DP2EAAAAAAAAAAGj///////////8BcAB4AIEBAAAAAAAAAACJAQAAAAAAAAAAkQEA
AAAAAAAAAJkBAAAAAAAAAACgAQA=
          No idea what this is - when playing a bit with coding/decoding I can recognize                   strings in it after decoding with base64: 
         Europe/Berlin:Google Play StoreQ  
 
  • batteryInformationDebug - here we can find similar information stored like the one in the older database version
# com.android.settings.fuelgauge.batteryusage.BatteryInformation@ffa34700
app_label: "Google Play Store"
background_usage_time_in_ms: 0
boot_timestamp: 41015613
consume_power: 5.988055555555555E-4
device_battery_state {
  battery_health: 2
  battery_level: 97
  battery_status: 2
}
drain_type: -1
foreground_service_usage_time_in_ms: 0
foreground_usage_time_in_ms: 0
zone_id: "Europe/Berlin"
The batteryInformationDebug was empty on my Fairphone 4, but held this information on my FP3 - I don't know exactly why - I read something about new features coming with Android 14 for battery health monitoring and that to use them you need to allow it in the developer options. But I did not do this. Either way - let's go through data what it can mean.

    • app_label - Yeah - the app label - nothing to add from my side
    • background_usage_time_in_ms - the time in ms the app used battery in background
    • boot_timestamp - the time since last reboot of the device in ms
    • consumer_power - consumed power - perhaps in mAH - not sure
    • device_battery_state
      • battery_health - the health status of the battery, I tested three of them (ok/hot/cold) with my test device - and they map to the one from the Android developer guide Android Developer Guide - Battery 
        • 1 = Unknown
        • 2 = Good
        • 3 = Overheat
        • 4 = Dead
        • 5 = Over Voltage
        • 6 = Unspecified Failure
        • 7 = Cold
      • battery_level - Current charging level in percentage value
      • battery_status - Same values like Kevin Pagano described in his post - I come to the same conclusion with my testing
        • 2 = Charging
        • 3 = Discharging
        • 5 = Fully Charged
    • drain_type - No idea what exactly this is. Value is either -1 or between 1 and 16 in my data.
    • foreground_service_usage_time_in_ms - time in foreground in ms - not sure what "service" means - app have either, only foreground service time or foreground time - I don't see both values for the same app
    • foreground_usage_time_in_ms - time in foreground in ms - like written above - not sure what the difference to foreground service is. 
    • zone_id - the time zone set on the device
    • total_power - Missing in the data above - but existent in some others - I don't know the meaning at the moment - in my data the value is either 30 or missing at all
    • is_hidden - Also missing in the data above - but existent in some others - Also here - I am not sure what the value means - it is either True or missing at all

     I've written a parser for ALEAPP for this database and the data in batteryInformationDebug. The output is similar to the one from Kevin Pagano so it is better comparable. Thanks to him - I used part of his code.


Okay, but, there are also other tables in the database. For me one interesting one is the following:

Table AppUsageEventEntity

  • mId - just an iterating id for this table - no correlation found to the other table
  • uid - the uid of the app
  • userId - the id of the user the app is running for (e.g. 0 for default user)
  • timestamp - Timestamp event was written in epoch - but written in real time, not only every hour like in the other table
  • appUsageEventType - I have two values in my test data and found the following meaning by testing
    • 1 = Paused -> Moved to background
    • 2 = Resumed -> Moved to foreground
  • packageName -  name of the package (e.g. com.android.settings)
  • instanceId -> ID of the instance running - I have no idea how it is generated and what it means
  • taskRootPackageName - Package name of the package that started/called this app


 I tested a bit with opening/closing apps and so on. And I can see exactly what I've done in this table.

We already know similar artifacts showing this on Android - but this one was new for me. Always good to know different ways to show things that happened on a device to correlate and verify the data and finding the truth.

I've written a ALEAPP parser for the data from this database too.


The other tables hold also some data - but I cannot makes sense out of them or see any useful data.


How long does the data stay?

Before I forget - for how long is data in the database?

Well - in my cases: Since the last Android Update. For one device it was about 10 days - I did a recheck few days later and it was about 14 days.

But double check is needed here.


Conclusion

As always - it was fun digging into the data.
More work need for some table/fields/data. And, as far as I found information - Google will bring new features for battery monitoring and battery health monitoring for the users. Perhaps that is what I already found in the database - we'll see.


The data in the batteryInformation field drives me crazy - 
CgYIYRACGAIQABi9sscTIg1FdXJvcGUvQmVybGluOhFHb29nbGUgUGxheSBTdG9yZVEAAAAAAAAA
AFkQG44jJZ9DP2EAAAAAAAAAAGj///////////8BcAB4AIEBAAAAAAAAAACJAQAAAAAAAAAAkQEA
AAAAAAAAAJkBAAAAAAAAAACgAQA=

If any hint from you - feel free to contact me - I am happy to learn new things. I found more fields with similar data in them i the other tables.

I hope you had a fun read. As always - thanks for your time and if any questions or suggestions come up - feel free to contact me.

UPDATE 2024-05-20:

Thanks to Kevin Pagano (stark4n6):

The data in batteryInformation is BLOB -> base64 -> protobuf

After decoding we'll have:

{

    "1": {

        "1": 97,

        "2": 2,

        "3": 2

    },

    "2": 0,

    "3": 41015613,

    "4": "Europe/Berlin",

    "7": "Google Play Store",

    "10": 0,

    "11": 4558662229688196000,

    "12": 0,

    "13": 18446744073709552000,

    "14": 0,

    "15": 0,

    "16": 0,

    "17": 0,

    "18": 0,

    "19": 0,

    "20": 0

}


Looks like similar values as in the field batteryInformationDebug.

Thanks a lot - now I can take a further look also into the other fields. Pretty sure I will come with an update soon :-)

UPDATE 2 FROM 2024-05-20:

So, I did some recoding and analyzing for the column "batteryInformation".

Here you can find the mapping from the keys to the decoded data in the column, for a few I currently don't have a mapping or an idea what the values could mean:


{

    "1": { = device_battery_state

        "1": 97, = battery_level

        "2": 2, = battery_status

        "3": 2 = battery_health

    },

    "2": 0, = is_hidden

    "3": 41015613, = boot_timestamp

    "4": "Europe/Berlin", = timezone

    "7": "Google Play Store", = app_label

    "10": 0,

    "11": 4558662229688196000,

    "12": 0,

    "13": 18446744073709552000, = drain_type

    "14": 0, = foreground_time_in_ms

    "15": 0, = background_time_in_ms

    "16": 0,

    "17": 0,

    "18": 0,

    "19": 0,

    "20": 0 = foreground_server_time_in_ms


I've also updated the parser for ALEAPP. Like I have written above - one of my two test devices didn't gave me data in the batteryInformationDebug, only in batteryInformation. But both devices gave me data in batteryInformation. So I decided to write the parser parsing always the batteryInformation.









Sunday, May 5, 2024

Analysis of App K-9 Mail for Android

Hi everyone :-)

It's now a few years ago that I've written my last post here. But now, finally, I decided to restart my work and sharing here.

Today I want to share my knowledge or better analysis results on the app K-9 Mail for Android.
It's a nice, open source, multi-account mail program - developed by Mozilla - so the Android version of Thunderbird . In the last few years I had a few cases, where this app was used as mail app on Android devices.

Android-Version: Android 13

App-Version: 6.802

Used tools for analysis: DB Browser for SQLite, 010 Editor, File Browser, Python (for developing parser for aLEAPP)

Path

The path of the application data is:

/data/data/com.fsck.k9

I checked all folders inside this one.
The most interesting is the folder databases.


As you can see in the picture, in my system there is a preferences_storage SQLITE database and a few other. The others begin with an UUID it seems - I assume, because I have configured two different accounts, the databases correspond with my accounts.

Let's see if I am correct, first I'll take a look into the preferences_storage file.


Accounts

In this database I find the table preferences_storage with the following content (column1 = primkey, column2 = value):


As you can see the UUID that begins with 9003efac relates to one of the mail accounts. There are a lot of other values in the table, e.g. incoming server settings, in JSON format:


For the first mail account there is also the password stored, nice thing.
The other account (UUID begins with 37e364a0), that is a Gmail account, uses OAUTH for connection, there is no Password in the JSON because of the different used authorization mechanism.

Okay, so I know that the UUIDs relate to the accounts, let us see what is in the other databases.

Messages


In the table messages of the database (here for UUID 9003efac) we can find a lot of infos.


This table gives an overview of all messages for an account including a preview of the messages, the number of attachments, etc.

There is also a table folders - with that we can also see in which folder the mails are stored.



IN the database there are a lot more tables. For me most interesting was the table message_parts, that, like the name says, holds the Content parts of the messages.


The field root relates to the filed message_part_id in the table messages. 
I can also see attachments, or at least the reference to them, in this table. But where are these attachments stored?

Attachments

As I could see in the folder structure of the folder databases there are two folders, starting with the already known UUIDs and ending with "db_att". Well, it could be, that the attachments are in these folders.

There are a lot of files, just with an id. This id corresponds with the field id in the table message_parts.
I tested sending a png-file to one of the mail accounts. Finally the file landed there, but base64 encoded. So yes, attachments, but also message parts that are too big to store directly in the database, can be found in this folder.
When testing sending the png file I recognized when exactly the png was stored in this folder. I will explain now:

Handling of Mails and Attachments


I did a four step process:

1. E-Mail is just received on the device and opened.
2. The content is downloaded (by default K-9 Mail won't download any attachments or inserted images automatically, that's a security and privacy feature)
3. The attachments is additionally saved
4. The mail is deleted

Step 1: E-Mail received and opened

In the table messages the is the message itself and in the table message_parts there is the content and a row for the attachment, but the attachment content is not on the device.

Step 2: Content downloaded

Now the attachment is on the device in the folder for the attachments.

In the table message_parts the field data_location has changed from 0 to 2 for the attachment entry.

Step 3: Attachments locally saved

When saving an attachment the user can choose where to save. The png file is than saved there (base64 encoded). But in the app context I could not find any traces of this. So at least for now I would not know, the an attachments was stored in a different location on the device.

Step 4: E-Mail deleted

Finally I deleted the mail. 
The file of the attachment in the attachment folder is gone. I did not try to recover it.
And the entries in the database are gone.
I can only see the now missing id in the table messages. So I would at least know, that one message is missing.
Important to say: It is possible, that the deleting mechanism is dependent on the server settings. I had thought, that the deleted message would first be moved into the "deleted" folder of the account, but at least for my account here, this did not happen.

The field data_location

When testing I could see changes in the field data_location in the table message_parts.

For now I can say the following:

Value 0 = The attachment is not downloaded and so not on the device
Value 1 = The message part and/or attachment is stored directly in the table, field data
Value 2 = Attachment/message part is stored in the attachment directory
Value 3 = I don't know yet - it seems there is something left on the server but already something stored on the device - but for the moment I just cannot say more

Parsing and decoding

So, after my analysis I also wanted to automate the parsing of this data based on my analysis.
For this I decided to write a plugin/parser for aLEAPP. If you don't know it already -> pretty nice tool, created by Alexis Brignoni and maintained by a lot of cool people  from the DFIR field.
You can find the code and the releases following this link: https://github.com/abrignoni/ALEAPP
My pull request with this plugin/parser can be found  here: https://github.com/abrignoni/ALEAPP/pull/485

My parser will get out the accounts, including the password and the server settings. And than will get the messages per account.
At the moment it is a bit tricky with the decoding of the message content - I am not very familiar with mail encoding - but I will get it work soon - it is just another thing I need to understand how it works. Too many different encoding formats :-D

What is currently missing: 
The content of the attachments are not shown. The parser currently only give hint, that there are attachments.
But also here - refinement will come as soon as I have some more time to code it.

Conclusion

K-9 Mail is an app than be found on Android devices.
From my current knowledge not all commercial tools in the DFIR field can decode this app. 
When doing analysis it is now much easier to also create a parser/decoder, because aLEAPP (and also the other "LEAPPs") exist and give an easy way to decode and than visualize the data. 
I am just at the beginning. I already pushed my parser for the Withings Health Mate App last week - and now I created the next pull request for aLEAPP with this parser.
I want to get better - especially in the frontend - how to show the data in a better way, not just tables everytime ;-). It's everything there I need - now I just need to develope it. ;-)

Thx for your time, hope you had a nice read. 
Special thanks to the developers/contributors of ALEAPP.

For any questions and suggestions, do not hesitate to contact me or leave a comment.