Skip to content
This repository has been archived by the owner on May 1, 2019. It is now read-only.

Commit

Permalink
Initial Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
thestr4ng3r committed Dec 28, 2017
0 parents commit b6fce00
Show file tree
Hide file tree
Showing 23 changed files with 1,102 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
*.swp
*.apk
*.jks
/arcore-preview2_patched_apk

87 changes: 87 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# ARCore Patch

This is an attempt to patch ARCore (Preview 2) to run on currently unsupported devices.

## Findings

Although not directly obvious to users, ARCore Preview 2 seems to have gone through huge changes compared to Preview 1. Thus, the approach from https://github.com/tomthecarrot/arcore-for-all is not directly applicable anymore.

Device compatibility related functionality has been moved from the `aar` packaged in apps to the `arcore-preview2.apk`. This apk now contains a native library called `libdevice_profile_loader.so` which is responsible for loading a profile for the device. In the following, memory addresses are specified as virtual addresses for the arm64-v8a version of this library.

Devices are hard-coded inside this library and are identified by an enum (just an int value) called `device_provider::DeviceType`. Luckily, there a function included that converts this value to a readable string called `device_provider::ToString(const device_provider::DeviceType &)` (at `0x00048ea0`). See [device_type_strings.txt](device_type_strings.txt) for possible strings (starting at `0x00157e5c`). Here are some examples for values with corresponding strings (incomplete list):

| DeviceType | String |
| ---------- | -------------------- |
| 0 | kUnknownDevice |
| 1 | kPeanut |
| 4 | kYellowstoneDVT2 |
| 5 | kYellowstoneDVT3 |
| 6 | kYellowstonePVT |
| 7 | kYellowstoneRangeEnd |
| 8 | kTwizzler |
| 9 | kRubicon |
| 10 | kSimulation |
| 11 | kCoconut |
| 12 | kPistachio |
| 13 | kLucid |
| 1000 | kLeTangoStart |
| 1001 | kMarlin |
| 1002 | kSailfish |
| 1003 | kMuskie |
| 1004 | kWalleye |
| 1005 | kTaimen |
| 1006 | kAngler |
| 1007 | kLucyevzwLucye |
| 1008 | kLucyesprusLucye |
| 1009 | kLucyeattusLucye |
| 1011 | kDukl09Hwduk |
| 1012 | kOneplus5Oneplus5 |
| 1013 | kG3123G3123 |
| 1014 | kG8142G8142 |

Obviously, `kMarlin` corresponds to the Pixel, `kSailfish` to the Pixel XL and so on. What is especially interesting here is that there are way more devices than the ones officially supported!
There are also some values that I cannot make sense of yet, such as `kPeanut`, `kCoconut` and so on. Just a very wild guess: Maybe `Peanut` is the codename for Android 9 and this value makes the library load the profile from the system itself instead of hard-coding anything?

