एक ConfuserEx2 डीओब्फस्केटर जिसमें एंटी-टैम्पर, कंप्रेसर, कॉन्स्टैंट्स, कंट्रोल फ्लो और रिसोर्स रिकवरी के लिए समर्थन है।
UnconfuserEx का संवर्धित fork, जिसमें आधुनिक ConfuserEx2 वेरिएंट्स, एंटी-टैम्पर रिकवरी, कंप्रेसर हटाना, कंट्रोल-फ्लो पुनर्स्थापना और रिसोर्स पुनर्निर्माण के लिए बेहतर समर्थन है।
https://github.com/user-attachments/assets/de2c7fd9-6736-4f39-83c0-3c25aa9c1f24
अगर आपने कभी मैलवेयर सैंपल्स के साथ खेला है, तो उनमें से कुछ ConfuserEx के साथ अस्पष्ट (obfuscated) होते हैं, और मैंने नवीनतम वर्जन के खिलाफ कुछ सार्वजनिक डी-ऑबफस्केटर्स को आज़माया, लेकिन वे काम नहीं किए, इसलिए मैंने एक सार्वजनिक फोर्क करने का फैसला किया जो उस नवीनतम वर्जन के खिलाफ काम करता था और इसे अपनी जरूरतों के अनुसार संशोधित किया।
यह रिपॉजिटरी MadMin3r/UnconfuserEx का एक फोर्क है। उन्हें भी श्रेय जाता है। मूल प्रोजेक्ट ने एक केंद्रित ConfuserEx2 डी-ऑबफस्केटर बनाने का कठिन काम किया जो वास्तविक सुरक्षा को हटा सकता था।
यही इस प्रोजेक्ट का काम है। यह एक निश्चित क्रम में रिमूवर्स की एक सूची चलाता है, जहाँ संभव हो मेथड बॉडी/रिसोर्स/मेटाडेटा को फिर से लिखता है, और एक नई असेंबली आउटपुट करता है। महत्वपूर्ण हिस्सा क्रम है। कंप्रेसर और एंटी टैम्पर को पहले होना पड़ता है क्योंकि बाकी मॉड्यूल अभी वास्तविक IL नहीं भी हो सकता है।
अपस्ट्रीम वर्जन पहले से ही उपयोगी था, लेकिन कुछ मामले सामने आते रहे।
एक LZMA पथ था। कुछ सैंपल ऐसे बाइट्स देते हैं जो कॉन्स्टेंट/रिसोर्सेज पेलोड जैसे दिखते हैं, लेकिन LZMA प्रॉपर्टीज़ बकवास होती हैं। यदि आप उसे सीधे डिकोडर में डालते हैं, तो आपको बेवकूफी भरे डिक्शनरी साइज़ मिलते हैं और अंततः ऐरे डाइमेंशन सपोर्टेड रेंज से अधिक होने जैसे अपवाद आते हैं। इसलिए यह वर्जन प्रॉपर्टीज़ की जाँच करता है, डिक्शनरी साइज़ को सीमित करता है, अनकम्प्रेस्ड साइज़ को सीमित करता है, और डिकोडर के कुछ बेवकूफी भरा आवंटन करने से पहले ही बाहर निकल जाता है।
LZMA properties => CE FD 62 5F 9F
Invalid LZMA properties byte 0xCE or unreasonable dictionary size
कॉन्स्टेंट्स की एक और बेवकूफी लेकिन वास्तविक समस्या थी। अधिकांश रिज़ॉल्वर कोड चाहता है कि गेटर कॉल के सामने वाला ID ldc.i4 हो। कभी-कभी वह एक इंस्ट्रक्शन नहीं रह जाता। वह एक छोटा अरिदमेटिक एक्सप्रेशन होता है।
ldc.i4 0x1234
ldc.i4 0x55
xor
call string <const getter>(int32)
मूल फोर्क xor देखता है, GetLdcI4Value() कॉल करता है, और मर जाता है क्योंकि xor स्पष्ट रूप से इंटीजर लोड नहीं है। यह वर्जन छोटे अरिदमेटिक सीक्वेंस पर पीछे जाता है, स्टैक को एम्यूलेट करता है, उसे एक ldc.i4 में समेटता है, और फिर सामान्य रिज़ॉल्वर को काम करने देता है।
इसलिए इसे पूरी तरह से अलग कॉन्स्टेंट्स प्रोटेक्शन मानने के बजाय, यह बन जाता है:
ldc.i4 0x1261
call string <const getter>(int32)
फिर मौजूदा सामान्य/x86 कॉन्स्टेंट रिज़ॉल्वर पथ अपना काम कर सकता है।
कंट्रोल फ्लो वह था जहाँ यह औसत दर्जे का था
स्विच रिमूवर सामान्य ConfuserEx स्विच डिस्पैचर आकार को संभाल सकता है। यह ब्लॉक्स पर चलता है, अगले लक्ष्य को पुनर्प्राप्त करता है, मृत ब्लॉक्स को हटाता है, और एक समझदार मेथड बॉडी एमिट करता है। लेकिन कुछ सैंपल ऐसे हैं जहाँ मेथड का केवल एक हिस्सा समझा जाता है। यदि आप आधे मेथड को म्यूटेट करते हैं और फिर पाते हैं कि वह अभी भी ऑबफस्केटेड है, तो आउटपुट बेकार से भी बदतर है क्योंकि अब आपके पास टूटी हुई IL है और यह समझने का कोई साफ तरीका नहीं है कि क्या हुआ।
इसलिए यह वर्जन मेथड बॉडी को छूने से पहले उसका स्नैपशॉट लेता है:
instructions
exception handlers
यदि डी-ऑबफस्केशन फेंकता है, या यदि मेथड बाद में भी ऑबफस्केटेड दिखता है, तो मूल बॉडी को बहाल कर दिया जाता है। लॉग अब भी कह सकता है "यह मेथड हल नहीं हुआ", लेकिन असेंबली चुपचाप दूषित नहीं होती सिर्फ इसलिए कि एक मेथड में एक अजीब डिस्पैचर था।
जंप/ट्रैम्पोलिन कंट्रोल फ्लो को भी अपना अलग पास मिला। कुछ मेथड केवल स्विच डिस्पैचर नहीं होते। वे छोटे ब्रांच ट्रैम्पोलिन होते हैं जो तब तक जुड़े रहते हैं जब तक वास्तविक ब्लॉक तक नहीं पहुँच जाते। अब उनका पता लगाया जाता है और उन्हें फोल्ड किया जाता है, जबकि पहले केवल स्विच पथ द्वारा उन्हें अनदेखा किया जाता था।
कंप्रेसर रिमूवर वह हिस्सा है जिसे बाकी सभी से पहले चलना होता है।
ConfuserEx कंप्रेसर स्टब्स आमतौर पर वास्तविक असेंबली को संपीड़ित रखते हैं, एक छोटा लोडर बूट करते हैं, पेलोड को डीकंप्रेस करते हैं, और रनटाइम पर इसे लोड करते हैं।
रिमूवर लोडर आकार ढूंढता है, एम्बेडेड पेलोड निकालता है, इसे डीकंप्रेस करता है, और मॉड्यूल को वास्तविक असेंबली पर स्वैप करता है। सामान्य और कॉम्पैक्ट कंप्रेसर लेआउट दोनों को संभाला जाता है।
[+] Compressor detected
[+] Extracted compressed module payload
[+] Decompressed real module
[+] Continuing pipeline on unpacked assembly
एंटी-टैम्पर के अब दो पथ हैं।
सामान्य/डायनामिक एंटी टैम्पर संरक्षित अनुभागों से मेथड बॉडी को डिक्रिप्ट करता है और पुनर्स्थापित बॉडी को वापस मॉड्यूल में लिखता है। JIT एंटी टैम्पर अधिक कष्टप्रद है क्योंकि बॉडी को रनटाइम द्वारा पूछे जाने पर मटेरियलाइज़ करने के लिए डिज़ाइन किया गया है।
मोटा आकार इस प्रकार है:
find init
extract keys
find encrypted JIT body section
derive per method key
read body
write CilBody back
यह अभी भी पैटर्न-आधारित है। यदि स्टब पर्याप्त रूप से बदल गया है, तो यह चूक जाएगा, जाहिर है।
रिसोर्स को कॉन्स्टेंट के समान ही संभाला जाता है: एन्क्रिप्टेड रिसोर्स ब्लॉब ढूंढें, कुंजी/डिक्रिप्टर आकार पुनर्प्राप्त करें, डिक्रिप्ट करें, यदि आवश्यक हो तो डीकंप्रेस करें, फिर रिसोर्स को वहाँ रखें जहाँ सामान्य .NET टूलिंग उन्हें अपेक्षा करती है।
एक वैकल्पिक एम्बेडेड PE पुनर्निर्माण पथ भी है। कुछ संरक्षित सैंपल एक प्रबंधित PE को एक रिसोर्स के अंदर ले जाते हैं। पुनर्निर्माण सक्षम होने पर, रिमूवर उस पेलोड को भी पार्स करने और फिर से लिखने का प्रयास करता है, बजाय इसके कि एक डी-ऑबफस्केटेड बाहरी असेंबली को एक अछूते आंतरिक असेंबली के साथ छोड़ दिया जाए।
UnConfuserEx.exe sample.exe sample.clean.exe --rebuild-embedded-pe
इसका उपयोग तब करें जब आप जानते हों कि सैंपल रिसोर्स के अंदर एक और प्रबंधित असेंबली छुपाता है। यदि पेलोड एक प्रबंधित PE नहीं है, तो पुनर्निर्माण पथ उसे अकेला छोड़ देगा।
इसे बनाएँ:
dotnet build .\UnConfuserEx.sln -c Release
इसे चलाएँ:
.\UnConfuserEx\bin\Release\net9.0\UnConfuserEx.exe .\protected.exe
या एक स्पष्ट आउटपुट पथ दें:
.\UnConfuserEx\bin\Release\net9.0\UnConfuserEx.exe .\protected.exe .\protected.clean.exe
यदि आप आउटपुट पथ नहीं देते हैं, तो यह इनपुट के बगल में -deobfuscated जोड़कर एक फाइल लिखता है।
एम्बेडेड प्रबंधित पेलोड के लिए:
.\UnConfuserEx\bin\Release\net9.0\UnConfuserEx.exe .\protected.exe .\protected.clean.exe --rebuild-embedded-pe
यह वर्तमान समर्थन सूची है। इसका मतलब यह नहीं है कि हर संभव ConfuserEx फोर्क काम करता है। इसका मतलब है कि पाइपलाइन इन आकृतियों की तलाश करना जानती है।
कोड में शायद और भी छिपा हुआ है जिसे मैं सूचीबद्ध करना भूल गया xD।
उपयोगी लॉग वे हैं जो बताते हैं कि कौन सा स्टेज विफल हुआ, न कि केवल यह कि आउटपुट नहीं चला।
एक कॉन्स्टेंट पथ का उदाहरण जो ठीक किया गया:
Constants detected, attempting to remove
Found 3 constant getter(s)
Detected constant decryption type is Dynamic
Decompressed constants blob to 18492 byte(s)
Resolving getter <Module>::???????? as String with 41 call site method(s)
Removed all instances of getter <Module>::????????
एक कंट्रोल-फ्लो मेथड का उदाहरण जिसे जानबूझकर अकेला छोड़ दिया गया:
Removing obfuscation from method System.Void Example::Run()
Method System.Void Example::Run() still appears obfuscated after deobfuscation -- left original body intact
Removed obfuscation from 42 methods. Failed to remove from 0 methods. 1 methods left untouched
वह दूसरा लॉग सही नहीं है, लेकिन कम से कम ईमानदार है
एक कस्टम ConfuserEx फोर्क जो हर हेल्पर आकार को बदलता है।
एक कॉन्स्टेंट्स गेटर जो अपने ID की गणना पूर्ण cf मेस के माध्यम से करता है, न कि एक छोटे स्टैक एक्सप्रेशन के माध्यम से।
एक cf ग्राफ जहाँ डिस्पैचर रनटाइम मूल्यों पर निर्भर करता है जिन्हें स्थैतिक एम्युलेटर नहीं जानता।
नेटिव हेल्पर जिन्हें IL एम्युलेशन के बजाय वास्तविक रनटाइम निष्पादन की आवश्यकता होती है।
असेंबली जो ऑबफस्केटेड होने से पहले ही टूटी हुई थीं।
JIT एंटी-टैम्पर वेरिएंट जिनमें एक अलग एन्क्रिप्टेड बॉडी लेआउट होता है।
यदि आप चाहते हैं कि कोई इश्यू उपयोगी हो, तो इसे पुन: पेश करने के लिए पर्याप्त डेटा शामिल करें।
सैंपल अपलोड करने से पहले उनमें से फ़ाइल एक्सटेंशन हटा दें।
सब कुछ एक साथ आर्काइव करें और इसे शामिल करें:
Command:
UnConfuserEx.exe <target> <optional output>
Failure stage:
- compressor
- anti tamper
- constants
- control flow
- resources
- writing output
- runtime after deobfuscation
Expected result:
Actual result:
Console output:
Archive link:
Notes / investigation:
यदि आप केवल "काम नहीं करता" भेजते हैं, तो उत्तर संभवतः "हाँ" होगा।




