bdsm - For utter dominance over Android's Binder RPC

Android's Binder is indubitably one of its least documented, (unnecessarily?) complex, yet crucial mechanisms, as it underpins nearly all IPC/RPC in the system. I've taken to the painful task of explicating every last bit of it in Volume II (Chapter 8, the longest in the book..), and throughout it have been using a tool of my own devising. This tool takes another tool of mine, bindump(j), and combines its functionality with AOSP's service and dumpsys.

Bindump, Dumpsys, Service & More

redfin:/ $ /data/local/tmp/bdsm
Usage: bdsm [-h|-?]
       bdsm [ns] list
       bdsm [ns] check SERVICE
       bdsm [ns] methods  SERVICE   # To list methods (if AIDL is loaded)
       bdsm [ns] call  SERVICE _meth_ [ _args_ ] ...
	       Where _meth_ is a method number, name (if AIDL is loaded), 
		or builtin (_PNG, _PID, _EXT, _NTF, _RPC, etc)
		and _args_ are optional arguments (if AIDL is loaded), and types will be auto-determined
       bdsm [ns] dump  SERVICE  # As per 'dumpsys' tool
       bdsm [ns] users SERVICE  # As per my 'bindump' tool (try 'all' for SERVICE)
       bdsm [ns] owner SERVICE  # As per my 'bindump' tool (try 'all' for SERVICE)

Where: [ns] is optionally 'binder' (default), 'hwbinder' or 'vndbinder'

Environment variables:
	JCOLOR: The usual curses based coloring
	JDEBUG: To get the behind the scenes binder transaction dumps, and other debug info
	JAIDL:  Path to AIDL directory (to override default, /data/local/tmp/aidl)

This is bdsm - Bindump, Dumpsys, Service & more, compiled on Jun 15 2022
This tool is part of the resources for 'Android Internals', Volume II, by Jonathan Levin
Free for non-commercial use at http://NewAndroidBook.com/
For commercial use (and pure C non-AOSP [hw]binder library) mailto://products@Technologeeks.com

If you find this useful, please go to http://NewAndroidBook.com/counter?bdsm,
 so I can get an idea of how many users I have. Also - I'll gladly take bug reports/feature requests.

bindump

My bindump is a 100% original tool I had originally derived from service. Android 8.0 broke my implementation, forcing me to rewrite it from scratch, with my own low-level Binder interface, rather than libbinder. The tool has its own detailed page, detailing how to use it to list the owners and users of [vnd]Binder users. As of today, it is effectively deprecated in favor of bdsm, which supports all of its functions.

The main use here is bdsm users (or owner), which will find who uses a particular Binder service (or is its owner), like so (su -c is actually not required for /dev/binder - force of habit there):


This is wicked useful. In the example above, users of SurfaceFlinger mean anyone who has registered a surface (i.e. has a view) - and I will explain that in Volume IV someday. Similar interesting services are power (wakelocks) activity (app components), etc. The "owner" is useful for pinpointing services hosted by their own binaries - especially if in the vendor space:

And this also works now to list HAL interfaces:

oriole:/ $ /data/local/tmp/bdsm hw list
Buffer of length: 16 @0x6dad761288
Got 182 entries
android.frameworks.cameraservice.service@2.0::ICameraService/default
android.frameworks.cameraservice.service@2.1::ICameraService/default
android.frameworks.cameraservice.service@2.2::ICameraService/default
android.frameworks.displayservice@1.0::IDisplayService/default
android.frameworks.sensorservice@1.0::ISensorManager/default
android.hardware.audio.effect@7.0::IEffectsFactory/default
...
vendor.samsung_slsi.telephony.hardware.radioExternal@1.0::IOemSlsiRadioExternal/rilExternal
vendor.samsung_slsi.telephony.hardware.radioExternal@1.1::IOemSlsiRadioExternal/rilExternal

dumpsys

Most users are probably familiar with dumpsys (or dumpstate, which uses it). This tool is really a fairly simple client which consists of :

