Add hooks for new reMarkable functions and improve build script

This commit is contained in:
√(noham)²
2025-12-02 22:52:47 +01:00
parent e8f204057e
commit 0bdda7bdf7
2 changed files with 114 additions and 19 deletions

View File

@@ -14,6 +14,25 @@ QT_PATH=${QT_PATH:-$(ls -d "$HOME/Qt/6."* 2>/dev/null | sort -V | tail -n1)}
# Parse build mode argument # Parse build mode argument
BUILD_MODE=${1:-rmfakecloud} BUILD_MODE=${1:-rmfakecloud}
# Determine final dylib name for the selected build mode
case "$BUILD_MODE" in
rmfakecloud)
DYLIB_NAME="rmfakecloud.dylib"
;;
qmldiff)
DYLIB_NAME="qmldiff.dylib"
;;
dev)
DYLIB_NAME="dev.dylib"
;;
all)
DYLIB_NAME="all.dylib"
;;
*)
DYLIB_NAME="reMarkable.dylib"
;;
esac
# Set CMake options based on build mode # Set CMake options based on build mode
CMAKE_OPTIONS="" CMAKE_OPTIONS=""
case "$BUILD_MODE" in case "$BUILD_MODE" in
@@ -54,12 +73,23 @@ fi
make reMarkable make reMarkable
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
# Rename the produced dylib so each build mode has a distinct file name
DYLIB_DIR="$PROJECT_DIR/build/dylibs"
DEFAULT_DYLIB="$DYLIB_DIR/reMarkable.dylib"
TARGET_DYLIB="$DYLIB_DIR/$DYLIB_NAME"
if [ -f "$DEFAULT_DYLIB" ]; then
mv "$DEFAULT_DYLIB" "$TARGET_DYLIB"
else
echo "⚠️ Expected dylib not found at $DEFAULT_DYLIB"
fi
echo "" echo ""
echo "✅ Compilation successful!" echo "✅ Compilation successful!"
echo "📍 Dylib: $PROJECT_DIR/build/dylibs/reMarkable.dylib" echo "📍 Dylib: $TARGET_DYLIB"
echo "" echo ""
echo "🚀 To inject into the reMarkable application:" echo "🚀 To inject into the reMarkable application:"
echo " DYLD_INSERT_LIBRARIES=\"$PROJECT_DIR/build/dylibs/reMarkable.dylib\" /Applications/reMarkable.app/Contents/MacOS/reMarkable" echo " DYLD_INSERT_LIBRARIES=\"$TARGET_DYLIB\" /Applications/reMarkable.app/Contents/MacOS/reMarkable"
echo "" echo ""
else else
echo "❌ Compilation failed" echo "❌ Compilation failed"

View File

