Skip to content
KitploitKITPLOIT
उपकरणब्लॉग
Log in
जमा करें
उपकरणब्लॉग
जमा करें

हैकिंग, पेनटेस्ट और साइबर सुरक्षा उपकरण आपके सुरक्षा शस्त्रागार के लिए!

Kitploit हैकिंग, साइबर सुरक्षा और पेंटेस्टिंग टूल्स की एक निर्देशिका है। कमजोरियों को खोजने, सिस्टम का विश्लेषण करने, परीक्षण को स्वचालित करने और अपनी सुरक्षा को मजबूत करने के लिए नवीनतम प्रोजेक्ट अपडेट खोजें।

फ़ीडसंपर्कगोपनीयता© 2026 Kitploit

टूल निर्देशिका

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
datadome-vm — नए Datadome VM का रिवर्स इंजीनियरिंग 🔥 | Kitploit
उपकरण/GitHubGitHub/xkiian/datadome-vm
गतिशील विश्लेषण (सैंडबॉक्सिंग)रिवर्स इंजीनियरिंगबाइनरी विश्लेषणलर्निंग और शिक्षाएंटी-बॉटकैप्चा बायपास
GitHubxkiian/datadome-vm

datadome-vm

नए Datadome VM का रिवर्स इंजीनियरिंग 🔥

रिपॉजिटरी देखें
12519637 महीने पहलेKitploit द्वारा समीक्षित

सबसे लोकप्रिय

सभी देखें →

हमारे समुदाय द्वारा सबसे अधिक उपयोग किए जाने वाले उपकरण खोजें।

सभी उपकरण खोजें

हमारे उपकरणों का संग्रह ब्राउज़ करें

सभी उपकरण देखें →
साझा करें

DataDome VM विश्लेषण

सारांश

यह रिपॉजिटरी DataDome के CAPTCHA/इंटरस्टीशियल फ़्लो में उपयोग किए जाने वाले ब्राउज़र-आंतरिक JavaScript वर्चुअल मशीन (VM) के पहले सार्वजनिक संस्करण का दस्तावेज़ीकरण करती है। इस विश्लेषण में शामिल हैं:

  • बाइटकोड लोडिंग और डिकोडिंग तंत्र
  • VM मेमोरी लेआउट और आर्किटेक्चर
  • एक प्रूफ-ऑफ-कॉन्सेप्ट डिसअसेम्बलर
  • नियंत्रण-प्रवाह विश्लेषण नोट्स

नोट: यह रिपॉजिटरी केवल एक (स्थिर) VM संस्करण को कवर करती है और सुरक्षा अनुसंधान एवं विश्लेषण उद्देश्यों के लिए है। इसमें डायनामिक सॉल्वर या उत्पादन सॉल्वर कार्यान्वयन शामिल नहीं हैं।

पृष्ठभूमि

14 जनवरी, 2026 को DataDome ने अपने क्लाइंट टैग में एक नया VM-आधारित घटक भेजना शुरू किया।

डिओबफ़स्केशन

VM कोड को कैप्चा चैलेंज से निकालकर vm.js (इस रिपॉजिटरी में उपलब्ध) में रखा गया है।

पहला कदम स्क्रिप्ट को डिओबफ़स्केट करना था:

ओबफ़स्केशन सीधा है: प्रत्येक वेरिएबल का मूल्यांकन करें और उसे उसके वास्तविक मान से बदलें। deobf.js में एक डिओबफ़स्केशन स्क्रिप्ट उपलब्ध है।

प्रारंभिक विश्लेषण

डिओबफ़स्केट किए गए कोड (out.js) को DevTools में चलाने पर VM का अपेक्षित आउटपुट दिखाई देता है:

आउटपुट एक JSON ऑब्जेक्ट है जिसमें दो संख्याएँ और एक स्ट्रिंग है। अब वास्तविक VM कार्यान्वयन में गोता लगाते हैं।

बाइटकोड डिकोडिंग

