
कोड डीऑब्फस्केशन फ्रेमवर्क जो मिक्स्ड बूलियन-अरिथमेटिक (MBA) एक्सप्रेशन्स को सरल बनाता है
लेखक: Tim Blazytko और Moritz Schloegel
msynth एक कोड डीऑब्फस्केशन फ्रेमवर्क है जो Mixed Boolean-Arithmetic (MBA) व्यंजकों को सरल बनाता है। एक पूर्व-गणना किए गए सरलीकरण ओरेकल को देखते हुए, यह एक अमूर्त सिंटैक्स ट्री (AST) के रूप में प्रस्तुत एक जटिल व्यंजक पर चलता है और विभिन्न बीजीय और अर्थपूर्ण सरलीकरण तकनीकों का उपयोग करके उप-ट्री को सरल बनाने का प्रयास करता है। वैकल्पिक रूप से, यह स्टोकेस्टिक प्रोग्राम संश्लेषण के माध्यम से व्यंजकों को सरल बनाने का प्रयास करता है।
msynth Miasm के ऊपर बनाया गया है और निम्नलिखित शोध पत्रों से प्रेरित है
"QSynth: A Program Synthesis based Approach for Binary Code Deobfuscation" — Robin David, Luigi Coniglio और Mariano Ceccato (NDSS, BAR 2020),
"Syntia: Synthesizing the Semantics of Obfuscated Code" — Tim Blazytko, Moritz Contag, Cornelius Aschermann और Thorsten Holz (USENIX Security 2017) और
"Search-Based Local Blackbox Deobfuscation: Understand, Improve and Mitigate" — Grégoire Menguy, Sébastien Bardin, Richard Bonichon और Cauim de Souza de Lima (CCS 2021)।
"Augmenting Search-based Program Synthesis with Local Inference Rules to Improve Black-box Deobfuscation" — Vidal Attias, Nicolas Bellec, Grégoire Menguy, Sébastien Bardin और Jean-Yves Marion (CCS 2025)।
"Efficient Deobfuscation of Linear Mixed Boolean-Arithmetic Expressions" — Benjamin Reichenwallner और Peter Meerwald-Stadler (CheckMATE 2022) और
"Simplification of General Mixed Boolean-Arithmetic Expressions: GAMBA" — Benjamin Reichenwallner और Peter Meerwald-Stadler (WORMA 2023)।
इसका उपयोग Miasm के सिंबॉलिक एक्ज़ीक्यूशन इंजन के साथ मिलाकर ऑब्फस्केटेड कोड में जटिल व्यंजकों को सरल बनाने के लिए किया जा सकता है, या MBA सरलीकरण के साथ प्रयोग करने के लिए एक स्टैंडअलोन टूल के रूप में भी।
original: {((((((((RSI[0:32] ^ 0xFFFFFFFF) & RDX[0:32]) + RSI[0:32]) ^ 0xFFFFFFFF) & RDX[0:32]) + ((RSI[0:32] ^ 0xFFFFFFFF) & RDX[0:32]) + RSI[0:32]) & (RDX[0:32] ^ 0xFFFFFFFF)) + -(((((((RSI[0:32] ^ 0xFFFFFFFF) & RDX[0:32]) + RSI[0:32]) ^ 0xFFFFFFFF) & RDX[0:32]) + ((RSI[0:32] ^ 0xFFFFFFFF) & RDX[0:32]) + RSI[0:32]) | (((RSI[0:32] ^ 0xFFFFFFFF) & RDX[0:32]) + RSI[0:32])) + ({RDI[0:32] & ({RDI[0:32] & RSI[0:32] 0 32, 0x0 32 64} * 0x2 + {RDI[0:32] ^ RSI[0:32] 0 32, 0x0 32 64})[0:32] 0 32, 0x0 32 64} * 0x2 + {((((RSI[0:32] ^ 0xFFFFFFFF) & RDX[0:32]) + RSI[0:32]) & RSI[0:32]) + (((RDI + {(RDI[0:32] ^ 0xFFFFFFFF) | RDX[0:32] 0 32, 0x0 32 64} + 0x1)[0:32] ^ 0xFFFFFFFF) & RDX[0:32]) + (RDI[0:32] ^ ({RDI[0:32] & RSI[0:32] 0 32, 0x0 32 64} * 0x2 + {RDI[0:32] ^ RSI[0:32] 0 32, 0x0 32 64})[0:32]) + ((RDI[0:32] ^ 0xFFFFFFFF) | RDX[0:32]) + (RDI + RDX + 0x1)[0:32] 0 32, 0x0 32 64})[0:32]) * 0x2 0 32, 0x0 32 64}
simplified: {(-RDX[0:32] + ((RDI[0:32] + RDX[0:32] + RSI[0:32]) << 0x1)) * 0x2 0 32, 0x0 32 64}
msynth को इंस्टॉल करने के लिए इन चरणों का पालन करें:
git clone https://github.com/mrphrazer/msynth.git
cd msynth
# optionally: use a virtual environment
python -m venv msynth-env
source msynth-env/bin/activate
# install dependencies
pip install -r requirements.txt
# install msynth
pip install .
# unzip database
unzip -d database -q database/3_variables_constants_7_nodes.txt.zip
किसी मौजूदा एनवायरनमेंट को अपडेट करते समय, पिन किए गए Miasm कमिट को प्राप्त करने के लिए निर्भरताओं को पुनः इंस्टॉल करें। भिन्न Miasm कमिट एक ही पैकेज संस्करण रिपोर्ट कर सकते हैं, इसलिए एक सामान्य इंस्टॉल पुराने कमिट को इंस्टॉल किए हुए छोड़ सकता है:
python -m pip install --force-reinstall -r requirements.txt
एक ओरेकल उत्पन्न करने के लिए, हमें एक सरलीकरण लुकअप तालिका (या डेटाबेस) की आवश्यकता होती है जिसमें बड़ी संख्या में व्यंजक हों। हमने निम्नलिखित विशिष्टताओं के अनुसार 8, 16, 32 और 64 बिट आकार वाले व्यंजकों को पूर्व-गणना करने के लिए एक गणनात्मक खोज (enumerative search) का उपयोग किया:
अधिकतम पाँच चर p0, p1, p2, p3 और p4
चरों को (यदि आवश्यक हो) 32, 16 और 8 बिट तक नीचे लाने के लिए ट्रंकेशन ऑपरेटर,
बिट वेक्टर संक्रियाएँ: जोड़, घटाव, गुणा, नेगेशन (यूनरी माइनस), बिटवाइज़ and/or/xor/not और लॉजिकल शिफ्ट लेफ्ट,
और, कुछ तालिकाओं के लिए, स्थिरांक 0x0, 0x1, 0x2, 0x80, 0xff, 0x800, 0xffff, 0x8000_0000, 0xffff_ffff, 0x8000_0000_0000_0000 और 0xffff_ffff_ffff_ffff।
database में शामिल उदाहरण डेटाबेस में तीन चरों और स्थिरांकों 0x0, 0x1 और 0x2 का उपयोग करके अधिकतम 7 नोड्स के लिए बनाए गए सभी 1,293,020 संयोजन शामिल हैं (उदाहरण के लिए, ((p0 + p1) * (p2 ^ 0x2)) या ((p0 - p2) << (p1 + p2)))। बड़े पूर्व-गणना किए गए डेटाबेस यहाँ पाए जा सकते हैं (~31GB अनज़िप किए जाने पर)। ध्यान दें कि व्यंजकों को पूर्व-गणना करने का कोड इस रिपॉज़िटरी का हिस्सा नहीं है। हम इसे भविष्य में किसी समय जारी करने की योजना बना रहे हैं।
पूर्व-गणना किए गए लुकअप तालिकाओं के विकल्प के रूप में, msynth स्टोकेस्टिक प्रोग्राम संश्लेषण के माध्यम से व्यंजक सरलीकरण का समर्थन करता है। किसी दिए गए जटिल अंकगणितीय व्यंजक के लिए, msynth एक छोटा व्यंजक सीख सकता है जो समान इनपुट-आउटपुट व्यवहार साझा करता है। फिलहाल, इसे एक स्टैंडअलोन घटक के रूप में लागू किया गया है। हालाँकि, हम भविष्य में दोनों सरलीकरण दृष्टिकोणों को संयोजित करने की योजना बना रहे हैं।
संश्लेषण पथ डिफ़ॉल्ट रूप से Search Modulo Inference Rules (Smir) का भी उपयोग करता है, जो ऊपर लिंक किए गए CCS 2025 पेपर का अनुसरण करता है। Smir स्थानीय खोज को बढ़ाता है और कठिन-से-संश्लेषित पैटर्न जैसे मनमाने स्थिरांक, मास्क, स्थिर शिफ्ट और रोटेशन, एफ़ाइन व्यंजक, और परिबद्ध बहुपद व्यंजकों के लिए निकटवर्ती उम्मीदवार प्राप्त करता है।
पहले, आइए एक सरलीकरण ओरेकल उत्पन्न करें जो इनपुट के रूप में एक पूर्व-गणना किए गए सरलीकरण डेटाबेस का उपयोग करता है और इसमें शामिल व्यंजकों को तुल्यता वर्गों में समूहित करता है।
$ python scripts/gen_oracle.py database/3_variables_constants_7_nodes.txt oracle.pickle
msynth - INFO: Computing oracle for 30 variables and 50 samples.
Using library at 'database/3_variables_constants_7_nodes.txt'
msynth - INFO: Writing oracle to oracle.pickle
msynth - INFO: Done in 632.84 seconds
पूर्व-गणना किए गए सरलीकरण डेटाबेस के आकार के आधार पर, आपके कंप्यूटर के आधार पर इसमें कुछ मिनट या घंटे लग सकते हैं। वैकल्पिक रूप से, आप पूर्व-गणना किए गए oracle.pickle का उपयोग कर सकते हैं।
वैकल्पिक रूप से, --sqlite फ़्लैग का उपयोग SQLite प्रारूप में ओरेकल उत्पन्न करने के लिए किया जा सकता है, जो लेज़ी लोडिंग और काफी तेज़ स्टार्टअप समय को सक्षम करता है:
$ python scripts/gen_oracle.py database/3_variables_constants_7_nodes.txt oracle.db --sqlite
इसके बाद, सीरियलाइज़ किए गए ओरेकल का उपयोग जटिल व्यंजकों को सरल बनाने के लिए किया जा सकता है:
from msynth import Simplifier
# initialize simplifier
simplifier = Simplifier(oracle_path)
# simplify expression
simplified = simplifier.simplify(expression)
वैकल्पिक रूप से, हम प्रोग्राम संश्लेषण के माध्यम से जटिल व्यंजकों को सरल बना सकते हैं और समान इनपुट-आउटपुट व्यवहार वाले व्यंजक सीख सकते हैं:
from msynth import Synthesizer
# initialize synthesizer
synthesizer = Synthesizer()
# simplify via program synthesis
simplified = synthesizer.simplify(expression)