오닉스 북스 리프2 (ONYX BOOX Leaf 2) 루팅하기

Jewon Joel Park·2023년 3월 5일
0

들어가기에 앞서

굳이 왜 범용 전자책 리더기를 샀는가

양적완화 이후 전 세계가 금리인상으로 허덕이며 정신없는 와중에 ChatGPT가 일으킨 파장으로, 인간만이 할 수 있는 철학적 고찰이 필요하다는 생각에 '문학'책을 읽어야한다는 압박아닌 압박이 들었다.

는 핑계고, 사실 그냥 토익 시험 결과 기다리면서 호그와트 레거시를 좀 찐하게 했던게 화근이다.

토익시험 당일을 포함해서 60시간(2.5일) 중 45시간을 갈아넣어서 엔딩을 봐버렸다. 다시 말하면 30대 아재가 옛날 향수에 젖어서 시간가는 줄 모르고 게임했다는 말이다. 아무튼, 해리포터 원작 소설에서도 자세한 언급이 없었던 래번클로 기숙사를 보고 있자니 원문 소설을 제대로 보고 싶다는 생각이 들었다.

그러다가 평소에도 책을 사서 스캔 떠놓고도 잘 안보게 됐던 이유를 생각해봤는데, 컴퓨터로 보기에도 애매하고 태블릿(아이패드)으로 보는 것도 뭔가 불편하다는 생각이 들면서 '전자책 시장이 점점 커지는 데에는 이유가 있지 않을까?' 라는 궁금증과 함께 이것 저것 찾아보다, 6인치+, MicroSD 확장, 물리버튼 키워드에 부합하는 표제 eBook 단말을 지르게 되었다.

이미 PDF, ePub, txt 파일들을 많이 들고 있었던 것도 있고, 저작권을 인질로 삼은 DRM을 명목으로 거지같은 사용성의 특화 단말을 쓴다는 것은 상상조차 할 수 없어서 범용 전자책 단말로 결정하게 된 것이다.

굳이 왜 루팅(Rooting)을 하는가

(중요) 사실 전자책 뷰어는 굳이 루팅할 필요가 없다.

하지만 중국제 단말(...)이라 개인정보 이슈도 있을 뿐더러, 내가 내 돈주고 산 단말을 관리자(Root User) 권한 없이 쓰는 것도 싫고, 무엇보다 기본 어플리케이션은 쓰지도 않는데 메모리만 차지하면서 삭제도 안되는 게 맘에 안들어서 어지간하면 루팅해서 사용한다.


서론

정말 기본적인 얘기지만, 루팅하면서 발생할 수 있는 모든 책임은 사용자 본인에게 있다. 공식 수리 서비스 못 받게되는 것 쯤은 아무것도 아니니, 항상 복구대책 등을 생각하고 본인이 감당할 수 있을 때에만 진행하자.

가뜩이나 국내 전자책 뷰어 시장도 작은데, 루팅까지 들어가니 정말 자료 찾기가 힘들었다.

20대 초반에 안드로이드 폰 3개 썼던 것과, 최근에 안드로이드 기반 태블릿 잠깐 쓰면서 루팅해본 기억이 전부라 고생(삽질)을 좀 (많이) 했다.
그래도 기존에 나왔던 모델들의 영문 레퍼런스들이 있어서 원산폭격급 맨땅 헤딩은 아니었다는게 다행이다.

진행 순서

  1. 기기에 맞는 firmware 파일을 찾아서 다운로드하기
  2. firmware 복호화
  3. payload.bin 추출
  4. (3)에서 boot.img 추출 후 Root Privilege 패치
  5. 권한이 적용된 boot.img 파일을 부트영역에 덮어쓰기

준비사항

  1. 벽돌 되는 것 쯤은 별 일 아니라는 마음가짐
  2. Python 코딩 기초 지식
    • 대단한 건 아니고 git clone같은 터미널 명령어 타이핑 정도
  3. on Android Device
    • 2-1. Hidden Settings // APK Link
    • 2-2. Magisk // Github Releases Link - 최신버전의 Assets에서 Magisk-v00.apk파일 다운로드
    • 2-3. (Optional) GetBooxUpxKeys // 모델의 Key Strings를 추출하는 앱. APK Link
  4. on Windows

본론

굳이 안해도 되는 과정

Step 0) Key Strings 확인

이 단계는 Android 10 <=에서 Boox OS 펌웨어를 Hasing & Decryption 하기 위한 키값을 추출하는 것으로, 작동 원리는 단말 내부의 OnyxOtaService.apk (구버전) 또는 libota_jni.so(신버전) 파일을 찾아 해당 파일에서 Key StringsFingerprint를 추출하는 것.

