This commit is contained in:
√(noham)²
2026-07-10 17:23:52 +02:00
commit 7ca09aa9ba
7 changed files with 176 additions and 0 deletions

25
.github/workflows/build.yml vendored Normal file
View File

@@ -0,0 +1,25 @@
name: Build
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
jobs:
build:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Build dylib
run: make
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: MasterPDFEditor.dylib
path: MasterPDFEditor.dylib

4
.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
*.dylib
*.a
!tinyhook/*.a
.DS_Store

3
.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "tinyhook"]
path = tinyhook
url = https://github.com/Antibioticss/tinyhook.git

51
Makefile Normal file
View File

@@ -0,0 +1,51 @@
TARGET = MasterPDFEditor.dylib
TINYHOOK = tinyhook
TINYHOOK_LIB_ARM64 = $(TINYHOOK)/libtinyhook_arm64.a
TINYHOOK_LIB_X86_64 = $(TINYHOOK)/libtinyhook_x86_64.a
TARGET_ARM64 = $(TARGET:.dylib=_arm64.dylib)
TARGET_X86_64 = $(TARGET:.dylib=_x86_64.dylib)
all: $(TARGET)
$(TINYHOOK_LIB_ARM64): $(TINYHOOK)/Makefile
$(MAKE) -C $(TINYHOOK) clean
$(MAKE) -C $(TINYHOOK) static ARCH=arm64 NO_EXPORT=1 CFLAGS="-arch arm64 -Iinclude -fvisibility=hidden -Os -Wall -Wshadow -DNO_EXPORT"
mv $(TINYHOOK)/libtinyhook.a $@
$(TINYHOOK_LIB_X86_64): $(TINYHOOK)/Makefile
$(MAKE) -C $(TINYHOOK) clean
$(MAKE) -C $(TINYHOOK) static ARCH=x86_64 NO_EXPORT=1 CFLAGS="-arch x86_64 -Iinclude -fvisibility=hidden -Os -Wall -Wshadow -DNO_EXPORT"
mv $(TINYHOOK)/libtinyhook.a $@
$(TARGET_ARM64): main.m $(TINYHOOK_LIB_ARM64)
clang -arch arm64 \
-framework Foundation \
-fobjc-arc \
main.m \
-L$(TINYHOOK) -ltinyhook_arm64 \
-I$(TINYHOOK) \
-dynamiclib \
-o $@ \
-current_version 1.0 \
-compatibility_version 1.0
$(TARGET_X86_64): main.m $(TINYHOOK_LIB_X86_64)
clang -arch x86_64 \
-framework Foundation \
-fobjc-arc \
main.m \
-L$(TINYHOOK) -ltinyhook_x86_64 \
-I$(TINYHOOK) \
-dynamiclib \
-o $@ \
-current_version 1.0 \
-compatibility_version 1.0
$(TARGET): $(TARGET_ARM64) $(TARGET_X86_64)
lipo -create -output $@ $^
clean:
$(MAKE) -C $(TINYHOOK) clean
rm -f $(TARGET) $(TARGET_ARM64) $(TARGET_X86_64) $(TINYHOOK_LIB_ARM64) $(TINYHOOK_LIB_X86_64)
.PHONY: all clean

29
README.md Normal file
View File

@@ -0,0 +1,29 @@
# Master PDF Editor Patch
Bypasses license validation for **Master PDF Editor 5.9.98** using inline hooking via [tinyhook](https://github.com/Antibioticss/tinyhook).
Supports both **Apple Silicon (arm64)** and **Intel (x86_64)** architectures.
## How it works
The dylib hooks `MainWindow::ValidateLicense` to force license flags, then calls `QDocTab::SetRegProgram` to complete activation.
## Build
```sh
git clone --recurse-submodules https://github.com/nohamelin/MasterPDFEditor-patch.git
cd MasterPDFEditor-patch
make
```
Output: `MasterPDFEditor.dylib`
## Usage
```sh
DYLD_INSERT_LIBRARIES=/path/to/MasterPDFEditor.dylib '/Applications/Master PDF Editor.app/Contents/MacOS/Master PDF Editor'
```
## Analysis
Full reverse engineering write-up: [noham.dev](https://noh.am/en/posts/master-pdf-editor-patch-analysis/)

63
main.m Normal file
View File

@@ -0,0 +1,63 @@
#import <Foundation/Foundation.h>
#import <mach-o/dyld.h>
#include "tinyhook/include/tinyhook.h"
#if defined(__arm64__) || defined(__aarch64__)
#define kValidateLicenseAddress 0x10034D4F0
#define kSetRegProgramAddress 0x10026C430
#elif defined(__x86_64__)
#define kValidateLicenseAddress 0x10038E2D0
#define kSetRegProgramAddress 0x100296D90
#endif
#define kGuardFlagOffset 107
#define kLicenseFlagOffset 105
#define kQDocTabPointerOffset 184
static void (*setRegProgram)(void *, BOOL);
static void hooked_ValidateLicense(void *self) {
*((uint8_t *)self + kGuardFlagOffset) = 1;
*((uint8_t *)self + kLicenseFlagOffset) = 1;
void **qdoctab = (void **)((char *)self + kQDocTabPointerOffset);
if (qdoctab && *qdoctab) {
setRegProgram(*qdoctab, YES);
}
}
static int imageIndex(const char *name) {
uint32_t count = _dyld_image_count();
for (uint32_t i = 0; i < count; i++) {
const char *path = _dyld_get_image_name(i);
const char *last = strrchr(path, '/');
if (last && strcmp(last + 1, name) == 0) return i;
if (!last && strcmp(path, name) == 0) return i;
}
return -1;
}
__attribute__((constructor))
static void init() {
@autoreleasepool {
NSLog(@"[MPE] loaded");
int idx = imageIndex("Master PDF Editor");
if (idx < 0) {
NSLog(@"[MPE] ERROR: image not found");
return;
}
intptr_t slide = _dyld_get_image_vmaddr_slide(idx);
void *target = (void *)(kValidateLicenseAddress + slide);
if (tiny_hook(target, hooked_ValidateLicense, NULL) != 0) {
NSLog(@"[MPE] ERROR: hook failed");
return;
}
setRegProgram = (void (*)(void *, BOOL))(kSetRegProgramAddress + slide);
NSLog(@"[MPE] ready");
}
}

1
tinyhook Submodule

Submodule tinyhook added at ff87982efb