For many of the listed devices, the apk then contains protobuf files (for some reason in text form, not the usual binary representation) in `assets` containing the profile data with exact calibration values for camera and IMU. Format definitions for these files recovered using [pbtk](https://github.com/marin-m/pbtk) are contained in this repository inside [proto](proto).

Unfortunately, I do not own any of these devices (the closest I have is a Nexus 5X), so I cannot test what happens when this is run on one of them. The `DeviceType` for the current device is determined inside the function `device_provider::InferDeviceTypeFromAndroidProperties(const std::string &)` (at `0x000496a4`). This function can be patched to always return a constant value.

One idea to get ARCore fully working on unsupported devices would be to patch this function for a specific value and modify the corresponding protobuf with values fitting for the device.

Running the Hello AR demo from google on my Nexus 5X crashes with many of the values, but with some (such as `kAngler`) it shows a camera image (upside down, which is a common issue with the Nexus 5X), but it is not able to track anything. Logcat gives valuable info on what goes wrong, but I have not investigated further yet.

## Patch

This repo includes a small bash script called [patch_apk.sh](patch_apk.sh) that can be used to patch the original `arcore-preview2.apk` to always assume a specific `DeviceType` as described above.

### Requirements

The script requires the following tools to be present in `PATH`:

- [apktool](https://ibotpeaches.github.io/Apktool/)
- [radare2](https://github.com/radare/radare2) (install from git, NOT any outdated distribution packages!)
- keytool
- zipalign and apksigner (from the Android SDK build tools)

### Patching

Download the original apk next to `patch_apk.sh`:
```
wget https://github.com/google-ar/arcore-android-sdk/releases/download/sdk-preview2/arcore-preview2.apk
```

Run the script in the same directory:
```
./patch_apk.sh [device-type]
```
Replace `[device-type]` with the device type you want, for example `1006` for Nexus 6P.

You should get an apk called `arcore-preview2-patched-signed.apk` that you can install to your device:
```
adb install -r arcore-preview2-patched-signed.apk
```

If have the original apk installed already, it is necessary to manually uninstall that before, since it is signed with a different key:
```
adb uninstall com.google.ar.core
```
110 changes: 110 additions & 0 deletions device_type_strings.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
vaddr=0x00157e5c paddr=0x00157e5c ordinal=331 sz=15 len=14 section=.rodata type=ascii string=kUnknownDevice
vaddr=0x00157e6b paddr=0x00157e6b ordinal=332 sz=8 len=7 section=.rodata type=ascii string=kPeanut
vaddr=0x00157e73 paddr=0x00157e73 ordinal=333 sz=19 len=18 section=.rodata type=ascii string=kYellowstoneDVT1_1
vaddr=0x00157e86 paddr=0x00157e86 ordinal=334 sz=19 len=18 section=.rodata type=ascii string=kYellowstoneDVT1_2
vaddr=0x00157e99 paddr=0x00157e99 ordinal=335 sz=17 len=16 section=.rodata type=ascii string=kYellowstoneDVT2
vaddr=0x00157eaa paddr=0x00157eaa ordinal=336 sz=17 len=16 section=.rodata type=ascii string=kYellowstoneDVT3
vaddr=0x00157ebb paddr=0x00157ebb ordinal=337 sz=16 len=15 section=.rodata type=ascii string=kYellowstonePVT
vaddr=0x00157ecb paddr=0x00157ecb ordinal=338 sz=21 len=20 section=.rodata type=ascii string=kYellowstoneRangeEnd
vaddr=0x00157ee0 paddr=0x00157ee0 ordinal=339 sz=10 len=9 section=.rodata type=ascii string=kTwizzler
vaddr=0x00157eea paddr=0x00157eea ordinal=340 sz=9 len=8 section=.rodata type=ascii string=kRubicon
vaddr=0x00157ef3 paddr=0x00157ef3 ordinal=341 sz=8 len=7 section=.rodata type=ascii string=kMarlin
vaddr=0x00157efb paddr=0x00157efb ordinal=342 sz=10 len=9 section=.rodata type=ascii string=kSailfish
vaddr=0x00157f05 paddr=0x00157f05 ordinal=343 sz=9 len=8 section=.rodata type=ascii string=kWalleye
vaddr=0x00157f0e paddr=0x00157f0e ordinal=344 sz=8 len=7 section=.rodata type=ascii string=kTaimen
vaddr=0x00157f16 paddr=0x00157f16 ordinal=345 sz=8 len=7 section=.rodata type=ascii string=kMuskie
vaddr=0x00157f1e paddr=0x00157f1e ordinal=346 sz=12 len=11 section=.rodata type=ascii string=kSimulation
vaddr=0x00157f2a paddr=0x00157f2a ordinal=347 sz=9 len=8 section=.rodata type=ascii string=kCoconut
vaddr=0x00157f33 paddr=0x00157f33 ordinal=348 sz=11 len=10 section=.rodata type=ascii string=kPistachio
vaddr=0x00157f3e paddr=0x00157f3e ordinal=349 sz=7 len=6 section=.rodata type=ascii string=kLucid
vaddr=0x00157f45 paddr=0x00157f45 ordinal=350 sz=14 len=13 section=.rodata type=ascii string=kLeTangoStart
vaddr=0x00157f53 paddr=0x00157f53 ordinal=351 sz=15 len=14 section=.rodata type=ascii string=kLucyevzwLucye
vaddr=0x00157f62 paddr=0x00157f62 ordinal=352 sz=17 len=16 section=.rodata type=ascii string=kLucyesprusLucye
vaddr=0x00157f73 paddr=0x00157f73 ordinal=353 sz=17 len=16 section=.rodata type=ascii string=kLucyeattusLucye
vaddr=0x00157f84 paddr=0x00157f84 ordinal=354 sz=20 len=19 section=.rodata type=ascii string=kZerofltedvZeroflte
vaddr=0x00157f98 paddr=0x00157f98 ordinal=355 sz=24 len=23 section=.rodata type=ascii string=kZerofltesprZerofltespr
vaddr=0x00157fb0 paddr=0x00157fb0 ordinal=356 sz=24 len=23 section=.rodata type=ascii string=kZerofltetmoZerofltetmo
vaddr=0x00157fc8 paddr=0x00157fc8 ordinal=357 sz=23 len=22 section=.rodata type=ascii string=kZeroflteueZerofltetmo
vaddr=0x00157fdf paddr=0x00157fdf ordinal=358 sz=23 len=22 section=.rodata type=ascii string=kZeroflteucZeroflteatt
vaddr=0x00157ff6 paddr=0x00157ff6 ordinal=359 sz=24 len=23 section=.rodata type=ascii string=kZerofltevzwZerofltevzw
vaddr=0x0015800e paddr=0x0015800e ordinal=360 sz=20 len=19 section=.rodata type=ascii string=kZerofltexxZeroflte
vaddr=0x00158022 paddr=0x00158022 ordinal=361 sz=22 len=21 section=.rodata type=ascii string=kZeroltesprZeroltespr
vaddr=0x00158038 paddr=0x00158038 ordinal=362 sz=22 len=21 section=.rodata type=ascii string=kZeroltetmoZeroltetmo
vaddr=0x0015804e paddr=0x0015804e ordinal=363 sz=21 len=20 section=.rodata type=ascii string=kZerolteucZerolteatt
vaddr=0x00158063 paddr=0x00158063 ordinal=364 sz=22 len=21 section=.rodata type=ascii string=kZeroltevzwZeroltevzw
vaddr=0x00158079 paddr=0x00158079 ordinal=365 sz=18 len=17 section=.rodata type=ascii string=kZeroltexxZerolte
vaddr=0x0015808b paddr=0x0015808b ordinal=366 sz=20 len=19 section=.rodata type=ascii string=kZenltesprZenltespr
vaddr=0x0015809f paddr=0x0015809f ordinal=367 sz=20 len=19 section=.rodata type=ascii string=kZenltetmoZenltetmo
vaddr=0x001580b3 paddr=0x001580b3 ordinal=368 sz=19 len=18 section=.rodata type=ascii string=kZenlteucZenlteatt
vaddr=0x001580c6 paddr=0x001580c6 ordinal=369 sz=20 len=19 section=.rodata type=ascii string=kZenltevzwZenltevzw
vaddr=0x001580da paddr=0x001580da ordinal=370 sz=11 len=10 section=.rodata type=ascii string=kHtc_pmewl
vaddr=0x001580e5 paddr=0x001580e5 ordinal=371 sz=13 len=12 section=.rodata type=ascii string=kDukl09Hwduk
vaddr=0x001580f2 paddr=0x001580f2 ordinal=372 sz=18 len=17 section=.rodata type=ascii string=kSdm66064Sdm66064
vaddr=0x00158104 paddr=0x00158104 ordinal=373 sz=18 len=17 section=.rodata type=ascii string=kOneplus5Oneplus5
vaddr=0x00158116 paddr=0x00158116 ordinal=374 sz=8 len=7 section=.rodata type=ascii string=kAngler
vaddr=0x0015811e paddr=0x0015811e ordinal=375 sz=12 len=11 section=.rodata type=ascii string=kG3123G3123
vaddr=0x0015812a paddr=0x0015812a ordinal=376 sz=12 len=11 section=.rodata type=ascii string=kG8142G8142
vaddr=0x00158136 paddr=0x00158136 ordinal=377 sz=12 len=11 section=.rodata type=ascii string=kSc02jSc02j
vaddr=0x00158142 paddr=0x00158142 ordinal=378 sz=12 len=11 section=.rodata type=ascii string=kSc03jSc03j
vaddr=0x0015814e paddr=0x0015814e ordinal=379 sz=17 len=16 section=.rodata type=ascii string=kScv36jpkdiScv36
vaddr=0x0015815f paddr=0x0015815f ordinal=380 sz=17 len=16 section=.rodata type=ascii string=kScv35jpkdiScv35
vaddr=0x00158170 paddr=0x00158170 ordinal=381 sz=22 len=21 section=.rodata type=ascii string=kDreamlteksDreamlteks
vaddr=0x00158186 paddr=0x00158186 ordinal=382 sz=24 len=23 section=.rodata type=ascii string=kDream2lteksDream2lteks
vaddr=0x0015819e paddr=0x0015819e ordinal=383 sz=26 len=25 section=.rodata type=ascii string=kDreamqltezmDreamqltecmcc
vaddr=0x001581b8 paddr=0x001581b8 ordinal=384 sz=28 len=27 section=.rodata type=ascii string=kDream2qltezmDream2qltecmcc
vaddr=0x001581d4 paddr=0x001581d4 ordinal=385 sz=26 len=25 section=.rodata type=ascii string=kDreamlteldukxDreamlteskt
vaddr=0x001581ee paddr=0x001581ee ordinal=386 sz=28 len=27 section=.rodata type=ascii string=kDream2lteldukxDream2lteskt
vaddr=0x0015820a paddr=0x0015820a ordinal=387 sz=20 len=19 section=.rodata type=ascii string=kDreamltexxDreamlte
vaddr=0x0015821e paddr=0x0015821e ordinal=388 sz=22 len=21 section=.rodata type=ascii string=kDream2ltexxDream2lte
vaddr=0x00158234 paddr=0x00158234 ordinal=389 sz=21 len=20 section=.rodata type=ascii string=kDreamltelduDreamlte
vaddr=0x00158249 paddr=0x00158249 ordinal=390 sz=23 len=22 section=.rodata type=ascii string=kDream2ltelduDream2lte
vaddr=0x00158260 paddr=0x00158260 ordinal=391 sz=24 len=23 section=.rodata type=ascii string=kDreamqltesqDreamqltesq
vaddr=0x00158278 paddr=0x00158278 ordinal=392 sz=26 len=25 section=.rodata type=ascii string=kDream2qltesqDream2qltesq
vaddr=0x00158292 paddr=0x00158292 ordinal=393 sz=27 len=26 section=.rodata type=ascii string=kDreamqlteldusqDreamqltesq
vaddr=0x001582ad paddr=0x001582ad ordinal=394 sz=29 len=28 section=.rodata type=ascii string=kDream2qlteldusqDream2qltesq
vaddr=0x001582ca paddr=0x001582ca ordinal=395 sz=24 len=23 section=.rodata type=ascii string=kDreamqlteueDreamqlteue
vaddr=0x001582e2 paddr=0x001582e2 ordinal=396 sz=26 len=25 section=.rodata type=ascii string=kDream2qlteueDream2qlteue
vaddr=0x001582fc paddr=0x001582fc ordinal=397 sz=25 len=24 section=.rodata type=ascii string=kDreamqltevlDreamqltecan
vaddr=0x00158315 paddr=0x00158315 ordinal=398 sz=27 len=26 section=.rodata type=ascii string=kDream2qltevlDream2qltecan
vaddr=0x00158330 paddr=0x00158330 ordinal=399 sz=10 len=9 section=.rodata type=ascii string=kHero2lte
vaddr=0x0015833a paddr=0x0015833a ordinal=400 sz=14 len=13 section=.rodata type=ascii string=kHero2qltetmo
vaddr=0x00158348 paddr=0x00158348 ordinal=401 sz=13 len=12 section=.rodata type=ascii string=kHero2lteskt
vaddr=0x00158355 paddr=0x00158355 ordinal=402 sz=14 len=13 section=.rodata type=ascii string=kHero2qlteatt
vaddr=0x00158363 paddr=0x00158363 ordinal=403 sz=13 len=12 section=.rodata type=ascii string=kHero2ltektt
vaddr=0x00158370 paddr=0x00158370 ordinal=404 sz=14 len=13 section=.rodata type=ascii string=kHero2qltechn
vaddr=0x0015837e paddr=0x0015837e ordinal=405 sz=17 len=16 section=.rodata type=ascii string=kHero2qltecctvzw
vaddr=0x0015838f paddr=0x0015838f ordinal=406 sz=13 len=12 section=.rodata type=ascii string=kHero2ltebmc
vaddr=0x0015839c paddr=0x0015839c ordinal=407 sz=7 len=6 section=.rodata type=ascii string=kScv33
vaddr=0x001583a3 paddr=0x001583a3 ordinal=408 sz=14 len=13 section=.rodata type=ascii string=kHero2qltevzw
vaddr=0x001583b1 paddr=0x001583b1 ordinal=409 sz=14 len=13 section=.rodata type=ascii string=kHero2qlteusc
vaddr=0x001583bf paddr=0x001583bf ordinal=410 sz=13 len=12 section=.rodata type=ascii string=kHero2qlteue
vaddr=0x001583cc paddr=0x001583cc ordinal=411 sz=13 len=12 section=.rodata type=ascii string=kHero2ltelgt
vaddr=0x001583d9 paddr=0x001583d9 ordinal=412 sz=14 len=13 section=.rodata type=ascii string=kHero2qltespr
vaddr=0x001583e7 paddr=0x001583e7 ordinal=413 sz=7 len=6 section=.rodata type=ascii string=kSc02h
vaddr=0x001583ee paddr=0x001583ee ordinal=414 sz=13 len=12 section=.rodata type=ascii string=kHeroqltetmo
vaddr=0x001583fb paddr=0x001583fb ordinal=415 sz=12 len=11 section=.rodata type=ascii string=kHerolteskt
vaddr=0x00158407 paddr=0x00158407 ordinal=416 sz=12 len=11 section=.rodata type=ascii string=kHeroltektt
vaddr=0x00158413 paddr=0x00158413 ordinal=417 sz=13 len=12 section=.rodata type=ascii string=kHeroqltechn
vaddr=0x00158420 paddr=0x00158420 ordinal=418 sz=13 len=12 section=.rodata type=ascii string=kHeroqlteacg
vaddr=0x0015842d paddr=0x0015842d ordinal=419 sz=13 len=12 section=.rodata type=ascii string=kHeroqlteaio
vaddr=0x0015843a paddr=0x0015843a ordinal=420 sz=12 len=11 section=.rodata type=ascii string=kHeroltebmc
vaddr=0x00158446 paddr=0x00158446 ordinal=421 sz=12 len=11 section=.rodata type=ascii string=kHeroltelgt
vaddr=0x00158452 paddr=0x00158452 ordinal=422 sz=13 len=12 section=.rodata type=ascii string=kHeroqltelra
vaddr=0x0015845f paddr=0x0015845f ordinal=423 sz=13 len=12 section=.rodata type=ascii string=kHeroqltemtr
vaddr=0x0015846c paddr=0x0015846c ordinal=424 sz=16 len=15 section=.rodata type=ascii string=kHeroqltecctvzw
vaddr=0x0015847c paddr=0x0015847c ordinal=425 sz=16 len=15 section=.rodata type=ascii string=kHeroqltetfnvzw
vaddr=0x0015848c paddr=0x0015848c ordinal=426 sz=12 len=11 section=.rodata type=ascii string=kHeroqlteue
vaddr=0x00158498 paddr=0x00158498 ordinal=427 sz=13 len=12 section=.rodata type=ascii string=kHeroqlteusc
vaddr=0x001584a5 paddr=0x001584a5 ordinal=428 sz=13 len=12 section=.rodata type=ascii string=kHeroqltevzw
vaddr=0x001584b2 paddr=0x001584b2 ordinal=429 sz=9 len=8 section=.rodata type=ascii string=kHerolte
vaddr=0x001584bb paddr=0x001584bb ordinal=430 sz=13 len=12 section=.rodata type=ascii string=kHeroqlteatt
vaddr=0x001584c8 paddr=0x001584c8 ordinal=431 sz=13 len=12 section=.rodata type=ascii string=kHeroqltespr
vaddr=0x001584d5 paddr=0x001584d5 ordinal=432 sz=24 len=23 section=.rodata type=ascii string=kNobleltevzwNobleltevzw
vaddr=0x001584ed paddr=0x001584ed ordinal=433 sz=22 len=21 section=.rodata type=ascii string=kGreatqltesqGreatqlte
vaddr=0x00158503 paddr=0x00158503 ordinal=434 sz=24 len=23 section=.rodata type=ascii string=kGreatqlteueGreatqlteue
vaddr=0x0015851b paddr=0x0015851b ordinal=435 sz=20 len=19 section=.rodata type=ascii string=kGreatltexxGreatlte
vaddr=0x0015852f paddr=0x0015852f ordinal=436 sz=10 len=9 section=.rodata type=ascii string=kNashNash
vaddr=0x00158539 paddr=0x00158539 ordinal=437 sz=16 len=15 section=.rodata type=ascii string=kNashsprintNash
vaddr=0x00158549 paddr=0x00158549 ordinal=438 sz=12 len=11 section=.rodata type=ascii string=kSagitSagit
vaddr=0x00158555 paddr=0x00158555 ordinal=439 sz=10 len=9 section=.rodata type=ascii string=kEmulator
vaddr=0x0015855f paddr=0x0015855f ordinal=440 sz=12 len=11 section=.rodata type=ascii string=kLeTangoEnd
46 changes: 46 additions & 0 deletions patch_apk.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/bin/bash

if [ "$#" -ne 1 ]; then
echo "usage: $0 [device-type]"
exit 1
fi

device_type=$1

if ! [[ "$device_type" =~ ^((0x[0-9a-fA-F]+)|([0-9]+))$ ]]; then
echo "device type must be a valid number."
fi

function log {
echo -e "\e[1m[$0] $1\e[0m"
}

log "Cleaning up old files"
rm -rf \
arcore-preview2_patched_apk \
arcore-preview2-patched-unsigned.apk \
arcore-preview2-patched-unsigned-aligned.apk \
arcore-preview2-patched-signed.apk

log "Extracting apk"
apktool -q d -s -r arcore-preview2.apk -o arcore-preview2_patched_apk || exit 1

log "Patching libdevice_profile_loader.so using radare2, our lord and savior"
radare2 -w arcore-preview2_patched_apk/lib/arm64-v8a/libdevice_profile_loader.so -q -c "\"wa movz x0, $device_type;ret\" @ 0x000496a4" || exit 1

log "Re-building apk"
apktool -q b arcore-preview2_patched_apk -o arcore-preview2-patched-unsigned.apk || exit 1

if [ ! -f keystore.jks ]; then
log "Keystore does not exist. Creating a new one."
keytool -genkeypair -keystore keystore.jks -storepass 123456 -keypass 123456 -dname "CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown"
fi

log "Signing apk"
zipalign -p 4 arcore-preview2-patched-unsigned.apk arcore-preview2-patched-unsigned-aligned.apk || exit 1
apksigner sign -ks keystore.jks --ks-pass pass:123456 --key-pass pass:123456 --out arcore-preview2-patched-signed.apk arcore-preview2-patched-unsigned-aligned.apk || exit 1

log "Verifying apk"
apksigner verify arcore-preview2-patched-signed.apk || exit 1

log "Success! Now install arcore-preview2-patched-signed.apk on your device!"
15 changes: 15 additions & 0 deletions proto/google/protobuf/any.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
syntax = "proto3";

package google.protobuf;

option csharp_namespace = "Google.Protobuf.WellKnownTypes";
option objc_class_prefix = "GPB";
option go_package = "github.com/golang/protobuf/ptypes/any";
option java_multiple_files = true;
option java_outer_classname = "AnyProto";
option java_package = "com.google.protobuf";

message Any {
string type_url = 1;
bytes value = 2;
}
Loading

0 comments on commit b6fce00

Please sign in to comment.