3/06/2016

Zeo Mobile, where leviathan sleeps

Serendipity cannot be summoned, one can only be shown the unknown. While looking at the model for protecting apk sqlite databases.. something unexpected happened.


I noticed a toggle for [Bug report shortcut] on the Power menu (this pops up when you hold the Power button too long) this feature "Adds" an option to immediately [dump] the logs to an email and a screenshot then offers to "Share" the content with an app or email it to you.

Android really does not have a documented method for generating logs, in fact its a somewhat "heated" debate between external developers and the Android team developing the APIs as displayed in this forum article:

READ_LOGS permission is not granted to 3rd party applications

Now that sounded a lot like the decision to [hide] or [protect] databases from 3rd party applications.. which if you recall merely required in development the apps have the [same signatures].

So how does an apk get its signature?

It gets it as the final step in the build system using the authors keystore to create a directory in the APK called the META_INF

There are two steps, development and release.. so different signatures are used.

The apk is just a "zip file" with a funky extension.. on windows 7zip will open it and show you stuff.

If you delete the META_INF and then resign it.. it will have your signature.
cd C:\Program Files\Java\jdk1.6.0_35\bin>
keytool -genkey -v -keystore debug.keystore -alias androiddebugkey -keyalg RSA -keysize 2048 -validity 10000
keystore password: android
key password for <androiddebugkey>: <return, same>

jarsigner -keystore debug.keystore -storepass android Zeo1.2.7.apk androiddebugkey <return>
<..no feedback.. but works.. verified with 7zip looking at META-INF>
Then the original apk installed can be deleted from the Android device and the [resigned] version installed, keep in mind it will "collide" with the other apk if it is not un-installed.. in fact it will assume this is an "Update" and try to patch the original.. but fail. So you have to not only remove the icon from your launchers page, but "really" uninstall the original apk.

My [thinking] was eventually we might enable side loading, or install from 3rd party apps.. then resign with personal signatures.. and resign either an existing 3rd party app.. or something new with the same key.. [in theory] if what I read is correct.. that would allow the other apk to access the /data/zeo/zeo.db database direct and you could periodically upload it.. but more on that later.. here's the [unexpected part]

The reason such a procedure [exists] to resign a compiled app, is to transition between development and released versions for developers.. and some people use that signature to pseudo enable/disable unsupported "logging" methods.. at least way back in ICS - Ice Cream Sandwidth "days" which .. happens to coencide with the original "target" for the MyZeo application.

I was bored..

I noticed this toggle and decided to enable it and see what it would do.

[.. answer.. a whole lot more than I thought ! ]

I've got to run.. and I'll update this posting later.. but here's a snap shot of what rolled into my emailbox

03-06 16:09:40.060 16981 23439 V BluetoothClient: Successfully connected to RFCOMM channel socket : Zeo with createInsecureRfcommSocket
03-06 16:09:40.061 16981 23439 D Headband: 188979628 Disconnect in headband.
03-06 16:09:40.126 16981 23439 V Headband: Update sleep record end reason with disconnected because headband is not connected.
03-06 16:09:40.151 16981 23439 V BluetoothClient: Successfully connected... starting thread.
03-06 16:09:40.167 16981 23441 V Headband: Attempting to upload headband state to myzeo.com
03-06 16:09:40.167 16981 23441 I Headband: Not uploading headband state when user not logged into myzeo.com
03-06 16:09:40.168 16981 23442 V BluetoothClient: Input thread started.
03-06 16:09:40.181 16981 23442 V Headband: Received message: com.myzeo.android.headband.ZeoMessage[mCreatedOn=Sun Mar 06 16:09:40 CST 2016, mIdentifier=1196641608, mCrc=52428, mVersion=2, mType=MESSAGE_TYPE_STATE_REPORT, mSequenceNumber=57, mSize=16, mAckRequest=0, mContents=com.myzeo.android.headband.StateReportMessage[mActiveForced=false, mBluetoothLocked=true, mDemoMode=false, mDocked=true, mOnHead=false, mRequiresPin=false, mWasCharged=true, mWasQueried=false, mHeadbandVoltage=233, mHeadbandVoltageStatus=1, mLastAlarmReason=0, mLastAlgorithmMode=0, mSensorUseSeconds=56893]]
03-06 16:09:40.181 16981 23442 V Headband: Handling state report
03-06 16:09:40.181 16981 23442 V Headband: Attempting to send message : com.myzeo.android.headband.ZeoMessage[mCreatedOn=Sun Mar 06 16:09:40 CST 2016, mIdentifier=1196641608, mCrc=25978, mVersion=2, mType=MESSAGE_TYPE_COMMAND_REQUEST, mSequenceNumber=14, mSize=4, mAckRequest=0, mContents=com.myzeo.android.headband.CommandRequestMessage[mCommand=8]]
03-06 16:09:40.219 16981 23442 V BluetoothClient: Sending data over bluetooth
03-06 16:09:40.225 16981 23439 D Headband: 188979792 Successfully connected to Zeo
03-06 16:09:40.228 16981 23444 V Headband: Attempting to upload headband state to myzeo.com
03-06 16:09:40.228 16981 23444 I Headband: Not uploading headband state when user not logged into myzeo.com
03-06 16:09:40.362 16981 23439 V HeadbandService: Trying to add headband: com.myzeo.android.headband.Headband[name=Zeo, address=4C:98:EF:00:DE:EC, connected=true, mCommFailures=0]
03-06 16:09:40.363 16981 23445 V Headband: Attempting to upload headband state to myzeo.com
03-06 16:09:40.363 16981 23445 I Headband: Not uploading headband state when user not logged into myzeo.com
03-06 16:09:40.364 16981 23439 V HeadbandService: Adding active headband: com.myzeo.android.headband.Headband[name=Zeo, address=4C:98:EF:00:DE:EC, connected=true, mCommFailures=0]
03-06 16:09:40.386 16981 23442 V Headband: Received message: com.myzeo.android.headband.ZeoMessage[mCreatedOn=Sun Mar 06 16:09:40 CST 2016, mIdentifier=1196641608, mCrc=19818, mVersion=2, mType=MESSAGE_TYPE_REPORT_SLEEP, mSequenceNumber=58, mSize=1144, mAckRequest=0, mContents=com.myzeo.android.headband.ReportSleepMessage[mReport=com.myzeo.android.headband.SleepReport[mDisplayHypnogramStartTime=1455700200000, mAwakenings=4, mTimeInDeep=88, mTimeInLight=332, mTimeInRem=211, mTimeInWake=29, mVoltageBattery=234, mUserInitiated=false, ]]]
03-06 16:09:40.386 16981 23442 V Headband: Handling sleep report.
03-06 16:09:40.389 16981 23442 D Headband: 188979956 Found offset for headband: -87