준비사항 2-3을 단말에서 다운받고 실행만 하면 됨

실행하면 위 화면처럼 MODEL, STRING_SETTINGS, STRING_UPGRADE, fingerprint 키에 해당하는 값들을 확인할 수 있음.

  • Leaf2 Key Strings > JSON Format
    "Leaf2": {
        "MODEL": "Leaf2",
        "STRING_SETTINGS": "okRZqgfOHft/Y5jHx1N0ECjqrc/Op/nADFj2uL7Jbuxq",
        "STRING_UPGRADE": "10Na33u5HfsCVHqjtwLrwACOW+2cz5MSnXUogONCTd9c"
    }
  • (중국제) Leaf2_P Key Strings > JSON Format
    "Leaf2_P": {
    		"MODEL": "Leaf2_P",
    		"STRING_SETTINGS": "lH1x4y+lRiS8YNYfiDJba3wOcacEOglrIMutctNhpAbL",
    		"STRING_UPGRADE": "6XR9lSuqRSd6Je0RDReTkVSVPHz3KytxeMRgVQvGyxn9"
    }

boot.img 추출

Step 1) firmware 다운로드

2022년 말을 기점으로 더 이상 공식 홈페이지에서 펌웨어를 다운로드 받을 수 없게 되었다. 하지만 언제나 방법은 있다. 아래 URL에서 MODEL_NAME 값을 본인 단말의 모델명으로 바꾸고 웹브라우저 주소창에 넣어 이동하자.

http://data.onyx-international.cn/api/firmware/update?where={"buildNumber":0,"buildType":"user","deviceMAC":"","lang":"en_US","model":"MODEL_NAME","submodel":"","fingerprint":""}

그러면 아래 JSON이 Response로 돌아온다.

{
  "_id": "635d30890da9ca3323343cdf",
  "updatedAt": "2022-10-31T10:18:51.093Z",
  "createdAt": "2022-10-29T13:54:17.167Z",
  "md5": "a29114b257c8a08ecc6e486726ac3fdf",
  "model": "Leaf2",
  "submodel": "",
  "brand": "Onyx",
  "fingerprint": "Onyx/Leaf2/Leaf2:11/2022-10-29_19-11_3.3.1_8c9d49397/1583:user/dev-keys",
  "buildType": "user",
  "buildNumber": 1583,
  "buildDisplayId": "2022-10-29_19-11_3.3.1_8c9d49397",
  "excludeGroups": false,
  "parentFingerprint": "",
  "force": false,
  "__v": 0,
  "whitelistMAC": [
    
  ],
  "size": 1500092388,
  "betaGroups": [
    
  ],
  "downloadUrlList": [
    "http://firmware-us-volc.boox.com/a29114b257c8a08ecc6e486726ac3fdf/update.upx"
  ],
  "changeList": [
    "Fix some UI problems"
  ],
  "fwType": "release"
}

여기에서 우리가 주목해야할 Key는 downloadUrlList로, 해당 URL로 이동하면 단말에 맞는 update.upx 펌웨어 파일을 다운로드 할 수 있다.

