From 5e98304b62be3560e317be92e4f0479b54625f57 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: Thu, 23 Oct 2025 21:41:46 +0200 Subject: [PATCH] First release --- .gitignore | 3 + CMakeLists.txt | 100 +++++++ LICENSE | 21 ++ README.md | 140 +++++++++ docs/help-config.png | Bin 0 -> 136951 bytes libs/libtinyhook.a | Bin 0 -> 42600 bytes scripts/build.sh | 39 +++ scripts/inject.sh | 85 ++++++ src/core/tinyhook.h | 51 ++++ src/core/tinyhook/memory.c | 39 +++ src/core/tinyhook/objcrt.c | 66 +++++ src/core/tinyhook/search.c | 23 ++ src/core/tinyhook/symsolve/symexport.c | 121 ++++++++ src/core/tinyhook/symsolve/symtable.c | 60 ++++ src/core/tinyhook/tinyhook.c | 183 ++++++++++++ src/reMarkable/reMarkable.h | 5 + src/reMarkable/reMarkable.m | 390 +++++++++++++++++++++++++ src/utils/Constant.h | 7 + src/utils/Constant.m | 25 ++ src/utils/Logger.h | 6 + src/utils/MemoryUtils.h | 33 +++ src/utils/MemoryUtils.m | 106 +++++++ src/utils/ResourceUtils.h | 42 +++ src/utils/ResourceUtils.m | 381 ++++++++++++++++++++++++ 24 files changed, 1926 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 LICENSE create mode 100644 README.md create mode 100644 docs/help-config.png create mode 100644 libs/libtinyhook.a create mode 100755 scripts/build.sh create mode 100755 scripts/inject.sh create mode 100644 src/core/tinyhook.h create mode 100644 src/core/tinyhook/memory.c create mode 100644 src/core/tinyhook/objcrt.c create mode 100644 src/core/tinyhook/search.c create mode 100644 src/core/tinyhook/symsolve/symexport.c create mode 100644 src/core/tinyhook/symsolve/symtable.c create mode 100644 src/core/tinyhook/tinyhook.c create mode 100644 src/reMarkable/reMarkable.h create mode 100644 src/reMarkable/reMarkable.m create mode 100644 src/utils/Constant.h create mode 100644 src/utils/Constant.m create mode 100644 src/utils/Logger.h create mode 100644 src/utils/MemoryUtils.h create mode 100644 src/utils/MemoryUtils.m create mode 100644 src/utils/ResourceUtils.h create mode 100644 src/utils/ResourceUtils.m diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9053de0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +build/ +.DS_Store +/.vscode diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..6f90501 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,100 @@ +cmake_minimum_required(VERSION 3.15) +project(RMHook) + +enable_language(OBJC OBJCXX) + +set(CMAKE_C_STANDARD 11) +set(CMAKE_CXX_STANDARD 17) + +# Compiler settings for macOS +set(CMAKE_MACOSX_RPATH 1) +set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version") + +# Architecture: x86_64 only for reMarkable +set(CMAKE_OSX_ARCHITECTURES "x86_64") + +# Project root directory +set(PROJECT_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}) + +# Include directories +include_directories( + ${PROJECT_ROOT_DIR}/src/core + ${PROJECT_ROOT_DIR}/src/utils +) + +# Find required libraries +find_library(FOUNDATION_LIBRARY Foundation REQUIRED) +find_library(COCOA_LIBRARY Cocoa REQUIRED) +find_library(SECURITY_LIBRARY Security REQUIRED) + +# Common libraries +set(LIBS + ${FOUNDATION_LIBRARY} + ${COCOA_LIBRARY} + ${SECURITY_LIBRARY} + ${PROJECT_ROOT_DIR}/libs/libtinyhook.a + z # zlib for compression/decompression +) + +# Locate Qt libraries +set(QT_LIB_TARGETS "") +set(_qt_candidate_roots "$ENV{HOME}/Qt/6.10.0") + +foreach(_qt_root ${_qt_candidate_roots}) + if(_qt_root AND EXISTS "${_qt_root}") + list(APPEND CMAKE_PREFIX_PATH "${_qt_root}") + endif() +endforeach() + +find_package(Qt6 COMPONENTS Core Network WebSockets QUIET) +if(Qt6_FOUND) + set(QT_LIB_TARGETS Qt6::Core Qt6::Network Qt6::WebSockets) +else() + find_package(Qt5 COMPONENTS Core Network WebSockets QUIET) + if(Qt5_FOUND) + set(QT_LIB_TARGETS Qt5::Core Qt5::Network Qt5::WebSockets) + endif() +endif() + +if(NOT QT_LIB_TARGETS) + message(FATAL_ERROR "Qt Core, Network and WebSockets not found. Set CMAKE_PREFIX_PATH to your Qt installation.") +endif() + +# Common sources +set(COMMON_SOURCES + ${PROJECT_ROOT_DIR}/src/utils/MemoryUtils.m + ${PROJECT_ROOT_DIR}/src/utils/Constant.m + ${PROJECT_ROOT_DIR}/src/utils/ResourceUtils.m +) + +# reMarkable dylib +set(REMARKABLE_SOURCES + ${PROJECT_ROOT_DIR}/src/reMarkable/reMarkable.m +) + +add_library(reMarkable SHARED + ${COMMON_SOURCES} + ${REMARKABLE_SOURCES} +) + +# Set source files as Objective-C++ +set_source_files_properties( + ${REMARKABLE_SOURCES} + PROPERTIES LANGUAGE OBJCXX +) + +set_target_properties(reMarkable PROPERTIES + PREFIX "" + SUFFIX ".dylib" + OUTPUT_NAME "reMarkable" + LIBRARY_OUTPUT_DIRECTORY "${PROJECT_ROOT_DIR}/build/dylibs" + MACOSX_RPATH ON +) + +add_definitions(-DQT_NO_VERSION_TAGGING) + +target_link_libraries(reMarkable PRIVATE + ${LIBS} + ${QT_LIB_TARGETS} + /opt/homebrew/Cellar/libzip/1.11.4/lib/intel/libzstd.1.5.7.dylib +) \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f2bb2bf --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Rivoirard Noham + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..77ffbec --- /dev/null +++ b/README.md @@ -0,0 +1,140 @@ +# RMHook + +A dynamic library injection tool for the reMarkable Desktop macOS application, enabling connection to self-hosted [rmfakecloud](https://github.com/ddvk/rmfakecloud) servers. + +## Overview + +RMHook hooks into the reMarkable Desktop app's network layer to redirect API calls from reMarkable's official cloud services to your own rmfakecloud server. This allows you to maintain full control over your documents and data. + +## Features + +- Network request interception and redirection +- WebSocket connection patching + +## Installation and usage + +### Important legal notice + +⚠️ **For legal reasons, this repository does not include a pre-patched reMarkable app.** However, the latest compiled dylib is available in the [Releases](https://github.com/NohamR/RMHook/releases/latest) section. + +### Step 1: Prepare the reMarkable app + +Uses the reMarkable Desktop app from your Applications folder or download it fresh from the [Mac App Store](https://apps.apple.com/app/remarkable-desktop/id1276493162). + +### Step 2: Inject the dylib + +Use the provided injection script: +```bash +./scripts/inject.sh reMarkable.dylib reMarkable.app +``` + +This script will: +- Copy the dylib to the app bundle's Resources folder +- Inject the load command into the executable using `optool` +- Remove the code signature and resign with ad-hoc signature +- Remove the `_MASReceipt` folder +- Fix file ownership + +### Step 3: Handle document storage + +#### Important path changes + +The original Mac App Store version stores data in sandboxed locations: +**Original sandboxed paths:** +- App data: `~/Library/Containers/com.remarkable.desktop/Data` +- Documents: `~/Library/Containers/com.remarkable.desktop/Data/Library/Application Support/remarkable` + +**After re-signing, the app is no longer sandboxed** and will use standard paths: +- Config: `~/Library/Preferences/rmfakecloud.config` +- Documents: `~/Library/Application Support/remarkable` + +#### Migration options + +**Option 1: Create a symbolic link** (recommended) +```bash +ln -s ~/Library/Containers/com.remarkable.desktop/Data/Library/Application\ Support/remarkable \ + ~/Library/Application\ Support/remarkable +``` +The symbolic link approach allows you to keep using the original App Store version alongside the patched version. + +**Option 2: Move files** +```bash +mv ~/Library/Containers/com.remarkable.desktop/Data/Library/Application\ Support/remarkable \ + ~/Library/Application\ Support/remarkable +``` + +### Step 4: Configure rmfakecloud server +Quickly access the configuration file from the app's Help menu: +![help-config.png](docs/help-config.png) +Edit the configuration file at: +``` +~/Library/Preferences/rmfakecloud.config +``` + +Example configuration: +```json +{ + "host": "your-server.example.com", + "port": 443 +} +``` + +### Step 5: Launch the patched app :p + +## How it works +RMHook uses [tinyhook](https://github.com/Antibioticss/tinyhook/) to hook into Qt framework functions at runtime: +1. **QNetworkAccessManager::createRequest** - Intercepts HTTP/HTTPS requests +2. **QWebSocket::open** - Patches WebSocket connections + +When the app attempts to connect to reMarkable's servers (e.g., `internal.cloud.remarkable.com`), the hooks redirect these requests to your configured host and port. + +## Configuration + +The config file (`~/Library/Preferences/rmfakecloud.config`) supports the following keys: +| Key | Type | Default | Description | +|--------|---------|-------------------|--------------------------------| +| `host` | String | `example.com` | Your rmfakecloud server host | +| `port` | Number | `443` | Your rmfakecloud server port | + +If the config file doesn't exist, it will be created automatically with default values on first launch. + +## Troubleshooting + +### App won't launch +- Ensure the code signature was properly applied +- Check that `xattr -cr` was run to clear quarantine attributes +- Verify the dylib is in `Contents/Resources/` folder + +### Document sync issues +- Ensure your rmfakecloud server is running and accessible +- Verify the storage path migration was completed + +## Credits +- **tinyhook**: [Antibioticss/tinyhook](https://github.com/Antibioticss/tinyhook/) - Function hooking framework +- **rmfakecloud**: [ddvk/rmfakecloud](https://github.com/ddvk/rmfakecloud) - Self-hosted reMarkable cloud +- **optool**: [alexzielenski/optool](https://github.com/alexzielenski/optool) - Mach-O binary modification tool + +## License + +This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details. + +## Disclaimer + +This project is not affiliated with, endorsed by, or sponsored by reMarkable AS. Use at your own risk. This tool modifies the reMarkable Desktop application and may violate the application's terms of service. + +## Contributing + +Contributions are welcome! Please feel free to submit issues or pull requests. + +## Building + +1. **Clone the repository:** +```bash +git clone http://github.com/NohamR/RMHook +cd RMHook +``` + +2. **Compile the dylib:** +```bash +./scripts/build.sh +``` \ No newline at end of file diff --git a/docs/help-config.png b/docs/help-config.png new file mode 100644 index 0000000000000000000000000000000000000000..9b987c1954b43f849e24ac510174b34ca48d7864 GIT binary patch literal 136951 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