Q.exports फ़ंक्शन की शुरुआत में, हम देख सकते हैं कि बाइटकोड कैसे डिकोड किया जाता है:

  1. इनपुट स्ट्रिंग को बेस64 डिकोड किया जाता है
  2. लंबाई 129,263 की एक सरणी बनाई जाती है
  3. प्रत्येक इंडेक्स को एक विशिष्ट सीमा के विरुद्ध जाँचा जाता है:
    • यदि इंडेक्स सीमा के भीतर आता है, तो मान डिकोड किया जाता है
    • अन्यथा, एक यादृच्छिक संख्या लौटाई जाती है (B() का उपयोग करके, एक स्यूडो-रैंडम नंबर जनरेटर) -> D कुछ यादृच्छिक "शोर" के साथ डिकोड किए गए बाइटकोड को धारण करता है

VM आर्किटेक्चर

नीचे स्क्रॉल करने पर VM एंट्री पॉइंट दिखाई देता है: दो पैरामीटर A (बाइटकोड) और Q (एक खाली शब्दकोश जो त्रुटि प्रबंधन के लिए उपयोग होता है) वाला एक फ़ंक्शन।

मेमोरी लेआउट

इस VM का सबसे दिलचस्प पहलू इसकी आर्किटेक्चर है: सब कुछ एक ही सरणी (A) में रहता है। इस सरणी में शामिल हैं:

  • स्टैक
  • रजिस्टर
  • ऑपकोड
  • बाइटकोड स्वयं
  • इंस्ट्रक्शन पॉइंटर

यह डिज़ाइन विशिष्ट मेमोरी क्षेत्रों वाले वास्तविक कंप्यूटर आर्किटेक्चर को दर्शाता है। अगला कदम प्रत्येक ऑफ़सेट को मैप करना है ताकि यह समझा जा सके कि कहाँ क्या संग्रहीत है:

var stack_pointer = 4593
var instruction_pointer = 4635
var frame_base_pointer = 4674
var last_result = 4633
var exit_flag = 4656
var current_opcode_handler = 4685
var current_opcode_id = 4675
var stack_offset = 124482
var vm_start = 5258

इन ऑफ़सेट्स के मैप होने के बाद VM संरचना स्पष्ट हो जाती है।

सहायक फ़ंक्शन

VM सहायक फ़ंक्शनों के एक संग्रह से शुरू होता है जो संभालते हैं:

  • स्टैक से टाइप किए गए मान पढ़ना
  • स्टैक और "रजिस्टरों" के बीच डेटा ले जाना

VM आरंभीकरण

सहायक फ़ंक्शनों के बाद, VM मुख्य मानों को आरंभ करता है:

  • सभी पॉइंटर (स्टैक, इंस्ट्रक्शन, फ्रेम बेस)
  • एग्ज़िट फ्लैग
  • अंतिम परिणाम रजिस्टर

आरंभीकरण के नीचे सभी इंस्ट्रक्शन हैंडलर हैं।

डिस्पैचर लूप

डिस्पैचर मुख्य VM लूप है जो `exit_flag` सेट होने तक चलता है:
  • I वर्तमान इंस्ट्रक्शन को दर्शाता है
  • P सरणी में वास्तविक ऑफ़सेट है (ओबफ़स्केशन को ध्यान में रखते हुए)
  • लूप वर्तमान इंस्ट्रक्शन को current_opcode_handler पर सेट करता है और current_opcode_id को अपडेट करता है

ऑपकोड कार्यान्वयन

ऑपकोड कैसे काम करते हैं

यहाँ एक ऑपकोड हैंडलर का एक मूल उदाहरण है:

  1. बाइटकोड से एक तत्काल मान लाता है
  2. स्टैक से शीर्ष मान प्राप्त करता है
  3. एक संक्रिया करता है (जैसे %= या ^=)
  4. अंत में fetch() फ़ंक्शन को कॉल करता है

दिलचस्प ऑपकोड

ऑपकोड 4919: फ़ंक्शन/क्लोज़र निर्माण

सबसे जटिल ऑपकोडों में से एक क्लोज़र/फ़ंक्शन बनाता है:

