2011-08-03 16 views
13

पर एक स्ट्रिंग शाब्दिक एन्क्रिप्टिंग/obfuscating मैं संकलन समय पर एक स्ट्रिंग को एन्क्रिप्ट/एन्कोड करना चाहता हूं ताकि मूल स्ट्रिंग संकलित निष्पादन योग्य में दिखाई न दे।कंपाइल-टाइम

मैंने कई उदाहरण देखे हैं लेकिन वे तर्क के रूप में एक स्ट्रिंग अक्षर नहीं ले सकते हैं। निम्नलिखित उदाहरण देखें:

template<char c> struct add_three { 
    enum { value = c+3 }; 
}; 

template <char... Chars> struct EncryptCharsA { 
    static const char value[sizeof...(Chars) + 1]; 
}; 

template<char... Chars> 
char const EncryptCharsA<Chars...>::value[sizeof...(Chars) + 1] = { 
    add_three<Chars>::value... 
}; 

int main() { 
    std::cout << EncryptCharsA<'A','B','C'>::value << std::endl; 
    // prints "DEF" 
} 

मैं प्रत्येक चरित्र को अलग तरह से प्रदान नहीं करना चाहता हूं। मेरा लक्ष्य एक स्ट्रिंग शाब्दिक पारित पसंद करने के लिए है इस प्रकार है:

EncryptString<"String to encrypt">::value 

वहाँ भी इस तरह कुछ उदाहरण हैं:

#define CRYPT8(str) { CRYPT8_(str "\0\0\0\0\0\0\0\0") } 
#define CRYPT8_(str) (str)[0] + 1, (str)[1] + 2, (str)[2] + 3, (str)[3] + 4, (str)[4] + 5, (str)[5] + 6, (str)[6] + 7, (str)[7] + 8, '\0' 

// calling it 
const char str[] = CRYPT8("ntdll"); 

लेकिन यह स्ट्रिंग के आकार को सीमित।

क्या मैं चाहता हूं कि हासिल करने का कोई तरीका है?

+8

इस प्रकार की समस्या के लिए एक आम दृष्टिकोण एक स्क्रिप्ट लिखना है जो आपकी स्रोत फ़ाइल को इनपुट के रूप में लेता है और एक संशोधित फ़ाइल को आउटपुट के रूप में बनाता है, जो तब आपकी बिल्ड प्रक्रिया द्वारा उपयोग किया जाएगा। इस मामले में, स्क्रिप्ट एन्क्रिप्ट करने के लिए 'एन्क्रिप्टेड स्ट्रिंग <"स्ट्रिंग की तलाश करेगा">' और एन्क्रिप्टेड/एन्कोडेड संस्करण के साथ स्ट्रिंग को प्रतिस्थापित करें। – jdigital

उत्तर

1

मुझे लगता है कि यह प्रश्न एक अद्यतन उत्तर के योग्य है।

जब मैंने कई साल पहले इस सवाल से पूछा, तो मैंने the difference between obfuscation and encryption पर विचार नहीं किया। अगर मैं इस अंतर को जानता था तो, मैंने पहले शीर्षक में ओबफ्यूशन शब्द शामिल किया होगा। एक प्रभावी और यथोचित सरल तरीके से (हालांकि मैं अभी तक कि प्रयास नहीं किया है, और संभवतः एन्क्रिप्शन)

सी ++ 11 और सी ++ 14 विशेषताएं है कि यह संभव संकलन समय स्ट्रिंग कहानियो को लागू करने के लिए बनाने के लिए है, और यह पहले से ही किया जा चुका है।

ADVobfuscator सेबस्टियन एंड्रेटेट द्वारा बनाई गई एक obfuscation लाइब्रेरी है जो किसी भी बाहरी उपकरण, बस सी ++ कोड का उपयोग किए बिना संकलन-समय obfuscated कोड उत्पन्न करने के लिए सी ++ 11/14 का उपयोग करता है। अतिरिक्त निर्माण चरणों को बनाने की कोई आवश्यकता नहीं है, बस इसे शामिल करें और इसका उपयोग करें। मुझे एक बेहतर संकलन-समय स्ट्रिंग एन्क्रिप्शन/obfuscation कार्यान्वयन नहीं पता है जो बाहरी उपकरण का उपयोग नहीं करता है या चरणों का निर्माण नहीं करता है। यदि आप करते हैं, तो कृपया साझा करें।

