  Native code is now commonplace within Android app packages where it co-exists
and interacts with Dex bytecode through the Java Native Interface to deliver
rich app functionalities. Yet, state-of-the-art static analysis approaches have
mostly overlooked the presence of such native code, which, however, may
implement some key sensitive, or even malicious, parts of the app behavior.
This limitation of the state of the art is a severe threat to validity in a
large range of static analyses that do not have a complete view of the
executable code in apps. To address this issue, we propose a new advance in the
ambitious research direction of building a unified model of all code in Android
apps. The JuCify approach presented in this paper is a significant step towards
such a model, where we extract and merge call graphs of native code and
bytecode to make the final model readily-usable by a common Android analysis
framework: in our implementation, JuCify builds on the Soot internal
intermediate representation. We performed empirical investigations to highlight
how, without the unified model, a significant amount of Java methods called
from the native code are "unreachable" in apps' call-graphs, both in goodware
and malware. Using JuCify, we were able to enable static analyzers to reveal
cases where malware relied on native code to hide invocation of payment library
code or of other sensitive code in the Android framework. Additionally,
JuCify's model enables state-of-the-art tools to achieve better precision and
recall in detecting data leaks through native code. Finally, we show that by
using JuCify we can find sensitive data leaks that pass through native code.
