
स्टैटिक डीऑबफस्केशन टूलकिट, संकलित V8 जावास्क्रिप्ट बाइटकोड के लिए, जो JSCeal पेलोड पर केंद्रित है। पैटर्न-आधारित फ़िल्टर, कंट्रोल-फ्लो अनफ्लैटनिंग, स्ट्रिंग पुनर्निर्माण, और विश्लेषण के लिए वैकल्पिक LLM-सहायता प्राप्त फ़ंक्शन नामकरण प्रदान करता है।
यह टूल javascript-obfuscator से सुरक्षित संकलित V8 JavaScript बाइटकोड को स्थैतिक रूप से डीऑबफस्केट करने के लिए समर्पित है।
यह मूल JavaScript स्रोत के बजाय View8 द्वारा उत्पादित स्यूडोकोड पर कार्य करता है। यह प्रोजेक्ट JSCeal पेलोड पर विकसित और परीक्षण किया गया था।
फ़िल्टर पैटर्न-संचालित हैं और मुख्य रूप से एक शोध टूलकिट और संदर्भ कार्यान्वयन के रूप में अभिप्रेत हैं। यह टूल नहीं है एक सामान्य-उद्देश्य JavaScript डीऑबफस्केटर, यह मूल स्रोत कोड का पुनर्निर्माण नहीं करता है, और चलने योग्य JavaScript उत्पन्न नहीं करता है। इसका आउटपुट View8 स्यूडोकोड ही रहता है जो स्थैतिक निरीक्षण, खोज, तुलना और फ़ंक्शन-ट्री निर्यात के लिए अभिप्रेत है।
pickle का उपयोग करती हैं। दुर्भावनापूर्ण या अविश्वसनीय .pkl फ़ाइल लोड करने से कोड निष्पादित हो सकता है। केवल उन क्रमबद्ध फ़ाइलों को लोड करें जिन्हें आपने स्थानीय रूप से View8 के साथ उत्पन्न किया है।requirements.txt से Python निर्भरताएँ;brotli कमांड-लाइन उपयोगिता;एक पृथक Python वातावरण बनाएँ:
python3 -m venv .venv
source .venv/bin/activate
python3 -m pip install --upgrade pip
python3 -m pip install -r requirements.txt
deobf_ai.py में OpenAI बैकएंड को अतिरिक्त रूप से OpenAI Python पैकेज की आवश्यकता होती है:
python3 -m pip install openai
Anthropic बैकएंड requests के माध्यम से HTTP API का उपयोग करता है। Ollama बैकएंड एक सुलभ Ollama सर्वर की अपेक्षा करता है।
मूल JSCeal app.jsc पेलोड Brotli-संपीड़ित है। Linux पर, इसे brotli उपयोगिता के साथ डीकंप्रेस किया जा सकता है:
brotli -d app.jsc -o app.decompressed.jsc
scripts/ के अंतर्गत बैच वर्कफ़्लो इस चरण को scripts/unpack_all.sh के साथ करता है।
Windows पर, या जब brotli कमांड-लाइन उपयोगिता अनुपलब्ध हो, तो शामिल Node.js सहायक का उपयोग फ़ॉलबैक के रूप में किया जा सकता है। यह केवल इनपुट को डीकंप्रेस करता है और इसे निष्पादित नहीं करता है:
node Utils/decompress-jsc.js app.jsc
यह लिखता है:
app.jsc.decompressed.jsc
V8 कोड कैश संस्करण-विशिष्ट है। पेलोड के समान V8 संस्करण के लिए निर्मित डिसअसेंबलर का उपयोग करें।
विकास के दौरान उपयोग किए गए JSCeal नमूने V8 10.2.154.26 पर आधारित थे। असंबंधित V8 बिल्ड के डिफ़ॉल्ट डिसअसेंबलर सही ढंग से काम नहीं करेंगे।
स्रोत ट्री में डिसअसेंबलर स्रोत और आवश्यक V8 पैच शामिल हैं:
Utils/disasm/v8dasm.cpp
Utils/disasm/patches/
एक पूर्व-निर्मित Linux बाइनरी प्रोजेक्ट रिलीज़ के साथ वितरित की जाती है, जबकि स्रोत ट्री में इसे पुनर्निर्माण करने के लिए आवश्यक स्रोत और पैच शामिल हैं। विस्तृत विवरण प्रोजेक्ट विकी पर उपलब्ध है। मिलान वाले v8dasm को प्राप्त करने या बनाने के बाद, चलाएँ:
/path/to/v8dasm app.decompressed.jsc > app.jsc.disasm.txt
डिसअसेंबल की गई फ़ाइल को view8.py में फ़ीड करें और आगे की प्रक्रिया के लिए क्रमबद्ध आउटपुट और मानव-पठनीय स्यूडोकोड दोनों उत्पन्न करें:
mkdir -p decompiled
python3 View8/view8.py \
--input_format disassembled \
--inp app.jsc.disasm.txt \
--normalize \
--out decompiled/app.dec.txt \
--export_format decompiled serialized
यह उत्पन्न करता है:
decompiled/app.dec.txt
decompiled/app.dec.pkl
--normalize विकल्प उत्पन्न फ़ंक्शन पहचानकर्ताओं को बार-बार डिसअसेंबली और डीकंपाइलेशन रनों में पुनरुत्पादनीय बनाता है।
व्यक्तिगत ऑबफस्केशन परतों के लिए अलग-अलग फ़िल्टर हैं। उन्हें deobf_all.py के साथ क्रमबद्ध View8 आउटपुट पर एक साथ लागू किया जा सकता है:
mkdir -p deobfuscated
python3 deobf_all.py \
--inp decompiled/app.dec.pkl \
--out deobfuscated/app.deobf.txt \
--export_format decompiled serialized
डिफ़ॉल्ट स्ट्रिंग फ़िल्टर वैरिएंट 2 है, जिसका उपयोग विश्लेषण किए गए अधिकांश JSCeal पेलोड द्वारा किया जाता है। सरल स्ट्रिंग योजना को स्पष्ट रूप से चुनने के लिए, जोड़ें:
--str_deobf 1
विशिष्ट आउटपुट हैं:
deobfuscated/app.deobf.txt
deobfuscated/app.deobf.pkl
deobfuscated/app.deobf.txt.strings.txt
decompiled/app.dec.resolved_funcs.csv
रिज़ॉल्व्ड-फ़ंक्शन CSV एक नमूना-विशिष्ट कैश है। जब यह अनुपस्थित होता है, तो स्ट्रिंग पास आवश्यक डिकोडर कॉन्फ़िगरेशन को पुनर्प्राप्त करता है, CSV लिखता है, और उसी रन में स्ट्रिंग्स को डीऑबफस्केट करना जारी रखता है। बाद के रन कैश का पुन: उपयोग करते हैं और आमतौर पर तेज़ होते हैं।
किसी भिन्न डीकंपाइल किए गए पेलोड के साथ रिज़ॉल्व्ड-फ़ंक्शन CSV का पुन: उपयोग न करें।
सभी संरचनात्मक डीऑबफस्केशन फ़िल्टर लागू होने के बाद, deobf_ai.py फ़ंक्शन व्यवहार का वर्णन करने वाले नाम प्रस्तावित कर सकता है। यह Anthropic, OpenAI और Ollama बैकएंड का समर्थन करता है।
मॉडल को स्पष्ट रूप से पास करें ताकि रन पुनरुत्पादनीय रहें।
export ANTHROPIC_API_KEY='...'
python3 deobf_ai.py \
--inp deobfuscated/app.deobf.pkl \
--out deobfuscated/app.renamed.txt \
--llm_backend anthropic \
--model '<model-id>' \
--export_format decompiled serialized
export OPENAI_API_KEY='...'
python3 deobf_ai.py \
--inp deobfuscated/app.deobf.pkl \
--out deobfuscated/app.renamed.txt \
--llm_backend openai \
--model '<model-id>' \
--export_format decompiled serialized
python3 deobf_ai.py \
--inp deobfuscated/app.deobf.pkl \
--out deobfuscated/app.renamed.txt \
--llm_backend ollama \
--model '<local-model>' \
--ollama_url http://localhost:11434 \
--export_format decompiled serialized
डिफ़ॉल्ट मोड में, रीनामर प्रवेश फ़ंक्शन से शुरू होकर एक प्रत्यक्ष-कॉल ट्री बनाता है और केवल कॉल के माध्यम से पहुंचे गए फ़ंक्शनों का नाम बदलता है। कॉलबैक और असाइन किए गए हैंडलर सहित सभी दृश्यमान फ़ंक्शन संदर्भों को शामिल करने के लिए --greedy जोड़ें।
उत्पन्न दो-स्तंभ CSV एक कैश के रूप में कार्य करता है और एक बाधित रन को जारी रखने की अनुमति देता है। --csv के साथ एक मौजूदा कैश स्पष्ट रूप से चुनें:
python3 deobf_ai.py \
--inp deobfuscated/app.deobf.pkl \
--out deobfuscated/app.renamed.txt \
--csv deobfuscated/app.deobf.renamed_funcs.greedy.example-model.csv \
--llm_backend anthropic \
--model '<model-id>' \
--greedy \
--export_format decompiled serialized
सामान्य मोड में, CSV को संभावित आंशिक कैश के रूप में माना जाता है। कैश किए गए नाम पहले लागू किए जाते हैं, कैश द्वारा पहले से कवर किए गए फ़ंक्शन चयनित कॉल या संदर्भ ट्री से हटा दिए जाते हैं, और LLM को केवल उन फ़ंक्शनों के लिए बुलाया जाता है जो अनसुलझे रहते हैं। यदि CSV उस ट्री को पूरी तरह से कवर करता है, तो कोई API कुंजी या LLM कनेक्शन आवश्यक नहीं है। यदि यह केवल ट्री के एक हिस्से को कवर करता है, तो चयनित बैकएंड प्रारंभ किया जाता है और नए उत्पन्न मैपिंग उसी CSV में जोड़ दिए जाते हैं।
उसी ट्री मोड का उपयोग करें जो CSV बनाते समय उपयोग किया गया था। एक --greedy रन से उत्पन्न CSV को सामान्य रूप से फिर से --greedy की आवश्यकता होती है यदि लक्ष्य उस रन को जारी रखना है न कि केवल प्रत्यक्ष-कॉल सबसेट का पुन: उपयोग करना।
--apply-csv-only का उपयोग करें जब CSV में पहले से वे लेबल हों जिन्हें आप लागू करना चाहते हैं, जिसमें समीक्षित, संपादित, आयातित या रीबेस्ड मैपिंग शामिल हैं:
python3 deobf_ai.py \
--inp deobfuscated/app.deobf.pkl \
--out deobfuscated/app.renamed.txt \
--csv renamed_functions.normalized.csv \
--apply-csv-only \
--export_format decompiled serialized
यह मोड:
--csv की आवश्यकता है;--func के साथ संयोजित नहीं किया जा सकता है।जिन पंक्तियों का मूल फ़ंक्शन पहचानकर्ता इनपुट में मौजूद नहीं है, उन्हें अनदेखा किया जाता है। कमांड तब विफल हो जाता है जब CSV में लोड की गई फ़ाइल पर लागू होने वाली कोई मैपिंग नहीं होती है।
एक डीऑबफस्केटेड फ़ंक्शन के केंद्रित शब्दार्थ विश्लेषण का अनुरोध करने के लिए सटीक पूर्ण फ़ंक्शन पहचानकर्ता के साथ --func का उपयोग करें:
python3 deobf_ai.py \
--inp deobfuscated/app.deobf.pkl \
--func func_example_0x100001234 \
--llm_backend anthropic \
--model '<model-id>'
विश्लेषण में एक प्रस्तावित नाम, व्यवहार सारांश, इनपुट और रिटर्न मान, दुष्प्रभाव, चरण-दर-चरण तर्क, साफ़ किया गया स्यूडोकोड, सहायक साक्ष्य और अनसुलझी अनिश्चितताएँ शामिल हैं। --csv प्रदान करना लोड किए गए कॉर्पस को संशोधित किए बिना चयनित फ़ंक्शन के अंदर संदर्भों के लिए संदर्भ के रूप में कैश किए गए शब्दार्थ नाम जोड़ता है। रिपोर्ट को Markdown के रूप में सहेजने के लिए --analysis-out analysis/function.md का उपयोग करें। फ़ज़ी मैच केवल सुझावों के रूप में मुद्रित होते हैं; अनुरोधित फ़ंक्शन पहचानकर्ता बिल्कुल मेल खाना चाहिए।
तापमान, बैचिंग, Anthropic सोच मोड, टोकन सीमा और कस्टम CSV पथों को नियंत्रित करने वाले विकल्पों के लिए --help का उपयोग करें।
LLM-जनित नाम नेविगेशन सहायक हैं, साक्ष्य नहीं। उन्हें हमेशा डीऑबफस्केटेड बॉडी के विरुद्ध सत्यापित करें।
डीऑबफस्केटेड JSCeal आउटपुट आमतौर पर बहुत बड़ा होता है। क्रमबद्ध आउटपुट को वापस View8 में लोड करें और इसे छोटे फ़ंक्शन ट्री में विभाजित करें।
इस चरण में, --scope 0 जोड़ें। स्कोप प्रसार पहले ही डीऑबफस्केटर द्वारा किया जा चुका है, और इसे दोहराने से मान गलत तरीके से प्रसारित हो सकते हैं।
घोषणाकर्ता संबंधों पर आधारित एक ट्री:
python3 View8/view8.py \
--input_format serialized \
--inp deobfuscated/app.deobf.pkl \
--out trees/declarers \
--export_format decompiled \
--tree start \
--scope 0
एक संक्षिप्त प्रत्यक्ष-कॉल अवलोकन:
python3 View8/view8.py \
--input_format serialized \
--inp deobfuscated/app.deobf.pkl \
--out trees/calls \
--export_format decompiled \
--tree start \
--scope 0 \
--split_mode calls \
--inline_depth 1 \
--split_depth 5
एक व्यापक संदर्भ ट्री, जिसमें कॉलबैक और असाइन किए गए हैंडलर शामिल हैं:
python3 View8/view8.py \
--input_format serialized \
--inp deobfuscated/app.deobf.pkl \
--out trees/references \
--export_format decompiled \
--tree start \
--scope 0 \
--split_mode references \
--inline_depth 1 \
--split_depth 3
विभिन्न JSC फ़ाइलें विभिन्न स्ट्रिंग-ऑबफस्केशन मोड का उपयोग कर सकती हैं।
सबसे सरल देखा गया मोड इंडेक्स शिफ्टिंग का उपयोग करता है और इसे deobf_str1.py द्वारा संभाला जाता है। सबसे सामान्य JSCeal मोड Base64, RC4, चंक्ड स्ट्रिंग्स और रूपांतरित इंडेक्स का उपयोग करता है; इसे deobf_str2.py द्वारा संभाला जाता है।
पूर्ण पाइपलाइन डिफ़ॉल्ट रूप से वैरिएंट 2 का चयन करती है। फ़िल्टर परीक्षण के लिए स्वतंत्र रूप से भी चलाए जा सकते हैं।
deobf_str2.pyसभी उपलब्ध मोड और विकल्प प्रदर्शित करने के लिए --help का उपयोग करें:
python3 deobf_str2.py --help
एक सीधा स्ट्रिंग-डीऑबफस्केशन रन इसके साथ शुरू किया जा सकता है:
python3 deobf_str2.py \
--inp decompiled/app.dec.pkl \
--out work/app.strings.txt \
--export_format decompiled serialized
रन के दौरान, स्क्रिप्ट स्ट्रिंग-डिकोडर फ़ंक्शनों की पहचान करता है, किसी भी मान्य कैश किए गए कॉन्फ़िगरेशन को लोड करता है, लापता को हल करता है, परिणामी CSV सहेजता है और स्ट्रिंग्स को डिकोड करता है। दूसरे रन की आवश्यकता नहीं है।
जब deobf_str2.py सीधे उपयोग किया जाता है, तो इसका डिफ़ॉल्ट CSV नाम resolved_funcs.csv होता है। --csv या -c के साथ एक नमूना-विशिष्ट पथ चुनें:
python3 deobf_str2.py \
--inp decompiled/app.dec.pkl \
--out work/app.strings.txt \
--csv decompiled/app.dec.resolved_funcs.csv \
--export_format decompiled serialized \
--verbosity 1
व्यक्तिगत फ़िल्टर श्रृंखलित करते समय, बाद के पास View8 ऑब्जेक्ट्स पर काम करना जारी रख सकें, इसके लिए चरणों के बीच क्रमबद्ध आउटपुट संरक्षित करें।
deobf_all.py निम्नलिखित चरणों को क्रम में लागू करता है:
LLM-सहायता प्राप्त फ़ंक्शन रीनामिंग वैकल्पिक है और संरचनात्मक डीऑबफस्केशन के बाद अलग से चलाया जाता है।
रिपॉजिटरी में scripts/ के अंतर्गत एक पूर्ण सहायक वर्कफ़्लो शामिल है। सभी स्क्रिप्ट एक निर्देशिका में रखी जाती हैं और समान केंद्रीकृत कॉन्फ़िगरेशन को स्रोत करती हैं।
scripts/config.sh साझा टूल और कार्यक्षेत्र पथ
scripts/copy_payloads.sh JSCeal app.jsc फ़ाइलें एकत्र करें और MD5-नाम दें
scripts/unpack_all.sh Brotli डीकंप्रेसन
scripts/disasm_all.sh बैच V8 डिसअसेंबली
scripts/decompile_all.sh बैच View8 डीकंपाइलेशन
scripts/deobfuscate_all.sh संयुक्त लॉग के साथ बैच डीऑबफस्केशन
scripts/run_unattended.sh अलग डीऑबफस्केशन और सत्यापन
scripts/collect_output.sh डिकोडर कैश और स्ट्रिंग सूचियाँ एकत्र करें
आपूर्ति किया गया scripts/config.sh एक उदाहरण वातावरण से पथ शामिल करता है:
JSC_DEOBF_ROOT="$HOME/jsc_deobfuscator"
V8DASM="$HOME/code/v8/v8dasm"
इंस्टॉलेशन पथ, मिलान V8 डिसअसेंबलर, कार्यक्षेत्र निर्देशिकाएँ, बाहरी कमांड, लॉग पथ और हार्वेस्ट लेआउट को कॉन्फ़िगर करने के लिए उस फ़ाइल को एक बार संपादित करें। कार्यक्षेत्र डिफ़ॉल्ट रूप से उस निर्देशिका पर जाता है जहाँ से सहायक स्क्रिप्ट लॉन्च की जाती है।
प्रत्येक मान को पर्यावरण चर के माध्यम से भी ओवरराइड किया जा सकता है। JSC_HELPER_CONFIG एक अलग कॉन्फ़िगरेशन फ़ाइल का चयन कर सकता है।
एक विशिष्ट बैच रन है:
scripts/copy_payloads.sh
scripts/unpack_all.sh
scripts/disasm_all.sh
scripts/decompile_all.sh
scripts/deobfuscate_all.sh
scripts/collect_output.sh
स्क्रिप्ट JSCeal कॉर्पस के लिए उपयोग की जाने वाली परंपराओं को संरक्षित करती हैं, जिसमें खोजी गई app.jsc फ़ाइलों को Brotli-संपीड़ित पेलोड के रूप में मानना और उन्हें MD5 द्वारा नाम देना शामिल है। वर्कफ़्लो को असंबंधित नमूनों पर लागू करने से पहले scripts/README.md की समीक्षा करें।
लंबे बैच के लिए, scripts/run_unattended.sh nohup के साथ डीऑबफस्केशन लॉन्च करता है, टाइमस्टैम्प्ड लॉग, PID और स्थिति फ़ाइलें लिखता है, और कैश किए गए स्ट्रिंग-डिकोडर फ़ंक्शनों के अनसुलझे संदर्भों के लिए प्रत्येक उत्पन्न आउटपुट को मान्य करता है:
scripts/run_unattended.sh
चयनित नमूने स्पष्ट रूप से प्रदान किए जा सकते हैं:
scripts/run_unattended.sh \
decompiled/sample1.dec.pkl \
decompiled/sample2.dec.pkl
View8/ View8 डीकंपाइलर और फ़ंक्शन-ट्री निर्यातक
Utils/decompress-jsc.js Windows के लिए Brotli डीकंप्रेसन फ़ॉलबैक
Utils/disasm/v8dasm.cpp V8 डिसअसेंबलर स्रोत
Utils/disasm/patches/ डिसअसेंबलर द्वारा आवश्यक V8 पैच
Utils/check_unresolved_decoder_references.py
आउटपुट सत्यापन सहायक
deobf_all.py पूर्ण डिफ़ॉल्ट डीऑबफस्केशन पाइपलाइन
deobf_str1.py सरल स्ट्रिंग-इंडेक्स-शिफ्ट फ़िल्टर
deobf_str2.py इंडेक्स पुनर्प्राप्ति के साथ RC4/Base64 स्ट्रिंग फ़िल्टर
deobf_scope2.py स्कोप और शब्दकोश प्रसार
deobf_unflattener.py नियंत्रण-प्रवाह अनफ़्लैटनिंग
deobf_replace_ops.py प्रॉक्सी और ऑपरेशन-रैपर प्रतिस्थापन
deobf_globals.py वैश्विक प्रसार
deobf_inline_temporaries.py रूढ़िवादी अंतिम सफाई
deobf_ai.py वैकल्पिक LLM-सहायता प्राप्त फ़ंक्शन रीनामिंग
scripts/ कॉन्फ़िगर करने योग्य बैच और सत्यापन सहायक
प्रत्येक प्रमुख पास को परीक्षण के लिए अलग से निष्पादित किया जा सकता है। इसका पूर्ण इंटरफ़ेस देखने के लिए चयनित स्क्रिप्ट को --help के साथ चलाएँ:
python3 deobf_str1.py --help
python3 deobf_str2.py --help
python3 deobf_scope2.py --help
python3 deobf_unflattener.py --help
python3 deobf_replace_ops.py --help
python3 deobf_globals.py --help
python3 deobf_inline_temporaries.py --help
javascript-obfuscator आउटपुट में देखे गए पैटर्न को पहचानता है। नए वेरिएंट के लिए अतिरिक्त डिटेक्टर या परिवर्तन की आवश्यकता हो सकती है।