|
|
[[_TOC_]]
|
|
|
|
|
|
Debugging Tor Browser on Android is a challenge sometimes, but don't get discouraged! Some parts of Mozilla's documentation are helpful:
|
|
|
|
|
|
[Geckoview](https://firefox-source-docs.mozilla.org/mobile/android/geckoview/contributor/for-gecko-engineers.html)
|
|
|
[Fenix](https://github.com/mozilla-mobile/fenix/blob/main/README.md#build-instructions)
|
|
|
|
|
|
(This page is a disorganized brain-dump, we'll organize it later, hopefully)
|
|
|
|
|
|
Tools:
|
|
|
- Android Studio
|
|
|
- Emulator or physical device (where you can reproduce the issue)
|
|
|
- Android SDK
|
|
|
- Android NDK
|
|
|
- `zip`/`unzip`
|
|
|
|
|
|
### Logcat
|
|
|
|
|
|
`adb logcat` is one of your more valuable tools. Looking at the logs does not always tell you explicitly why an app crashed, but it usually gives you useful hints:
|
|
|
|
|
|
```
|
|
|
$ adb logcat
|
|
|
```
|
|
|
|
|
|
(This assume `adb` is in your path. It comes from `path/to/android-sdk/platform-tools`).
|
|
|
|
|
|
### Debuggable App
|
|
|
|
|
|
Android Studio is the primary interface for debugging running code on Android. Mozilla has a short guide for configuring your environment for debugging native code:
|
|
|
https://firefox-source-docs.mozilla.org/mobile/android/geckoview/contributor/native-debugging.html
|
|
|
|
|
|
You want an apk that has the `debuggable` flag set to `true`, this usually means you want to create a `debug` variant (`assembleDebug`). When an apk is debuggable, Android will allow you to attach a debugger to the running app's process(es).
|
|
|
|
|
|
If you can build the app in Android Studio and run the debug app from within that environment, then you mostly can ignore these details. If you can't do this, for whatever reason, then you can take some manual steps to accomplish this.
|
|
|
|
|
|
After you install the apk that is `debuggable`, tell Android that the package should be run in `debug`:
|
|
|
|
|
|
```
|
|
|
$ adb shell am set-debug-app -w org.torproject.torbrowser_alpha`
|
|
|
```
|
|
|
|
|
|
`-w` tells Android that launching the app should hang until a debugger is attached to the process.
|
|
|
Replace `org.torproject.torbrowser_alpha` with the correct package name.
|
|
|
|
|
|
Next, run the app and attach the debugger in Android Studio by selecting `Run -> Attach Debugger to Android Process` and select the app from the list.
|
|
|
|
|
|
You can reset the debug mode by using:
|
|
|
|
|
|
```
|
|
|
adb shell am clear-debug-app org.torproject.torbrowser_alpha
|
|
|
```
|
|
|
|
|
|
After you attach the debugger, it should catch the crash and you can inspect the state of the program. However, if the crash is in native code, then you should try producing a build with debug symbols. If you can't reproduce the crash when debug symbols are included, then this may not be very helpful.
|
|
|
|
|
|
### Swapping components within the app
|
|
|
|
|
|
Often injecting and/or swapping certain components/dependencies/libraries within the app is useful. For example, you may want to build a `debug` variant apk [locally](https://gitlab.torproject.org/tpo/applications/tor-browser/-/wikis/Hacking/Hacking#building-android-tor-browser) but the bug/crash only manifests in a `build `libxul.so` produced in `tor-browser-build`.
|
|
|
|
|
|
How do?
|
|
|
|
|
|
It's simple, we just (ab)use `zip` and `unzip`.
|
|
|
|
|
|
1. Create the locally built apk.
|
|
|
2. Obtain the apk (or build artifact) where the crash/bug is reproducible
|
|
|
3. Extract component from step 2
|
|
|
4. Inject component into output of step 1
|
|
|
5. Sign modified apk from step 4
|
|
|
|
|
|
This could look something like the following steps from within a fenix repo:
|
|
|
|
|
|
```
|
|
|
# Step 1
|
|
|
$ JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 ANDROID_SDK_ROOT=~/.mozbuild/android-sdk-linux/ ./gradlew clean app:assembleDebug
|
|
|
# Step 2
|
|
|
$ tar xf /home/user/tor-browser-build/out/geckoview/geckoview-2fbebf5fc327-android-armv7-8faf7e.tar.gz
|
|
|
# Step 3
|
|
|
$ unzip -d geckoview geckoview/geckoview-beta-omni-armeabi-v7a-99.0.20220606110101.aar jni/armeabi-v7a/libxul.so
|
|
|
$ mv geckoview/jni geckoview/lib
|
|
|
# Step 4
|
|
|
$ zip app/build/outputs/apk/debug/app-armeabi-v7a-debug.apk lib/armeabi-v7a/libxul.so
|
|
|
# Step 5
|
|
|
$ cp app/build/outputs/apk/debug/app-armeabi-v7a-debug.apk ./app-armeabi-v7a-debug.apk && zip -qr app-armeabi-v7a-debug.apk assets/ && ~/.mozbuild/android-sdk-linux/build-tools/31.0.0/zipalign -vp 4 app-armeabi-v7a-debug.apk app-armeabi-v7a-debug-unsigned.apk && ~/.mozbuild/android-sdk-linux/build-tools/31.0.0/apksigner sign --verbose --min-sdk-version 17 --ks /home/android/tor-browser-build/projects/tor-browser/android-qa.keystore --out app-armeabi-v7a-debug-qa.apk --in app-armeabi-v7a-debug-unsigned.apk --ks-key-alias androidqakey --key-pass pass:android --ks-pass pass:android
|
|
|
```
|
|
|
|
|
|
(This assumes following the steps in [Building Android Tor Browser](https://gitlab.torproject.org/tpo/applications/tor-browser/-/wikis/Hacking/Hacking#building-android-tor-browser).)
|
|
|
|
|
|
Alternatively, you can modify the build process(es) within `tor-browser-build`.
|
|
|
|
|
|
### Objdump and Readelf
|
|
|
|
|
|
You may need to look at the binary file. Use the `objdump` and `readelf` tools provided by the Android NDK for this (substituting the correct target architecture):
|
|
|
|
|
|
```
|
|
|
$ ls /path/to/android-ndk-r21d/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/arm-linux-androideabi/bin/
|
|
|
ar as ld ld.bfd ld.gold nm objcopy objdump ranlib readelf strip
|
|
|
``` |
|
|
\ No newline at end of file |