Skip to content

Instantly share code, notes, and snippets.

@rawmain
Forked from DavidBuchanan314/zshield_notes.md
Last active June 30, 2024 15:13
Show Gist options
  • Save rawmain/9b171a8029f5a07de8e415d6bd94498c to your computer and use it in GitHub Desktop.
Save rawmain/9b171a8029f5a07de8e415d6bd94498c to your computer and use it in GitHub Desktop.

Zimperium zShield RE Notes

Newer versions of the Rabbit R1's APK are protected by https://www.zimperium.com/zshield/ (I don't know this for certain, somebody told me it is but I haven't really seen any identifying marks in the code yet)

Interesting assets within the APK:

lib/arm64-v8a/liboptipkawfn.so    ~3MB packed/encrypted ELF
assets/optipkawfn/0.odex          only 41 bytes
assets/optipkawfn.szip            ~8MB - I predict containing encrypted+compressed bytecode

The substring "optipkawfn" is randomised between builds.

ELF/SO protection

The ELF entrypoint has a few anti-analysis tricks up its sleeve:

  • Per the marketing brief, the code is "diversified" meaning different builds might make slightly different checks in different orders.

  • Checking /proc/self/status for non-zero TracerPid (anti-debugger checks)

  • Finds libc via /proc/self/maps and calls pthread_create to spawn a sub-thread which:

    • Checks for the following Naughty Paths in the filesystem (via newfstatat):
/sbin/su
/system/bin/su
/system/xbin/su
/system/xbin/daemonsu
/su/bin/su
/su/bin/daemonsu
/system/xbin/bstk/su
/data/xposed/XposedBridge.jar
/storage/emulated/0/MagiskManager
/data/data/com.topjohnwu.magisk
/data/user_de/0/com.topjohnwu.magisk
/data/user/0/com.topjohnwu.magisk
/magisk
/data/magisk
/data/magisk.img
/root/magisk
/root/magiskinit
/system/lib/libxposed_art.so
/system/bin/app_process64_xposed
/data/dalvik-cache/xposed_XResourcesSuperClass.dex
/data/dalvik-cache/arm64/system@framework@[email protected]@xposed
/data/dalvik-cache/oat/arm64/xposed_XTypedArraySuperClass.odex
/system/lib/libriruloader.so
/system/lib64/libriruloader.so
  • (subthread continued):

    • In an infinite loop (every 10ms), it checks:
    • /proc/self/status (for a debugger, probably)
    • /proc/self/maps (looking for traces of frida, I believe)
    • Checks /proc/net/unix for... something (probably frida traces again).
    • I see mentions of /etc/hosts and /proc/cpuinfo in strings but I'm not sure they're ever checked.
  • (Back on the main thread now)

  • Spams prctl(0xdeadbeef, ...), no idea what that's about?

  • Checks /proc/net/unix similarly.

  • Self-decrypts the body of the ELF using the XXTEA cipher.

  • Joins the subthread

  • Checks for KernelSU via prctl(0xdeadbeef) (source)

  • TODO: what happens with relocations?

  • Cleans everything up and returns from the entrypoint (back to dlopen I guess)

Aaaaand that's as far as I've got so far. I wrote an unpacker for the XXTEA stuff, but there's a lot more work to be done.

The code itself is control-flow flattened and obfuscated (OLLVM-style), and strings/buffers are "encrypted" with a weak made-up(?) cipher with 32-bit keys.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment