I can’t seem to find any results for “does Spotify use ultrasonic beacon?”
Surely I am not the first to stumble on this.
So… two potential routes to attack this.
Path #1: Audio analysis.
The strings suggest it happens during voice ads. Since the tones are meant to be picked up be phones, I think a simple phone recording would suffice. If not, I could borrow a zoom recorder for a higher quality samples.
Put on the podcast, wait for ads and record a bunch of audio samples during voice ads.
Then throw it in a spectogram to easily visualize the patterns in the 18kHz+ part of the spectrum. (I’m a big fan of the spectogram in foobar2k)
Looking for something like this:
Source: from the ‘Privacy Threats through Ultrasonic Side Channels on Mobile Devices’ paper link in previous post.
And dig more into the existing detection techniques.
Path #2: chase the calls
Checking my notes again, this is where I got lazy last time. I remember now trying to chase the paths and xrefs, and ran into a bunch of “do nothing functions”
Meaning a bunch of calls were wrapped with funtions that did nothing and then returned. Obfuscation.
**************************************************************
* FUNCTION *
**************************************************************
undefined FUN_026f8900()
undefined AL:1 <RETURN>
FUN_026f8900 XREF[3]: 0083bc88, 010dee18(*),
thunk_FUN_026f8900:026f88f0(T),
thunk_FUN_026f8900:026f88f0(j)
026f8900 48 89 f8 MOV RAX,RDI
026f8903 c3 RET
Which essentially translates to
undefined8 FUN_026f8900(undefined8 param_1) {
return param_1;
}
I had to learn what is a ‘thunk’
Thunk function: a thunk is a subroutine used to inject a calculation into another subroutine. Thunks are primarily used to delay a calculation until its result is needed, or to insert operations at the beginning or end of the other subroutine: Thunk - Wikipedia
A thunk is another word for a function. But it’s not just any old function. It’s a special (and uncommon) name for a function that’s returned by another. Basically a wrapped function:
function wrapper_function() {
// this one is a "thunk" because it defers work for later:
return function thunk() { // it can be named, or anonymous
console.log('do stuff now');
};
}
Anywho, this was a common pattern. I started renaming these functions manually as func_donothing_xxxxxx()
But there were to many, I got tired of renaming these manually. Who’d a thunc it?
So I started looking at Ghidra’s scripting capabilities.
The pattern itself is very easy to detect.
- they all seem to do the same thing which is just return the parameter that was passed to the function. or just return immediately and do absolutely literally nothing.
- they seem to be in close proximity
026f10c0 48 89 f8 c3 cc cc cc cc cc cc cc cc cc cc cc cc <-- bs func A
026f10d0 48 89 f8 c3 cc cc cc cc cc cc cc cc cc cc cc cc <-- bs func B
026f10e0 48 89 f8 c3 cc cc cc cc cc cc cc cc cc cc cc cc <-- bs func C
026f10f0 c3 cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc <-- variation of BS func that just ret instead of returning the parameter
I wanted to write a function to detect these “do nothing” thuncs and funcs and rename them for me so I don’t waste time stepping into them.
I started reading about the scripting functions but got busy with other things. This is where I stopped.
This is a great channel: https://www.youtube.com/@0x6d696368
Probably better to exhaust approach #1 first as it seems like less work.