[Update] end of night...

Got very close to the final goal.. but not there yet. It seems there are [two] requirements for shared database access. (1) same signing signature (2) same userID shared between applications

android:sharedUserId
The name of a Linux user ID that will be shared with other applications. By default, Android assigns each application its own unique user ID. However, if this attribute is set to the same value for two or more applications, they will all share the same ID — provided that they are also signed by the same certificate. Application with the same user ID can access each other's data and, if desired, run in the same process.
Re-signing the apk appears a trivial thing that happens all the time, because the signing certificates expire, the Zeo app is set to expire in in the year 2039... so not an impending y2k.. but hence why the method must exist.

Assigning a unique "sharedUserID" was a surprise.. but equally easy to do.. in fact it may not even be necessary.. but I did test the motions.. and with the new found [debug] logging.. I could verify that it did indeed work. I set it to "com.myzeo" however it appears the assignment follows a predictable pattern.. so it appears unnecessary as long as you know what it will be.
suid,2000,android.uid.shell
suid,10001,android.uid.calendar
suid,10249,com.myzeo
The final test of course will be creating a test app, or service that can copy the the database to a more accessible location on command.

If this works.. it was quite a lesson in apk signatures, debug logging and shared database access.

I can't think of a way of [ever] creating a new apk and uploading it to the Google Play store or Amazon App store that has a common signature.. it would just be wrong. And there is no way to get a companion app signed by the same private key used to sign the existing apk in the Google Play store.

So this will always require enabling [settings > security > Allow installation of apps from sources other than the Play store] but the "big win" -- if it works -- will be [root-ing] the device will no longer be necessary.

The native apk can continue to provide the service it was designed to provide and the user will be able to access the full sqlite.db file the apk creates.

Unlike the former .DAT files of the bedside unit (which I have never had access to..) the sqlite database format is well known and accessible using many free and commerical tools.

I hope it works.

I think the [debug] logging might eventually turn out to be more beneficial since that may help understand the Bluetooth protocol and lead to native apps for other platforms to do similar things to what the original apk did on Android.

[another random thought..]

The debug log output indicates the Zeo app is trying to upload the data to myzeo.com but does not because the user is not signed up or something.

AppleTV version2/3 does not officially support a Plex application for playing streaming content from a Plex media server.. this was brought into the fold with AppleTV version 4

But that didn't prevent some resourceful people from developing a by-pass. They configured the AppleTV version 2/3 to use  a different DNS server on the local network which intercepted calls for the Trailers website and directed those requests to a Plex media server that could service the Trailers request and present a Plex media server experience.

I think it would be overreaching to run down that path but its a thought.

Really its probably more interesting to make native apps for more platforms.

[ Another thought.. that Red LED problem ]

If the Red LED represents something, or is the result of something in the android app.. I have hopes that the 'Verbose' debug logging will reveal what it is.. and possibly suggest a solution.

One of the things the [Diagnostics] page in the app does is collect state data.. but it doesn't save it.

The debug logging saves the data and can be referred to later to correlate the behavior.

CyberMike confirmed the Zeo has been Info debug logging all the time.. I just didn't know how to get the logs.. but he did say this procedure {enabled} Verbose logging which apparently represents more data than it was spewing forth before.

In addition CyberMike told me the debug logging could be monitored [realtime] using the AndroidStudio.. which made me think of the ADB - Android Debugging interface.. which I know little about.

ADB provides a shell interface when an Android device is connected to a USB serial port for debugging programs under development.. technically [re-signing] "turned back the clock" on the released version of the APK and made it think it was still under development and {enabled} the verbose debug logging.. which while unexpected.. was 'guessed' at based on looking at software archeology of the period for 'Android - Ice Cream Sandwich' - its a relic from the past - a behavior of programmers from a bygone era.