(필자의 변)
사실 펌웨어 구하는 데 시간을 제일 많이 썼다.
내 단말 빌드는 2022-11-22_10-20_3.3.1_e4f27d41a 버전인데 API가 보내준 빌드는 2022-10-29_19-11_3.3.1_8c9d49397이라 자칫 잘못하면 다 날아갈 수 있다는 생각에 현재 버전의 펌웨어를 구하려고 시도한 짓은 다음과 같다.

  • $ adb shellboot.img 추출하기
    • How to extract your boot.img from any rom (adb) 이걸 보고 시도하게 됐는데, TWRP를 써야한다고 했다. 찾아보니 펌웨어를 추출하고 공유하는 오픈소스 커뮤니티 프로젝트였다. (링크)
    • 하지만 내 모델은 신상이고 펌웨어가 오픈되어있지 않아서 찾을 수 없었다.
  • EDL(Emergency Download) 9008 모드로 부팅해서 펌웨어 받기
    • adb reboot edl로 기기를 재부팅시키고 펌웨어를 받는데, Qualcomm Sahara / Firehose Attack Client / Diag Tools 이 코드로 EDL 모드에서 명령어로 단말을 핸들링 할 수 있다고 했다. (EDL에서는 ADBFastboot도 안된다.)
    • 이 때 필요한 드라이버 등을 설치해야하는데, pyusb, libusb, UsbDk, QDLoaderHS_USB_Driver, Zadig로 겨우겨우 EDL에서 명령어를 입력할 수 있게 되었다.
    • 하지만 Note Air 2 rooting guide 이 글을 너무 성실히 따라해버리는 바람에, Loader가 다를 수 있다는 걸 몰랐다. SDM662라는 걸 보고 프로세서에 따라 로더가 달라진다는 걸 알았어야했다. (Note Air 2는 퀄컴 스냅드래곤 662를 사용한다.)
    • 어찌어찌 사태를 파악하고 내 단말에 맞는 로더를 찾는데, 프로세서 정보가 비공개다(...). 한참을 구글링하다 우연히 본 YouTubeCPU-z를 쓰니 프로세서 정보가 나오는 장면을 확인하고 바로 다운받았다. 덕분에 Leaf2스냅드래곤 630을 쓴다는 정보를 얻게 되었다.
    • 맞는 Loader를 찾아내어 돌렸는데.. 터미널에 변화가 없었다.
      $ python edl r boot_a boot.img --memory=ufs --loader ./Loaders/qualcomm/factory/sdm630/000ac0e100000000_7be49b72f9e43372_fhprg_asus_peek.bin
      	Qualcomm Sahara / Firehose Client V3.60 (c) B.Kerler 2018-2022.
      	main - Using loader ./Loaders/qualcomm/factory/sdm630/000ac0e100000000_7be49b72f9e43372_fhprg_asus_peek.bin ...
      	main - Waiting for the device
      	main - Device detected :)
      	main - Mode detected: sahara
    • 사용한 로더가 문제였을까, 위 상태에서 더 이상 진행되지 않았다. 한숨자고 일어났는데도 변화가 없어서 포기할까 하다가 '에라 모르겠다' 하고 구버전 빌드이지만 그냥 해당 펌웨어를 사용하기로 했다. (그런데 성공했다)

Step 2) firmware 복호화

준비사항 3-2. decryptBooxUpdateUpx를 사용한다.

  1. 2023년 3월 5일 기준 Leaf2모델의 정보가 없으므로, 해당 프로젝트 내 DeBooxUpx.py 코드 200번줄 즈음 작성된 dict타입 데이터에 Leaf2의 Key Strings를 추가한다.

    "Leaf2": {
    	"MODEL": "Leaf2",
    	"STRING_SETTINGS": "okRZqgfOHft/Y5jHx1N0ECjqrc/Op/nADFj2uL7Jbuxq",
    	"STRING_UPGRADE": "10Na33u5HfsCVHqjtwLrwACOW+2cz5MSnXUogONCTd9c"
    }
  2. Step 1에서 다운받은 update.upx 파일을 프로젝트 폴더로 이동시킨 뒤 아래 명령어를 터미널에서 실행한다.

    python DeBooxUpx.py Leaf2
  3. 생각보다 금방 처리되며, update.zip 파일이 생성된다.

  4. update.zip를 압축해제하고 payload.bin파일을 확보한다.

Step 3) payload.bin 추출

준비사항 3-3. payload-dumper-go를 사용한다.
1. 다운로드 받은 압축파일을 압축 해제하면 payload-dumper-go.exe가 포함된 폴더가 생성된다.
2. Step 2에서 확보한 payload.bin을 위 1항의 payload-dumper-go.exe 파일 위에 드래그 & 드랍해서 exe파일을 실행시킨다.
3. extracted_{DATETIME_YYYYMMDD_HHMMSS} 폴더가 생성되며, 내부에 boot.img를 비롯한 시스템 파일들이 생성된다. 우리는 boot.img만 잘 챙겨서 단말 내 로컬 스토리지에 옮기면 된다.

Root Privilege 패치

이 때 사전작업이 살짝 필요한데, 단말에서 개발자모드로 전환하고 USB Debugging을 활성화 해야한다.

Step 4) 개발자모드 전환

준비사항 2-1. Hidden Settings를 사용한다.

  1. (숨겨진) 안드로이드 기본 설정에 들어간다.
  2. 화면 최하단에 위치한 태블릿 정보 클릭
  3. 화면 최하단에 위치한 빌드 번호를 빠르게 5번+@ 클릭하여 개발자모드 활성화

Step 5) USB 디버깅 활성화

(위 Step 4에서 계속)
1. 다시 (숨겨진) 안드로이드 기본 설정 최상위로 이동
2. 화면 최하단에 위치한 시스템 클릭

3. [고급]을 선택하여 메뉴를 확장하고 개발자 옵션 클릭

4. (활성화 안돼있을 경우) 개발자 옵션 ON
5. 화면을 아래로 스크롤하여 디버깅 탭의 USB 디버깅을 ON으로 전환 (이미 켜져 있더라도 껐다가 다시 ON)