यह न केवल तारों को दबाता है, लेकिन इसमें अन्य उपयोगी चीजें हैं जैसे कि संकलन-समय एफएसएम (Finite State Machine) जो यादृच्छिक रूप से फ़ंक्शन कॉल, और एक संकलन-समय छद्म-यादृच्छिक संख्या जेनरेटर को खराब कर सकती हैं, लेकिन ये दायरे से बाहर हैं इस जवाब का।

#include "MetaString.h" 

using namespace std; 
using namespace andrivet::ADVobfuscator; 

void Example() 
{ 
    /* Example 1 */ 

    // here, the string is compiled in an obfuscated form, and 
    // it's only deobfuscated at runtime, at the very moment of its use 
    cout << OBFUSCATED("Now you see me") << endl; 

    /* Example 2 */ 

    // here, we store the obfuscated string into an object to 
    // deobfuscate whenever we need to 
    auto narrator = DEF_OBFUSCATED("Tyler Durden"); 

    // note: although the function is named `decrypt()`, it's still deobfuscation 
    cout << narrator.decrypt() << endl; 
} 

आप मैक्रो DEF_OBFUSCATED और OBFUSCATED अपने मैक्रो के साथ की जगह ले सकता:

यहाँ एक सरल स्ट्रिंग कहानियो ADVobfuscator का उपयोग कर उदाहरण है। उदाहरण के लिए .:

#define _OBF(s) OBFUSCATED(s) 

... 

cout << _OBF("klapaucius"); 

यह कैसे काम करता है?

आप MetaString.h में इन दो मैक्रो की परिभाषा पर एक नज़र डालें, तो आप देखेंगे:

#define DEF_OBFUSCATED(str) MetaString<andrivet::ADVobfuscator::MetaRandom<__COUNTER__, 3>::value, andrivet::ADVobfuscator::MetaRandomChar<__COUNTER__>::value, Make_Indexes<sizeof(str) - 1>::type>(str) 

#define OBFUSCATED(str) (DEF_OBFUSCATED(str).decrypt()) 

असल में, MetaString वर्ग (स्ट्रिंग कहानियो की कोर) के तीन अलग-अलग रूपों देखते हैं । प्रत्येक का अपना obfuscation एल्गोरिदम है। लाइब्रेरी के छद्म-यादृच्छिक संख्या जेनरेटर (MetaRandom) के साथ, इन तीनों प्रकारों में से एक को यादृच्छिक रूप से संकलित समय पर चुना जाता है, साथ ही यादृच्छिक char के साथ चुने गए एल्गोरिदम द्वारा xor स्ट्रिंग वर्णों के लिए उपयोग किया जाता है।

"अरे, लेकिन हम गणित, 3 एल्गोरिदम * 255 संभव चार कुंजियों (0 नहीं किया जाता है) = अस्पष्ट स्ट्रिंग के 765 वेरिएंट करते हैं"

आप सही हैं। एक ही स्ट्रिंग को केवल 765 विभिन्न तरीकों से खराब किया जा सकता है। यदि आपके पास कुछ सुरक्षित की आवश्यकता है (आप पागल हैं/आपके आवेदन की सुरक्षा में वृद्धि की मांग है) तो आप लाइब्रेरी का विस्तार कर सकते हैं और मजबूत obfuscation या यहां तक ​​कि एन्क्रिप्शन (White-Box cryptography lib का रोडमैप में) का उपयोग करके अपने स्वयं के एल्गोरिदम लागू कर सकते हैं।


कहाँ/कैसे यह समझ से परे तार की दुकान करता है?

एक चीज जो मुझे इस कार्यान्वयन के बारे में दिलचस्प लगता है वह यह है कि यह निष्पादन योग्य के डेटा खंड में obfuscated स्ट्रिंग को संग्रहीत नहीं करता है। इसके बजाए, यह स्थिर रूप से MetaString ऑब्जेक्ट (स्टैक पर) में संग्रहीत है और एल्गोरिदम इसे रनटाइम पर स्थानांतरित करता है। यह दृष्टिकोण obfuscated तारों को, स्थिर रूप से या रनटाइम पर ढूंढना बहुत कठिन बनाता है।

आप अपने आप से कार्यान्वयन में गहराई से गोता लगा सकते हैं। यह एक बहुत अच्छा बुनियादी obfuscation समाधान है और एक जटिल बिंदु के लिए एक प्रारंभिक बिंदु हो सकता है।

+0