A[4919] = function () {
    var Q = readUint8();  // अपेक्षित तर्कों की संख्या
    var B = [];
    for (var E = readUint8(), D = 0; D < E; D++) {
        var g = readUint8();
        var a = A[A[frame_base_pointer] + g];
        B.push(a);  // वर्तमान स्कोप से वेरिएबल कैप्चर करें
    }
    var h = A[instruction_pointer] + 3;  // फ़ंक्शन बॉडी का पता सहेजें
    A[A[stack_pointer]++] = function (E) {
        // कॉल होने पर नया स्टैक फ्रेम सेट करें
        var e = A[stack_pointer] - E;
        while (E < Q) {
            A[e + E++] = undefined;  // गुम तर्कों को undefined से भरें
        }
        A[stack_pointer] = e + Q;
        for (var D = 0; D < B.length; D++) {
            var g = B[D];
            A[A[stack_pointer]++] = g;  // कैप्चर किए गए वेरिएबल को पुश करें
        }
        A[e - 2] = A[frame_base_pointer];  // पुराना फ्रेम पॉइंटर सहेजें
        A[e - 1] = A[instruction_pointer];  // वापसी पता सहेजें
        A[frame_base_pointer] = e;
        A[instruction_pointer] = h;  // फ़ंक्शन बॉडी पर जाएं
    };
    fetch();
};

यह ऑपकोड:

  1. अपेक्षित तर्क गणना पढ़ता है
  2. वर्तमान स्कोप से वेरिएबल कैप्चर करता है (क्लोज़र)
  3. एक फ़ंक्शन बनाता है जो उचित कॉलिंग कन्वेंशन के साथ एक नया स्टैक फ्रेम सेट करता है
  4. गुम तर्कों को undefined से भरकर संभालता है
  5. उचित वापसी के लिए वापसी पता और फ्रेम पॉइंटर सहेजता है

ऑपकोड 5003: डायनामिक फ़ंक्शन कॉल

यह ऑपकोड फ़ंक्शन कॉल के लिए एक रैपर बनाता है जो नियमित और कंस्ट्रक्टर दोनों कॉल को संभालता है:

A[5003] = function () {
    var Q = A[--A[stack_pointer]];  // POP फ़ंक्शन
    var B = A[--A[stack_pointer]];  // POP 'this' संदर्भ

    function E(e) {  // e = तर्क गणना
        var D = A[stack_pointer];
        var g = A.slice(D - e, D);  // स्टैक से तर्क प्राप्त करें
        if (this instanceof E) {
            // कंस्ट्रक्टर कॉल (new E(...))
            g.unshift(null);
            var h = Function.prototype.bind.apply(Q, g);
            A[stack_pointer] -= e;
            try {
                a = new h();
            } catch (A) {
                a = A.message;
            }
            A[A[stack_pointer]++] = a;
        } else {
            // नियमित फ़ंक्शन कॉल
            var t;
            try {
                t = Q.apply(B, g);
            } catch (A) {
                t = A.message;
            }
            A[stack_pointer] -= e + 2;
            A[A[stack_pointer]++] = t;
        }
    }

    A[A[stack_pointer]++] = E;
    fetch();
};

यह ऑपकोड:

  1. फ़ंक्शन और संदर्भ को स्टैक से पॉप करता है
  2. एक रैपर बनाता है जिसे तर्कों के साथ कॉल किया जा सकता है
  3. पता लगाता है कि यह कंस्ट्रक्टर कॉल (new) है या नियमित कॉल
  4. उचित संदर्भ और त्रुटि प्रबंधन के साथ फ़ंक्शन को लागू करता है
  5. परिणाम को वापस स्टैक पर पुश करता है

ऑपकोड 4961: ऑब्जेक्ट लिटरल निर्माण

A[4961] = function () {
    var Q = {};
    for (var E = readUint16(), e = 0; e < E; e++) {
        var D = A[--A[stack_pointer]];  // पहला POP
        var g = A[--A[stack_pointer]];  // दूसरा POP
        Q[D] = g;
    }
    A[A[stack_pointer]++] = Q;
    fetch();
};
टूल डाउनलोड करें