@@ -254,6 +254,12 @@ static ssize_t (*original_qIODevice_write)(
const char *data, const char *data,
qint64 maxSize) = NULL; qint64 maxSize) = NULL;
// Hook for function at 0x10015A130
static int64_t (*original_function_at_0x10015A130)(int64_t a1, int64_t a2) = NULL;
// Hook for function at 0x10015BC90
static void (*original_function_at_0x10015BC90)(int64_t a1, int64_t a2) = NULL;
// Hook for function at 0x10016D520 // Hook for function at 0x10016D520
static int64_t (*original_function_at_0x10016D520)(int64_t a1, int64_t *a2, unsigned int a3, int64_t a4) = NULL; static int64_t (*original_function_at_0x10016D520)(int64_t a1, int64_t *a2, unsigned int a3, int64_t a4) = NULL;
@@ -356,26 +362,47 @@ static inline bool shouldPatchURL(const QString &host) {
#endif #endif
#ifdef BUILD_MODE_DEV #ifdef BUILD_MODE_DEV
// // Hook function at address 0x1????
// [MemoryUtils hookAddress:@"reMarkable"
// staticAddress:0x????
// hookFunction:(void *)hooked_function_at_0x????
// originalFunction:(void **)&original_function_at_0x????
// logPrefix:@"[reMarkable]"];
NSLogger(@"[reMarkable] Build mode: dev/reverse engineering"); NSLogger(@"[reMarkable] Build mode: dev/reverse engineering");
[MemoryUtils hookSymbol:@"QtCore" // [MemoryUtils hookSymbol:@"QtCore"
symbolName:@"__ZN9QIODevice5writeEPKcx" // symbolName:@"__ZN9QIODevice5writeEPKcx"
hookFunction:(void *)hooked_qIODevice_write // hookFunction:(void *)hooked_qIODevice_write
originalFunction:(void **)&original_qIODevice_write // originalFunction:(void **)&original_qIODevice_write
logPrefix:@"[reMarkable]"]; // logPrefix:@"[reMarkable]"];
// Hook function at address 0x10016D520 // // Hook function at address 0x10015A130
[MemoryUtils hookAddress:@"reMarkable" // [MemoryUtils hookAddress:@"reMarkable"
staticAddress:0x10016D520 // staticAddress:0x10015A130
hookFunction:(void *)hooked_function_at_0x10016D520 // hookFunction:(void *)hooked_function_at_0x10015A130
originalFunction:(void **)&original_function_at_0x10016D520 // originalFunction:(void **)&original_function_at_0x10015A130
logPrefix:@"[reMarkable]"]; // logPrefix:@"[reMarkable]"];
// Hook function at address 0x1001B6EE0 // // Hook function at address 0x10015BC90
[MemoryUtils hookAddress:@"reMarkable" // [MemoryUtils hookAddress:@"reMarkable"
staticAddress:0x1001B6EE0 // staticAddress:0x10015BC90
hookFunction:(void *)hooked_function_at_0x1001B6EE0 // hookFunction:(void *)hooked_function_at_0x10015BC90
originalFunction:(void **)&original_function_at_0x1001B6EE0 // originalFunction:(void **)&original_function_at_0x10015BC90
logPrefix:@"[reMarkable]"]; // logPrefix:@"[reMarkable]"];
// // Hook function at address 0x10016D520
// [MemoryUtils hookAddress:@"reMarkable"
// staticAddress:0x10016D520
// hookFunction:(void *)hooked_function_at_0x10016D520
// originalFunction:(void **)&original_function_at_0x10016D520
// logPrefix:@"[reMarkable]"];
// // Hook function at address 0x1001B6EE0
// [MemoryUtils hookAddress:@"reMarkable"
// staticAddress:0x1001B6EE0
// hookFunction:(void *)hooked_function_at_0x1001B6EE0
// originalFunction:(void **)&original_function_at_0x1001B6EE0
// logPrefix:@"[reMarkable]"];
#endif #endif
return YES; return YES;
@@ -437,6 +464,9 @@ extern "C" void hooked_qWebSocket_open(
#endif // BUILD_MODE_RMFAKECLOUD #endif // BUILD_MODE_RMFAKECLOUD
#ifdef BUILD_MODE_QMLDIFF #ifdef BUILD_MODE_QMLDIFF
// See https://deepwiki.com/search/once-the-qrr-file-parsed-take_871f24a0-8636-4aee-bddf-7405b6e32584 for details on qmldiff replacement strategy
extern "C" int hooked_qRegisterResourceData( extern "C" int hooked_qRegisterResourceData(
int version, int version,
const unsigned char *tree, const unsigned char *tree,
@@ -501,6 +531,41 @@ extern "C" ssize_t hooked_qIODevice_write(
return 0; return 0;
} }
extern "C" int64_t hooked_function_at_0x10015A130(int64_t a1, int64_t a2) {
NSLogger(@"[reMarkable] Hook at 0x10015A130 called!");
NSLogger(@"[reMarkable] a1 = 0x%llx", (unsigned long long)a1);
NSLogger(@"[reMarkable] a2 = 0x%llx", (unsigned long long)a2);
logMemory("Memory at a1", (void *)a1, 64);
logMemory("Memory at a2", (void *)a2, 64);
if (original_function_at_0x10015A130) {
int64_t result = original_function_at_0x10015A130(a1, a2);
NSLogger(@"[reMarkable] result = 0x%llx", (unsigned long long)result);
return result;
}
NSLogger(@"[reMarkable] WARNING: Original function at 0x10015A130 not available, returning 0");
return 0;
}
extern "C" void hooked_function_at_0x10015BC90(int64_t a1, int64_t a2) {
NSLogger(@"[reMarkable] Hook at 0x10015BC90 called!");
NSLogger(@"[reMarkable] a1 = 0x%llx", (unsigned long long)a1);
NSLogger(@"[reMarkable] a2 = 0x%llx", (unsigned long long)a2);
logMemory("Memory at a1", (void *)a1, 64);
logMemory("Memory at a2", (void *)a2, 64);
if (original_function_at_0x10015BC90) {
original_function_at_0x10015BC90(a1, a2);
NSLogger(@"[reMarkable] original function returned (void)");
return;
}
NSLogger(@"[reMarkable] WARNING: Original function at 0x10015BC90 not available");
}
extern "C" int64_t hooked_function_at_0x10016D520(int64_t a1, int64_t *a2, unsigned int a3, int64_t a4) { extern "C" int64_t hooked_function_at_0x10016D520(int64_t a1, int64_t *a2, unsigned int a3, int64_t a4) {
NSLogger(@"[reMarkable] Hook at 0x10016D520 called!"); NSLogger(@"[reMarkable] Hook at 0x10016D520 called!");
NSLogger(@"[reMarkable] a1 = 0x%llx", (unsigned long long)a1); NSLogger(@"[reMarkable] a1 = 0x%llx", (unsigned long long)a1);