Objective-C
(Muhtemelen sadece Mac OS X'te clang ile derlenmişse)
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
void unusedFunction(void) {
printf("huh?\n");
exit(0);
}
int main() {
NSString *string;
string = (__bridge id)(void*)0x2A27; // Is this really valid?
NSLog(@"%@", [string stringByAppendingString:@"foo"]);
return 0;
}
@interface MyClass : NSObject
@end
@implementation MyClass
+ (void)load {
Class newClass = objc_allocateClassPair([NSValue class], "MyClass2", 0);
IMP imp = class_getMethodImplementation(self, @selector(unusedMethod));
class_addMethod(object_getClass(newClass), _cmd, imp, "");
objc_registerClassPair(newClass);
[newClass load];
}
- (void)unusedMethod {
Class class = [self superclass];
IMP imp = (IMP)unusedFunction;
class_addMethod(class, @selector(doesNotRecognizeSelector:), imp, "");
}
@end
Bu kod kullanılmayan işleve ulaşmak için birkaç püf noktası kullanır. Birincisi, 0x2A27 değeridir. Bu, bir nesnenin ayrılmasını önlemek için işaretçideki değeri kodlayan tamsayı 42 için etiketli bir işaretçidir .
Sonraki olduğunu MyClass. Hiçbir zaman kullanılmaz, ancak çalışma zamanı +loadönceden yüklendiğinde yöntemi çağırır main. Bu dinamik NSValueolarak, üst sınıfı olarak kullanılan yeni bir sınıf yaratır ve kaydeder . Ayrıca , uygulama olarak 's' +loadkullanarak o sınıf için bir yöntem ekler . Kayıt olduktan sonra, yeni sınıftaki load yöntemini çağırır (nedense otomatik olarak aranmaz).MyClass-unusedMethod
Yeni sınıfın load metodu unusedMethodetkin olarak adlandırılan ile aynı uygulamayı kullandığından . Üst unusedFunctionsınıfını alır ve bu sınıfın doesNotRecognizeSelector:yöntemi için bir uygulama olarak ekler . Bu yöntem başlangıçta bir örnek yöntemdi MyClass, ancak yeni sınıfta bir sınıf yöntemi olarak adlandırılıyor self, yeni sınıf nesnesi de öyle. Bu nedenle, süper sınıf NSValue, bunun için de süper sınıftır NSNumber.
Sonunda mainkoşar. İşaretçi değerini alır ve bir NSString *değişkene ( ARC ile veya ARC olmadan kullanılmasına izin veren __bridgeilk döküm) yapışır void *. Sonra, bu stringByAppendingString:değişkeni aramaya çalışır . Aslında, bu yöntemi uygulamayan bir sayı olduğu için, doesNotRecognizeSelector:bunun yerine, yöntem kullanılarak, sınıflandırma hiyerarşisi boyunca NSValueuygulandığı yere kadar ilerleyen bir yöntem çağrılır unusedFunction.
Not: Diğer sistemlerle uyumsuzluk, diğer uygulamalar tarafından gerçekleştirildiğine inanmadığım etiketli işaretçi kullanımından kaynaklanmaktadır. Bu normalde oluşturulmuş bir numara ile değiştirilmişse, kodun geri kalanı iyi çalışmalıdır.