Skip to content

Using the Roborock App

Use this after Installation and Onboarding if you want the official Roborock app to talk to your local stack.

During the MITM login step, the script now needs to sync the captured protocol-auth session back to your server. Pass admin.session_secret from the active server config as --sync-secret. That sync callback always uses the --local-api host and port.

The launcher can auto-load a sync secret from config.toml beside mitm_redirect.py, but that is only correct when that file matches the config used by the running server. If you run the MITM step from a second machine, or your server is using a generated Home Assistant config or another config file, pass --sync-secret explicitly.

The launcher now preflights that callback before starting mitmweb. If the --local-api host cannot be reached, if the TLS certificate does not validate for that host, or if the sync secret is rejected, the script exits immediately instead of letting you proceed into a broken login flow.

iPhone

  1. Log out of the app on your phone.

  2. On a machine that is not running the server, run the MITM script:

uv run mitm_redirect.py --local-api api-roborock.example.com --sync-secret YOUR_ADMIN_SESSION_SECRET

Use the admin.session_secret value from the config file your running server actually uses for YOUR_ADMIN_SESSION_SECRET.

If startup fails with invalid_sync_secret, the launcher either auto-loaded the wrong local config.toml or you copied a stale secret. Re-read admin.session_secret from the active server config and pass it explicitly with --sync-secret.

If you use the default local stack ports, host-only values are fine here: the script assumes HTTPS :555 and MQTT TLS :8881.

If your stack uses custom ports, include them directly. For example:

uv run mitm_redirect.py --local-api api-roborock.example.com:8443 --local-mqtt api-roborock.example.com:9443 --sync-secret YOUR_ADMIN_SESSION_SECRET

The --local-api hostname must resolve from the MITM machine and match the HTTPS certificate served by your local stack. A raw IP such as 127.0.0.1 will fail unless your certificate is valid for that IP.

  1. Install the WireGuard app on your phone. Then tap the plus button in WireGuard, choose to add from QR code, and scan the code at http://127.0.0.1:8081/#/capture.

  2. Open mitm.it in your web browser (iPhone). Follow the instructions there for your device. In Safari, complete all device-specific steps, including installing and trusting the certificate.

  3. Once the MITM setup is working, open the Roborock app, log back in, enter your verification code, and the server should automatically show the vacuums already known to your local stack. Turn off WireGuard, disable the MITM certificate, and then open one of your devices to confirm the map loads.

Android

Note: It is recommended to disable auto update in the Roborock App.

Note: This workaround has only been tested and confirmed working on Roborock app version 4.60.06. Newer versions may ship a different librrcodec.so with different offsets, in which case the patch script will need to be updated.

Android 7+ (API level 24+) only trusts system certificates, so the app will reject the MITM certificate by default. On top of that, the Roborock app includes a native library (librrcodec.so) that checks the APK's signing certificate on startup and kills the process if it doesn't match, meaning a simple apk-mitm patch isn't enough.

To work around both issues, you need to patch librrcodec.so to remove the integrity check, then repackage the APK.

Prerequisites

Make sure you have the following installed:

Patching the APK

  1. Download the Roborock APK (e.g. from APKMirror) and place it in your working directory.

  2. Run apk-mitm to patch the APK for certificate trust:

   apk-mitm roborock.apk
  1. Decompile the patched APK:
   apktool d roborock-patched.apk -o roborock_work
  1. Patch librrcodec.so to remove the signature integrity check.

First, save a copy of the original librrcodec.so as librrcodec.so.bak.

   cp roborock_work/lib/arm64-v8a/librrcodec.so roborock_work/lib/arm64-v8a/librrcodec.so.bak

Now run the patcher from the repository root using the script in patcher/. You can pass the path to librrcodec.so explicitly (as shown below), or run it with no arguments from inside the unpacked APK and it will find the file itself.

Use python or python3 depending on your system (Python 3.8+ is required).

  ```bash
     python patcher/patch_librrcodec.py roborock_work/lib/arm64-v8a/librrcodec.so
  ```
  1. Rebuild the APK:
   apktool b roborock_work -o roborock_final.apk
  1. Sign the APK. You have two options:

Option A — Create a new signing key and sign:

   keytool -genkey -v -keystore my-key.keystore -alias mykey -keyalg RSA -keysize 2048 -validity 10000
   apksigner sign --ks my-key.keystore roborock_final.apk

Option B — Use an existing JKS keystore:

   apksigner sign --ks my-key.jks --v1-signing-enabled true --v2-signing-enabled true roborock_final.apk
7. Uninstall the original Roborock app from your phone (required because the signing key is different), then install the patched APK:

   adb uninstall com.roborock.smart
   adb install roborock_final.apk
  1. On a machine that is not running the server, run the MITM script:
   uv run mitm_redirect.py --local-api api-roborock.example.com --sync-secret YOUR_ADMIN_SESSION_SECRET

Use the admin.session_secret value from the config file your running server actually uses for YOUR_ADMIN_SESSION_SECRET.

If startup fails with invalid_sync_secret, the launcher either auto-loaded the wrong local config.toml or you copied a stale secret. Re-read admin.session_secret from the active server config and pass it explicitly with --sync-secret.

If you use the default local stack ports, host-only values are fine here: the script assumes HTTPS :555 and MQTT TLS :8881.

If your stack uses custom ports, include them directly. For example:

   uv run mitm_redirect.py --local-api api-roborock.example.com:8443 --local-mqtt api-roborock.example.com:9443 --sync-secret YOUR_ADMIN_SESSION_SECRET

The --local-api hostname must resolve from the MITM machine and match the HTTPS certificate served by your local stack. A raw IP such as 127.0.0.1 will fail unless your certificate is valid for that IP.

  1. Install the WireGuard app on your phone. Then tap the plus button in WireGuard, choose to add from QR code, and scan the code at http://127.0.0.1:8081/#/capture.

  2. Open mitm.it in your web browser (Android). Follow the instructions there for your device. In Chrome, complete all device-specific steps, including installing and trusting the certificate.

  3. Once the MITM setup is working, open the Roborock app, log back in, enter your verification code, and the server should automatically show the vacuums already known to your local stack. Then close the Roborock app, turn off WireGuard, disable or delete the MITM certificate, reopen the Roborock app, and select your device or devices to confirm the map loads.

What the patch does

During JNI_OnLoad, librrcodec.so calls a verification function that retrieves the APK's signing certificate via PackageManager.getPackageInfo(), hashes it with MessageDigest, and compares it against a hardcoded value. If the hash doesn't match, it calls Process.killProcess(). The patch replaces the two BL (branch-link) instructions that call this function with NOP, so the check never runs. In the disassembly, these call sites are at VA 0x4bdcc and 0x4c428; in patcher/patch_librrcodec.py, the corresponding file offsets are 0x4adcc and 0x4b428. The crypto functions the app actually needs are unaffected.

Note: This patch has only been tested and confirmed working on Roborock app version 4.60.06, against the librrcodec.so with build ID becc35bc1a75903df1eae3f90b380ca5403d06cb. If Roborock releases a new app version, the virtual addresses and file offsets may change and the patch script will need to be updated.