
Hola a todos! Nos tomamos el tiempo para continuar una serie de artículos sobre el dispositivo Android interno. En este artículo, hablaré sobre el proceso de arranque de Android, sobre el contenido del sistema de archivos, sobre cómo se almacenan los datos de los usuarios y las aplicaciones, sobre el acceso a la raíz, sobre la portabilidad de las compilaciones de Android y sobre el problema de fragmentación.
Artículos de la serie:
Paquetes
Como dije antes, la arquitectura de Android se basa en aplicaciones. Son las aplicaciones que juegan un papel clave en el dispositivo de muchas partes del sistema, es para la interacción armoniosa de las aplicaciones que se construyen los modelos de actividad e intención, y el modelo de seguridad de Android se basa en el aislamiento de las aplicaciones. Y si el administrador de actividades se dedica a organizar la interacción de los componentes de la aplicación, entonces el administrador de paquetes es responsable de instalar, actualizar y administrar los derechos de la aplicación (administrador de paquetes; puede llamarlo en el shell con el comando pm
).
Como su nombre indica "administrador de paquetes", en este nivel las aplicaciones a menudo se denominan paquetes . Los paquetes se distribuyen en formato APK (paquete de Android): archivos zip especiales. Cada paquete tiene un nombre (también conocido como ID de aplicación ) que identifica de forma exclusiva esta aplicación (pero no su versión específica; por el contrario, los nombres de las diferentes versiones del paquete deben coincidir, de lo contrario, se considerarán paquetes separados). Los nombres de los paquetes generalmente se escriben en notación del nombre DNS inverso ; por ejemplo, la aplicación de YouTube usa el nombre del paquete com.google.android.youtube
. A menudo, el nombre del paquete coincide con el espacio de nombres utilizado en su código Java, pero Android no lo requiere (además, los archivos APK de la aplicación generalmente incluyen bibliotecas de terceros, cuyo espacio de nombres, por supuesto, no tiene nada que ver con los nombres de los paquetes, quien los usa).
Cada APK durante el ensamblaje debe estar firmado por el desarrollador mediante una firma digital. Android comprueba la presencia de esta firma al instalar la aplicación y, al actualizar una aplicación ya instalada, compara además las claves públicas con las que se firman las versiones antigua y nueva; deben coincidir, lo que garantiza que la nueva versión fue creada por el mismo desarrollador que la anterior. (Si esta verificación no estuviera disponible, el atacante podría crear un paquete con el mismo nombre que la aplicación existente, convencer al usuario para que lo instale "actualizando" la aplicación y obtener acceso a los datos de esta aplicación).
La actualización del paquete en sí es la instalación de su nueva versión en lugar de la anterior con la preservación de los datos y permisos recibidos del usuario. También puede "degradar" las aplicaciones a versiones anteriores, pero al mismo tiempo, de forma predeterminada, Android borra los datos guardados por la nueva versión, ya que es posible que la versión anterior no pueda funcionar con los formatos de datos que usa la nueva versión.
Como ya dije, generalmente el código de cada aplicación se ejecuta bajo su propio usuario Unix (UID), lo que garantiza su aislamiento mutuo. Varias aplicaciones pueden solicitar explícitamente a Android que use un UID común para ellos, lo que les permitirá acceder directamente a los archivos de los demás e incluso, si lo desea, ejecutarse en el mismo proceso.
Aunque generalmente un paquete corresponde a un archivo APK, Android admite paquetes que consisten en varios APK (esto se denomina APK dividido o APK dividido ). Esta es la base de tales características "mágicas" de Android, como la carga dinámica de módulos de aplicaciones adicionales (módulos de características dinámicas ) y Instant Run en Android Studio (actualización automática del código de la aplicación en ejecución sin su reinstalación completa y, en muchos casos, incluso sin reiniciar).

