, iOS

2016-10-01 25 views
7

üzerinde yansımayı önler (objc/runtime) Hassas verileri işleyen statik bir kitaplık üzerinde çalışıyorum. Kütüphaneyi kullanan geliştiricinin kütüphanede yansımayı kullanması şart değildir. Android'de, iOS

, biz service s ile bir aar dosyasını geliştirerek sorunu çözmek ve ayrı sürecine service işletilmektedir ve (hizmet sonra geliştirici yansıma kullanamaz başka bir süreç içine çalışırken) ama bir şey olmadığını merak ediyorum iOS'de benzer var mı?

Statik kütüphaneyi ayrı bir sürece uygulayabilir miyiz? değilse, statik kütüphanelerimizde yansımayı nasıl önleyebiliriz? Örneğin

:

 MyTestObject *obj = [[[myTestView alloc] init ]; 

     //=========================================== 

     Class clazz = [obj class]; 
     u_int count; 
     Ivar* ivars = class_copyIvarList(clazz, &count); 
     NSMutableArray* ivarArray = [NSMutableArray arrayWithCapacity:count]; 
     for (int i = 0; i < count ; i++) 
     { 
      const char* ivarName = ivar_getName(ivars[i]); 
      [ivarArray addObject:[NSString stringWithCString:ivarName encoding:NSUTF8StringEncoding]]; 
     } 
     free(ivars); 

     objc_property_t* properties = class_copyPropertyList(clazz, &count); 
     NSMutableArray* propertyArray = [NSMutableArray arrayWithCapacity:count]; 
     for (int i = 0; i < count ; i++) 
     { 
      const char* propertyName = property_getName(properties[i]); 
      [propertyArray addObject:[NSString stringWithCString:propertyName encoding:NSUTF8StringEncoding]]; 
     } 
     free(properties); 

     Method* methods = class_copyMethodList(clazz, &count); 
     NSMutableArray* methodArray = [NSMutableArray arrayWithCapacity:count]; 
     for (int i = 0; i < count ; i++) 
     { 
      SEL selector = method_getName(methods[i]); 
      const char* methodName = sel_getName(selector); 
      [methodArray addObject:[NSString stringWithCString:methodName encoding:NSUTF8StringEncoding]]; 
     } 
     free(methods); 

     NSDictionary* classDump = [NSDictionary dictionaryWithObjectsAndKeys: 
            ivarArray, @"ivars", 
            propertyArray, @"properties", 
            methodArray, @"methods", 
            nil]; 

     NSLog(@"%@", classDump); 

     //====================================================== 

     int v2 = [[obj valueForKey:@"testValue"] intValue]; 

     SEL s = NSSelectorFromString(@"wannatTestIt"); 
     [obj performSelector:s]; 

MyTestObject benim kütüphaneden bir sınıftır. İlk satırda, bir nesneyi bu sınıftan başlatıyorum.

Bir sonraki satırda, sınıfın değişkenlerini, yöntemlerini ve özellik listesini okuyup kaydediyorum.

{ 
    ivars =  (
     testValue 
    ); 
    methods =  (
     printTestValue, 
     wannatTestIt, 
     "initWithFrame:" 
    ); 
    properties =  (
    ); 
} 

wannaTestIt özel bir yöntemdir ve testValue özel değişkendir: Sonuç ortada. Bu yüzden kütüphaneyi kullanan geliştiricinin bunlara erişemeyeceğini düşünüyorum. Bununla birlikte, kütüphanenin kullanıcısı ismini alabildiğinden, kullanıcı iVar'ın değerini okumak için en sonunda yönteme başvurabilir.

Bunu nasıl önleyebilirim?

cevap

5

Yansıma tamamen "önleme" yapmak istiyorsanız, o zaman farklı bir dil kullanmalısınız. Yansıma, Objective C'de önemli bir şeydir ve onu "engellemek" veya "devre dışı bırakmak" mümkün değildir. Bununla birlikte, bu çalışma zamanı bilgisini araştırmacı tarafından daha az yararlı hale getirebilirsiniz. Örneğin, bu araca bir göz atın: https://github.com/Polidea/ios-class-guard. Bu sadece bir örnektir. Bu özel proje ile ilgili değilim ve farklı bir obfuscator seçebilir veya kendiniz yazabilirsiniz.

ne gerek sadece ve hatta bir numara özel yöntemler ve (gerçek adları olmadan) Ivars aitifşa kamu API yansıma sınırlamaktır o zaman size hassas kod yazarken daha başka çaremiz yok için tamam değilse farklı bir dilde. İstediğinizi elde etmek için Pimpl tasarım desenini kullanabilirsiniz. Bu şekilde, sınıflarınızın sadece kamu yöntemleri ve tek bir özel idir _impl (veya bunun gibi bir şey) olurdu. Burada _impl, C++ (veya ObjC API'lerine erişmeniz gerekiyorsa Object C++) yazılan uygulama sınıfının bir örneğidir ve tüm genel yöntemler bir proxy gibi davranır. Böyle bir şey:

- (NSInteger)computeSuperSensitiveStuffWithFoo:(Foo *)foo Bar:(Bar *)bar { 
    return _impl->computeStuff(foo, bar); 
} 

Bütün kişisel verilerinizi ve yöntemler MyClassImpl sınıfta kapsüllü olacağını Bu şekilde. Bu tür bir sınıfın bildirimini ve uygulanmasını gizli tutarsanız (yani, kitaplığınızla birlikte MyClassImpl.h dosyasını dağıtmazsanız) ve uygulamak için C++ gibi bir dil kullanırsanız, istediğinizi elde edersiniz.

Ayrıca Amaç C seçerseniz ++ sonra MyClassImpl bir (class anahtar sözcüğüyle bildirilen) C++ sınıfı değil Objective C sınıfı (@interface/@end bloğu ile beyan ve @implementation/@end bloğun içine uygulanan) olması gerektiğini unutmayın.Aksi halde, tüm özel verileriniz yansıma için kullanılabilir olacak, ancak araştırmacıdan birkaç adım daha atılması gerekecek.

+0

Benim kütüphanemde uiviewcontrollers var. Uiview denetleyicilerini de destekleyen C++ kodları geliştirebilir miyiz? –

+0

@HuseinBehboodiRad, tabi. UIViewControllers için değişiklik gerekmez. Sadece sıradan bir UIViewController' alt sınıfı oluşturun (“MyViewController” deyin), Objective C++ ile yazılmış uygulama sınıfını yaratın (“MyVCImpl” deyin). Ve cevabımda tarif ettiğim şeyleri aynen yap. 'MyViewController'' 'MyVCImpl' örneğine işaret eden _impl' ivar ekleyin. Tüm kamu yöntemlerini "_impl" ve "MyVCImpl" içindeki tüm özel yöntemleri/alanları saklamak için kullanın. Uygulama sınıfının içinden gerçek görüntü denetleyicisine erişmek için 'self'' MyVCImpl' öğesinin yapıcısına geçebilirsiniz. –