छोटे केंद्रित सुधार बड़े पुनर्लेखन से बेहतर हैं।
यदि आप एक नए प्रोटेक्शन आकार के लिए समर्थन जोड़ते हैं, तो इसे उस रिमूवर के लिए अलग रखें जो इसका मालिक है। यदि आप फ़ॉलबैक व्यवहार जोड़ते हैं, तो सुनिश्चित करें कि विफलता आउटपुट असेंबली को दूषित न करे। यदि आप कंट्रोल फ़्लो को छूते हैं, तो मान लें कि आपने जिस अजीब सैंपल को ठीक किया है वह एकमात्र अजीब सैंपल नहीं है :DDD।
बस टूल को डीबग करने में कठिन न बनाएँ।
यह प्रोजेक्ट MadMin3r/UnconfuserEx पर आधारित है।
मूल प्रोजेक्ट ने नींव और अधिकांश कोर डी-ऑबफस्केशन पाइपलाइन प्रदान की। यह फोर्क विश्वसनीयता में सुधार, अतिरिक्त प्रोटेक्शन वेरिएंट के लिए समर्थन जोड़ने और वास्तविक दुनिया के सैंपल में देखे गए किनारे के मामलों को संभालने पर केंद्रित है।
यह प्रोजेक्ट एक सॉफ्टवेयर इंजीनियरिंग अभ्यास के बजाय एक व्यावहारिक रिवर्स-इंजीनियरिंग टूल के रूप में शुरू हुआ। ध्यान हमेशा सही कोड गुणवत्ता बनाए रखने के बजाय संरक्षित असेंबली को विश्वसनीय रूप से पुनर्प्राप्त करने पर रहा है।
यह टूल अधिकृत मैलवेयर विश्लेषण, रिवर्स इंजीनियरिंग, सॉफ्टवेयर रिकवरी, इंटरऑपरेबिलिटी और शैक्षिक अनुसंधान के लिए है।
उपयोगकर्ता लागू कानूनों का पालन करने और सॉफ्टवेयर या सिस्टम का विश्लेषण, एक्सेस या प्रोसेस करने से पहले किसी भी आवश्यक प्राधिकरण को प्राप्त करने के लिए जिम्मेदार हैं।
Zypherion Technologies इस टूल के अवैध उपयोग को अधिकृत नहीं करता है और तीसरे पक्ष द्वारा दुरुपयोग के लिए दायित्व को अस्वीकार करता है।
इस रिपॉजिटरी या www.zypherion.tech पर कुछ भी कानूनी सलाह नहीं है।