diff --git a/Stinger/Classes/STDefines.h b/Stinger/Classes/STDefines.h index c4ab8bd..9c2cc25 100644 --- a/Stinger/Classes/STDefines.h +++ b/Stinger/Classes/STDefines.h @@ -75,6 +75,7 @@ typedef NS_ENUM(NSInteger, STHookResult) { @property (nonatomic, weak) Class hookedCls; @property (nonatomic, weak) Class statedCls; @property (nonatomic, assign) BOOL isInstanceHook; +@property (nonatomic, assign) BOOL isInstanceIsaHook; + (instancetype)poolWithTypeEncoding:(NSString *)typeEncoding originalIMP:(IMP)imp selector:(SEL)sel; @end diff --git a/Stinger/Classes/STHookInfoPool.m b/Stinger/Classes/STHookInfoPool.m index 912d105..6770ca9 100644 --- a/Stinger/Classes/STHookInfoPool.m +++ b/Stinger/Classes/STHookInfoPool.m @@ -214,6 +214,7 @@ @implementation STHookInfoPool { @synthesize hookedCls = _hookedCls; @synthesize statedCls = _statedCls; @synthesize isInstanceHook = _isInstanceHook; +@synthesize isInstanceIsaHook = _isInstanceIsaHook; @synthesize semaphore = _semaphore; @@ -408,7 +409,9 @@ NS_INLINE void _st_ffi_function(ffi_cif *cif, void *ret, void **args, void *user void **slf = args[0]; if (hookedClassInfoPool->_isInstanceHook) { - statedClassInfoPool = _st_fast_get_HookInfoPool(hookedClassInfoPool->_statedCls, hookedClassInfoPool->_uniqueKey); + if (!hookedClassInfoPool->_isInstanceIsaHook) { + statedClassInfoPool = _st_fast_get_HookInfoPool(hookedClassInfoPool->_statedCls, hookedClassInfoPool->_uniqueKey); + } instanceInfoPool = _st_fast_get_HookInfoPool((__bridge id)(*slf), hookedClassInfoPool->_uniqueKey); } diff --git a/Stinger/Classes/Stinger.m b/Stinger/Classes/Stinger.m index d345349..239ed0a 100644 --- a/Stinger/Classes/Stinger.m +++ b/Stinger/Classes/Stinger.m @@ -18,11 +18,11 @@ @implementation NSObject (Stinger) #pragma mark - For specific class + (STHookResult)st_hookInstanceMethod:(SEL)sel option:(STOption)option usingIdentifier:(STIdentifier)identifier withBlock:(id)block { - return hookMethod(self, sel, option, identifier, block); + return hookMethod(self, sel, option, identifier, block, NO); } + (STHookResult)st_hookClassMethod:(SEL)sel option:(STOption)option usingIdentifier:(STIdentifier)identifier withBlock:(id)block { - return hookMethod(object_getClass(self), sel, option, identifier, block); + return hookMethod(object_getClass(self), sel, option, identifier, block, NO); } + (NSArray *)st_allIdentifiersForKey:(SEL)key { @@ -56,7 +56,7 @@ - (STHookResult)st_hookInstanceMethod:(SEL)sel option:(STOption)option usingIden Class stSubClass = getSTSubClass(self); if (!stSubClass) return STHookResultOther; - STHookResult hookMethodResult = hookMethod(stSubClass, sel, option, identifier, block); + STHookResult hookMethodResult = hookMethod(stSubClass, sel, option, identifier, block, YES); if (hookMethodResult != STHookResultSuccess) return hookMethodResult; if (!objc_getAssociatedObject(self, STSubClassKey)) { object_setClass(self, stSubClass); @@ -91,7 +91,7 @@ - (BOOL)st_removeHookWithIdentifier:(STIdentifier)identifier forKey:(SEL)key { #pragma mark - inline functions -NS_INLINE STHookResult hookMethod(Class hookedCls, SEL sel, STOption option, STIdentifier identifier, id block) { +NS_INLINE STHookResult hookMethod(Class hookedCls, SEL sel, STOption option, STIdentifier identifier, id block, BOOL byInstanceHook) { NSCParameterAssert(hookedCls); NSCParameterAssert(sel); NSCParameterAssert(identifier); @@ -124,11 +124,13 @@ NS_INLINE STHookResult hookMethod(Class hookedCls, SEL sel, STOption option, STI st_setHookInfoPool(hookedCls, sel, hookInfoPool); } if (st_isIntanceHookCls(hookedCls)) { - return STHookResultSuccess; - } else { - STHookInfo *hookInfo = [STHookInfo infoWithOption:option withIdentifier:identifier withBlock:block]; - return [hookInfoPool addInfo:hookInfo] ? STHookResultSuccess : STHookResultErrorIDExisted; + if (byInstanceHook) { + return STHookResultSuccess; + } + hookInfoPool.isInstanceIsaHook = YES; } + STHookInfo *hookInfo = [STHookInfo infoWithOption:option withIdentifier:identifier withBlock:block]; + return [hookInfoPool addInfo:hookInfo] ? STHookResultSuccess : STHookResultErrorIDExisted; } }