So now that, too, is integrated into bdsm*. The only difference is I stick to a single thread and (at least for now) directly give out the stdout handle (i.e. direct to working terminal or '>' redirection. But it still works similarly.

redfin:/ $ data/local/tmp/bdsm dump uimode                                                                     
Current UI Mode Service state:
mDockState=0 mLastBroadcastState=0
mStartDreamImmediatelyOnDock=true  mNightMode=2 (yes)  mOverrideOn/Off=false/false mNightModeLocked=true
mCarModeEnabled=false (carModeApps=
waitScreenOff=false mComputedNightMode=true customStart=22:00 customEnd06:00 mCarModeEnableFlags=0 mEnableCarDockLaunch=true
mCurUiMode=0x21 mUiModeLocked=false mSetUiMode=0x21
mHoldingConfiguration=false mSystemReady=true
mTwilightService.getLastTwilightState()=null

service

AOSP's service is a generic Binder client, and absolutely one of its most useful CLI utilities. Although it steadily improves (floats and fds at last!), it still falls very short of its true promise. Most of what bdsm does is first match service's capabilities, then address this utility's shortcomings.

More**

This is where things get interesting: I've compiled bdsm with my own AIDL parsing library, which I call aidlwise. This is really a simple AIDL parser, but opens up wonderful possibilities - once you install the AIDLs. By default, put them all (from AOSP) into /data/local/tmp/aidl, and then bdsm does the rest:

oriole:/ $ /data/local/tmp/bdsm call package isPackageAvailable com.android.chrome 0                                          
Returned boolean: true (0x1)
oriole:/ $ /data/local/tmp/bdsm call window showGlobalActions
oriole:/ $ /data/local/tmp/bdsm call window _NTF
android.view.IWindowManager
oriole:/ $ /data/local/tmp/bdsm call window _PNG                                                                               

oriole:/ $ /data/local/tmp/bdsm call window _PID                                                                               
1378

oriole:/ $ /data/local/tmp/bdsm call procstats 1 
# Raw types I can't recognized are dumped in hex, like service
0x0000: 00 00 00 00 84 AE 03 00 54 54 53 50 28 00 00 00   ........TTSP(...
0x0010: 10 00 00 00 08 00 00 00 0A 00 00 00 10 00 00 00   ................
0x0020: 00 10 00 00 01 00 00 00 6D 3E FA 60 6F 01 00 00   ........m>.`o...
0x0030: 9F 29 00 00 00 00 00 00 1E 7F BF 00 00 00 00 00   .)..............
0x0040: 9F 29 00 00 00 00 00 00 32 5A 49 00 00 00 00 00   .)......2ZI.....
...
0x3AF70: 01 00 00 00 00 00 00 00 85 2A 64 66 7F 01 00 00   .........*df....
0x3AF80: 0B 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00                                                   
# Objects are automatically recognized
Object 0 is a filedescriptor (4 = /data/system/procstats/state-2022-04-17-02-37-09.bin)!
Object 1 is a filedescriptor (5 = /data/system/procstats/state-2022-04-09-09-51-52.bin)!
Object 2 is a filedescriptor (6 = /data/system/procstats/state-2022-04-08-20-47-09.bin)!
Object 3 is a filedescriptor (7 = /data/system/procstats/state-2022-04-08-17-47-08.bin)!
Object 4 is a filedescriptor (8 = /data/system/procstats/state-2022-04-08-14-47-06.bin)!
Object 5 is a filedescriptor (9 = /data/system/procstats/state-2022-04-08-11-47-04.bin)!
Object 6 is a filedescriptor (10 = /data/system/procstats/state-2022-04-08-08-47-03.bin)!
Object 7 is a filedescriptor (11 = /data/system/procstats/state-2022-04-08-05-47-01.bin)!
	
CAVEAT: You *HAVE* to use the AIDLs from the AOSP build your device is running. GOOGL freely edits their AIDL and messes up method numbering frequently (especially in beta releases, but even in _r version updates). It's not me. It's them. There's actually a way to figure out the correct method number at runtime without AIDL, but it's too complicated for the moment.

Note: A nice added benefit of installing AIDL files is that jtrace(j) (which I've also compiled with AIDLwise) will automatically load them when parsing Binder calls, and tell you the method names and arguments!

Questions/comments/etc

always welcome.


This tool (like all my tools) contains no code from AOSP, and is entirely 100% proprietary, original code

Get it

right here. Or HERE (for the nightly build).

Upload to your and then (from root) tar xvf /data/local/tmp/bdsm.tgz, which will also expand all the AIDL files to /data/local/tmp/aidl. An experimental ARMv7 version (runs on my 64-bit device but might need fixing for legacy 32-bit devices, which I no longer have) is here. Let me know if it needs any fixes (though note Android deprecates 32-bit as of 8.0 and eliminates it entirely in 13.0).











* - Without the 'D' of 'dumpsys' I'd have ended up with BSM - which I dearly love as an artifact of my beloved Solaris (even more so, now that AAPL killed it in macOS 10.18 in favor of EndpointSecurity.framework..
** - without 'M'ore I'd have ended up with "bds", which would piss off my Israeli readers. Also, considering OpenBinder's origins (and the excruciating suffering inflicted upon me over the years as I tried to figure out how Binder works), I think I ended up with the most apt name possible (with love to @hackbod).