@o>E2Q{c2(swSAd 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 literal 0 HcmV?d00001 diff --git a/scripts/build.sh b/scripts/build.sh new file mode 100755 index 0000000..d58d02e --- /dev/null +++ b/scripts/build.sh @@ -0,0 +1,39 @@ +#!/bin/bash +# Script to compile the reMarkable dylib + +# By default, compile reMarkable +APP_NAME=${1:-reMarkable} +PROJECT_DIR=$(cd "$(dirname "$0")/.." && pwd) + +# Qt path detection (adjust according to your installation) +QT_PATH=${QT_PATH:-"$HOME/Qt/6.10.0"} + +echo "🔨 Compiling $APP_NAME.dylib..." +echo "📦 Qt path: $QT_PATH" + +# Create build directories if necessary +mkdir -p "$PROJECT_DIR/build" +cd "$PROJECT_DIR/build" + +# Configure with CMake and compile +if [ -d "$QT_PATH" ]; then + cmake -DCMAKE_PREFIX_PATH="$QT_PATH" .. +else + echo "⚠️ Qt not found at $QT_PATH, trying without specifying path..." + cmake .. +fi + +make $APP_NAME + +if [ $? -eq 0 ]; then + echo "" + echo "✅ Compilation successful!" + echo "📍 Dylib: $PROJECT_DIR/build/dylibs/$APP_NAME.dylib" + echo "" + echo "🚀 To inject into the reMarkable application:" + echo " DYLD_INSERT_LIBRARIES=\"$PROJECT_DIR/build/dylibs/$APP_NAME.dylib\" /Applications/reMarkable.app/Contents/MacOS/reMarkable" + echo "" +else + echo "❌ Compilation failed" + exit 1 +fi \ No newline at end of file diff --git a/scripts/inject.sh b/scripts/inject.sh new file mode 100755 index 0000000..f60e8ae --- /dev/null +++ b/scripts/inject.sh @@ -0,0 +1,85 @@ +#!/bin/bash + +set -e + +# Function to display usage instructions +usage() { + echo "Usage: $0 " + echo " dylib - The dynamic library to inject." + echo " app_path - The path to the .app bundle." + exit 1 +} + +# Ensure required arguments are provided +if [ "$#" -ne 2 ]; then + echo "[ERROR] Incorrect number of arguments." + usage +fi + +DYLIB=$1 +APP_PATH=$2 + +# Validate inputs +if [ ! -f "$DYLIB" ]; then + echo "[ERROR] The specified dynamic library ($DYLIB) does not exist." + exit 1 +fi + +if [ ! -d "$APP_PATH" ]; then + echo "[ERROR] The specified app path ($APP_PATH) does not exist." + exit 1 +fi + +INFO_PLIST_PATH="$APP_PATH/Contents/Info.plist" +if [ ! -f "$INFO_PLIST_PATH" ]; then + echo "[ERROR] Info.plist not found at $INFO_PLIST_PATH" + exit 1 +fi + +# Get the executable name from Info.plist +APP_NAME=$(/usr/libexec/PlistBuddy -c "Print CFBundleExecutable" "$INFO_PLIST_PATH") +if [ -z "$APP_NAME" ]; then + echo "[ERROR] Could not read CFBundleExecutable from $INFO_PLIST_PATH" + exit 1 +fi + +echo "[INFO] Executable name: $APP_NAME" + +EXECUTABLE_PATH="$APP_PATH/Contents/MacOS/$APP_NAME" +if [ ! -f "$EXECUTABLE_PATH" ]; then + echo "[ERROR] The specified executable ($EXECUTABLE_PATH) does not exist." + exit 1 +fi + +mkdir -p "$APP_PATH/Contents/Resources/" + +# Copy the dylib to the Resources folder +cp "$DYLIB" "$APP_PATH/Contents/Resources/" +echo "[INFO] Copied $DYLIB to $APP_PATH/Contents/Resources/" + +optool install -c load -p "@executable_path/../Resources/$(basename "$DYLIB")" -t "$EXECUTABLE_PATH" +echo "[INFO] Injected $DYLIB into $EXECUTABLE_PATH" + +sudo codesign --remove-signature "$EXECUTABLE_PATH" +sudo xattr -cr "$EXECUTABLE_PATH" +sudo codesign -f -s - --timestamp=none --all-architectures "$EXECUTABLE_PATH" +sudo xattr -cr "$EXECUTABLE_PATH" + +echo "Signed successfully." + +# Change ownership to current user +CURRENT_USER=$(whoami) +CURRENT_GROUP=$(id -gn) +echo "Changing ownership to $CURRENT_USER:$CURRENT_GROUP for $APP_PATH ..." +sudo chown -R "$CURRENT_USER:$CURRENT_GROUP" "$APP_PATH" + +# Remove _MASReceipt if it exists +RECEIPT_PATH="$APP_PATH/Contents/_MASReceipt" +if [ -d "$RECEIPT_PATH" ]; then + echo "Removing _MASReceipt..." + rm -r "$RECEIPT_PATH" +else + echo "No _MASReceipt directory found." +fi + +exit 0 \ No newline at end of file diff --git a/src/core/tinyhook.h b/src/core/tinyhook.h new file mode 100644 index 0000000..88eba0f --- /dev/null +++ b/src/core/tinyhook.h @@ -0,0 +1,51 @@ +#ifndef tinyhook_h +#define tinyhook_h + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define CLASS_METHOD 0 +#define INSTANCE_METHOD 1 + +/* inline hook */ +int tiny_hook(void *function, void *destination, void **origin); + +int tiny_insert(void *address, void *destination, bool link); + +int tiny_insert_far(void *address, void *destination, bool link); + +/* objective-c runtime */ +int ocrt_hook(const char *cls, const char *sel, void *destination, void **origin); + +int ocrt_swap(const char *cls1, const char *sel1, const char *cls2, const char *sel2); + +void *ocrt_impl(const char *cls, const char *sel, bool type); + +Method ocrt_method(const char *cls, const char *sel, bool type); + +/* memory access */ +int read_mem(void *destination, const void *source, size_t len); + +int write_mem(void *destination, const void *source, size_t len); + +/* solve symbol */ +void *symtbl_solve(uint32_t image_index, const char *symbol_name); + +void *symexp_solve(uint32_t image_index, const char *symbol_name); + +/* find in memory */ +// int find_code(uint32_t image_index, const unsigned char *code, size_t len, int count, void **out); + +int find_data(void *start, void *end, const unsigned char *data, size_t len, int count, void **out); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/core/tinyhook/memory.c b/src/core/tinyhook/memory.c new file mode 100644 index 0000000..70b26d3 --- /dev/null +++ b/src/core/tinyhook/memory.c @@ -0,0 +1,39 @@ +#include // mach_task_self() +#include // mach_vm_* +#include // memcpy() + +#ifndef COMPACT +#include // mach_error_string() +#include // fprintf() +#endif + +#include "../include/tinyhook.h" + +int read_mem(void *destination, const void *source, size_t len) { + int kr = 0; + vm_offset_t data; + mach_msg_type_number_t dataCnt; + kr |= mach_vm_read(mach_task_self(), (mach_vm_address_t)source, len, &data, &dataCnt); + memcpy((unsigned char *)destination, (unsigned char *)data, dataCnt); + kr |= mach_vm_deallocate(mach_task_self(), data, dataCnt); +#ifndef COMPACT + if (kr != 0) { + fprintf(stderr, "read_mem: %s\n", mach_error_string(kr)); + } +#endif + return kr; +} + +int write_mem(void *destination, const void *source, size_t len) { + int kr = 0; + kr |= mach_vm_protect(mach_task_self(), (mach_vm_address_t)destination, len, FALSE, + VM_PROT_READ | VM_PROT_WRITE | VM_PROT_COPY); + kr |= mach_vm_write(mach_task_self(), (mach_vm_address_t)destination, (vm_offset_t)source, len); + kr |= mach_vm_protect(mach_task_self(), (mach_vm_address_t)destination, len, FALSE, VM_PROT_READ | VM_PROT_EXECUTE); +#ifndef COMPACT + if (kr != 0) { + fprintf(stderr, "write_mem: %s\n", mach_error_string(kr)); + } +#endif + return kr; +} \ No newline at end of file diff --git a/src/core/tinyhook/objcrt.c b/src/core/tinyhook/objcrt.c new file mode 100644 index 0000000..3b2ffb5 --- /dev/null +++ b/src/core/tinyhook/objcrt.c @@ -0,0 +1,66 @@ +#include // objc_*, ... + +#ifndef COMPACT +#include // mach_error_string() +#include // fprintf() +#endif + +#include "../include/tinyhook.h" + +Method ocrt_method(const char *cls, const char *sel, bool type) { + Method oc_method = NULL; + Class oc_class = objc_getClass(cls); + SEL oc_selector = sel_registerName(sel); + if (type == CLASS_METHOD) { + oc_method = class_getClassMethod(oc_class, oc_selector); + } else if (type == INSTANCE_METHOD) { + oc_method = class_getInstanceMethod(oc_class, oc_selector); + } +#ifndef COMPACT + else { + fprintf(stderr, "ocrt_method: invalid method type: %d\n", type); + } +#endif + return oc_method; +} + +void *ocrt_impl(const char *cls, const char *sel, bool type) { + return method_getImplementation(ocrt_method(cls, sel, type)); +} + +static Method ensure_method(const char *cls, const char *sel); + +int ocrt_swap(const char *cls1, const char *sel1, const char *cls2, const char *sel2) { + Method oc_method1 = ensure_method(cls1, sel1); + Method oc_method2 = ensure_method(cls2, sel2); + if (oc_method1 == NULL || oc_method2 == NULL) { + return 1; + } + method_exchangeImplementations(oc_method1, oc_method2); + return 0; +} + +int ocrt_hook(const char *cls, const char *sel, void *destination, void **origin) { + Method oc_method = ensure_method(cls, sel); + if (oc_method == NULL) { + return 1; + } + void *origin_imp = method_setImplementation(oc_method, destination); + if (origin != NULL) { + *origin = origin_imp; + } + return 0; +} + +static Method ensure_method(const char *cls, const char *sel) { + Method oc_method = ocrt_method(cls, sel, CLASS_METHOD); + if (oc_method == NULL) { + oc_method = ocrt_method(cls, sel, INSTANCE_METHOD); + } +#ifndef COMPACT + if (oc_method == NULL) { + fprintf(stderr, "ensure_method: method not found!\n"); + } +#endif + return oc_method; +} \ No newline at end of file diff --git a/src/core/tinyhook/search.c b/src/core/tinyhook/search.c new file mode 100644 index 0000000..e5f7192 --- /dev/null +++ b/src/core/tinyhook/search.c @@ -0,0 +1,23 @@ +#ifndef COMPACT +#include // fprintf() +#endif + +#include "skip/skip.h" + +#include "../include/tinyhook.h" + +int find_data(void *start, void *end, const unsigned char *data, size_t len, int count, void **out) { + int matched; + skipidx_t idx; + skip_init(&idx, len, data); + matched = skip_match(&idx, start, end, count, (offset_t *)out); + skip_release(&idx); +#ifndef COMPACT + if (matched == 0) { + fprintf(stderr, "find_data: data not found!\n"); + } +#endif + return matched; +} + +// int find_code(uint32_t image_index, const unsigned char *code, size_t len, int count, void **out); \ No newline at end of file diff --git a/src/core/tinyhook/symsolve/symexport.c b/src/core/tinyhook/symsolve/symexport.c new file mode 100644 index 0000000..43151a4 --- /dev/null +++ b/src/core/tinyhook/symsolve/symexport.c @@ -0,0 +1,121 @@ +#include // _dyld_* +#include // mach_header_64, load_command... +#include // nlist_64 +#include // strcmp() + +#ifndef COMPACT +#include // fprintf() +#endif + +#include "../../include/tinyhook.h" + +static void *trie_query(const uint8_t *export, const char *name); + +void *symexp_solve(uint32_t image_index, const char *symbol_name) { + void *symbol_address = NULL; + intptr_t image_slide = _dyld_get_image_vmaddr_slide(image_index); + struct mach_header_64 *mh_header = (struct mach_header_64 *)_dyld_get_image_header(image_index); + struct load_command *ld_command = (void *)mh_header + sizeof(struct mach_header_64); +#ifndef COMPACT + if (mh_header == NULL) { + fprintf(stderr, "symexp_solve: image_index out of range!\n"); + } +#endif + struct dyld_info_command *dyldinfo_cmd = NULL; + struct segment_command_64 *linkedit_cmd = NULL; + for (int i = 0; i < mh_header->ncmds; i++) { + if (ld_command->cmd == LC_SEGMENT_64) { + const struct segment_command_64 *segment = (struct segment_command_64 *)ld_command; + if (strcmp(segment->segname, "__LINKEDIT") == 0) { + linkedit_cmd = (struct segment_command_64 *)ld_command; + } + } else if (ld_command->cmd == LC_DYLD_INFO_ONLY || ld_command->cmd == LC_DYLD_INFO) { + dyldinfo_cmd = (struct dyld_info_command *)ld_command; + if (linkedit_cmd != NULL) { + break; + } + } + ld_command = (void *)ld_command + ld_command->cmdsize; + } + if (dyldinfo_cmd == NULL) { +#ifndef COMPACT + fprintf(stderr, "symexp_solve: LC_DYLD_INFO_ONLY segment not found!\n"); +#endif + return NULL; + } + // stroff and strtbl are in the __LINKEDIT segment + // Its offset will change when loaded into the memory, so we need to add this slide + intptr_t linkedit_slide = linkedit_cmd->vmaddr - linkedit_cmd->fileoff; + uint8_t *export_offset = (uint8_t *)image_slide + linkedit_slide + dyldinfo_cmd->export_off; + symbol_address = trie_query(export_offset, symbol_name); + + if (symbol_address != NULL) { + symbol_address += image_slide; + } +#ifndef COMPACT + else { + fprintf(stderr, "symexp_solve: symbol not found!\n"); + } +#endif + return symbol_address; +} + +inline uint64_t read_uleb128(const uint8_t **p) { + int bit = 0; + uint64_t result = 0; + do { + uint64_t slice = **p & 0x7f; + result |= (slice << bit); + bit += 7; + } while (*(*p)++ & 0x80); + return result; +} + +static void *trie_query(const uint8_t *export, const char *name) { + // most comments below are copied from , not AI generated :P + // a trie node starts with a uleb128 stored the lenth of the exported symbol information + uint64_t node_off = 0; + const char *rest_name = name; + void *symbol_address = NULL; + bool go_child = true; + while (go_child) { + const uint8_t *cur_pos = export + node_off; + uint64_t info_len = read_uleb128(&cur_pos); + // the exported symbol information is followed by the child edges + const uint8_t *child_off = cur_pos + info_len; + + if (rest_name[0] == '\0') { + if (info_len != 0) { + // first is a uleb128 containing flags + uint64_t flag = read_uleb128(&cur_pos); + if (flag == EXPORT_SYMBOL_FLAGS_KIND_REGULAR) { + // normally, it is followed by a uleb128 encoded function offset + uint64_t symbol_off = read_uleb128(&cur_pos); + symbol_address = (void *)symbol_off; + } + } + break; + } else { + go_child = false; + cur_pos = child_off; + // child edges start with a byte of how many edges (0-255) this node has + uint8_t child_count = *(uint8_t *)cur_pos++; + // then followed by each edge. + for (int i = 0; i < child_count; i++) { + // each edge is a zero terminated UTF8 of the addition chars + char *cur_str = (char *)cur_pos; + size_t cur_len = strlen(cur_str); + cur_pos += cur_len + 1; + // then followed by a uleb128 offset for the node that edge points to + uint64_t next_off = read_uleb128(&cur_pos); + if (strncmp(rest_name, cur_str, cur_len) == 0) { + go_child = true; + rest_name += cur_len; + node_off = next_off; + break; + } + } + } + } + return symbol_address; +} \ No newline at end of file diff --git a/src/core/tinyhook/symsolve/symtable.c b/src/core/tinyhook/symsolve/symtable.c new file mode 100644 index 0000000..e04b0d8 --- /dev/null +++ b/src/core/tinyhook/symsolve/symtable.c @@ -0,0 +1,60 @@ +#include // _dyld_* +#include // mach_header_64, load_command... +#include // nlist_64 +#include // strcmp() + +#ifndef COMPACT +#include // fprintf() +#endif + +#include "../../include/tinyhook.h" + +void *symtbl_solve(uint32_t image_index, const char *symbol_name) { + void *symbol_address = NULL; + intptr_t image_slide = _dyld_get_image_vmaddr_slide(image_index); + struct mach_header_64 *mh_header = (struct mach_header_64 *)_dyld_get_image_header(image_index); + struct load_command *ld_command = (void *)mh_header + sizeof(struct mach_header_64); +#ifndef COMPACT + if (mh_header == NULL) { + fprintf(stderr, "symtbl_solve: image_index out of range!\n"); + } +#endif + struct symtab_command *symtab_cmd = NULL; + struct segment_command_64 *linkedit_cmd = NULL; + for (int i = 0; i < mh_header->ncmds; i++) { + if (ld_command->cmd == LC_SEGMENT_64) { + const struct segment_command_64 *segment = (struct segment_command_64 *)ld_command; + if (strcmp(segment->segname, "__LINKEDIT") == 0) { + linkedit_cmd = (struct segment_command_64 *)ld_command; + } + } else if (ld_command->cmd == LC_SYMTAB) { + symtab_cmd = (struct symtab_command *)ld_command; + if (linkedit_cmd != NULL) { + break; + } + } + ld_command = (void *)ld_command + ld_command->cmdsize; + } + // stroff and strtbl are in the __LINKEDIT segment + // Its offset will change when loaded into the memory, so we need to add this slide + intptr_t linkedit_slide = linkedit_cmd->vmaddr - linkedit_cmd->fileoff; + struct nlist_64 *nl_tbl = (void *)image_slide + linkedit_slide + symtab_cmd->symoff; + char *str_tbl = (void *)image_slide + linkedit_slide + symtab_cmd->stroff; + for (int j = 0; j < symtab_cmd->nsyms; j++) { + if ((nl_tbl[j].n_type & N_TYPE) == N_SECT) { + if (strcmp(symbol_name, str_tbl + nl_tbl[j].n_un.n_strx) == 0) { + symbol_address = (void *)nl_tbl[j].n_value; + break; + } + } + } + if (symbol_address != NULL) { + symbol_address += image_slide; + } +#ifndef COMPACT + else { + fprintf(stderr, "symtbl_solve: symbol not found!\n"); + } +#endif + return symbol_address; +} \ No newline at end of file diff --git a/src/core/tinyhook/tinyhook.c b/src/core/tinyhook/tinyhook.c new file mode 100644 index 0000000..bbce0da --- /dev/null +++ b/src/core/tinyhook/tinyhook.c @@ -0,0 +1,183 @@ +#include // mach_task_self() +#include // mach_vm_* +#include // atexit() +#include // memcpy() + +#ifndef COMPACT +#include // mach_error_string() +#include // fprintf() +#endif + +#ifdef __x86_64__ +#include "fde64/fde64.h" +#endif + +#include "../include/tinyhook.h" + +#define MB (1ll << 20) +#define GB (1ll << 30) + +#ifdef __aarch64__ +#define AARCH64_B 0x14000000 // b +0 +#define AARCH64_BL 0x94000000 // bl +0 +#define AARCH64_ADRP 0x90000011 // adrp x17, 0 +#define AARCH64_BR 0xd61f0220 // br x17 +#define AARCH64_BLR 0xd63f0220 // blr x17 +#define AARCH64_ADD 0x91000231 // add x17, x17, 0 +#define AARCH64_SUB 0xd1000231 // sub x17, x17, 0 + +#define MAX_JUMP_SIZE 12 + +#elif __x86_64__ +#define X86_64_CALL 0xe8 // call +#define X86_64_JMP 0xe9 // jmp +#define X86_64_JMP_RIP 0x000025ff // jmp [rip] +#define X86_64_CALL_RIP 0x000015ff // call [rip] +#define X86_64_MOV_RI64 0xb848 // mov r64, m64 +#define X86_64_MOV_RM64 0x8b48 // mov r64, [r64] + +#define MAX_JUMP_SIZE 14 +#endif + +int tiny_insert(void *address, void *destination, bool link) { + size_t jump_size; + int assembly; + unsigned char bytes[MAX_JUMP_SIZE]; +#ifdef __aarch64__ + // b/bl imm ; go to destination + jump_size = 4; + assembly = (destination - address) >> 2 & 0x3ffffff; + assembly |= link ? AARCH64_BL : AARCH64_B; + *(int *)bytes = assembly; +#elif __x86_64__ + // jmp/call imm ; go to destination + jump_size = 5; + *bytes = link ? X86_64_CALL : X86_64_JMP; + assembly = (long)destination - (long)address - 5; + *(int *)(bytes + 1) = assembly; +#endif + write_mem(address, bytes, jump_size); + return jump_size; +} + +int tiny_insert_far(void *address, void *destination, bool link) { + size_t jump_size; + unsigned char bytes[MAX_JUMP_SIZE]; +#ifdef __aarch64__ + // adrp x17, imm + // add x17, x17, imm ; x17 -> destination + // br/blr x17 + jump_size = 12; + int assembly; + assembly = (((long)destination >> 12) - ((long)address >> 12)) & 0x1fffff; + assembly = ((assembly & 0x3) << 29) | (assembly >> 2 << 5) | AARCH64_ADRP; + *(int *)bytes = assembly; + assembly = ((long)destination & 0xfff) << 10 | AARCH64_ADD; + *(int *)(bytes + 4) = assembly; + *(int *)(bytes + 8) = link ? AARCH64_BLR : AARCH64_BR; +#elif __x86_64__ + jump_size = 14; + // jmp [rip] ; rip stored destination + *(int *)bytes = link ? X86_64_CALL_RIP : X86_64_JMP_RIP; + bytes[5] = bytes[6] = 0; + *(long long *)(bytes + 6) = (long long)destination; +#endif + write_mem(address, bytes, jump_size); + return jump_size; +} + +int position = 0; +mach_vm_address_t vm; + +static int get_jump_size(void *address, void *destination); +static int insert_jump(void *address, void *destination); +static int save_header(void *address, void *destination, int *skip_len); + +int tiny_hook(void *function, void *destination, void **origin) { + int kr = 0; + if (origin == NULL) + insert_jump(function, destination); + else { + if (!position) { + // alloc a vm to store headers and jumps + kr = mach_vm_allocate(mach_task_self(), &vm, PAGE_SIZE, VM_FLAGS_ANYWHERE); +#ifndef COMPACT + if (kr != 0) { + fprintf(stderr, "mach_vm_allocate: %s\n", mach_error_string(kr)); + } +#endif + } + int skip_len; + *origin = (void *)(vm + position); + position += save_header(function, (void *)(vm + position), &skip_len); + position += insert_jump((void *)(vm + position), function + skip_len); + insert_jump(function, destination); + } + return kr; +} + +static int get_jump_size(void *address, void *destination) { + long long distance = destination > address ? destination - address : address - destination; +#ifdef __aarch64__ + return distance < 128 * MB ? 4 : 12; +#elif __x86_64__ + return distance < 2 * GB ? 5 : 14; +#endif +} + +static int insert_jump(void *address, void *destination) { + if (get_jump_size(address, destination) <= 5) + return tiny_insert(address, destination, false); + else + return tiny_insert_far(address, destination, false); +} + +static int save_header(void *address, void *destination, int *skip_len) { + int header_len = 0; +#ifdef __aarch64__ + header_len = *skip_len = get_jump_size(address, destination); + unsigned char bytes_out[MAX_JUMP_SIZE]; + read_mem(bytes_out, address, MAX_JUMP_SIZE); + for (int i = 0; i < header_len; i += 4) { + int cur_asm = *(int *)(bytes_out + i); + long cur_addr = (long)address + i, cur_dst = (long)destination + i; + if (((cur_asm ^ 0x90000000) & 0x9f000000) == 0) { + // adrp + // modify the immediate + int len = (cur_asm >> 29 & 0x3) | ((cur_asm >> 3) & 0x1ffffc); + len += (cur_addr >> 12) - (cur_dst >> 12); + cur_asm &= 0x9f00001f; + cur_asm = ((len & 0x3) << 29) | (len >> 2 << 5) | cur_asm; + *(int *)(bytes_out + i) = cur_asm; + } + } +#elif __x86_64__ + int min_len; + struct fde64s assembly; + unsigned char bytes_in[MAX_JUMP_SIZE * 2], bytes_out[MAX_JUMP_SIZE * 4]; + read_mem(bytes_in, address, MAX_JUMP_SIZE * 2); + min_len = get_jump_size(address, destination); + for (*skip_len = 0; *skip_len < min_len; *skip_len += assembly.len) { + long long cur_addr = (long long)address + *skip_len; + decode(bytes_in + *skip_len, &assembly); + if (assembly.opcode == 0x8B && assembly.modrm_rm == 0b101) { + // mov r64, [rip+] + // split it into 2 instructions + // mov r64 $rip+(immediate) + // mov r64 [r64] + *(short *)(bytes_out + header_len) = X86_64_MOV_RI64; + bytes_out[header_len + 1] += assembly.modrm_reg; + *(long long *)(bytes_out + header_len + 2) = assembly.disp32 + cur_addr + assembly.len; + header_len += 10; + *(short *)(bytes_out + header_len) = X86_64_MOV_RM64; + bytes_out[header_len + 2] = assembly.modrm_reg << 3 | assembly.modrm_reg; + header_len += 3; + } else { + memcpy(bytes_out + header_len, bytes_in + *skip_len, assembly.len); + header_len += assembly.len; + } + } +#endif + write_mem(destination, bytes_out, header_len); + return header_len; +} \ No newline at end of file diff --git a/src/reMarkable/reMarkable.h b/src/reMarkable/reMarkable.h new file mode 100644 index 0000000..ba2cdcb --- /dev/null +++ b/src/reMarkable/reMarkable.h @@ -0,0 +1,5 @@ +#import + +@interface reMarkable : NSObject + +@end \ No newline at end of file diff --git a/src/reMarkable/reMarkable.m b/src/reMarkable/reMarkable.m new file mode 100644 index 0000000..c789c40 --- /dev/null +++ b/src/reMarkable/reMarkable.m @@ -0,0 +1,390 @@ +#import "reMarkable.h" +#import +#import "Constant.h" +#import "MemoryUtils.h" +#import "Logger.h" +#import "ResourceUtils.h" +#import +#import +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static NSString *const kReMarkableConfigFileName = @"rmfakecloud.config"; +static NSString *const kReMarkableConfigHostKey = @"host"; +static NSString *const kReMarkableConfigPortKey = @"port"; +static NSString *const kReMarkableDefaultHost = @"example.com"; +static NSNumber *const kReMarkableDefaultPort = @(443); + +static NSString *gConfiguredHost = @"example.com"; +static NSNumber *gConfiguredPort = @(443); +static pthread_mutex_t gResourceMutex = PTHREAD_MUTEX_INITIALIZER; + +static NSString *ReMarkablePreferencesDirectory(void); + +static NSString *ReMarkablePreferencesDirectory(void) { + NSArray *libraryPaths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES); + NSString *libraryDir = [libraryPaths firstObject]; + if (![libraryDir length]) { + libraryDir = [NSHomeDirectory() stringByAppendingPathComponent:@"Library"]; + } + return [libraryDir stringByAppendingPathComponent:@"Preferences"]; +} + +static NSString *ReMarkableConfigFilePath(void) { + return [ReMarkablePreferencesDirectory() stringByAppendingPathComponent:kReMarkableConfigFileName]; +} + +static BOOL ReMarkableWriteConfig(NSString *path, NSDictionary *config) { + NSError *error = nil; + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:config options:NSJSONWritingPrettyPrinted error:&error]; + if (!jsonData || error) { + NSLogger(@"[reMarkable] Failed to serialize config: %@", error); + return NO; + } + if (![jsonData writeToFile:path atomically:YES]) { + NSLogger(@"[reMarkable] Failed to write config file at %@", path); + return NO; + } + return YES; +} + +static void ReMarkableLoadOrCreateConfig(void) { + NSString *configPath = ReMarkableConfigFilePath(); + NSString *directory = [configPath stringByDeletingLastPathComponent]; + NSFileManager *fileManager = [NSFileManager defaultManager]; + BOOL isDirectory = NO; + NSError *error = nil; + + if (![fileManager fileExistsAtPath:directory isDirectory:&isDirectory] || !isDirectory) { + if (![fileManager createDirectoryAtPath:directory withIntermediateDirectories:YES attributes:nil error:&error]) { + NSLogger(@"[reMarkable] Failed to create config directory %@: %@", directory, error); + } + } + + NSDictionary *defaults = @{kReMarkableConfigHostKey : kReMarkableDefaultHost, + kReMarkableConfigPortKey : kReMarkableDefaultPort}; + + if ([fileManager fileExistsAtPath:configPath isDirectory:&isDirectory] && !isDirectory) { + NSData *data = [NSData dataWithContentsOfFile:configPath]; + if ([data length] > 0) { + NSError *jsonError = nil; + id jsonObject = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError]; + if (!jsonError && [jsonObject isKindOfClass:[NSDictionary class]]) { + NSDictionary *configDict = (NSDictionary *)jsonObject; + NSString *hostValue = configDict[kReMarkableConfigHostKey]; + NSNumber *portValue = configDict[kReMarkableConfigPortKey]; + + NSString *resolvedHost = ([hostValue isKindOfClass:[NSString class]] && [hostValue length]) ? hostValue : kReMarkableDefaultHost; + NSInteger portCandidate = kReMarkableDefaultPort.integerValue; + if ([portValue respondsToSelector:@selector(integerValue)]) { + NSInteger candidate = [portValue integerValue]; + if (candidate > 0 && candidate <= 65535) { + portCandidate = candidate; + } else { + NSLogger(@"[reMarkable] Ignoring invalid port value %@, falling back to default.", portValue); + } + } + + gConfiguredHost = [resolvedHost copy]; + gConfiguredPort = @(portCandidate); + NSLogger(@"[reMarkable] Loaded config from %@ with host %@ and port %@", configPath, gConfiguredHost, gConfiguredPort); + return; + } else { + NSLogger(@"[reMarkable] Failed to parse config file %@: %@", configPath, jsonError); + } + } else { + NSLogger(@"[reMarkable] Config file %@ was empty, rewriting with defaults.", configPath); + } + } + + if (ReMarkableWriteConfig(configPath, defaults)) { + NSLogger(@"[reMarkable] Created default config at %@", configPath); + } + gConfiguredHost = [kReMarkableDefaultHost copy]; + gConfiguredPort = kReMarkableDefaultPort; +} + +static inline QString QStringFromNSStringSafe(NSString *string) { + if (!string) { + return QString(); + } + return QString::fromUtf8([string UTF8String]); +} + +@interface MenuActionController : NSObject +@property (strong, nonatomic) NSURL *targetURL; +- (void)openURLAction:(id)sender; ++ (void)addCustomHelpMenuEntry:(NSString *)title withURL:(NSString *)url; ++ (void)addCustomHelpMenuEntry:(NSString *)title withURL:(NSString *)url withDelay:(NSTimeInterval)delay; +@end + +@implementation MenuActionController + +- (void)openURLAction:(id)sender { + if (self.targetURL) { + [[NSWorkspace sharedWorkspace] openURL:self.targetURL]; + NSLogger(@"[+] URL opened successfully: %@", self.targetURL); + } +} + ++ (void)addCustomHelpMenuEntry:(NSString *)title withURL:(NSString *)url { + [self addCustomHelpMenuEntry:title withURL:url withDelay:1.0]; +} + ++ (void)addCustomHelpMenuEntry:(NSString *)title withURL:(NSString *)url withDelay:(NSTimeInterval)delay { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + MenuActionController *controller = [[MenuActionController alloc] init]; + controller.targetURL = [NSURL URLWithString:url]; + + NSMenu *mainMenu = [NSApp mainMenu]; + if (!mainMenu) { + NSLogger(@"[-] Main menu not found"); + return; + } + + NSMenuItem *helpMenuItem = nil; + for (NSMenuItem *item in [mainMenu itemArray]) { + if ([[item title] isEqualToString:@"Help"]) { + helpMenuItem = item; + break; + } + } + + if (!helpMenuItem) { + NSLogger(@"[-] Help menu item not found"); + return; + } + + NSMenu *helpMenu = [helpMenuItem submenu]; + if (!helpMenu) { + NSLogger(@"[-] Help submenu not found"); + return; + } + + if ([helpMenu numberOfItems] > 0) { + [helpMenu addItem:[NSMenuItem separatorItem]]; + } + + NSMenuItem *customMenuItem = [[NSMenuItem alloc] initWithTitle:title + action:@selector(openURLAction:) + keyEquivalent:@""]; + [customMenuItem setTarget:controller]; + [helpMenu addItem:customMenuItem]; + + objc_setAssociatedObject(helpMenu, + [title UTF8String], + controller, + OBJC_ASSOCIATION_RETAIN); + + NSLogger(@"[+] Custom menu item '%@' added successfully", title); + }); +} + +@end + +@interface reMarkableDylib : NSObject + +- (BOOL)hook; + +@end + +@implementation reMarkable + ++ (void)load { + NSLogger(@"reMarkable dylib loaded successfully"); + + // Initialize the hook + reMarkableDylib *dylib = [[reMarkableDylib alloc] init]; + [dylib hook]; + + // Add custom Help menu entry to open config file + NSString *configPath = ReMarkableConfigFilePath(); + NSString *fileURL = [NSString stringWithFormat:@"file://%@", configPath]; + [MenuActionController addCustomHelpMenuEntry:@"Open rmfakecloud config" + withURL:fileURL + withDelay:2.0]; +} + +@end + +@implementation reMarkableDylib + +static QNetworkReply *(*original_qNetworkAccessManager_createRequest)( + QNetworkAccessManager *self, + QNetworkAccessManager::Operation op, + const QNetworkRequest &request, + QIODevice *outgoingData) = NULL; + +static void (*original_qWebSocket_open)( + QWebSocket *self, + const QNetworkRequest &request) = NULL; + +static int (*original_qRegisterResourceData)( + int, + const unsigned char *, + const unsigned char *, + const unsigned char *) = NULL; + +static inline bool shouldPatchURL(const QString &host) { + if (host.isEmpty()) { + return false; + } + + return QString(R"""( + hwr-production-dot-remarkable-production.appspot.com + service-manager-production-dot-remarkable-production.appspot.com + local.appspot.com + my.remarkable.com + ping.remarkable.com + internal.cloud.remarkable.com + eu.tectonic.remarkable.com + backtrace-proxy.cloud.remarkable.engineering + dev.ping.remarkable.com + dev.tectonic.remarkable.com + dev.internal.cloud.remarkable.com + eu.internal.tctn.cloud.remarkable.com + webapp-prod.cloud.remarkable.engineering + )""") + .contains(host, Qt::CaseInsensitive); +} + +- (BOOL)hook { + NSLogger(@"[reMarkable] Starting hooks..."); + + ReMarkableLoadOrCreateConfig(); + NSLogger(@"[reMarkable] Using override host %@ and port %@", gConfiguredHost, gConfiguredPort); + + [MemoryUtils hookSymbol:@"QtNetwork" + symbolName:@"__ZN21QNetworkAccessManager13createRequestENS_9OperationERK15QNetworkRequestP9QIODevice" + hookFunction:(void *)hooked_qNetworkAccessManager_createRequest + originalFunction:(void **)&original_qNetworkAccessManager_createRequest + logPrefix:@"[reMarkable]"]; + + [MemoryUtils hookSymbol:@"QtWebSockets" + symbolName:@"__ZN10QWebSocket4openERK15QNetworkRequest" + hookFunction:(void *)hooked_qWebSocket_open + originalFunction:(void **)&original_qWebSocket_open + logPrefix:@"[reMarkable]"]; + + // WIP: Implement resource data registration hooking + // [MemoryUtils hookSymbol:@"QtCore" + // symbolName:@"__Z21qRegisterResourceDataiPKhS0_S0_" + // hookFunction:(void *)hooked_qRegisterResourceData + // originalFunction:(void **)&original_qRegisterResourceData + // logPrefix:@"[reMarkable]"]; + + return YES; +} + +extern "C" QNetworkReply* hooked_qNetworkAccessManager_createRequest( + QNetworkAccessManager* self, + QNetworkAccessManager::Operation op, + const QNetworkRequest& req, + QIODevice* outgoingData +) { + const QString host = req.url().host(); + if (shouldPatchURL(host)) { + // Clone request to keep original immutable + QNetworkRequest newReq(req); + QUrl newUrl = req.url(); + const QString overrideHost = QStringFromNSStringSafe(gConfiguredHost); + newUrl.setHost(overrideHost); + newUrl.setPort([gConfiguredPort intValue]); + newReq.setUrl(newUrl); + + if (original_qNetworkAccessManager_createRequest) { + return original_qNetworkAccessManager_createRequest(self, op, newReq, outgoingData); + } + return nullptr; + } + + if (original_qNetworkAccessManager_createRequest) { + return original_qNetworkAccessManager_createRequest(self, op, req, outgoingData); + } + return nullptr; +} + +extern "C" void hooked_qWebSocket_open( + QWebSocket* self, + const QNetworkRequest& req +) { + if (!original_qWebSocket_open) { + return; + } + + const QString host = req.url().host(); + if (shouldPatchURL(host)) { + QUrl newUrl = req.url(); + const QString overrideHost = QStringFromNSStringSafe(gConfiguredHost); + newUrl.setHost(overrideHost); + newUrl.setPort([gConfiguredPort intValue]); + + QNetworkRequest newReq(req); + newReq.setUrl(newUrl); + + original_qWebSocket_open(self, newReq); + return; + } + + original_qWebSocket_open(self, req); +} + +extern "C" int hooked_qRegisterResourceData( + int version, + const unsigned char *tree, + const unsigned char *name, + const unsigned char *data +) { + if (!original_qRegisterResourceData) { + return 0; + } + + pthread_mutex_lock(&gResourceMutex); + + struct ResourceRoot resource = { + .data = (uint8_t *)data, + .name = (uint8_t *)name, + .tree = (uint8_t *)tree, + .treeSize = 0, + .dataSize = 0, + .originalDataSize = 0, + .nameSize = 0, + .entriesAffected = 0, + }; + + statArchive(&resource, 0); + processNode(&resource, 0, ""); + resource.tree = (uint8_t *)malloc(resource.treeSize); + if (resource.tree) { + memcpy(resource.tree, tree, resource.treeSize); + } + + NSLogger(@"[reMarkable] Registering Qt resource version %d tree:%p (size:%zu) name:%p (size:%zu) data:%p (size:%zu)", + version, tree, resource.treeSize, name, resource.nameSize, data, resource.dataSize); + + int status = original_qRegisterResourceData(version, tree, name, data); + pthread_mutex_unlock(&gResourceMutex); + if (resource.tree) { + free(resource.tree); + } + return status; +} + +@end \ No newline at end of file diff --git a/src/utils/Constant.h b/src/utils/Constant.h new file mode 100644 index 0000000..5659eb0 --- /dev/null +++ b/src/utils/Constant.h @@ -0,0 +1,7 @@ +#import + +@interface Constant : NSObject + ++ (NSString *)getCurrentAppPath; + +@end diff --git a/src/utils/Constant.m b/src/utils/Constant.m new file mode 100644 index 0000000..ece64be --- /dev/null +++ b/src/utils/Constant.m @@ -0,0 +1,25 @@ +#import +#import "Constant.h" +#import +#import "Logger.h" + +@implementation Constant + +static NSString *_currentAppPath; + ++ (void)initialize { + if (self == [Constant class]) { + NSLogger(@"[Constant] Initializing..."); + + NSBundle *app = [NSBundle mainBundle]; + _currentAppPath = [[app bundlePath] copy]; + + NSLogger(@"[Constant] App path: %@", _currentAppPath); + } +} + ++ (NSString *)getCurrentAppPath { + return _currentAppPath; +} + +@end diff --git a/src/utils/Logger.h b/src/utils/Logger.h new file mode 100644 index 0000000..5ab39ee --- /dev/null +++ b/src/utils/Logger.h @@ -0,0 +1,6 @@ +#ifndef Logger_h +#define Logger_h + +#define NSLogger(fmt, ...) NSLog((fmt), ##__VA_ARGS__) + +#endif /* Logger_h */ diff --git a/src/utils/MemoryUtils.h b/src/utils/MemoryUtils.h new file mode 100644 index 0000000..5836d18 --- /dev/null +++ b/src/utils/MemoryUtils.h @@ -0,0 +1,33 @@ +#import + +@interface MemoryUtils : NSObject + +/** + * Hooks a function by symbol name with automatic fallback from symtbl_solve to symexp_solve. + * + * @param imageName The name of the image/library to search in (e.g., "QtNetwork"). + * @param symbolName The mangled symbol name to hook. + * @param hookFunction The function to replace the original with. + * @param originalFunction Pointer to store the original function address. + * @param logPrefix Prefix for log messages (optional, can be nil). + * @return YES if the hook was successfully installed, NO otherwise. + */ ++ (BOOL)hookSymbol:(NSString *)imageName + symbolName:(NSString *)symbolName + hookFunction:(void *)hookFunction + originalFunction:(void **)originalFunction + logPrefix:(NSString *)logPrefix; + +/** + * Hooks a function by symbol name with delay support. + * + * @param delayInSeconds The delay in seconds before installing the hook (use 0 for immediate hooking). + */ ++ (BOOL)hookSymbol:(NSString *)imageName + symbolName:(NSString *)symbolName + hookFunction:(void *)hookFunction + originalFunction:(void **)originalFunction + logPrefix:(NSString *)logPrefix + delayInSeconds:(NSTimeInterval)delayInSeconds; + +@end diff --git a/src/utils/MemoryUtils.m b/src/utils/MemoryUtils.m new file mode 100644 index 0000000..76c6608 --- /dev/null +++ b/src/utils/MemoryUtils.m @@ -0,0 +1,106 @@ +#import +#import "MemoryUtils.h" +#import +#import "Logger.h" +#import "tinyhook.h" + +@implementation MemoryUtils + ++ (int)indexForImageWithName:(NSString *)imageName { + uint32_t imageCount = _dyld_image_count(); + for (uint32_t i = 0; i < imageCount; i++) { + const char* currentImageName = _dyld_get_image_name(i); + NSString *currentImageNameString = [NSString stringWithUTF8String:currentImageName]; + + if ([currentImageNameString.lastPathComponent isEqualToString:imageName]) { + return i; + } + } + + return -1; +} + ++ (BOOL)hookSymbol:(NSString *)imageName + symbolName:(NSString *)symbolName + hookFunction:(void *)hookFunction + originalFunction:(void **)originalFunction + logPrefix:(NSString *)logPrefix { + return [self hookSymbol:imageName + symbolName:symbolName + hookFunction:hookFunction + originalFunction:originalFunction + logPrefix:logPrefix + delayInSeconds:0]; +} + ++ (BOOL)hookSymbol:(NSString *)imageName + symbolName:(NSString *)symbolName + hookFunction:(void *)hookFunction + originalFunction:(void **)originalFunction + logPrefix:(NSString *)logPrefix + delayInSeconds:(NSTimeInterval)delayInSeconds { + + if (delayInSeconds > 0) { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [self performHookSymbol:imageName + symbolName:symbolName + hookFunction:hookFunction + originalFunction:originalFunction + logPrefix:logPrefix]; + }); + return YES; + } else { + return [self performHookSymbol:imageName + symbolName:symbolName + hookFunction:hookFunction + originalFunction:originalFunction + logPrefix:logPrefix]; + } +} + ++ (BOOL)performHookSymbol:(NSString *)imageName + symbolName:(NSString *)symbolName + hookFunction:(void *)hookFunction + originalFunction:(void **)originalFunction + logPrefix:(NSString *)logPrefix { + + NSLogger(@"%@ Starting hook installation for %@", logPrefix, symbolName); + + int imageIndex = [self indexForImageWithName:imageName]; + if (imageIndex < 0) { + NSLogger(@"%@ ERROR: Image %@ not found", logPrefix, imageName); + return NO; + } + + void* symbolAddress = NULL; + + // Try to find the symbol address using symtbl_solve first + symbolAddress = symtbl_solve(imageIndex, [symbolName UTF8String]); + + if (symbolAddress) { + NSLogger(@"%@ %@ found with symtbl_solve at address: %p", logPrefix, symbolName, symbolAddress); + } else { + NSLogger(@"%@ %@ not found with symtbl_solve, trying symexp_solve...", logPrefix, symbolName); + symbolAddress = symexp_solve(imageIndex, [symbolName UTF8String]); + + if (symbolAddress) { + NSLogger(@"%@ %@ found with symexp_solve at address: %p", logPrefix, symbolName, symbolAddress); + } else { + NSLogger(@"%@ ERROR: Unable to find symbol %@", logPrefix, symbolName); + return NO; + } + } + + // Install the hook using tiny_hook and get the original function trampoline if requested + int hookResult = tiny_hook(symbolAddress, hookFunction, originalFunction); + + if (hookResult == 0) { + NSLogger(@"%@ Hook successfully installed for %@", logPrefix, symbolName); + return YES; + } else { + NSLogger(@"%@ ERROR: Failed to install hook for %@ (code: %d)", logPrefix, symbolName, hookResult); + return NO; + } +} + +@end diff --git a/src/utils/ResourceUtils.h b/src/utils/ResourceUtils.h new file mode 100644 index 0000000..a6776e4 --- /dev/null +++ b/src/utils/ResourceUtils.h @@ -0,0 +1,42 @@ +#ifndef ResourceUtils_h +#define ResourceUtils_h + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct ResourceRoot { + uint8_t *data; + uint8_t *name; + uint8_t *tree; + size_t treeSize; + size_t dataSize; + size_t originalDataSize; + size_t nameSize; + int entriesAffected; +}; + +#define TREE_ENTRY_SIZE 22 +#define DIRECTORY 0x02 + +// Read/Write utilities +uint32_t readUInt32(uint8_t *addr, int offset); +uint16_t readUInt16(uint8_t *addr, int offset); +void writeUint32(uint8_t *addr, int offset, uint32_t value); +void writeUint16(uint8_t *addr, int offset, uint16_t value); + +// Resource tree utilities +int findOffset(int node); +void nameOfChild(struct ResourceRoot *root, int node, int *size, char *buffer, int max); +void statArchive(struct ResourceRoot *root, int node); +void processNode(struct ResourceRoot *root, int node, const char *rootName); +void ReMarkableDumpResourceFile(struct ResourceRoot *root, int node, const char *rootName, const char *fileName, uint16_t flags); + +#ifdef __cplusplus +} +#endif + +#endif /* ResourceUtils_h */ diff --git a/src/utils/ResourceUtils.m b/src/utils/ResourceUtils.m new file mode 100644 index 0000000..4a55117 --- /dev/null +++ b/src/utils/ResourceUtils.m @@ -0,0 +1,381 @@ +#import "ResourceUtils.h" +#import "Logger.h" +#import +#import +#import +#import +#import + +static NSString *ReMarkableDumpRootDirectory(void); +static NSString *ReMarkablePreferencesDirectory(void); + +static NSString *ReMarkablePreferencesDirectory(void) { + NSArray *libraryPaths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES); + NSString *libraryDir = [libraryPaths firstObject]; + if (![libraryDir length]) { + libraryDir = [NSHomeDirectory() stringByAppendingPathComponent:@"Library"]; + } + return [libraryDir stringByAppendingPathComponent:@"Preferences"]; +} + +static NSString *ReMarkableDumpRootDirectory(void) { + static NSString *dumpDirectory = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSString *preferencesDir = ReMarkablePreferencesDirectory(); + NSString *candidate = [preferencesDir stringByAppendingPathComponent:@"dump"]; + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSError *error = nil; + if (![fileManager fileExistsAtPath:candidate]) { + if (![fileManager createDirectoryAtPath:candidate withIntermediateDirectories:YES attributes:nil error:&error]) { + NSLogger(@"[reMarkable] Failed to create dump directory %@: %@", candidate, error); + } + } + dumpDirectory = [candidate copy]; + }); + return dumpDirectory; +} + +uint32_t readUInt32(uint8_t *addr, int offset) { + return (uint32_t)(addr[offset + 0] << 24) | + (uint32_t)(addr[offset + 1] << 16) | + (uint32_t)(addr[offset + 2] << 8) | + (uint32_t)(addr[offset + 3] << 0); +} + +void writeUint32(uint8_t *addr, int offset, uint32_t value) { + addr[offset + 0] = (uint8_t)(value >> 24); + addr[offset + 1] = (uint8_t)(value >> 16); + addr[offset + 2] = (uint8_t)(value >> 8); + addr[offset + 3] = (uint8_t)(value >> 0); +} + +void writeUint16(uint8_t *addr, int offset, uint16_t value) { + addr[offset + 0] = (uint8_t)(value >> 8); + addr[offset + 1] = (uint8_t)(value >> 0); +} + +uint16_t readUInt16(uint8_t *addr, int offset) { + return (uint16_t)((addr[offset + 0] << 8) | + (addr[offset + 1] << 0)); +} + +int findOffset(int node) { + return node * TREE_ENTRY_SIZE; +} + +void statArchive(struct ResourceRoot *root, int node) { + int offset = findOffset(node); + int thisMaxLength = offset + TREE_ENTRY_SIZE; + if (thisMaxLength > (int)root->treeSize) root->treeSize = (size_t)thisMaxLength; + uint32_t nameOffset = readUInt32(root->tree, offset); + uint32_t thisMaxNameLength = nameOffset + readUInt16(root->name, (int)nameOffset); + if (thisMaxNameLength > root->nameSize) root->nameSize = thisMaxNameLength; + int flags = readUInt16(root->tree, offset + 4); + if (!(flags & DIRECTORY)) { + uint32_t dataOffset = readUInt32(root->tree, offset + 4 + 2 + 4); + uint32_t dataSize = readUInt32(root->data, (int)dataOffset); + uint32_t thisMaxDataLength = dataOffset + dataSize + 4; + if (thisMaxDataLength > root->dataSize) root->dataSize = thisMaxDataLength; + } else { + uint32_t childCount = readUInt32(root->tree, offset + 4 + 2); + offset += 4 + 4 + 2; + uint32_t childOffset = readUInt32(root->tree, offset); + for (int child = (int)childOffset; child < (int)(childOffset + childCount); child++){ + statArchive(root, child); + } + } + root->originalDataSize = root->dataSize; +} + +void nameOfChild(struct ResourceRoot *root, int node, int *size, char *buffer, int max) { + if (!buffer || max <= 0) { + if (size) { + *size = 0; + } + return; + } + + if (!root || !root->tree || !root->name) { + if (size) { + *size = 0; + } + buffer[0] = '\0'; + return; + } + + if (!node) { + if (size) { + *size = 0; + } + buffer[0] = '\0'; + return; + } + + const int offset = findOffset(node); + uint32_t nameOffset = readUInt32(root->tree, offset); + uint16_t nameLength = readUInt16(root->name, (int)nameOffset); + + if (nameLength > (uint16_t)(max - 1)) { + nameLength = (uint16_t)(max - 1); + } + + nameOffset += 2; // skip length prefix + nameOffset += 4; // skip hash + + if (size) { + *size = (int)nameLength; + } + + for (int i = 1; i < (int)nameLength * 2; i += 2) { + buffer[i / 2] = ((const char *)root->name)[nameOffset + i]; + } + buffer[nameLength] = '\0'; +} + +void ReMarkableDumpResourceFile(struct ResourceRoot *root, int node, const char *rootName, const char *fileName, uint16_t flags) { + if (!root || !root->tree || !root->data || !fileName) { + return; + } + + const int baseOffset = findOffset(node); + const uint32_t dataOffset = readUInt32(root->tree, baseOffset + 4 + 2 + 4); + const uint32_t dataSize = readUInt32(root->data, (int)dataOffset); + if (dataSize == 0) { + return; + } + + const uint32_t payloadStart = dataOffset + 4; + if (root->dataSize && (payloadStart + dataSize) > root->dataSize) { + NSLogger(@"[reMarkable] Skipping dump for node %d due to size mismatch (%u bytes beyond bounds)", (int)node, dataSize); + return; + } + + const uint8_t *payload = root->data + payloadStart; + uint8_t *ownedBuffer = NULL; + size_t bytesToWrite = dataSize; + + if (flags == 4) { + size_t expectedSize = ZSTD_getFrameContentSize(payload, dataSize); + if (expectedSize == ZSTD_CONTENTSIZE_ERROR) { + NSLogger(@"[reMarkable] ZSTD frame content size error for node %d", (int)node); + return; + } + + size_t bufferSize; + if (expectedSize == ZSTD_CONTENTSIZE_UNKNOWN) { + if ((size_t)dataSize > SIZE_MAX / 4) { + bufferSize = (size_t)dataSize; + } else { + bufferSize = (size_t)dataSize * 4; + } + } else { + bufferSize = expectedSize; + } + if (bufferSize < (size_t)dataSize) { + bufferSize = (size_t)dataSize; + } + + if (bufferSize > SIZE_MAX - 1) { + NSLogger(@"[reMarkable] ZSTD decompression size too large for node %d", (int)node); + return; + } + + for (int attempt = 0; attempt < 6; ++attempt) { + ownedBuffer = (uint8_t *)malloc(bufferSize + 1); + if (!ownedBuffer) { + NSLogger(@"[reMarkable] Failed to allocate %zu bytes for ZSTD decompression", bufferSize + 1); + return; + } + + size_t decompressedSize = ZSTD_decompress(ownedBuffer, bufferSize, payload, dataSize); + if (!ZSTD_isError(decompressedSize)) { + bytesToWrite = decompressedSize; + ownedBuffer[bytesToWrite] = 0; + break; + } + + ZSTD_ErrorCode errorCode = ZSTD_getErrorCode(decompressedSize); + free(ownedBuffer); + ownedBuffer = NULL; + + if (errorCode == ZSTD_error_dstSize_tooSmall) { + if (bufferSize > SIZE_MAX / 2) { + NSLogger(@"[reMarkable] ZSTD decompression buffer would overflow for node %d", (int)node); + return; + } + bufferSize *= 2; + continue; + } + + NSLogger(@"[reMarkable] ZSTD decompression failed for node %d: %s", (int)node, ZSTD_getErrorName(decompressedSize)); + return; + } + + if (!ownedBuffer) { + NSLogger(@"[reMarkable] ZSTD decompression exhausted retries for node %d", (int)node); + return; + } + } else if (flags == 0) { + if ((size_t)dataSize > SIZE_MAX - 1) { + NSLogger(@"[reMarkable] Raw resource size too large for node %d", (int)node); + return; + } + ownedBuffer = (uint8_t *)malloc((size_t)dataSize + 1); + if (!ownedBuffer) { + NSLogger(@"[reMarkable] Failed to allocate %u bytes for raw copy", (unsigned)(dataSize + 1u)); + return; + } + memcpy(ownedBuffer, payload, dataSize); + ownedBuffer[dataSize] = 0; + bytesToWrite = dataSize; + + } else if (flags == 1) { + if (dataSize <= 4) { + NSLogger(@"[reMarkable] Zlib compressed resource too small for node %d", (int)node); + return; + } + + const uint32_t expectedSize = + ((uint32_t)payload[0] << 24) | + ((uint32_t)payload[1] << 16) | + ((uint32_t)payload[2] << 8) | + ((uint32_t)payload[3] << 0); + + if (!expectedSize) { + NSLogger(@"[reMarkable] Zlib resource reported zero size for node %d", (int)node); + return; + } + + const uint8_t *compressedPayload = payload + 4; + const size_t compressedSize = (size_t)dataSize - 4; + if (compressedSize > UINT_MAX) { + NSLogger(@"[reMarkable] Zlib compressed payload too large for node %d", (int)node); + return; + } + + z_stream stream; + memset(&stream, 0, sizeof(stream)); + stream.next_in = (Bytef *)compressedPayload; + stream.avail_in = (uInt)compressedSize; + + int status = inflateInit(&stream); + if (status != Z_OK) { + NSLogger(@"[reMarkable] Failed to initialize zlib for node %d: %d", (int)node, status); + return; + } + + ownedBuffer = (uint8_t *)malloc((size_t)expectedSize + 1); + if (!ownedBuffer) { + NSLogger(@"[reMarkable] Failed to allocate %u bytes for zlib decompression", (unsigned)expectedSize + 1u); + inflateEnd(&stream); + return; + } + + stream.next_out = ownedBuffer; + stream.avail_out = (uInt)expectedSize; + + status = inflate(&stream, Z_FINISH); + if (status != Z_STREAM_END) { + NSLogger(@"[reMarkable] Zlib decompression failed for node %d with status %d", (int)node, status); + free(ownedBuffer); + ownedBuffer = NULL; + inflateEnd(&stream); + return; + } + + bytesToWrite = (size_t)stream.total_out; + inflateEnd(&stream); + ownedBuffer[bytesToWrite] = 0; + } else { + NSLogger(@"[reMarkable] Unknown compression flag %u for node %d; skipping dump", flags, (int)node); + return; + } + + NSString *dumpRoot = ReMarkableDumpRootDirectory(); + if (![dumpRoot length]) { + if (ownedBuffer) { + free(ownedBuffer); + } + return; + } + + NSString *rootComponent = [NSString stringWithUTF8String:rootName ? rootName : ""]; + NSString *fileComponent = [NSString stringWithUTF8String:fileName]; + if (!rootComponent) { + rootComponent = @""; + } + if (!fileComponent) { + fileComponent = @""; + } + + NSString *relativePath = [rootComponent stringByAppendingString:fileComponent]; + if ([relativePath hasPrefix:@"/"]) { + relativePath = [relativePath substringFromIndex:1]; + } + if (![relativePath length]) { + return; + } + + NSString *fullPath = [dumpRoot stringByAppendingPathComponent:relativePath]; + NSString *directoryPath = [fullPath stringByDeletingLastPathComponent]; + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSError *directoryError = nil; + if ([directoryPath length] && ![fileManager createDirectoryAtPath:directoryPath withIntermediateDirectories:YES attributes:nil error:&directoryError]) { + NSLogger(@"[reMarkable] Failed to create directory for dump %@: %@", directoryPath, directoryError); + if (ownedBuffer) { + free(ownedBuffer); + } + return; + } + + const void *dataSource = ownedBuffer ? (const void *)ownedBuffer : (const void *)payload; + NSData *dataObject = [NSData dataWithBytes:dataSource length:bytesToWrite]; + NSError *writeError = nil; + if (![dataObject writeToFile:fullPath options:NSDataWritingAtomic error:&writeError]) { + NSLogger(@"[reMarkable] Failed to write dump file %@: %@", fullPath, writeError); + } else { + NSLogger(@"[reMarkable] Dumped resource to %@ (%zu bytes)", fullPath, bytesToWrite); + } + + if (ownedBuffer) { + free(ownedBuffer); + } +} + +void processNode(struct ResourceRoot *root, int node, const char *rootName) { + int offset = findOffset(node) + 4; + uint16_t flags = readUInt16(root->tree, offset); + offset += 2; + int stringLength = 0; + char nameBuffer[256]; + nameOfChild(root, node, &stringLength, nameBuffer, (int)sizeof(nameBuffer)); + + if (flags & DIRECTORY) { + uint32_t childCount = readUInt32(root->tree, offset); + offset += 4; + uint32_t childOffset = readUInt32(root->tree, offset); + const size_t rootLength = rootName ? strlen(rootName) : 0; + char *tempRoot = (char *)malloc(rootLength + (size_t)stringLength + 2); + if (!tempRoot) { + return; + } + + if (rootLength > 0) { + memcpy(tempRoot, rootName, rootLength); + } + memcpy(tempRoot + rootLength, nameBuffer, (size_t)stringLength); + tempRoot[rootLength + stringLength] = '/'; + tempRoot[rootLength + stringLength + 1] = '\0'; + + for (uint32_t child = childOffset; child < childOffset + childCount; ++child) { + processNode(root, (int)child, tempRoot); + } + + free(tempRoot); + } else { + NSLogger(@"[reMarkable] Processing node %d: %s%s", (int)node, rootName ? rootName : "", nameBuffer); + uint16_t fileFlags = readUInt16(root->tree, offset - 2); + ReMarkableDumpResourceFile(root, node, rootName ? rootName : "", nameBuffer, fileFlags); + } +}