Sistema de archivos
El dispositivo del sistema de archivos es uno de los problemas más importantes e interesantes en la arquitectura del sistema operativo, y el dispositivo del sistema de archivos en Android no es una excepción.
Es interesante, en primer lugar, qué sistemas de archivos se utilizan, es decir, en qué formato se guardan los contenidos de los archivos en un disco condicional (en el caso de Android, esto suele ser memoria flash y tarjetas SD) y cómo el núcleo del sistema proporciona soporte para este formato . El kernel de Linux utilizado en Android, en un grado u otro, admite una gran cantidad de sistemas de archivos diferentes, desde los utilizados en Windows FAT y NTFS y los utilizados en Darwin por el infame HFS + y APFS moderno, hasta la red 9pfs del Plan 9. Hay muchos "nativos »Para sistemas de archivos Linux, por ejemplo, Btrfs y la familia ext.
El estándar de facto para Linux ha sido durante mucho tiempo ext4 , utilizado por defecto por las distribuciones de Linux más populares. Por lo tanto, no hay nada inesperado en el hecho de que se use en Android. Algunos ensamblajes (y algunos entusiastas) también usan F2FS (sistema de archivos compatible con Flash), optimizado específicamente para la memoria flash (sin embargo, con sus ventajas, no todo está tan claro ).
En segundo lugar, el llamado diseño del sistema de archivos es de interés: la ubicación del sistema y las carpetas y archivos del usuario en el sistema de archivos. El diseño del sistema de archivos en "Linux normal" merece una descripción más detallada (que se puede encontrar, por ejemplo, en este enlace ); Mencionaré aquí solo algunos de los directorios más importantes:
/home
almacena las carpetas de inicio del usuario; aquí, en varias carpetas ocultas ( .cache
, .cache
, .config
y otras), los programas almacenan sus configuraciones, datos y caché, específicos para el usuario,/boot
almacena el kernel de Linux y la imagen initramfs (sistema especial de archivos de arranque),/usr
(sería más lógico llamar /system
) almacena la parte principal del sistema en sí, incluidas bibliotecas, archivos ejecutables, archivos de configuración, así como recursos: temas para la interfaz, iconos, contenido del manual del sistema, etc./etc
(sería más lógico llamar /config
) almacena la /config
todo el sistema,/dev
almacena archivos de dispositivo y otros archivos especiales (por ejemplo, el socket /dev/log
),/var
almacena datos mutables: registros, caché del sistema, contenido de la base de datos, etc.
Android usa un diseño de sistema de archivos similar pero notablemente diferente. Estas son algunas de las partes más importantes:
/data
almacena datos mutables,- El núcleo y la imagen initramfs se almacenan en una partición flash separada, que no se puede montar en el sistema de archivos principal.
/system
coincide con /usr
y almacena el sistema,/vendor
: un análogo de /system
diseñado para archivos específicos de este ensamblado de Android, y no incluido en el Android "estándar",/dev
, como en "Linux normal", almacena archivos de dispositivo y otros archivos especiales.
Los más interesantes de estos directorios son /data
y /system
. El contenido de /system
describe el sistema y contiene la mayoría de sus archivos constituyentes. /system
está ubicado en una sección separada de la memoria flash, que está montada por defecto en modo de solo lectura; por lo general, los datos que contiene cambian solo cuando se actualiza el sistema. /data
también se encuentra en una sección separada y describe el estado cambiante de un dispositivo en particular, incluida la configuración del usuario, las aplicaciones instaladas y sus datos, cachés, etc. Borrar todos los datos del usuario, el llamado restablecimiento de fábrica, con este esquema es simplemente borrar el contenido de la sección de datos ; un sistema intacto permanece instalado en la sección del sistema .
# mount | grep /system /dev/block/mmcblk0p14 on /system type ext4 (ro,seclabel,relatime,data=ordered) # mount | grep /data /dev/block/mmcblk0p24 on /data type ext4 (rw,seclabel,nosuid,nodev,noatime,noauto_da_alloc,data=writeback)
Las aplicaciones, es decir, sus archivos APK, odex (código Java compilado antes de tiempo) y bibliotecas ELF, se instalan en /system/app
(para aplicaciones entregadas con el sistema) o en /data/app
(para instaladas por el usuario aplicaciones). Al crear un ensamblado de Android, a cada aplicación preinstalada se le asigna una carpeta con el nombre del formulario /system/app/Terminal
, y para las aplicaciones instaladas por el usuario durante la instalación, se crean carpetas cuyos nombres comienzan con su nombre de paquete. Por ejemplo, una aplicación de YouTube se guarda en una carpeta con un nombre como /data/app/com.google.android.youtube-bkJAtUtbTuzvAioW-LEStg==/
.
Sobre este sufijoEl sufijo en el nombre de las carpetas de la aplicación es de 16 bytes aleatorios codificados en Base64. El uso de este sufijo evita que otras aplicaciones "adivinen" la ruta a una aplicación que no deberían conocer. En principio, la lista de aplicaciones instaladas en el dispositivo y las rutas hacia ellas no es un secreto, se puede obtener a través de API estándar , pero en algunos casos (es decir, para aplicaciones instantáneas) el acceso a estos datos está restringido.
Este sufijo tiene otro propósito. Cada vez que se actualiza la aplicación, el nuevo APK se instala en la carpeta con un nuevo sufijo, después de lo cual se elimina la carpeta anterior. Antes de la versión 8.0 Oreo, este era el propósito de los sufijos, y en lugar de bytes aleatorios , -1
y -2
usaban alternativamente (por ejemplo, /data/app/com.google.android.youtube-2
para YouTube).
La ruta completa a la carpeta de la aplicación en /system/app
o /data/app
se puede obtener mediante el pm path org.example.packagename
API estándar o pm path org.example.packagename
, que muestra las rutas de todos los archivos APK de la aplicación.
# pm path com.android.egg package:/system/app/EasterEgg/EasterEgg.apk
Dado que las aplicaciones preinstaladas se almacenan en la sección del sistema (el contenido de las cuales, recuerdo, cambian solo cuando se actualiza el sistema), no se pueden eliminar (en cambio, Android proporciona la capacidad de "deshabilitarlas"). Sin embargo, se admite la actualización de aplicaciones preinstaladas; en este caso, se crea una carpeta en /data/app
para la nueva versión, y la versión suministrada con el sistema permanece en /system/app
. En este caso, el usuario tiene la oportunidad de "eliminar actualizaciones" de dicha aplicación, volviendo a la versión de /system/app
.
Otra característica de las aplicaciones preinstaladas es que pueden recibir permisos especiales de "sistema" . Por ejemplo, las aplicaciones de terceros no obtienen el permiso DELETE_PACKAGES
, que le permite eliminar otras aplicaciones, REBOOT
, que le permite reiniciar el sistema, y READ_FRAME_BUFFER
, que permite el acceso directo a los contenidos de la pantalla. Estos permisos tienen un nivel de protección de firma , es decir, la aplicación que intenta acceder a ellos debe estar firmada con la misma clave que la aplicación o el servicio en el que se implementan, en este caso, dado que el sistema implementa estos permisos, la clave con la que se firma Android build
Para almacenar datos mutables, a cada aplicación se le asigna una carpeta en /data/data
(por ejemplo, /data/data/com.google.android.youtube
para YouTube). Solo la aplicación en sí tiene acceso a esta carpeta, es decir, solo el UID bajo el cual se inicia esta aplicación (si la aplicación usa varios UID, o si varias aplicaciones usan un UID común, todo puede ser más complicado). En esta carpeta, las aplicaciones guardan la configuración, el caché (en las subcarpetas shared_prefs
y cache
, respectivamente) y cualquier otro dato que necesiten:
# ls /data/data/com.google.android.youtube/ cache code_cache databases files lib no_backup shared_prefs # cat /data/data/com.google.android.youtube/shared_prefs/youtube.xml <?xml version='1.0' encoding='utf-8' standalone='yes' ?> <map> <string name="user_account">username@gmail.com</string> <boolean name="h264_main_profile_supported7.1.2" value="true" /> <int name="last_manual_video_quality_selection_max" value="-2" /> <...> </map>
El sistema conoce la existencia de la carpeta de cache
y puede limpiarla por sí sola si no hay suficiente espacio. Cuando desinstala la aplicación, toda la carpeta de esta aplicación se elimina por completo y la aplicación no deja rastros. Alternativamente, ambos usuarios pueden hacer explícitamente en la configuración:

