Previously to running applications, the ART
initializes a set of classes during the first boot (or
after system modifications), generating a file that
contains an executable image with extension "art "
with all the loaded classes and objects that are part
of the Android framework. This file, called boot.art,
is mapped into memory during the Zygote boot
process, and basically contains natively compiled
objects who hold address references (pointers) with
absolute addresses within the image itself and
references to methods in the code contained in
framework files (inside the framework file there are
absolute pointers to the image as well). The overall
data structure related to the compilation and
execution in the ART environment is then described
in the image header, including a field that stores the
respective offset from the beginning of the file. This
value changes at every boot so that the image is not
loaded at the same address (in AOSP version 5.0, the
base address for the displacement of ASLR was set
to 0x70000000).
After the initial preparation, the byte-code of
each installed application is compiled to native code
before its first run. The product of this compilation,
comprising each application byte-code and libraries
that make up the Android framework, are files in
Executable and Linking Format - ELF, called OAT
(specifically boot.oat for the framework). These
files, compiled to boot the Android framework and
to install applications, contain three dynamic symbol
tables called oatdata, oatexec and oatlastword that
respectively contain the OAT header and DEX files,
the compiled native code for each method, and the
last 4 bytes of generated native code functioning as a
final section marker.
For memory management, the ART divides the
virtual memory as follows: a main space for
application’s Java objects (heap), a space for the
image objects and classes of the Android
framework, a space for Zygote’s shared objects, and
a space for large object (Large Objects Space –
LOS). The first three are arranged in a continuous
address space while there is a collection of
discontinuous addresses for the LOS. In addition to
these spaces, there are data structures related to
garbage collection whose types are related to the GC
and the Java object heap allocation and that can be
active depending on the GC plan that is working.
The GC plan is usually set by the manufacturer
according to the device's intrinsic characteristics and
according to the plan established by the memory
allocator. For devices such as common use
smartphones, without strong memory constraints,
there is generally a defined plan whose operating
mode works with the allocator called Runs-Of-Slots-
Allocator (RosAlloc) for mutable objects and with
Dlmalloc for immutable objects.
The RosAlloc came up with the ART runtime
environment, and is the main allocator responsible
of heap memory space for Java objects. It organizes
this memory space in rows of slots of the same size.
These runs are clustered as pages within brackets.
The first page of a bracket contains a header that
determines the number of pages this bracket contains
and the slot’s allocation bitmap. The number of slots
per page is set according to the size of the bracket,
the header length and the byte alignment (which
depends on the target device architecture). Figure 1
illustrates an example of a heap structure and
mapping schema. Each slot stores data for one object
and the first bytes store its parent class address. The
slot is classified according to the size of the object as
a means to reduce fragmentation and allow parallel
GC. Objects with big data (≥ 12 KiB) are spread
through LOS allocation areas, allowing the kernel to
conveniently manage address spaces to store this
data.
The allocator maintains an allocation map for the
brackets pages (each page with 4 KiB size) setting in
this map the type of each page in the allocation
space. This map is stored in a mapped file in RAM
(rosalloc page map). For the allocation of the heap
space, it sets the address to start near the lowest
virtual address of the process, from 0x12c00000
bytes (300 MiB).
Considering this memory layout information,
drawn from our analysis of the AOSP source code, it
is possible to establish a strategy for locating objects
by scanning the bracket's slots inside the heap
mapped file and decoding the data set for each
allocated object. This is also possible for a
recoverable object from a deallocated slot. While
these are subjects of the present paper, as
approached in the next section, the analysis of data
stored in structures related to large objects or
allocated by native libraries, which have specific
allocation mechanisms, are considered for future
work.
5 OBJECT ANALYSIS
TECHNIQUE
As exposed above, in an application’s runtime
environment there are mapped files in RAM
containing: information about system properties,
Android framework, Java object heap, mapping of