This is the third part of the Bit Twiddling series. For your convenience you can find other parts in the table of contents in Par 1 — Modifying Android application on a binary level
Today we’re going to enable calls recording in Google Phone dialer using low level tricks. Let’s see how this can be done. This is just an exploration and I’m also making educated guesses about various things so they may not be rock solid.
You can download APK from APK Mirror. Just keep in mind not all versions allow for recordings — for instance versions “downloadable” are the regular ones you can get from Google Play Store and they don’t allow that. Versions marked as “go” can do that so use any of those. I’ll play with com.google.android.dialer_77.0.432472356-go-8761782_minAPI24(nodpi)_apkmirror.com.apk
Recording is in the app but is disabled based on your country. There are multiple threads on XDA like this one or this one explaining that Google Phone uses some flags under the hood to override the behavior and enable/disable the feature. What people do is they root their phones and then insert flags into the database so that Google Phone reads them and enables the logic. However, nothing stops us from modifying the APK on a binary level and ignore the values in databases entirely. And this works on non-rooted phones! You just need to install the APK and you’re good to go.
First thing you do is you disassemble the application with the following:
1 |
apktool.bat decode com.google.android.dialer_77.0.432472356-downloadable-8761773_minAPI28(arm64-v8a)(nodpi)_apkmirror.com.apk |
Read Part 1 to see where you can get tools from.
Next, open the APK with jadx and search for the following string: Always record calls with numbers not in your contacts?
If you find it in resource strings then it means that your APK should have recording functionality (it’s just a guess based on various samples I toyed with). So now you can go and start modifying the application.
Now, look for enable_call_recording
. You should see something similar to this one:
Last 3 lines effectively define a content of some map holding the parameters so you can safely ignore them. However, first 3 lines are used in runtime when app tests if it should do something. If you modify database under the hood then these will get their value from the database and allow for recording. However, you can modify these places directly to enable the feature on non-rooted phones.
Let’s go to the first method ayv.b
:
You can see it does the following:
1 |
return Boolean.valueOf(((klm) this.a.im().a.a()).a("com.google.android.dialer G__enable_call_recording").j()); |
So it extracts some flag and then gets its value. You can see that it extracts some Boolean and then casts it. What we can do is we can modify the parameter passed to Boolean.valueOf
to get something like Boolean.valueOf(true)
. Let’s do it — go to smalli file and see this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
:pswitch_1e iget-object v1, v0, Layv;->a:Layy; invoke-virtual {v1}, Layy;->im()Ljfw; move-result-object v1 iget-object v1, v1, Ljfw;->a:Ljava/lang/Object; .line 105 invoke-interface {v1}, Lnic;->a()Ljava/lang/Object; move-result-object v1 check-cast v1, Lklm; const-string v2, "com.google.android.dialer G__enable_call_recording" invoke-interface {v1, v2}, Lklm;->a(Ljava/lang/String;)Lkln; move-result-object v1 invoke-virtual {v1}, Lkln;->j()Z move-result v1 .line 106 invoke-static {v1}, Ljava/lang/Boolean;->valueOf(Z)Ljava/lang/Boolean; move-result-object v1 return-object v1 |
Lovely. We now need to change the part calling valueOf
to something like this:
1 2 3 |
.line 106 const/4 v1, 0x1 invoke-static {v1}, Ljava/lang/Boolean;->valueOf(Z)Ljava/lang/Boolean; |
Repeat that for other flags (look for enable_call_recording
, force_within_call_recording_geofence_value
, use_call_recording_geofence_overrides
, force_within_crosby_geofence_value
and probably some other variations) and that’s it.
Now, assemble the APK back:
1 |
apktool.bat b --use-aapt2 -f -o dialer.apk com.google.android.dialer_77.0.432472356-downloadable-8761773_minAPI28(arm64-v8a)(nodpi)_apkmirror.com.apk |
sign it:
1 |
java.exe -jar uber-apk-signer-1.2.1.jar --apks dialer.apk |
And you’re done.