Solid writeup. From someone who does/did a lot of this professionally:

1. Android typically is easier for this kind of work (you don't even need a rooted/jailbroken device, and it's all Java/smali),

2. That said, instead of installing an entire framework like Xposed that hooks the process to bypass certificate pinning, you can usually just decompile the APK and nop out all the function calls in the smali related to checking if the certificate is correct, then recompile/resign it for your device (again, easier on Android than iOS),

3. Request signing is increasingly implemented on APIs with any sort of business value, but you can almost always bypass it within an hour by searching through the application for functions related to things like "HMAC", figuring out exactly which request inputs are put into the algorithm in which order, and seeing where/how the secret key is stored (or loaded, as it were),

4. There is no true way to protect an API on a mobile app. You can only make it more or less difficult to secure. The best you can do is a frequently rotated secret key stored in shared libraries with weird parameters attached to the signing algorithm. To make up for this savvy companies typically reduce the cover time required (i.e. change the secret key very frequently by updating the app weekly or biweekly) or by using using a secret key with several parts generated from components in .so files, which are significantly more tedious to reverse.

> That said, instead of installing an entire framework like Xposed that hooks the process to bypass certificate pinning, you can usually just decompile the APK

I remember reading something years back about Java decompiling, and I believe it said that all Java code is decompileable except for inner classes and nested try-catch. Assuming my memory and the source are correct (which might not be the case), why hasn't it become standard practice for developers who don't want their app reverse-engineered to just put every class inside a wrapper class? I can imagine there could even be tools for doing this at compile time so that you wouldn't need to manually deal with the indirection when writing the code.

The standard way of frustrating decompilers for Android applications is with heavy obfuscation using ProGuard [1] or DexGuard. [2] IMO, DexGuard is a real pain in the ass to reverse around. If you aren't dealing with heavy obfuscation, decompiling APKs is trivial using jadx. [3]

In general I have found that most smaller app developers don't obfuscate at all, and often you can find hardcoded keys/secrets in these smaller applications.

[1] https://developer.android.com/studio/build/shrink-code.html

[2] https://www.guardsquare.com/en/dexguard

[3] https://github.com/skylot/jadx