6. USB 케이블을 사용하여 데스크탑과 연결 (함께 제공된 케이블이 아니면 잘 안되는 경우가 있으므로 가급적 정품 케이블 사용 권장)

Step 6) boot.img에 권한 부여 패치

준비사항 2-2. Magisk를 사용한다.

  1. Magisk 앱을 실행한다
  2. 홈 화면 상단에 위치한 Magisk 우측의 설치 버튼 클릭
  3. 설치 방법 탭에서 파일 선택 및 패치 버튼을 클릭
  4. 아까 옮겨놓은 boot.img 파일을 선택한 뒤 설치 버튼 클릭
  5. 패치가 완료되어 생성된 부트이미지 magisk_patched-xxxxx_XXXX.img컴퓨터로 복사

Step 7) ROOT 권한으로 부팅

준비사항 3-1. ADB, Fastboot를 사용한다.

  1. 다운로드 받은 파일을 실행하여 설치한다. (참고자료 링크)
  2. Win + R을 눌러 [실행]창을 열고 cmd 입력 후 Ctrl + Shift + Enter를 눌러 관리자 권한으로 명령프롬프트 실행
  3. 아래 명령어를 순차적으로 실행
    cd C:\adb
    adb devices
    cf) List of devices attached 하단에 기기가 전시된다면 다음을 진행하고, 안된다면 장치관리자를 확인하여 드라이버 재설치
    adb reboot bootloader
    fastboot devices
    cf2) List of devices attached 하단에 기기가 전시된다면 다음을 진행하고, 안된다면 장치관리자를 확인하여 드라이버 재설치
  4. Step 6에서 복사해놓은 파일을 C:\adb로 이동하고 파일명+확장자를 복사
  5. 아래 명령어를 실행
    fastboot boot 파일명+확장자
  6. Sending 'boot.img'Booting, Finished가 처리 및 출력되며 단말이 재부팅

Step 8) ROOT 권한 적용

  1. 부팅이 완료된 후 Magisk 앱 실행
  2. 화면 상단의 Magisk 항목의 설치됨 영역에 Magisk 버전이 전시되는지 확인
  3. 우측 설치 버튼 클릭
  4. 설치 방법 탭에 바로 설치(권장됨) 체크 후 우측 설치 버튼 클릭
  5. 단말에서 아래 작업이 진행되고, 완료된 뒤 하단의 다시 시작 버튼 클릭

Step 9) ROOT 권한 확인

단말이 재부팅 되면 아래 명령어를 명령프롬프트에서 실행하여 루팅 상태 확인

> adb shell
$ su
# _

shell의 상태가 $에서 #로 바뀌면 su(Super User) 권한으로 변경된 상태임이 확인


결론

그렇게 필요한가? 싶긴 하지만 아래 스크립트를 실행해서 눈에 가시같던 불필요 앱들을 정리할 수 있었다.

> adb shell
$ pm list packages
$ su
# pm disable <package>;pm hide <package>

여담이지만, uninstall 명령어로 완전히 지워버릴 수 있는데, 혹시 몰라서 disable하고 hide로 숨김처리했다. 해당 처리를 진행한 패키지 목록은 다음과 같다.

com.onyx.calculator
com.onyx.appmarket
com.onyx.floatingbutton
com.onyx.mail
com.onyx.kime
com.onyx.latinime
org.chromium.chrome

좀 의아할만한 패키지는 아래 설명으로 갈음한다.

  • floatingbutton: 제스처로 다 커버가 돼서 필요가 없음
  • appmarket: 플레이스토어 두고 왜 쓰는지 모르겠음
  • kime: 오닉스 기본 한글 입력기는 💩
  • latinime: 마찬가지로 오닉스 영어 기본 입력기..
  • chrome: NeoBrowser (자세한 설명은 생략한다.)

References

Hacking the Onyx Boox Note Air E-Ink Tablet
[GUIDE] How to dump and write back the storage on most of Qualcomm devices
DOWNLOAD AND INSTALL QUALCOMM HS-USB QDLOADER 9008

profile
10년을 돌고 돌아 마침내 제자리를 찾은 문과 출신 Python 개발자의 인생기록장

2개의 댓글

comment-user-thumbnail
2024년 1월 3일

아오 성공했네요 ㅋㅋ Leaf3 직구로 ..
근데 루팅은 했는데 뭐 이후에 어떻게 해야할지 모르겠어요.

저는 중국어 -> 영어로 다 바뀌는 줄 알았거든요 ㅠ

1개의 답글