जबकि आपका उत्तर आपके द्वारा लिंक किए गए टूल का उपयोग करने के तरीके पर अच्छी जानकारी देता है, तो यह बहुत अच्छा होगा यदि आप यहां कार्यान्वयन के विवरण (कम से कम कुछ) जोड़ सकते हैं। अन्यथा, यदि आपका लिंक मर जाता है, तो भविष्य के पाठक केवल यह देखने में सक्षम होंगे कि एक obfuscator के कार्यान्वयन का उपयोग कैसे किया जाए, जिनके पास पहुंच नहीं है, जो हल्के से क्रूर हो जाएगा। –

+0

आपके सुझाव के लिए धन्यवाद। मैं कार्यान्वयन के विवरण पोस्ट करूंगा। – karliwson

3

कारण आपके द्वारा प्राप्त किए गए उदाहरण स्ट्रिंग अक्षर नहीं ले सकते हैं क्योंकि टेम्पलेट तर्क इसलिए है क्योंकि इसे आईएसओ सी ++ मानक द्वारा अनुमति नहीं है। ऐसा इसलिए है, भले ही सी ++ में एक स्ट्रिंग क्लास है, फिर भी एक स्ट्रिंग अक्षर अभी भी एक कॉन्स char * है। इसलिए, आप इसे बदल नहीं सकते हैं, या नहीं, इसे बदल सकते हैं (अपरिभाषित व्यवहार की ओर जाता है), भले ही आप इस तरह के एक संकलन-समय स्ट्रिंग अक्षर के पात्रों तक पहुंच सकें।

मैं देखता हूं कि एकमात्र तरीका परिभाषा का उपयोग कर रहा है, क्योंकि उन्हें कंपाइलर से पहले प्रीप्रोसेसर द्वारा संभाला जाता है। हो सकता है कि बढ़ावा आपको उस मामले में मददगार हाथ देगा।

2

एक मैक्रो आधारित समाधान एक भिन्न तर्क लेने और एक टोकन के रूप में स्ट्रिंग के प्रत्येक भाग में गुजरना होगा। फिर टोकन को स्ट्रिंग करें और इसे एन्क्रिप्ट करें और सभी टोकन को संयोजित करें। अंतिम परिणाम कुछ

CRYPT(m y _ s t r i n g) 

कहां _ व्हाइटस्पेस चरित्र शाब्दिक के लिए कुछ प्लेसहोल्डर है। बहुत गन्दा और मैं इस पर हर दूसरे समाधान पसंद करेंगे।

ऐसा कुछ ऐसा कर सकता है हालांकि बूस्ट.पीपी अनुक्रम इसे किसी भी सुंदर नहीं बना रहा है।

#include <iostream> 
#include <boost/preprocessor/stringize.hpp> 
#include <boost/preprocessor/seq/for_each.hpp> 

#define GARBLE(x) GARBLE_ ## x 
#define GARBLE_a x 
#define GARBLE_b y 
#define GARBLE_c z 

#define SEQ (a)(b)(c) 
#define MACRO(r, data, elem) BOOST_PP_STRINGIZE(GARBLE(elem)) 

int main() { 
    const char* foo = BOOST_PP_SEQ_FOR_EACH(MACRO, _, SEQ); 
    std::cout << foo << std::endl; 
} 
7

खुद को बचाने टेम्पलेट metaprogramming साथ और योग्य स्वतंत्र कार्यक्रम है कि स्ट्रिंग एन्क्रिप्ट करता है और एक cpp स्रोत फ़ाइल जो तब में संकलित किया गया है का उत्पादन सिर्फ लिखने लाइन नीचे मुसीबत का एक ढेर। इससे पहले कि आप संकलन इस कार्यक्रम को चलाने के हैं और एक सीपीपी और/या हेडर फ़ाइल उत्पन्न करेगा जिसमें आपके लिए उपयोग करने के लिए एन्क्रिप्टेड स्ट्रिंग होगी।

  1. encrypted_string.cpp और encrypted_string.h (जो खाली कर रहे हैं)
  2. एक स्क्रिप्ट या स्टैंडअलोन एप्लिकेशन कि एक इनपुट के रूप में एक पाठ फ़ाइल लेता है और अधिक encrypted_string लिखते हैं:

    तो यहाँ क्या आप के साथ शुरू है .cpp और encrypted_string.h

यदि स्क्रिप्ट विफल हो जाती है, तो आपकी संकलन विफल हो जाएगी क्योंकि आपके कोड में ऐसे चर के संदर्भ होंगे जो मौजूद नहीं हैं। आप समझदार हो सकते हैं, लेकिन यह शुरू करने के लिए पर्याप्त है।