Workflow for patch development using OCRunner.

The main differences between OCRunner and JSPatch, OCEval and MangoFix, etc.

  • Deliver the binary patch file. Increase security, reduce patch size, omit lexical analysis and syntax analysis, optimize startup time, which can be optimized in the PatchGenerator stage (TODO: information about uncalled functions will be filtered)

  • Custom Arm64 ABI (can do without libffi)

  • Full Objective-C syntax support, minus precompilation and partial syntax

OCRunner runs the patch locally

OCRunnerDemo can be used as a reference throughout the process.

1. Cocoapods imports OCRunner

pod 'OCRunner'      Support all architectures, including libffi.a
# or
pod 'OCRunnerArm64' # support arm64 and arm64e only, no libffi.a
Copy the code

2. DownloadPatchGenerator

Unzip patchGenerato.zip and save the PatchGenerator to /usr/bin/ or the project directory.

3. Add PatchGeneratorRun Script

  1. Project Setting -> Build Phases -> Top left + -> New Run Script Phase

  2. Path of PatchGenerator -Files Objective-C source file list or folder -refs Objective-C header file list or folder -output Location where the output patch is saved

  3. Such as the Run Script in OCRunnerDemo

    $SRCROOT/OCRunnerDemo/PatchGenerator -files $SRCROOT/OCRunnerDemo/ViewController1 -refs  $SRCROOT/OCRunnerDemo/Scripts.bundle -output $SRCROOT/OCRunnerDemo/binarypatch
    Copy the code

4. In the development environment: Run patches

  1. Add the generated patch file to the project as a resource file

  2. Appdelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
#if DEBUG
    NSString *patchFilePath = [[NSBundle mainBundle] pathForResource:@"PatchFileName" ofType:nil];
#else
   // download from server
#endif
    [ORInterpreter excuteBinaryPatchFile:patchFilePath];
    return YES;
}
Copy the code
  1. Each time you modify the file, remember Command+B, call Run Scrip, and regenerate the patch file.

5. Formal environment

  1. Upload the patch to the server
  2. Download the patch file from App and save it locally
  3. Use the * * [ORInterpreter excuteBinaryPatchFile: PatchFilePath] * * patch

Used to introduce

1. Introduce structs, enumerations, typedef

You can run the following code by modifying ViewController1 in OCRunnerDemo.

// A new type called dispatch_once_t will be added
typedef NSInteger dispatch_once_t;
// link NSLog
void NSLog(NSString*format, ...) ;typedef enum: NSUInteger{
    UIControlEventTouchDown                                         = 1 <<  0.UIControlEventTouchDownRepeat                                   = 1 <<  1.UIControlEventTouchDragInside                                   = 1 <<  2.UIControlEventTouchDragOutside                                  = 1 <<  3.UIControlEventTouchDragEnter                                    = 1 <<  4
}UIControlEvents;

int main(){
    UIControlEvents events = UIControlEventTouchDown | UIControlEventTouchDownRepeat;
    if (events & UIControlEventTouchDown) {NSLog(@"UIControlEventTouchDown");
    }
    NSLog(@"enum test: %lu",events);
    return events;
}
main();
Copy the code

Tips:

It is recommended to create a new file to place the above code, similar to the UIKitRefrence and GCDRefrence files in OCRunnerDemo, and then use PatchGenerator to add the patch generation as **-links**. The author wants to steal lazy, do not want to CV again, header file too much 😭.

2. Use the built-in C function

//you only need to add the C function declaration in Script.
//link NSLog
void NSLog(NSString*format, ...) ;//then you can use it in Scrtips.
NSLog(@"test for link function %@".@"xixi");
Copy the code

When you run the code above. OCRunner will use ORSearchedFunction to search for Pointers to functions.

The core implementation of this process is SymbolSearch (modified from Fishhook).

If the result is NULL, OCRunner will automatically print the following information on the console:

| -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - | | ❕ you need add ⬇ ️ codein the application file |
|----------------------------------------------|
[ORSystemFunctionTable reg:@"dispatch_source_set_timer" pointer:&dispatch_source_set_timer];
Copy the code

3. Fix OC object (class) methods and add attributes

Little genius English learning machine, not where point where

Want to fix which method, will change the method implementation, do not need to implement other methods.

@interface ORTestClassProperty:NSObject
@property (nonatomic.copy)NSString *strTypeProperty;
@property (nonatomic.weak)id weakObjectProperty;
@end
@implementation ORTestClassProperty
- (void)otherMethod{
    self.strTypeProperty = @"Mango";
}
- (NSString *)testObjectPropertyTest{
    [self otherMethod];
    return self.strTypeProperty;
}
@end
Copy the code

4.Block use, circular reference solution

// Used to resolve circular references
__weak id object = [NSObject new];
// The simplest block declaration
void (^a)(void) = ^ {int b = 0;
};
a();
Copy the code

More content

Updated GitPage, but did not submit md source file, can only update nuggets after home 😂.