Este almacenamiento de datos asignado a cada aplicación se denomina almacenamiento interno.
Además, Android tiene otro tipo de almacenamiento, el denominado almacenamiento externo ( almacenamiento externo; este nombre refleja la idea original de que el almacenamiento externo debe ubicarse en una tarjeta SD externa insertada en el teléfono). De hecho, el almacenamiento externo desempeña el papel de la carpeta de inicio del usuario: allí se encuentran carpetas como Documentos, Descargas, Música e Imágenes, es el almacenamiento externo que los administradores de archivos abren como la carpeta predeterminada, permite que la computadora acceda al contenido del almacenamiento externo cuando está conectado por cable
# ls /sdcard Alarms Download Podcasts Android Movies Ringtones Books Music Subtitles DCIM Notifications bluetooth Documents Pictures
A diferencia del almacenamiento interno, dividido en carpetas de aplicaciones individuales, el almacenamiento externo es una "zona común": cualquier aplicación que haya recibido el permiso apropiado del usuario tiene acceso total a ella. Como mencioné en un artículo anterior, las aplicaciones como el administrador de archivos deberían solicitar este permiso; y para la mayoría de las otras aplicaciones, es mejor utilizar la intención con la acción ACTION_GET_CONTENT
, que le da al usuario la oportunidad de elegir el archivo deseado en el administrador de archivos del sistema.
Muchas aplicaciones prefieren guardar algunos de sus archivos internos, que son grandes (por ejemplo, un caché de imágenes descargadas y archivos de audio) en almacenamiento externo. Para hacer esto, Android asigna a aplicaciones en carpetas de almacenamiento externo con nombres de la forma Android/data/com.google.android.youtube
. La aplicación en sí no requiere permiso para acceder a todo el almacenamiento externo para acceder a esta carpeta (ya que su UID está configurado como el propietario de esta carpeta), pero cualquier otra aplicación que tenga este permiso puede acceder a esta carpeta, por lo que realmente vale la pena usarla. Solo para almacenar datos públicos y no críticos. Cuando desinstale la aplicación, el sistema también eliminará su carpeta especial en el almacenamiento externo; pero los archivos creados por aplicaciones en almacenamiento externo fuera de su carpeta especial se consideran pertenecientes al usuario y permanecen en su lugar después de la eliminación de la aplicación que los creó.
Como mencioné anteriormente, inicialmente se suponía que el almacenamiento externo estaría ubicado en una tarjeta SD externa, ya que en ese momento el volumen de las tarjetas SD era significativamente mayor que la cantidad de memoria integrada en los teléfonos (en HTC Dream era solo 256 megabytes, de los cuales se asignaron alrededor de 90 megabytes a la sección de datos ). Desde entonces, muchas condiciones han cambiado; los teléfonos modernos a menudo no tienen una ranura para tarjeta SD, pero los estándares móviles instalan una gran cantidad de memoria interna (por ejemplo, en el Samsung Galaxy Note 9 puede tener hasta 512 gigabytes ).
Por lo tanto, en el Android moderno, casi siempre el almacenamiento interno y externo se encuentra en la memoria interna. La ruta real a lo largo de la cual se encuentra el almacenamiento externo en el sistema de archivos toma la forma /data/media/0
( se crea un almacenamiento externo separado para cada usuario del dispositivo, y el número en la ruta corresponde al número de usuario). Para fines de compatibilidad, también se puede acceder al almacenamiento externo a través de las /sdcard
, /mnt/sdcard
, /storage/self/primary
, /storage/emulated/0
, varias rutas que comienzan con /mnt/runtime/
y algunas otras.
Por otro lado, muchos dispositivos todavía tienen una ranura para tarjeta SD. La tarjeta SD insertada en el dispositivo Android se puede usar como una unidad externa normal (sin convertirla en almacenamiento interno o externo del sistema): guarde los archivos, abra los archivos almacenados en ella, úsela para transferir archivos a otros dispositivos, etc. Además, Android le permite "tomar prestada" una tarjeta SD y colocar almacenamiento interno y externo en ella (esto se llama almacenamiento prestado - almacenamiento adoptado ). Al mismo tiempo, el sistema reformatea la tarjeta SD y encripta su contenido; los datos almacenados en ella no pueden leerse conectándolos a otro dispositivo.

