What a split or bundle install produces on a device
An app bundle is a publishing format rather than an installed artifact. The distribution service builds a set of APKs from it, and the installer places the ones that match the device. What lands on the device is a base APK plus zero or more configuration splits, each named for the dimension it serves.
- The base APK carries the manifest, the code and the resources that every device needs. It is the file a single-APK distribution would have contained, minus the parts that can be varied.
- An ABI split carries the native libraries for one processor architecture. A device that supports more than one architecture still receives the split the installer selected.
- A density split carries graphics for one screen density range. It changes what the app renders and rarely changes what it sends over the network.
- A language split carries translated strings. It matters when a request contains a message the app displays or a locale value the user selected.
The installer selects splits from the device's reported capabilities: the list of supported processor architectures, the screen density, and the language configuration. The device ends up with a coherent subset rather than the whole package.
Why the native library may arrive in a separate file
A universal APK contains the shared object for every supported architecture. When the distribution service builds per-architecture splits, the libraries move out of the base APK and into the ABI APK. The base then holds no native library at all, which is why a tool that reads only the base reports no shared object and why a hook placed into the base changes nothing.
The library still loads. The installer registers all the installed APKs for the app as one logical package, and the platform resolves a library path inside that package set the same way it resolved a path inside a single APK. The file is a different artifact and it is present on the device.
This separation produces two common mistakes. Extracting only the base and concluding that the app is pure Java and Kotlin means the native signer or the native transport is invisible in the analysis. Extracting only the ABI split and reading the library without the base means the Java side that calls it is missing.
How ABI selection works
Each shared object is compiled for one processor architecture, and the runtime refuses to load one built for a different architecture. The installer records which split supplied the library, and the device picks the variant that its processor supports.
For a 64-bit device the selection generally prefers the 64-bit variant when the app provides one, and falls back to a 32-bit variant only when it does not. A device that lacks a matching split cannot run the app at all, because the library it needs was never installed. That is a packaging fact rather than a defensive measure, and it explains why an emulator configured for a different architecture fails at startup instead of at the first call.
Selection also decides which binary is worth reading. Libraries for different architectures are built from the same source and can differ in their compiled layout, so the architecture of the binary you analyse has to match the device you observed. Reading a 32-bit library while capturing traffic from a 64-bit install produces two accounts of the same flow.
Gathering a complete artifact set before analysis
The workable rule is to collect what the device installed rather than what was distributed, then confirm that the set is complete.
- List the installed split names before pulling files. The package manager reports the APKs that belong to the app, and the list is the definition of the artifact set. Pulling files without that list is how a split goes missing.
- Pull every file in the list, not only the base. The set includes the ABI split, the density split, the language split and any additional APK the app installed for itself.
- Record the device properties that drove selection. The architecture list, the density and the language explain why this set exists and are needed to interpret a native library that has no counterpart in the base.
- Check for expansion or downloaded files. Assets and libraries that the app fetches after installation are not part of the split set and will not appear in it.
With the full set in hand, the analysis proceeds as it would on a single APK, and the mapping between code and library is visible again. Projects that begin from a complete set reach a working client faster, and delivered clients include a Python, JavaScript or TypeScript library, an importable Postman collection and documentation, starting at $120 with most projects finished in 24 to 72 hours.
Related work
Reviewed 28 September 2026 · SReverse research desk