非常好的一篇英文文章The State of ASLR on Android Lollipop,有机会全部翻译一下。
重点如下:
Brief history of ASLR on Android
Early Android versions only had stack randomization due to lack of kernel support for ASLR on ARM. The 4.0 release introduced mmap randomization thanks to upstream progress. The kernel also gained support for ARM exec and brk randomization but Android still lacked userspace support. The 4.1 release introduced support for full ASLR by enabling heap (brk) randomization and adding linker support for self-relocation and Position Independent Executables (PIE).
Lollipop is the latest step forwards, as non-PIE executable support was dropped and all processes now have full ASLR.
The generated code has a hard-wired base address just like native binaries, and is always relocated by default on a production Android system. Since this occurs in userspace, the Android Runtime code is responsible for choosing an address. The main base image is currently chosen by applying a delta generated with the following code to the base address:
std::default_random_engine generator;
generator.seed(NanoTime() * getpid());
std::uniform_int_distribution<int32_t> distribution(min_delta, max_delta);
In Lollipop, Android moved to a compacting garbage collector as part of replacing Dalvik with the new Android Runtime (ART) but still uses dlmalloc to implement a separate garbage collected heap for the remaining non-movable objects. The malloc implementation in Bionic was replaced with jemalloc for improved performance and scalability along with with lower fragmentation and lazy purging of unused page spans.
Unlike dlmalloc, jemalloc does reduce heap randomization entropy. It’s a side effect of the low-level chunk allocation model, where all memory is allocated via naturally aligned chunks of the same size. The jemalloc version used in the current release of Lollipop uses 4MiB chunks (4MiB aligned) while the upcoming release will use 256kiB chunks (256kiB aligned) due to changes in the upstream jemalloc design (for reasons unrelated to ASLR). With 4MiB chunks, it loses 10 bits of ASLR entropy relative to 4k page granularity (2^12 -> 2^22) while the new default chunk size causes a less severe 6-bit loss of entropy.