Puede leer más sobre todo esto, por ejemplo, en esta publicación y en la documentación oficial para desarrolladores de aplicaciones y creadores de ensamblados de Android .
Cargando
El enfoque tradicional de la seguridad del sistema informático se limita a proteger el sistema de ataques de software. Se cree que si un atacante tiene acceso físico a una computadora, el juego ya está perdido : puede obtener acceso completo a cualquier información almacenada en él. Para esto, es suficiente para él, por ejemplo, ejecutar en esta computadora un sistema operativo arbitrario controlado por él, que le permite evitar cualquier restricción impuesta por el sistema de derechos "principal", o conectar directamente el disco de datos a otro dispositivo. Si lo desea, un atacante puede dejar la computadora en estado operativo, pero parchear el sistema instalado en ella, instalar puertas traseras arbitrarias, keyloggers, etc.
Es la protección contra ataques de software que se centra en el modelo de restricción de derechos de usuario en Unix (y la tecnología de sandbox de aplicaciones basada en Android); La restricción de Unix en sí misma no protege el sistema de un usuario que se dirigió a la sala de servidores y obtuvo acceso físico a la computadora. Y si los servidores serios de múltiples usuarios pueden y deben protegerse del acceso físico no autorizado, a las computadoras personales, y especialmente a los dispositivos móviles, este enfoque simplemente no es aplicable.
Hay dos formas de tratar de mejorar la situación con protección contra un atacante que ha obtenido acceso físico al dispositivo:
- En primer lugar, es posible encriptar los datos almacenados en un disco , evitando así que un atacante obtenga acceso a los datos en sí, incluso si tiene acceso a los contenidos del disco.
- En segundo lugar, es posible limitar de alguna manera la capacidad de cargar sistemas operativos arbitrarios en el dispositivo , lo que obliga a un atacante a realizar procedimientos de autenticación y autorización en el sistema instalado.
Es con estas dos áreas de protección que se asocia el modelo de arranque seguro en Android.
Arranque verificado
El proceso de arranque de Android está diseñado para que, por un lado, no permita a los atacantes descargar un sistema operativo arbitrario en el dispositivo, por otro lado, permite a los usuarios instalar ensamblados de Android personalizados (y otros sistemas).
En primer lugar, los dispositivos Android, a diferencia de las computadoras "de escritorio", generalmente no permiten que un usuario (o un atacante) arranque desde un medio externo; en su lugar, el gestor de arranque instalado en el dispositivo (gestor de arranque) se inicia inmediatamente. Bootloader es un programa relativamente simple cuyas tareas (cuando se carga en modo normal) incluyen:
- inicialización y configuración del entorno de ejecución de confianza (por ejemplo, ARM TrustZone),
- encontrar particiones de memoria interna que almacenan imágenes del kernel de Linux e initramfs,
- verificación de su integridad (integridad) (de lo contrario, la descarga se interrumpe con un mensaje de error) al verificar la firma digital del fabricante,
- cargar el kernel e initramfs en la memoria y transferir el control al kernel.
Parpadeo, desbloqueo, arranque rápido y recuperación
Además, el gestor de arranque admite funcionalidades adicionales para actualizar y reinstalar el sistema.
-, (Android) , recovery . recovery, Android- , , Android recovery .
«» bootloader', — ( flashing ) . bootloader , fastboot mode ( bootloader mode), bootloader' fastboot ( fastboot
Android SDK ).
bootloader' . , Samsung, bootloader'a (Loke) (Odin). Odin Samsung ( Odin), Heimdall .
bootloader' ( ), recovery Android, , :
$ fastboot flash recovery recovery.img $ fastboot flash boot boot.img $ fastboot flash system system.img
; : , , bootloader' Android, , , , .
, bootloader' (unlocking the bootloader, OEM unlock) — bootloader' recovery, ( ). Android, LineageOS ( CyanogenMod ), Paranoid Android , AOKP , OmniROM .
bootloader' - , ( data ) . , , (, Google ), — , .

