2016-10-01 8 views
7

पर प्रतिबिंब (objc/runtime) को रोकें, मैं एक स्थिर पुस्तकालय पर काम कर रहा हूं जो संवेदनशील डेटा को संभालता है। यह जरूरी है कि पुस्तकालय का उपयोग करने वाला डेवलपर लाइब्रेरी पर प्रतिबिंब का उपयोग नहीं कर सके।आईओएस

एंड्रॉयड पर, हम service रों साथ एक aar फ़ाइल के विकास के द्वारा समस्या का समाधान और अलग प्रक्रिया में service चलाने, (जब सेवा तो डेवलपर प्रतिबिंब उपयोग नहीं कर सकते किसी अन्य प्रक्रिया में चल रहा है), लेकिन मैं अगर कुछ सोच रहा हूँ आईओएस में भी इसी तरह मौजूद है?

क्या हम एक स्थिर पुस्तकालय को एक अलग प्रक्रिया में निष्पादित कर सकते हैं? यदि नहीं, तो हम अपने स्थिर पुस्तकालयों पर प्रतिबिंब से कैसे बच सकते हैं?

उदाहरण के लिए:

 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 मेरी लाइब्रेरी से एक वर्ग है। पहली पंक्ति में, मैं इस वर्ग से एक वस्तु शुरू करता हूं।

अगली पंक्ति में, मैंने कक्षा के चर, विधियों और संपत्ति सूची को पढ़ा और इसे लॉग किया।

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

wannaTestIt एक निजी तरीका है और testValue एक निजी चर रहा है: यहाँ परिणाम है। इसलिए मैं उम्मीद करता हूं कि लाइब्रेरी का उपयोग करने वाले डेवलपर उन्हें एक्सेस नहीं कर सकते हैं। हालांकि, क्योंकि पुस्तकालय के उपयोगकर्ता को नाम मिल सकता है, उपयोगकर्ता अंततः iVar के मान को पढ़ने के लिए विधि को कॉल कर सकता है।

मैं इसे कैसे रोक सकता हूं?

उत्तर

5

यदि आप प्रतिबिंब को पूरी तरह से "रोकना" चाहते हैं, तो, आपको एक अलग भाषा का उपयोग करना होगा। प्रतिबिंब उद्देश्य सी में एक महत्वपूर्ण बात है और इसे "ब्लॉक" या "अक्षम" करना संभव नहीं है।

हालांकि, आप इस रन-टाइम जानकारी को शोधकर्ता के लिए बहुत कम उपयोगी बना सकते हैं। उदाहरण के लिए, इस टूल पर एक नज़र डालें: https://github.com/Polidea/ios-class-guard। यह सिर्फ एक उदाहरण है। मैं इस विशेष परियोजना से संबंधित नहीं हूं और आप स्वतंत्र रूप से एक अलग obfuscator चुन सकते हैं या अपना खुद का लिख ​​सकते हैं।

क्या आप की जरूरत ही और भी का खुलासा एक नंबर निजी तरीकों और ivars (उनके वास्तविक नाम के बिना) के सार्वजनिक एपीआई के प्रतिबिंब को सीमित करने के लिए आप तो आप आप संवेदनशील कोड लिखने के अलावा कोई अन्य विकल्प नहीं है, ठीक नहीं है, तो एक अलग भाषा में। आप जो चाहते हैं उसे प्राप्त करने के लिए आप Pimpl डिज़ाइन पैटर्न का उपयोग कर सकते हैं। इस तरह, आपके वर्गों में केवल सार्वजनिक विधियां और एक निजी ivar _impl (या ऐसा कुछ) होगा। जहां _impl सी ++ में लिखा गया कार्यान्वयन वर्ग का एक उदाहरण है (या उद्देश्य सी ++ यदि आपको ओबीजेसी एपीआई तक पहुंच की आवश्यकता है) और सभी सार्वजनिक विधियां प्रॉक्सी की तरह कार्य करती हैं। कुछ इस तरह:

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

इस तरह से अपने सभी निजी डेटा और तरीकों MyClassImpl वर्ग में समाहित किया जाएगा। यदि आप निजी रूप से ऐसी कक्षा की घोषणा और कार्यान्वयन करते हैं (यानी अपनी लाइब्रेरी के साथ MyClassImpl.h फ़ाइल वितरित न करें) और इसे लागू करने के लिए सी ++ जैसी भाषा का उपयोग करें, तो आप जो चाहते हैं उसे प्राप्त करेंगे।

यह भी ध्यान रखें कि यदि आप उद्देश्य सी चुना ++ तो MyClassImpl एक सी ++ वर्ग (class कीवर्ड के साथ घोषित) और नहीं उद्देश्य सी क्लास (साथ @interface/@end ब्लॉक घोषित कर दिया और अंदर @implementation/@end ब्लॉक कार्यान्वित) होना चाहिए।अन्यथा आप सभी निजी डेटा प्रतिबिंब के लिए उपलब्ध होंगे, लेकिन शोधकर्ता से कुछ अतिरिक्त कदमों की आवश्यकता होगी।

+0

मेरी लाइब्रेरी में uiviewcontrollers भी हैं। क्या हम C++ के साथ कोड विकसित कर सकते हैं जो uiviewcontrollers का भी समर्थन करते हैं? –

+0

@HuseinBehboodiRad, निश्चित रूप से। UIViewControllers के लिए कोई बदलाव आवश्यक नहीं है। बस एक सामान्य 'UIViewController' subclass (कहें,' MyViewController') बनाएं, उद्देश्य C++ (कहें, 'MyVCImpl') में लिखित कार्यान्वयन वर्ग बनाएं। और वैसे ही वही काम करें जो मैंने अपने उत्तर में वर्णित किया है। 'MyViewController' में '_impl' ivar' MyVCImpl 'के उदाहरण को इंगित करते हुए जोड़ें। '_impl' के लिए सभी सार्वजनिक विधियों को प्रॉक्सी करें और सभी निजी विधियों/फ़ील्ड को 'MyVCImpl' के अंदर रखें। कार्यान्वयन वर्ग के अंदर से वास्तविक दृश्य नियंत्रक तक पहुंच प्राप्त करने के लिए आप 'MyVCImpl' के निर्माता को 'self' पास कर सकते हैं। –