사전격리 등
2025년 3월 10일
ref #
사전 지식 #
앱 격리 매커니즘 #
안드로이드는 각 앱이 UID를 가지고 있고, 그 권한으로 실행되며 앱의 데이터 폴더 또한 앱의 UID 소유로 되어있기 때문에 권한을 얻기 전까지 서로의 영역(메모리, 폴더)을 침범할 수 없게 구현되어 있다.
루트 권한으로 data 폴더를 확인해보면, 앱별로 u0_a205 형식의 소유자가 지정되어 있는것을 볼 수 있고 앱 실행권한에서도 확인할 수 있다. system 권한은 시스템 앱에 부여되는 권한이며, radio 같은 권한들은 중요한 하드웨어 기능에 권한을 분리해서 관리해야되는 시스템 앱들에 부여된다.
adb 역시 shell 권한으로 실행되며, 폴더 내용을 볼 수 없다.
가상머신 #
앱이 빌드되면 플랫폼에 독립적인 dex 파일(바이트코드) 형태로 만들어지고, 런타임 컴파일러가 dex의 바이트코드를 각 기기에 맞는 기계어 코드로 런타임에 컴파일한다.
결국 플랫폼 독립적이기 위해 바이트코드로 컴파일되기 때문에 코드가 디컴파일되기 쉽고 변조나 복제, 리소스추출이 가능하게된다.
Dalvik #
- 안드로이드 4.4 (KitKat) 까지 사용되던 런타임
- JIT 컴파일 방식을 사용한다.
- 설치, 부팅 시점에 odex파일로 최적화(바이트코드 변형) 하고 런타임에 VM을 통해 기계어로 컴파일하면서 실행한다.
- 멀티덱스를 개발자가 코드단에서 설정해줘야 한다.
ART(Android RunTime) #
- 안드로이드 5.0 (Lolipop) 부터 사용되는 런타임
- 주로 AOT 컴파일 방식을 사용하지만, 네이티브코드로 변환되지 않은 코드의 경우 JIT 컴파일도 사용한다.
- 설치 시점에 기계어 코드(oat)로 변환해두고
- 멀티덱스를 코드단에(MultiDex.install) 작성하지 않아도 자동으로 지원한다.
컴파일 방식 #
공식롬은 런타임 컴파일 방식이 버전에따라 정해져있는데, 커스텀롬에서는 해당되지 않을 수 있다.
JIT (Just In Time) #
- ~ android 4.4
- 코드가 실행될 때마다 필요한 부분만 바이트 코드에서 네이티브(기계어) 코드로 변환한다.
- 변환된 코드는 메모리상의 JIT 캐시 (코드캐시) 영역에 저장되며 재부팅 시 지워진다.
- 처음 설치하는 동안 모든 코드를 컴파일 할 필요가 없으므로 초기 설치가 빠르다
- 처음 실행되는 코드의 일부에 대해 컴파일에 따른 딜레이가 발생할 수 있다.
AOT (Ahead Of Time) #
- android 5.0 ~ android 6.0
- 코드가 디바이스에 설치될 때, dex 파일의 전체 바이트 코드가 네이티브 코드로 미리 변환된다.
- 변환된 네이티브 코드는 /data/app/
경로에 oat 파일로 저장된다. - 앱 실행 시에 추가적인 컴파일 시간 없이 빠른 시작 및 최적의 성능을 제공한다.
- 앱의 설치 나 업데이트 할 때 모든 코드가 미리 컴파일되기 때문에 설치 시간이 길어지며, 더 많은 설치 공간이 필요하게된다.
프로파일 기반 AOT #
- android 7.0 ~
- 처음 앱이 설치되어 실행될땐 JIT 방식을 사용하고, 앱 실행도중 프로파일링을 한다. 이후 디바이스가 사용중이 아닐때 프로파일 정보를 통해 AOT 방식으로 컴파일해둔다.
- 처음 앱이 실행될땐 최적화가 되어있지 않고, 앱 실행중 프로파일링에 대한 오버헤드도 생긴다.
- 컴파일 중간에 인터랙션이 발생하면 즉시 컴파일을 중단하고 앱을 실행한다. 컴파일되지 않은 부분은 JIT로 실행되며, 컴파일이 완료된 부분은 네이티브로 실행된다.