From 1d191304e05f9fc3369b52b672af0f938a2d0643 Mon Sep 17 00:00:00 2001 From: Ke Ming Jiang <389185764@qq.com> Date: Tue, 23 Feb 2021 13:21:10 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E5=91=BD=E5=90=8D=E4=B8=BArecover?= =?UTF-8?q?=E5=B9=B6=E6=B7=BB=E5=8A=A0=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OCRunner.podspec | 2 +- OCRunner/ORInterpreter.h | 3 +- OCRunner/ORInterpreter.m | 20 ++++++++----- OCRunner/RunEnv/MFValue.m | 1 + OCRunner/RunEnv/ORStructDeclare.m | 2 +- ...sses+Reverse.h => RunnerClasses+Recover.h} | 8 ++--- ...sses+Reverse.m => RunnerClasses+Recover.m} | 14 ++++----- OCRunnerArm64.podspec | 2 +- .../OCRunnerDemo.xcodeproj/project.pbxproj | 6 ++++ OCRunnerTests/ORTestWithObjc.m | 29 +++++++++++++++++++ OCRunnerTests/TestClass/ORRecoverClass.h | 21 ++++++++++++++ OCRunnerTests/TestClass/ORRecoverClass.m | 22 ++++++++++++++ 12 files changed, 107 insertions(+), 23 deletions(-) rename OCRunner/{RunnerClasses+Reverse.h => RunnerClasses+Recover.h} (66%) rename OCRunner/{RunnerClasses+Reverse.m => RunnerClasses+Recover.m} (90%) create mode 100644 OCRunnerTests/TestClass/ORRecoverClass.h create mode 100644 OCRunnerTests/TestClass/ORRecoverClass.m diff --git a/OCRunner.podspec b/OCRunner.podspec index c98f6d9..7d57648 100644 --- a/OCRunner.podspec +++ b/OCRunner.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "OCRunner" -s.version = "1.0.9" +s.version = "1.0.10" s.summary = "OCRunner" s.description = <<-DESC Execute Objective-C code Dynamically. iOS hotfix SDK. diff --git a/OCRunner/ORInterpreter.h b/OCRunner/ORInterpreter.h index f6f949c..1c27cf2 100644 --- a/OCRunner/ORInterpreter.h +++ b/OCRunner/ORInterpreter.h @@ -14,7 +14,8 @@ NS_ASSUME_NONNULL_BEGIN + (void)excuteBinaryPatchFile:(NSString *)path; + (void)excuteJsonPatchFile:(NSString *)path; + (void)excuteNodes:(NSArray *)nodes; -+ (void)reverse; ++ (void)recover; ++ (void)recoverWithClearEnvironment:(BOOL)clear; @end NS_ASSUME_NONNULL_END diff --git a/OCRunner/ORInterpreter.m b/OCRunner/ORInterpreter.m index 0938887..aac15c9 100644 --- a/OCRunner/ORInterpreter.m +++ b/OCRunner/ORInterpreter.m @@ -8,7 +8,7 @@ #import "ORInterpreter.h" #import "RunnerClasses+Execute.h" -#import "RunnerClasses+Reverse.h" +#import "RunnerClasses+Recover.h" #import "MFScopeChain.h" #import "ORSearchedFunction.h" #import "MFValue.h" @@ -125,19 +125,23 @@ + (NSArray *)linkFunctions:(NSArray *)nodes scope:(MFScopeChain *)scope{ return normalStatements; } -+ (void)reverse{ ++ (void)recover{ + [self recoverWithClearEnvironment:YES]; +} ++ (void)recoverWithClearEnvironment:(BOOL)clear{ if (ORInterpreter.shared.currentNodes == nil) { return; } for (ORNode *node in ORInterpreter.shared.currentNodes) { - [node reverse]; + [node recover]; } - [[MFScopeChain topScope] clear]; - [[MFStaticVarTable shareInstance] clear]; - [[ORStructDeclareTable shareInstance] clear]; - [[ORTypeSymbolTable shareInstance] clear]; [[ORffiResultCache shared] clear]; + if (clear) { + [[MFScopeChain topScope] clear]; + [[MFStaticVarTable shareInstance] clear]; + [[ORStructDeclareTable shareInstance] clear]; + [[ORTypeSymbolTable shareInstance] clear]; + } ORInterpreter.shared.currentNodes = [NSArray array]; - } @end diff --git a/OCRunner/RunEnv/MFValue.m b/OCRunner/RunEnv/MFValue.m index 63a5865..92525ab 100644 --- a/OCRunner/RunEnv/MFValue.m +++ b/OCRunner/RunEnv/MFValue.m @@ -378,6 +378,7 @@ - (void)setTypeBySearchInTypeSymbolTable{ } - (void)writePointer:(void *)pointer typeEncode:(const char *)typeEncode{ + typeEncode = typeEncode == NULL ? OCTypeStringPointer : typeEncode; if (pointer == NULL) { return; } diff --git a/OCRunner/RunEnv/ORStructDeclare.m b/OCRunner/RunEnv/ORStructDeclare.m index 0561c26..f4460b5 100644 --- a/OCRunner/RunEnv/ORStructDeclare.m +++ b/OCRunner/RunEnv/ORStructDeclare.m @@ -151,7 +151,7 @@ - (void)addTypePair:(ORTypeVarPair *)typePair{ [self addTypePair:typePair forAlias:typePair.var.varname]; } - (void)addTypePair:(ORTypeVarPair *)typePair forAlias:(NSString *)alias{ - ORSymbolItem *item = [self symbolItemForTypeName:alias]; + ORSymbolItem *item = [self symbolItemForTypeName:typePair.type.name]; if (item == nil) { item = [[ORSymbolItem alloc] init]; item.typeEncode = [NSString stringWithUTF8String:typePair.typeEncode]; diff --git a/OCRunner/RunnerClasses+Reverse.h b/OCRunner/RunnerClasses+Recover.h similarity index 66% rename from OCRunner/RunnerClasses+Reverse.h rename to OCRunner/RunnerClasses+Recover.h index 4bd4c7c..5a3efce 100644 --- a/OCRunner/RunnerClasses+Reverse.h +++ b/OCRunner/RunnerClasses+Recover.h @@ -8,12 +8,12 @@ #import #import NS_ASSUME_NONNULL_BEGIN -@protocol OCReverse -- (void)reverse; +@protocol OCRecover +- (void)recover; @end -@interface ORNode (Reverse) -- (void)reverse; +@interface ORNode (Recover) +- (void)recover; @end NS_ASSUME_NONNULL_END diff --git a/OCRunner/RunnerClasses+Reverse.m b/OCRunner/RunnerClasses+Recover.m similarity index 90% rename from OCRunner/RunnerClasses+Reverse.m rename to OCRunner/RunnerClasses+Recover.m index cfc749c..731fb51 100644 --- a/OCRunner/RunnerClasses+Reverse.m +++ b/OCRunner/RunnerClasses+Recover.m @@ -5,7 +5,7 @@ // Created by Jiang on 2021/2/1. // -#import "RunnerClasses+Reverse.h" +#import "RunnerClasses+Recover.h" #import "MFScopeChain.h" #import "util.h" #import "MFMethodMapTable.h" @@ -20,7 +20,7 @@ #import "ORCoreImp.h" #import "ORSearchedFunction.h" #import "ORffiResultCache.h" -void reverse_method(BOOL isClassMethod, Class clazz, SEL sel){ +void recover_method(BOOL isClassMethod, Class clazz, SEL sel){ NSString *orgSelName = [NSString stringWithFormat:@"ORG%@",NSStringFromSelector(sel)]; SEL orgsel = NSSelectorFromString(orgSelName); Method ocMethod; @@ -38,7 +38,7 @@ void reverse_method(BOOL isClassMethod, Class clazz, SEL sel){ } @implementation ORNode (Reverse) -- (void)reverse{ +- (void)recover{ } @end @@ -51,13 +51,13 @@ - (void)deallocffiReusltForKey:(NSValue *)key{ or_ffi_result_free(result); } } -- (void)reverse{ +- (void)recover{ Class class = NSClassFromString(self.className); // Reverse时,释放ffi_closure和ffi_type for (ORMethodImplementation *imp in self.methods) { SEL sel = NSSelectorFromString(imp.declare.selectorName); BOOL isClassMethod = imp.declare.isClassMethod; - reverse_method(isClassMethod, class, sel); + recover_method(isClassMethod, class, sel); [self deallocffiReusltForKey:[NSValue valueWithPointer:(__bridge void *)imp]]; CFRelease((__bridge CFTypeRef)(imp)); } @@ -67,8 +67,8 @@ - (void)reverse{ NSString *str2 = name.length > 1 ? [name substringFromIndex:1] : nil; SEL getterSEL = NSSelectorFromString(name); SEL setterSEL = NSSelectorFromString([NSString stringWithFormat:@"set%@%@:",str1,str2]); - reverse_method(NO, class, getterSEL); - reverse_method(NO, class, setterSEL); + recover_method(NO, class, getterSEL); + recover_method(NO, class, setterSEL); [self deallocffiReusltForKey:[NSValue valueWithPointer:(__bridge void *)prop]]; CFRelease((__bridge CFTypeRef)(prop)); } diff --git a/OCRunnerArm64.podspec b/OCRunnerArm64.podspec index e614d9c..42076bd 100644 --- a/OCRunnerArm64.podspec +++ b/OCRunnerArm64.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "OCRunnerArm64" -s.version = "1.0.9" +s.version = "1.0.10" s.summary = "OCRunnerArm64" s.description = <<-DESC Only Support Arm64, Execute Objective-C code Dynamically. iOS hotfix SDK. diff --git a/OCRunnerDemo/OCRunnerDemo.xcodeproj/project.pbxproj b/OCRunnerDemo/OCRunnerDemo.xcodeproj/project.pbxproj index 6a5a889..aab911d 100644 --- a/OCRunnerDemo/OCRunnerDemo.xcodeproj/project.pbxproj +++ b/OCRunnerDemo/OCRunnerDemo.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 0480FEE82580A77F00D6D914 /* ORWeakPropertyAndIvar.m in Sources */ = {isa = PBXBuildFile; fileRef = 0480FEE72580A77F00D6D914 /* ORWeakPropertyAndIvar.m */; }; + 04A634D125E4AB5A00DB31A6 /* ORRecoverClass.m in Sources */ = {isa = PBXBuildFile; fileRef = 04A634C925E4A79300DB31A6 /* ORRecoverClass.m */; }; 32C54D1C256B4E6D00D067A2 /* jsonpatch in Resources */ = {isa = PBXBuildFile; fileRef = 32C54D1B256B4E6D00D067A2 /* jsonpatch */; }; 994370B6E6826AB9C293F686 /* Pods_OCRunnerDemo_OCRunnerDemoUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2566C827C6925E5FB35FC01D /* Pods_OCRunnerDemo_OCRunnerDemoUITests.framework */; }; D71B1056F7894677E4150783 /* Pods_OCRunnerDemo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A0001072323984F1566D9A7 /* Pods_OCRunnerDemo.framework */; }; @@ -53,6 +54,8 @@ 038B17776BFE18A7DEB3184D /* Pods-OCRunnerDemo-OCRunnerDemoTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OCRunnerDemo-OCRunnerDemoTests.release.xcconfig"; path = "Target Support Files/Pods-OCRunnerDemo-OCRunnerDemoTests/Pods-OCRunnerDemo-OCRunnerDemoTests.release.xcconfig"; sourceTree = ""; }; 0480FEE62580A77F00D6D914 /* ORWeakPropertyAndIvar.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ORWeakPropertyAndIvar.h; sourceTree = ""; }; 0480FEE72580A77F00D6D914 /* ORWeakPropertyAndIvar.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ORWeakPropertyAndIvar.m; sourceTree = ""; }; + 04A634C825E4A79300DB31A6 /* ORRecoverClass.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ORRecoverClass.h; sourceTree = ""; }; + 04A634C925E4A79300DB31A6 /* ORRecoverClass.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ORRecoverClass.m; sourceTree = ""; }; 0EA667C064BFFB79847D34F5 /* Pods-OCRunnerDemoTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OCRunnerDemoTests.release.xcconfig"; path = "Target Support Files/Pods-OCRunnerDemoTests/Pods-OCRunnerDemoTests.release.xcconfig"; sourceTree = ""; }; 1C9D422B1CDEE6B7B4FBECF4 /* Pods-OCRunnerDemo-OCRunnerDemoUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OCRunnerDemo-OCRunnerDemoUITests.release.xcconfig"; path = "Target Support Files/Pods-OCRunnerDemo-OCRunnerDemoUITests/Pods-OCRunnerDemo-OCRunnerDemoUITests.release.xcconfig"; sourceTree = ""; }; 2566C827C6925E5FB35FC01D /* Pods_OCRunnerDemo_OCRunnerDemoUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_OCRunnerDemo_OCRunnerDemoUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -248,6 +251,8 @@ EEBF3344248E84A900DDE2E9 /* ORTestClassProperty.m */, EEBF3345248E84A900DDE2E9 /* ORTestReplaceClass.h */, EEBF334A248E84A900DDE2E9 /* ORTestReplaceClass.m */, + 04A634C825E4A79300DB31A6 /* ORRecoverClass.h */, + 04A634C925E4A79300DB31A6 /* ORRecoverClass.m */, ); name = TestClass; path = ../../OCRunnerTests/TestClass; @@ -566,6 +571,7 @@ EEBF3351248E84AA00DDE2E9 /* ORTestReplaceClass.m in Sources */, EEBF3353248E84D100DDE2E9 /* ORTestWithObjc.m in Sources */, EEBF334E248E84AA00DDE2E9 /* ORTestClassProperty.m in Sources */, + 04A634D125E4AB5A00DB31A6 /* ORRecoverClass.m in Sources */, EEBF334F248E84AA00DDE2E9 /* ORTestClassIvar.m in Sources */, EEBF334C248E84AA00DDE2E9 /* ORCallOCPropertyBlockTest.m in Sources */, EEBF333E248E848100DDE2E9 /* OCRunnerTests.swift in Sources */, diff --git a/OCRunnerTests/ORTestWithObjc.m b/OCRunnerTests/ORTestWithObjc.m index 95d3f24..fab2009 100644 --- a/OCRunnerTests/ORTestWithObjc.m +++ b/OCRunnerTests/ORTestWithObjc.m @@ -10,6 +10,7 @@ #import #import "ORTypeVarPair+TypeEncode.h" #import +#import "ORRecoverClass.h" #import #import "ORWeakPropertyAndIvar.h" @interface ORTestWithObjc : XCTestCase @@ -577,6 +578,34 @@ - (void)testWeakPropertyAndIvar{ } XCTAssert([ivarWeak isEqualToString:@"dealloc"]); } +- (void)testRecover{ + NSString *source = @"\ + @interface ORRecoverClass : NSObject\ + @property (nonatomic, assign)int value1;\ + @property (nonatomic, copy)NSString *value2;\ + @end\ + @implementation ORRecoverClass\ + + (int)classMethodTest{ return 0; }\ + - (int)methodTest1{ return 0; }\ + - (int)methodTest2{ return 0; }\ + - (int)value1{ return 1; }\ + - (NSString *)value2{ return @\"123\"; }\ + @end"; + AST *ast = [OCParser parseSource:source]; + [ORInterpreter excuteNodes:ast.nodes]; + ORRecoverClass *object = [ORRecoverClass new]; + XCTAssert([object value1] == 1); + XCTAssert([[object value2] isEqual:@"123"]); + XCTAssert([object methodTest1] == 0); + XCTAssert([object methodTest2] == 0); + XCTAssert([ORRecoverClass classMethodTest] == 0); + [ORInterpreter recoverWithClearEnvironment:NO]; + XCTAssert([object value1] == 0); + XCTAssert([object value2] == nil); + XCTAssert([object methodTest1] == 1); + XCTAssert([object methodTest2] == 1); + XCTAssert([ORRecoverClass classMethodTest] == 1); +} - (void)testOCRecursiveFunctionPerformanceExample { [self measureBlock:^{ fibonaccia(20); diff --git a/OCRunnerTests/TestClass/ORRecoverClass.h b/OCRunnerTests/TestClass/ORRecoverClass.h new file mode 100644 index 0000000..9e919fc --- /dev/null +++ b/OCRunnerTests/TestClass/ORRecoverClass.h @@ -0,0 +1,21 @@ +// +// ORRecoverClass.h +// OCRunnerDemoTests +// +// Created by Jiang on 2021/2/23. +// Copyright © 2021 SilverFruity. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface ORRecoverClass : NSObject +@property (nonatomic, assign)int value1; +@property (nonatomic, copy)NSString *value2; ++ (int)classMethodTest; +- (int)methodTest1; +- (int)methodTest2; +@end + +NS_ASSUME_NONNULL_END diff --git a/OCRunnerTests/TestClass/ORRecoverClass.m b/OCRunnerTests/TestClass/ORRecoverClass.m new file mode 100644 index 0000000..c9d426b --- /dev/null +++ b/OCRunnerTests/TestClass/ORRecoverClass.m @@ -0,0 +1,22 @@ +// +// ORRecoverClass.m +// OCRunnerDemoTests +// +// Created by Jiang on 2021/2/23. +// Copyright © 2021 SilverFruity. All rights reserved. +// + +#import "ORRecoverClass.h" + +@implementation ORRecoverClass ++ (int)classMethodTest{ + return 1; +} +- (int)methodTest1{ + return 1; +} +- (int)methodTest2{ + return 1; +} + +@end