%hook NSString
-(NSString *)stringWithString:(NSString *)str {
//....
%orig;
}
%end
THEOS 언어를 사용해봤다면, 메서드를 위와 같이 후킹해서 사용하게 된다.
근데 저건 탈옥해서 트윅을 사용할 때의 얘기이고,,,
맥용 앱을 제작할 때 메서드 후킹이 필요할 때가 있을 수 있다.
(iOS 에서는 확인 안해봤지만,, 안되겠지?)
일반적인 경우라면 새로운 클래스를 만들고 원래 클래스를 상속받아서 사용하면 되겠지만..
@interface A : NSObject
@end
@interface B : A
@end
주저리주저리 하고 싶은 말이 많지만 생략하고, 오버라이딩(후킹)을 위해선 아래 함수를 사용하면 된다.
더보기 클릭!
#include <objc/runtime.h>
void MethodSwizzle(Class aClass, SEL orig_sel, SEL alt_sel) {
// First, look for the methods
Method orig_method = NULL, alt_method = NULL;
orig_method = class_getInstanceMethod(aClass, orig_sel);
alt_method = class_getInstanceMethod(aClass, alt_sel);
// If both are found, swizzle them
if ((orig_method != NULL) && (alt_method != NULL))
{
method_exchangeImplementations(orig_method, alt_method);
}
}
사용방법은
1. 해당 클래스에 카테고리로 대체용 함수를 만든다.
2. MethodSwizzle 함수를 사용해 필요한 때에 바꿔준다.
3. 원래 메서드를 호출하고 싶다면, 카테고리로 만든 메서드를 호출해 주면 된다.
예시:
@interface NSString (Swizzle)
-(NSString *)alt_stringWithString:(NSString *)str;
@end
@implementation NSString (Swizzle)
-(NSString *)alt_stringWithString:(NSString *)str {
//......
return [self alt_stringWithString:str];
}
@end
...
-(void)somewhereInYourMind {
MethodSwizzle([NSString class], @selector(stringWithString:), @selector(alt_stringWithString:));
[NSString stringWithString:@""];
}
이렇게 하면 원래 메서드(여기선 stringWithString:) 를 호출하면
alt_stringWithString: 을 거친 다음 원래 메서드가 호출되고, 반환된다.
출처: http://cocoadev.com/MethodSwizzling