recovery bootloader , .
bootloader' :

recovery, «» (flashaholics) — TWRP (Team Win Recovery Project). - «», zip-, :

Android ( file-based encryption ). ext4 , Linux ( fscrypt ), .
, data , , (credential encrypted storage). , , . , , .

credential encrypted storage Android device encrypted storage — , ( Trusted Execution Environment). , , , . , Direct Boot : ; ( ) device encrypted storage, , . , Direct Boot , , - .
Root
root- — « root» (UID 0, ). , root — Unix-, — — , .
, Android , root- . , « », Android « », root- «», :
- — , APK ,
- : -, email-, , , , , , ( activity intent', ),
- (icon packs),
- , ,
- ( Android-) ,
- , Android, .

, , , root- . root- ( ), Android root . , , Unix-; shell, adb shell
, Unix- shell .
, , root :
- -, root- Android — Android Studio QEMU, .

- -, root- Android ( pre-rooted ROMs).
- -, bootloader' root- Android , ,
su
, bootloader. - , -, , , root-, ( root- ). , 2016 , root- Dirty Cow .
? , root- . , root-, , , . — , . , , system ( ).
, root- — , .
root-
With great power comes great responsibility.
, . , root- .
, , . , root- , , , root- . root, , , , — , , , ..
, Unix, Android , — . root- , , . , root- Android, .
, , root- , . , , , , , . , — , Google Pay ( Android Pay) — root- , .

, - Pokémon GO root- , , .
Google Play root-
Google Google Play Store Google Play Services , root- , Android , , , , . Play Store — ( , ) Android, . ( — , Amazon Android Fire OS — Echo, Fire TV, Fire Phone, Kindle Fire Tablet — Google). root- Android-.
, Google , root-, Google Play ( Open GApps ); Google , .
Device manufacturers work with Google to certify that Android devices with Google apps installed are secure and will run apps correctly. To be certified, a device must pass Android compatibility tests. If you are unable to add a Google Account on your Android device, your Android device software might not have passed Android compatibility tests, or the device manufacturer has not submitted the results to Google to seek approval. As a result, your device is uncertified. This means that your device might not be secure.
If you are a User wanting to use custom ROMs on your device, please register your device by submitting your Google Services Framework Android ID below.
root
«» Linux, Unix-, root- ( sudo
su
) ( , Unix- root, ) (, ). , root-.
su
Android Open Source Project , Unix- shell ( root), root-. su
, , , .
, su
. su
, root-. , SuperSU ; Magisk .

Magisk
Magisk — , , /system
, system ( systemless-ly ), «» Linux . Magisk Hide — root-, root- Magisk — - Google Pay, root- . Magisk Hide root-, SafetyNet Google.
, , Google Pay root- — root- . , root-, - Google Pay. , .
Magisk systemless- «» Magisk Modules , Magisk. , , root- Xposed ViPER , .
SoC,
, «», , — , — (, Wi-Fi ).
, Android- (system on a chip, SoC). — , , -, , LTE-, Bluetooth- Wi-Fi- .. — . , , , , , .
, , . , «», , , , . , , -, , , , .
— Android — SoC . , , — LTE- — . , ; , , .
SoC (, Qualcomm) Android- (, Sony LG), Android, Android Open Source Project. , Android, , , .
Android Android-. , Android. Android , , . .
, : Android — , . Android, .
, , , Android. .
-, . , . , , , , .
-, Android — developer experience (DX, user experience/UX). , Android, API — Android Framework, OpenGL/Vulkan — . , , , Android — , , .

Don't Stop Thinking About Tomorrow
Android- . , Google Nexus Pixel , Android. Android , , , .
, , Android, SoC. Android «» (, , Android-x86 RemixOS ). Android ChromeOS, Chromebook' Android- Linux- -. — Android — Anbox , Android- «» Linux-. (, Android- x86-, , Java, .)

, Android — , Android .
— Android. , , . , , Android .
. 2017 Google Project Treble — , ( HAL, hardware abstraction layer) ( , ) . Treble , , , — — .
Treble . Treble (Sony, Nokia, OnePlus, Oppo, Xiaomi, Essential Vivo — Google) - Android Pie. Treble Essential Android Pie Essential Phone Android Pie. Android — - — , Treble, , SoC.
Treble . Java «write once, run everywhere» — Android- . Treble — , Android SoC. , , Treble. , Android- .
userspace Android: init, Zygote, Binder, props.