Skip to content

everettjf/WasmPatch

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

WasmPatch 🧱

GitHub Stars GitHub Forks License Issues

WebAssembly-driven hot patching for iOS/macOS Objective-C apps

English

Hot-fix iOS/macOS apps using WebAssembly payloads. Compile C code to WASM and replace Objective-C methods at runtime.


🎯 What is WasmPatch?

WasmPatch bridges Objective-C and WebAssembly. It compiles C code into WebAssembly modules and lets those modules call any Objective-C class or method dynamically.

This gives apps the ability to:

  • 🔧 Hot-fix bugs without shipping a new binary
  • Add features via WebAssembly payloads
  • 🔄 Replace methods at runtime (class and instance)

WasmPatch Architecture


✨ Features

Feature Description
🧱 WASM Compilation Compile C code to WebAssembly with clang/LLVM
🔗 Objective-C Bridge Call any Obj-C class or method from WebAssembly
🔄 Method Replacement Hot-fix by replacing Obj-C methods at runtime
🍎 Cross-Platform Works on both iOS and macOS
🛠️ Runtime Diagnostics Load state, reset hooks, and inspect last runtime error
🧪 Regression Assets Test case bundle and fixture hosts for bridge validation

🏗️ How It Works

graph TD
    A[C Code] --> B[clang/LLVM]
    B --> C[WebAssembly Module]
    C --> D[WasmPatch Runtime]
    D --> E[Objective-C Runtime]
    E --> F[Hot-fix Applied!]
    
    style A fill:#f9f,color:#000
    style C fill:#bbf,color:#000
    style F fill:#bfb,color:#000
Loading
  1. Write your patch logic in C
  2. Compile to WebAssembly using clang/LLVM
  3. Load the wasm module in your app
  4. Call Objective-C classes/methods from WebAssembly
  5. Replace methods on the fly

🚀 Quick Start

Prerequisites

# Install LLVM with WebAssembly target
brew install llvm

# Or use the provided script
sh Tool/install-llvm.sh

1. Clone and Setup

git clone https://github.com/everettjf/WasmPatch.git
cd WasmPatch

2. Compile a Patch

# Simplest entry point
sh Tool/build-patch.sh your_patch.c

# Optional explicit output path
sh Tool/build-patch.sh your_patch.c build/your_patch.wasm

3. Load in Your App

#import <WasmPatch/WAPPatchLoader.h>

NSError *error = nil;
WAPPatchLoaderOptions *options = [WAPPatchLoader recommendedOptions];
options.expectedSHA256Hex = @"<optional sha256>";

BOOL success = [WAPPatchLoader loadPatchNamed:@"your_patch"
                                     inBundle:NSBundle.mainBundle
                                      options:options
                                        error:&error];

if (!success) {
    NSLog(@"load failed: %@", error.localizedDescription);
    NSLog(@"runtime detail: %@", error.userInfo[WAPPatchLoaderRuntimeMessageKey]);
}

Low-level C API is still available when you need it:

#import <WasmPatch/WasmPatch.h>

BOOL success = wap_load_file("your_patch.wasm");
if (success) {
    NSLog(@"loaded");
} else {
    NSLog(@"load failed: %s", wap_last_error());
}

📁 Project Structure

WasmPatch/
├── WasmPatch/              # Core framework
│   ├── WasmPatch.h         # Public C API
│   ├── core/runtime/       # WASM runtime and exports
│   └── core/method/        # Obj-C method bridge and hooks
├── Tool/                   # Build tools
│   ├── c2wasm.sh           # C to WASM compiler
│   └── install-llvm.sh     # LLVM installer
├── TestCase/               # Test cases
│   ├── compile-testcase.sh # Test compiler
│   └── WasmPatch-TestCase/ # Sample host classes and wasm fixtures
├── Image/                  # Documentation images
├── Demo/                   # Demo projects
│   ├── iOS/               # iOS demo
│   └── macOS/             # macOS demo
└── README.md

💻 Examples

Public Runtime API

bool wap_load_file(const char * path);
bool wap_load_data(const void * bytes, unsigned int size);
void wap_reset_runtime(void);
bool wap_runtime_is_loaded(void);
const char * wap_last_error(void);

High-Level Objective-C API

NSError *error = nil;
WAPPatchLoaderOptions *options = [WAPPatchLoader recommendedOptions];
options.allowReload = YES;
options.resetBeforeLoad = YES;

[WAPPatchLoader loadPatchAtPath:path options:options error:&error];
[WAPPatchLoader loadPatchNamed:@"objc" inBundle:bundle options:options error:&error];
[WAPPatchLoader loadPatchData:data options:options error:&error];
[WAPPatchLoader reset];

Error handling:

if (error.code == WAPPatchLoaderErrorCodeSHA256Mismatch) {
    NSLog(@"patch tampered: %@", error.userInfo[WAPPatchLoaderRuntimeMessageKey]);
}

Call Objective-C from WASM

// advanced_patch.c
#include <wasmpatch.h>

int entry() {
    WAPObject message = new_objc_nsstring("WasmPatch detected request");
    call_class_method_1("NetworkManager", "logRequest:", message);
    dealloc_object(message);

    replace_instance_method("NetworkManager", "sendRequest:", "wasm_custom_send_request");
    return 0;
}

🛠️ Development

Requirements

Requirement Version Description
macOS 10.14+ Development environment
Xcode 11+ iOS/macOS SDK
LLVM/Clang 14+ C to WASM compilation
wabt latest wasm2wat tooling

Build

# Build the framework
cd WasmPatch/WasmPatch.xcodeproj
xcodebuild -project WasmPatch.xcodeproj \
  -scheme WasmPatch \
  -configuration Release \
  -sdk iphoneos build

# Build for macOS
xcodebuild -project WasmPatch.xcodeproj \
  -scheme WasmPatch \
  -configuration Release \
  -sdk macosx build

Test

# Compile testcase wasm fixtures
cd TestCase
sh compile-testcase.sh

# Compile your own patch with defaults
sh Tool/build-patch.sh path/to/patch.c

# Verify wasm modules
wasm2wat your_patch.wasm -o your_patch.wat

Production validation:

sh Tool/validate-production.sh

macOS host validation only:

sh Tool/run-macos-validation.sh

📱 Platform Support

Platform Support Min Version
iOS ✅ Full 10.0
macOS ✅ Full 10.14
Simulator ✅ Full Same as above

🧪 Test Cases

Test Case Description
objc.c Objective-C bridge coverage and method replacement fixture
CallMe Host methods for bridge argument/result validation
ReplaceMe Host methods used for runtime replacement verification

Run all tests:

sh TestCase/compile-testcase.sh

📚 Documentation

Current Maturity

  • Stronger than the original prototype on diagnostics, reset safety, and scripting.
  • Still behind best-in-class hotfix platforms on sandboxing, signature coverage, ABI compatibility testing, and release automation.

Release Checklist

sh Tool/build-patch.sh your_patch.c
sh Tool/validate-production.sh

If both pass, the current repo state is ready for internal release and integration validation.


🤝 Contributing

Contributions are welcome! Areas to help:

  • 🐛 Bug fixes
  • ✨ New features
  • 📝 Documentation
  • 🧪 Test cases
  • 💡 Performance improvements

📜 License

WasmPatch is released under the MIT License.


🙏 Acknowledgements

Inspired by:


📈 Star History

Star History Chart


📞 Support

GitHub Issues WeChat

有问题?去 Issues 提问!


Made with ❤️ by Everett

Project Link: https://github.com/everettjf/WasmPatch

About

🧱Yet Another Patch Module for iOS/macOS via WebAssembly

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors