From d407221fda08884470ad4f4d73385709b73ee896 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=88=9A=28noham=29=C2=B2?= <100566912+NohamR@users.noreply.github.com> Date: Wed, 26 Aug 2026 00:23:17 +0200 Subject: [PATCH] Add auto-install flow and move scripts folder --- README.md | 32 ++++++------ scripts/auto-install.sh | 94 +++++++++++++++++++++++++++++++++++ {script => scripts}/build.sh | 2 +- {script => scripts}/inject.sh | 2 +- 4 files changed, 113 insertions(+), 17 deletions(-) create mode 100755 scripts/auto-install.sh rename {script => scripts}/build.sh (99%) rename {script => scripts}/inject.sh (98%) diff --git a/README.md b/README.md index 23ade29..452c815 100644 --- a/README.md +++ b/README.md @@ -28,20 +28,22 @@ Only `arm64-v8a` is supported (the hook library and PLT hooks are ARM64-specific ## Installation and usage -⚠️ **For legal reasons, this repository does not include the reMarkable app.** You must provide your own APKs (see the Building section). +⚠️ **For legal reasons, this repository does not include the reMarkable app.** However, the latest compiled `.so` files are available in the [Releases](https://github.com/NohamR/RMHook-Android/releases/latest) section. -### Prerequisites +### Auto installation -A macOS or Linux build host with: +Run in a terminal: +**Requirements:** `apktool`, `adb`, Android SDK build-tools (`zipalign`, `apksigner`), and `keytool` must be installed. -- **Android SDK Build Tools** (`zipalign`, `apksigner`) — install via Android Studio's SDK Manager or `sdkmanager "build-tools;36.0.0"`. -- **Android NDK** — e.g. `brew install --cask android-ndk` on macOS. Used to cross-compile `librmhook.so` for `aarch64-linux-android`. -- **apktool** — `brew install apktool` on macOS. Used to inject the `System.loadLibrary` call into `MainActivity.smali`. -- **Python 3** — used to install Qt via `aqtinstall`. -- **Java** — for `keytool` (signing keystore generation). -- The reMarkable Android **APK splits** (base + arm64 + xxhdpi). +```bash +bash <(curl -sL https://raw.githubusercontent.com/NohamR/RMHook-Android/refs/heads/main/scripts/auto-install.sh) +``` -### Pull the APK splits from your device +This will download the pre-built libraries, pull the APK splits from your device, inject the hook, and install the patched app. + +### Manual installation + +#### Step 1: Pull the APK splits from your device ```bash # List the paths of the installed splits @@ -62,13 +64,13 @@ You should now have three files in `~/reMarkable/app/`: ### Build ```bash -./script/build.sh +./scripts/build.sh ``` ### Inject & sign ```bash -./script/inject.sh [apk_dir] # apk_dir defaults to ~/reMarkable/app +./scripts/inject.sh [apk_dir] # apk_dir defaults to ~/reMarkable/app ``` Patches `base.apk`'s smali to `loadLibrary("rmhook")`, bundles `librmhook.so` + `libshadowhook_nothing.so` into the arm64 split, aligns and signs everything and puts the result in `output/`. @@ -125,7 +127,7 @@ Ensure the following are set or auto-detected: ### 3. Compile ```bash -./script/build.sh +./scripts/build.sh ``` ## Debugging @@ -172,8 +174,8 @@ When the app attempts to connect to reMarkable's servers (e.g., `internal.cloud. - xovi-rmfakecloud: [asivery/xovi-rmfakecloud](https://github.com/asivery/xovi-rmfakecloud) - Original hooking information - rmfakecloud: [ddvk/rmfakecloud](https://github.com/ddvk/rmfakecloud) - Self-hosted reMarkable cloud -- bytedance/android-inline-hook: [bytedance/android-inline-hook](https://github.com/bytedance/android-inline-hook) — ShadowHook, the inline hook library used for intercepting Qt function calls -- Dapitch666: [Dapitch666](https://github.com/dapitch666/) — initial proof-of-concept for hooking the reMarkable Android app and redirecting to rmfakecloud +- ShadowHook: [bytedance/android-inline-hook](https://github.com/bytedance/android-inline-hook) - Inline hook library for intercepting Qt function calls +- Dapitch666: [dapitch666](https://github.com/dapitch666/) - Initial proof-of-concept for hooking the reMarkable Android app ## License diff --git a/scripts/auto-install.sh b/scripts/auto-install.sh new file mode 100755 index 0000000..8f87088 --- /dev/null +++ b/scripts/auto-install.sh @@ -0,0 +1,94 @@ +#!/usr/bin/env bash +REPO="NohamR/RMHook-Android" +WORKDIR="/tmp/rmhook" + +set -euo pipefail + +# --- Check dependencies --- +echo "[INFO] Checking dependencies..." +MISSING=() +for cmd in adb apktool keytool; do + command -v "$cmd" >/dev/null 2>&1 || MISSING+=("$cmd") +done +# Check Android SDK build-tools (zipalign + apksigner) +SDK_ROOT="${ANDROID_SDK_ROOT:-$HOME/Library/Android/sdk}" +BUILD_TOOLS="$(find "$SDK_ROOT/build-tools" -maxdepth 1 -type d 2>/dev/null | sort -V | tail -1)" +if [ -z "$BUILD_TOOLS" ] || [ ! -d "$BUILD_TOOLS" ]; then + MISSING+=("Android SDK build-tools (zipalign, apksigner)") +fi +if [ ${#MISSING[@]} -gt 0 ]; then + echo "❌ Missing required tools:" + for m in "${MISSING[@]}"; do echo " - $m"; done + echo "" + echo "Install with:" + echo " brew install apktool android-platform-tools" + echo " # Android SDK build-tools via Android Studio SDK Manager" + exit 1 +fi +export ANDROID_SDK_BUILD_TOOLS="$BUILD_TOOLS" + +# --- Setup workspace --- +echo "[INFO] Setting up workspace..." +rm -rf "$WORKDIR" +mkdir -p "$WORKDIR/build" "$WORKDIR/libs" "$WORKDIR/config" "$WORKDIR/output" + +# --- Download .so files from releases --- +echo "[INFO] Downloading librmhook.so..." +curl -sL \ + -o "$WORKDIR/build/librmhook.so" \ + "https://github.com/$REPO/releases/latest/download/librmhook.so" + +echo "[INFO] Downloading libshadowhook_nothing.so..." +curl -sL \ + -o "$WORKDIR/libs/libshadowhook_nothing.so" \ + "https://github.com/$REPO/releases/latest/download/libshadowhook_nothing.so" + +# --- Download inject script --- +echo "[INFO] Downloading inject script..." +curl -sL \ + -o "$WORKDIR/inject.sh" \ + "https://raw.githubusercontent.com/$REPO/refs/heads/main/scripts/inject.sh" +chmod +x "$WORKDIR/inject.sh" + +# --- Pull APK splits from device --- +APK_DIR="$HOME/reMarkable/app" +mkdir -p "$APK_DIR" + +echo "[INFO] Detecting reMarkable app on device..." +PKG_PATHS="$(adb shell pm path com.remarkable.mobile 2>/dev/null || true)" +if [ -z "$PKG_PATHS" ]; then + echo "❌ reMarkable app not found on device. Install it from the Play Store first." + exit 1 +fi + +echo "[INFO] Pulling APK splits..." +while IFS= read -r line; do + APK_PATH="${line#package:}" + APK_NAME="$(basename "$APK_PATH")" + echo " Pulling $APK_NAME..." + adb pull "$APK_PATH" "$APK_DIR/$APK_NAME" 2>/dev/null +done <<< "$PKG_PATHS" + +if [ ! -f "$APK_DIR/base.apk" ]; then + echo "❌ Failed to pull base.apk" + exit 1 +fi + +# --- Run inject --- +echo "[INFO] Running inject script..." +"$WORKDIR/inject.sh" "$APK_DIR" + +# --- Install --- +echo "[INFO] Installing patched APKs..." +adb uninstall com.remarkable.mobile 2>/dev/null || true +adb install-multiple --no-streaming "$WORKDIR/output/base.apk" "$WORKDIR/output/split_config.arm64_v8a.apk" "$WORKDIR/output/split_config.xxhdpi.apk" + +echo "" +echo "✅ Done! RMHook is installed on your reMarkable." +echo "" +echo "📋 Next steps:" +echo " 1. Open the reMarkable app" +echo " 2. Configure your rmfakecloud host and port" +echo "" +echo "🔍 To debug:" +echo " adb logcat -s 'RMHook:*'" diff --git a/script/build.sh b/scripts/build.sh similarity index 99% rename from script/build.sh rename to scripts/build.sh index 8e3585c..1ca7e6b 100755 --- a/script/build.sh +++ b/scripts/build.sh @@ -120,5 +120,5 @@ echo "✅ Compilation successful!" echo "📍 Library: $BUILD_DIR/$SO_NAME ($(ls -lh "$BUILD_DIR/$SO_NAME" | awk '{print $5}'))" echo "" echo "🚀 To inject into the reMarkable application:" -echo " ./script/inject.sh" +echo " ./scripts/inject.sh" echo "" \ No newline at end of file diff --git a/script/inject.sh b/scripts/inject.sh similarity index 98% rename from script/inject.sh rename to scripts/inject.sh index 115f381..2cf3a59 100755 --- a/script/inject.sh +++ b/scripts/inject.sh @@ -60,7 +60,7 @@ echo "📦 APK source: $APK_DIR" echo "" if [ ! -f "$BUILD_DIR/librmhook.so" ]; then - echo "❌ librmhook.so not found. Run ./script/build.sh first." + echo "❌ librmhook.so not found. Run ./scripts/build.sh first." exit 1 fi