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

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

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

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

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

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
P4wnP1_aloa — P4wnP1 A.L.O.A. by MaMe82 एक फ्रेमवर्क है जो Rapsberry Pi Zero W को एक लचीला, कम लागत वाला प्लेटफॉर्म बनाता है पेंटेस्टिंग, रेड टीमिंग और फिजिकल एंगेजमेंट्स के लिए ... या "ए लिटिल ऑफेंसिव एप्लायंस" में। | Kitploit
उपकरण/GitHubGitHub/rogandawes/p4wnp1_aloa
वाई-फाई ऑडिटिंगब्लूटूथ सुरक्षाशोषण फ्रेमवर्कनेटवर्क मैपिंगहार्डवेयर हैकिंगपेनिट्रेशन टेस्टिंगरेड टीमिंगपेलोड डेवलपमेंट
GitHubrogandawes/p4wnp1_aloa

P4wnP1_aloa

P4wnP1 A.L.O.A. by MaMe82 एक फ्रेमवर्क है जो Rapsberry Pi Zero W को एक लचीला, कम लागत वाला प्लेटफॉर्म बनाता है पेंटेस्टिंग, रेड टीमिंग और फिजिकल एंगेजमेंट्स के लिए ... या "ए लिटिल ऑफेंसिव एप्लायंस" में।

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

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

सभी देखें →

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

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

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

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

P4wnP1 A.L.O.A.

P4wnP1 A.L.O.A. द्वारा MaMe82 एक ढाँचा है जो Rapsberry Pi Zero W को एक लचीले, कम लागत वाले प्लेटफ़ॉर्म में बदल देता है पेंटेस्टिंग, रेड टीमिंग और भौतिक कार्यों के लिए ... या "एक छोटी सी आक्रामक उपकरण" में।

0. कैसे स्थापित करें

नवीनतम छवि रिलीज़ टैब के अंतर्गत मिल सकती है।

एक ताज़ा P4wnP1 A.L.O.A. स्थापना तक पहुँचने का सबसे आसान तरीका वेब क्लाइंट का उपयोग करना है जो उत्पन्न WiFi के माध्यम से होता है (PSK MaMe82-P4wnP1 है, URL http://172.24.0.1:8000) या SSH (डिफ़ॉल्ट पासवर्ड toor है)।

1. विशेषताएँ

प्लग & प्ले USB उपकरण अनुकरण

  • USB कार्य:
    • USB ईथरनेट (RNDIS और CDC ECM)
    • USB सीरियल
    • USB मास स्टोरेज (फ्लैशड्राइव या CD-Rom)
    • HID कीबोर्ड
    • HID माउस
  • USB स्टैक का रनटाइम पुनर्विन्यास (कोई रीबूट नहीं)
  • कनेक्ट/डिस्कनेक्ट का पता लगाने से P4wnP1 A.L.O.A. को चालू रखना संभव हो जाता है (बाहरी आपूर्ति) और ट्रिगर कार्रवाई करना यदि अनुकरणित USB उपकरण किसी नए होस्ट से जुड़ा है
  • विभिन्न आंतरिक ईथरनेट इंटरफ़ेस से निपटने की आवश्यकता नहीं, क्योंकि CDC ECM और RNDIS एक वर्चुअल ब्रिज से जुड़े हैं
  • USB सेटिंग्स के लिए कॉन्फ़िगरेशन टेम्पलेट्स का लगातार भंडारण और लोड

HIDScript

  • सीमित DuckyScript के लिए प्रतिस्थापन
  • कीबोर्ड और माउस को स्वचालित करने के लिए परिष्कृत स्क्रिप्टिंग भाषा
  • 8 HIDScript जॉब तक समानांतर में चल सकते हैं (एक जॉब को माउस झटकने के लिए चालू रखें, जबकि अन्य मांग पर शुरू होते हैं) मनमाने माउस और कीस्ट्रोक इंजेक्शन को निर्बाध रूप से करने के लिए
  • HIDScript JavaScript पर आधारित है, जिसमें सामान्य पुस्तकालय उपलब्ध हैं, जो अधिक जटिल स्क्रिप्ट की अनुमति देता है (फ़ंक्शन कॉल, माउस गणनाओं के लिए Math का उपयोग आदि)
  • कीबोर्ड
    • UTF-8 पर आधारित, इसलिए ASCII वर्णों तक सीमित नहीं
    • NUMLOCK, CAPSLOCK और SCROLLLOCK के LED स्थिति परिवर्तनों को पढ़कर होस्ट के वास्तविक कीबोर्ड से प्रतिक्रिया पर प्रतिक्रिया कर सकता है (यदि लक्ष्य OS सभी जुड़े कीबोर्ड पर LED स्थिति साझा करता है, जो OSX के लिए मामला नहीं है)
    • LED प्रतिक्रिया के आधार पर HIDScript में शाखा निर्णय ले सकता है
  • माउस
    • सापेक्ष गति (तेज़, लेकिन सटीक नहीं)
    • चरणबद्ध सापेक्ष गति (धीमी, लेकिन सटीक ... माउस को 1 DPI चरणों में चलाता है)
    • विंडोज़ पर पूर्ण स्थिति निर्धारण (पिक्सेल परिपूर्ण यदि लक्ष्य की स्क्रीन आयाम ज्ञात हैं)
  • कीबोर्ड और माउस न केवल एक ही स्क्रिप्टिंग भाषा द्वारा नियंत्रित होते हैं, दोनों का उपयोग एक ही स्क्रिप्ट में किया जा सकता है। यह उन्हें संयोजित करने की अनुमति देता है ताकि ऐसे लक्ष्य प्राप्त किए जा सकें जो केवल कीबोर्ड या माउस का उपयोग करके प्राप्त नहीं किए जा सकते।
  • वर्तमान भाषा लेआउट: br, de, es, fr, gb, it, ru और us

ब्लूटूथ

  • Bluez स्टैक के लिए पूर्ण इंटरफ़ेस (वर्तमान में दूरस्थ उपकरण खोज/कनेक्शन के लिए समर्थन नहीं)
  • ब्लूटूथ नेटवर्क एक्सेस पॉइंट (NAP) चलाने की अनुमति देता है
  • अनुकूलन योग्य पेयरिंग (PIN आधारित लीगेसी मोड या SSP)
  • उच्च गति समर्थन (WiFi जैसी स्थानांतरण दर प्राप्त करने के लिए 802.11 फ्रेम का उपयोग करता है)
  • ब्लूटूथ स्टैक का रनटाइम पुनर्विन्यास
  • नोट: PANU भी संभव है, लेकिन वर्तमान में समर्थित नहीं है (कोई दूरस्थ उपकरण कनेक्शन नहीं)
  • ब्लूटूथ सेटिंग्स के लिए कॉन्फ़िगरेशन टेम्पलेट्स का लगातार भंडारण और लोड

WiFi

  • संशोधित फर्मवेयर (Nexmon ढाँचे के साथ निर्मित)
    • KARMA की अनुमति देता है (दूरस्थ उपकरणों द्वारा खोजे गए एक्सेस पॉइंट्स के लिए मान्य उत्तरों का अनुकरण और संघ की अनुमति)
    • अतिरिक्त बीकन प्रसारित करने के लिए, कई SSID का अनुकरण करने के लिए
    • WiFi गुप्त चैनल
    • नोट: Nexmon लीगेसी मॉनिटर मोड शामिल है, लेकिन P4wnP1 द्वारा समर्थित नहीं है। मॉनिटर मोड अभी भी बगी है और संभावित रूप से फर्मवेयर को क्रैश कर सकता है यदि कॉन्फ़िगरेशन बदलता है।
  • आसान एक्सेस पॉइंट कॉन्फ़िगरेशन
  • आसान स्टेशन मोड कॉन्फ़िगरेशन (मौजूदा AP से कनेक्ट)
  • फेलओवर मोड (यदि लक्ष्य एक्सेस पॉइंट से कनेक्ट करना संभव नहीं है, तो अपना स्वयं का एक्सेस पॉइंट स्थापित करें)
  • WiFi स्टैक का रनटाइम पुनर्विन्यास
  • WiFi सेटिंग्स के लिए कॉन्फ़िगरेशन टेम्पलेट्स का लगातार भंडारण और लोड

नेटवर्किंग

  • आसान ईथरनेट इंटरफ़ेस कॉन्फ़िगरेशन के लिए
    • ब्लूटूथ NAP इंटरफ़ेस
    • USB इंटरफ़ेस (यदि RNDIS/CDC ECM सक्षम है)
    • WiFi इंटरफ़ेस
  • प्रति इंटरफ़ेस समर्पित DHCP सर्वर का समर्थन करता है
  • DHCP क्लाइंट मोड के लिए समर्थन
  • मैन्युअल कॉन्फ़िगरेशन
  • प्रत्येक इंटरफ़ेस के लिए कॉन्फ़िगरेशन टेम्पलेट्स का लगातार भंडारण और लोड

उपकरण

यहाँ कहने के लिए बहुत कुछ नहीं है, P4wnP1 A.L.O.A. KALI लिनक्स द्वारा समर्थित है, इसलिए सब कुछ आपकी उंगलियों पर होना चाहिए (या apt का उपयोग करके स्थापित किया जा सकता है)

CLI के माध्यम से कॉन्फ़िगरेशन और नियंत्रण, यदि आवश्यक हो तो दूरस्थ रूप से

  • अब तक उल्लिखित सभी विशेषताओं को CLI क्लाइंट का उपयोग करके कॉन्फ़िगर किया जा सकता है
  • P4wnP1 कोर सेवा एक एकल बाइनरी है, जो systemd इकाई के रूप में चलती है जो रनटाइम स्थिति को संरक्षित करती है
  • CLI क्लाइंट इस सेवा के साथ RPC (विशेष रूप से gRPC) के माध्यम से इंटरफ़ेस करता है ताकि कोर की स्थिति बदल सके
  • चूंकि CLI एक RPC दृष्टिकोण का उपयोग करता है, इसका उपयोग दूरस्थ कॉन्फ़िगरेशन के लिए भी किया जा सकता है
  • यदि P4wnP1 SSH के माध्यम से एक्सेस किया जाता है, तो CLI क्लाइंट वहाँ आपके आदेशों (या आपके टैब पूर्णता कुंग फू) की प्रतीक्षा कर रहा है
  • CLI Go में लिखा गया है (जैसा कि अधिकांश कोड है) और इस प्रकार अधिकांश प्रमुख प्लेटफ़ॉर्म और आर्किटेक्चर के लिए संकलित होता है

इसलिए यदि आप दूरस्थ Windows होस्ट पर चल रही एक बैच फ़ाइल का उपयोग करके P4wnP1 को कॉन्फ़िगर करना चाहते हैं ... कोई समस्या नहीं:

  1. क्लाइंट को विंडोज़ के लिए संकलित करें
  2. सुनिश्चित करें कि आप किसी भी तरह P4wnP1 से कनेक्ट कर सकते हैं (ब्लूटूथ, WiFi, USB)
  3. अपने क्लाइंट आदेशों में host पैरामीटर जोड़ें
  4. ... और CLI का उपयोग उसी प्रकार करें जैसे आप स्थानीय पहुँच के साथ करते हैं।

वेब क्लाइंट के माध्यम से कॉन्फ़िगरेशन और नियंत्रण

यद्यपि शुरू में योजना नहीं थी, P4wnP1 A.L.O.A. को वेब क्लाइंट का उपयोग करके कॉन्फ़िगर किया जा सकता है। भले ही क्लाइंट की योजना नहीं थी, यह एक अच्छे सॉफ़्टवेयर के रूप में विकसित हुआ। वास्तव में यह P4wnP1 A.L.O.A. के लिए मुख्य कॉन्फ़िगरेशन उपकरण बन गया। वेब क्लाइंट में ऐसी क्षमताएँ हैं जो CLI से एक्सेस नहीं की जा सकतीं (टेम्पलेट्स भंडारण, "TriggerActions" का निर्माण)।

मुख्य विशेषताएँ:

  • अधिकांश प्रमुख मोबाइल और डेस्कटॉप ब्राउज़रों पर काम करना चाहिए, सुसंगत रूप और अनुभव के साथ (Quasar Framework)
  • वेबसॉकेट के माध्यम से gRPC का उपयोग करता है (कोई RESTful API नहीं, कोई XHR नहीं, लगभग CLI के समान दृष्टिकोण)
  • इस इंटरफ़ेस के कारण, वेब क्लाइंट केवल अनुरोध और उत्तर योजना पर निर्भर नहीं करता, बल्कि P4wnP1 कोर से "पुश घटनाएँ" प्राप्त करता है। इसका मतलब है:
    • यदि आप (या कोई स्क्रिप्ट) P4wnP1 A.L.O.A. की स्थिति बदलते हैं, तो ये परिवर्तन तुरंत वेब क्लाइंट में प्रतिबिंबित होंगे
    • यदि आपके पास एक से अधिक वेब क्लाइंट चल रहे हैं, तो कोर की स्थिति में परिवर्तन एक क्लाइंट से सभी अन्य क्लाइंट्स में प्रतिबिंबित होगा
  • एक HIDScript संपादक शामिल है, जिसमें
    • सिंटैक्स हाइलाइटिंग
    • ऑटो-पूर्णता (CTRL+SPACE)
    • HIDScripts के लिए लगातार भंडारण और लोड
    • ब्राउज़र से सीधे HIDScript का मांग पर निष्पादन
    • एक HIDScript जॉब प्रबंधक (चल रही जॉब्स को रद्द करना, जॉब स्थिति और परिणामों का निरीक्षण)
  • TriggerActions के लिए एक अवलोकन और संपादक शामिल है
  • अब तक वर्णित सभी विशेषताओं के लिए पूर्ण टेम्पलेट समर्थन
  • वेब क्लाइंट एक एकल पृष्ठ अनुप्रयोग है, एक बार लोड होने पर सब कुछ क्लाइंट साइड चलता है, केवल gRPC अनुरोधों का आदान-प्रदान होता है

स्वचालन

पुराने P4wnP1 संस्करण (स्थैतिक बैश स्क्रिप्ट) के स्वचालन दृष्टिकोण का अब उपयोग नहीं किया जा सकता।

P4wnP1 A.L.O.A. के स्वचालन दृष्टिकोण को इन आवश्यकताओं को पूरा करना था:

  • उपयोग करने और समझने में आसान
  • वेब क्लाइंट से उपयोग करने योग्य
  • एक साथ सामान्य और लचीला होना
  • पुराने "बैश स्क्रिप्ट" दृष्टिकोण से जो कुछ भी किया जा सकता था, वह अभी भी संभव होना चाहिए
  • सभी उप-प्रणालियों (USB, WiFi, ब्लूटूथ, ईथरनेट इंटरफ़ेस, HIDScript ...) तक पहुँचने में सक्षम
  • पुन: प्रयोज्य भागों के साथ मॉड्यूलर
  • (सरल) तार्किक कार्यों का समर्थन करने की क्षमता बिना अतिरिक्त कोड लिखे
  • GPIO पोर्ट का उपयोग करके भौतिक कंप्यूटिंग की अनुमति देना

तथाकथित "TriggerActions" की शुरूआत और उन्हें टेम्पलेट सिस्टम (सभी उप-प्रणालियों के लिए लगातार सेटिंग्स भंडारण) के साथ संयोजित करके सभी आवश्यकताओं को संतुष्ट किया जा सकता है। TriggerActions पर विवरण कार्यप्रवाह अनुभाग में पाया जा सकता है।

उपयोग ट्यूटोरियल

2. कार्यप्रवाह भाग 1 - HIDScript

P4wnP1 A.L.O.A. स्थैतिक कॉन्फ़िगरेशन या पेलोड जैसी अवधारणाओं का उपयोग नहीं करता। वास्तव में इसका कोई स्थैतिक कार्यप्रवाह नहीं है।

P4wnP1 A.L.O.A. का उद्देश्य यथासंभव लचीला होना है, ताकि इसे सभी संभावित परिदृश्यों में उपयोग किया जा सके (उन लोगों सहित जो मैं P4wnP1 A.L.O.A. बनाते समय सोच नहीं सका)।

लेकिन कुछ बुनियादी अवधारणाएँ हैं, जिन्हें मैं इस अनुभाग में समझाना चाहूँगा। चूँकि उचित (वीडियो) दस्तावेज़ीकरण बनाए बिना सब कुछ समझाना कठिन है, मैं कुछ सामान्य उपयोग के मामलों और उदाहरणों पर विचार करता हूँ ताकि समझाया जा सके कि क्या समझाने की आवश्यकता है।

फिर भी, यह संभावना नहीं है कि मेरे पास एक पूर्ण दस्तावेज़ीकरण प्रदान करने का समय होगा। इसलिए मैं सभी को प्रोत्साहित करता हूँ कि वे ट्यूटोरियल और विचारों के साथ मेरा समर्थन करें, जिन्हें इस README में वापस जोड़ा जा सकता है

अब सबसे बुनियादी कार्यों में से एक से शुरू करते हैं:

2.1 एक होस्ट के विरुद्ध कीस्ट्रोक इंजेक्शन चलाएँ, जिससे P4wnP1 USB के माध्यम से जुड़ा हुआ है

इस लक्ष्य को प्राप्त करने के लिए न्यूनतम कॉन्फ़िगरेशन आवश्यकता है:

  • USB उप-प्रणाली को कम से कम एक कीबोर्ड का अनुकरण करने के लिए कॉन्फ़िगर किया गया है
  • कीस्ट्रोक इंजेक्शन शुरू करने के लिए P4wnP1 तक (दूरस्थ रूप से) पहुँचने का कोई तरीका है

P4wnP1 (अपरिवर्तित छवि) का डिफ़ॉल्ट कॉन्फ़िगरेशन पहले से ही इन आवश्यकताओं को पूरा करता है:

  • USB सेटिंग्स कीबोर्ड, माउस और ईथरनेट ओवर USB (RNDIS और CDC ECM दोनों) प्रदान करने के लिए प्रारंभ की जाती हैं
  • P4wnP1 को पहले से ही निम्नलिखित विधियों में से एक का उपयोग करके दूरस्थ रूप से एक्सेस किया जा सकता है:
    • WiFi
      • एक्सेस पॉइंट का नाम स्पष्ट होना चाहिए
      • पासवर्ड MaMe82-P4wnP1 है
      • P4wnP1 का IP 172.24.0.1 है
    • USB ईथरनेट
      • P4wnP1 का IP 172.16.0.1 है
    • ब्लूटूथ
      • उपकरण का नाम P4wnP1
      • PIN 1337
      • IP 172.26.0.1 है
      • नोट: सुरक्षित सरल पेयरिंग बंद है ताकि PIN पेयरिंग को बल दिया जा सके। इसका मतलब है कि हाई स्पीड मोड भी बंद है। इसलिए ब्लूटूथ कनेक्शन बहुत धीमा है, जो SSH पहुँच के लिए कम समस्या है, लेकिन वेब क्लाइंट का अनुरोध करने में 10 मिनट तक लग सकते हैं (इसके विपरीत हाई स्पीड सक्षम होने पर कुछ सेकंड)।
  • एक SSH सर्वर उपरोक्त सभी IP से सुलभ है
  • KALI लिनक्स के लिए SSH उपयोगकर्ता root है, डिफ़ॉल्ट पासवर्ड toor है
  • वेब क्लाइंट तीनों कनेक्शनों पर पोर्ट 8000 पर HTTP के माध्यम से पहुँचा जा सकता है

नोट: HTTPS कनेक्शन तैनात करना वर्तमान में परियोजना के दायरे में नहीं है। इसलिए कृपया इसे ध्यान में रखें यदि आप संवेदनशील डेटा, जैसे WiFi क्रेडेंशियल्स, वेब क्लाइंट में संभालते हैं। पूरी परियोजना सुरक्षा को ध्यान में रखकर नहीं बनाई गई है (और यह संभावना नहीं है कि यह कभी आवश्यकता बनेगी)। इसलिए कृपया उपयुक्त उपाय तैनात करें (जैसे, iptables के साथ वेब क्लाइंट तक पहुँच को प्रतिबंधित करना यदि एक्सेस पॉइंट ओपन ऑथेंटिकेशन के साथ कॉन्फ़िगर किया गया है; ब्लूटूथ खोज योग्यता और कनेक्टेबिलिटी को PIN सुरक्षा के बिना सक्षम न रखें आदि आदि)

इस बिंदु पर मैं मान लेता हूँ:

  1. आपने P4wnP1 को किसी लक्ष्य होस्ट से USB के माध्यम से जोड़ा है (Raspberry का सबसे भीतरी माइक्रो USB पोर्ट वह है जिसका उपयोग करना है)
  2. USB होस्ट एक एप्लिकेशन चला रहा है जो कीस्ट्रोक प्राप्त करने में सक्षम है और उसके पास वर्तमान कीबोर्ड इनपुट फ़ोकस है (जैसे, एक टेक्स्ट एडिटर)
  3. आप P4wnP1 से SSH के माध्यम से दूरस्थ रूप से जुड़े हैं (सबसे अच्छा तरीका WiFi है), अधिमानतः SSH कनेक्शन एक अलग होस्ट से चल रहा है, न कि उस होस्ट से जिससे P4wnP1 A.L.O.A. USB के माध्यम से जुड़ा है

SSH सत्र से CLI क्लाइंट चलाने के लिए, निम्नलिखित आदेश जारी करें:``` root@kali:~# P4wnP1_cli The CLI client tool could be used to configure P4wnP1 A.L.O.A. from the command line. The tool relies on RPC so it could be used remotely.

Version: v0.1.0-alpha1

Usage: P4wnP1_cli [command]

Available Commands: db Database backup and restore evt Receive P4wnP1 service events help Help about any command hid Use keyboard or mouse functionality led Set or Get LED state of P4wnP1 net Configure Network settings of ethernet interfaces (including USB ethernet if enabled) system system commands template Deploy and list templates trigger Fire a group send action or wait for a group receive trigger usb USB gadget settings wifi Configure WiFi (spawn Access Point or join WiFi networks)

Flags: -h, --help help for P4wnP1_cli --host string The host with the listening P4wnP1 RPC server (default "localhost") --port string The port on which the P4wnP1 RPC server is listening (default "50051")

Use "P4wnP1_cli [command] --help" for more information about a command.

root@kitploit:~
सहायता स्क्रीन पहले से ही दिखाती है, कि CLI क्लाइंट P4wnP1 A.L.O.A. के विभिन्न उप-प्रणालियों के साथ अंतःक्रिया करने के लिए विभिन्न कमांड का उपयोग करता है। इनमें से अधिकांश कमांड के अपने स्वयं के उप-कमांड भी होते हैं। प्रत्येक कमांड या उप-कमांड के लिए सहायता को CLI कमांड में `-h` जोड़कर एक्सेस किया जा सकता है:```
root@kali:~# P4wnP1_cli hid run -h
Run script provided from standard input, commandline parameter or by path to script file on P4wnP1

Usage:
  P4wnP1_cli hid run [flags]

Flags:
  -c, --commands string      HIDScript commands to run, given as string
  -h, --help                 help for run
  -r, --server-path string   Load HIDScript from given path on P4wnP1 server
  -t, --timeout uint32       Interrupt HIDScript after this timeout (seconds)

Global Flags:
      --host string   The host with the listening P4wnP1 RPC server (default "localhost")
      --port string   The port on which the P4wnP1 RPC server is listening (default "50051")

अब, USB होस्ट को "Hello world" टाइप करने के लिए, निम्नलिखित CLI कमांड का उपयोग किया जा सकता है:

P4wnP1_cli hid run -c 'type("Hello world")'

SSH सत्र में परिणाम आउटपुट कुछ इस प्रकार दिखना चाहिए:``` TempFile created: /tmp/HIDscript295065725 Start appending to 'HIDscript295065725' in folder 'TMP' Result: null

root@kitploit:~
USB होस्ट पर, कीबोर्ड फोकस वाले एप्लिकेशन में "Hello World" टाइप किया जाना चाहिए था।

*यदि आपका SSH क्लाइंट USB होस्ट पर ही चलता है, तो टाइप किया गया "Hello world" CLI कमांड के परिणामी आउटपुट के बीच कहीं समाप्त हो जाता है (यह आउटपुट का हिस्सा नहीं है, बल्कि बीच में टाइप किया गया है)।*

**लक्ष्य प्राप्त हुआ। हमने लक्ष्य में कीस्ट्रोक्स इंजेक्ट किए।**
 
कीस्ट्रोक इंजेक्शन जैसे सरल कार्य के लिए बहुत अधिक पढ़ना, लेकिन फिर से, यह खंड बुनियादी अवधारणाओं को समझाने के लिए है।

### 2.2 HIDScript की अधिक उन्नत भाषा सुविधाओं की ओर बढ़ना

यदि आप "Hello world" कीस्ट्रोक इंजेक्शन चलाने में सफल रहे, तो यह कुछ अतिरिक्त HIDScript सुविधाओं का पता लगाने का एक अच्छा समय है। 

हम पहले से ही `type` कमांड को जानते हैं, लेकिन आइए कुछ और उन्नत HIDScript कमांड पर चर्चा करने का प्रयास करें: 

#### विशेष कुंजियाँ और संयोजन दबाना

`type` कमांड इनपुट स्ट्रिंग में "new line" कैरेक्टर को एन्कोड करके रिटर्न दबाने का समर्थन करता है, इस प्रकार:```
P4wnP1_cli hid run -c 'type("line 1\nline 2\nline 3 followed by pressing RETURN three times\n\n\n")'

लेकिन विशेष कुंजियों या कुंजी संयोजनों के बारे में क्या?

press कमांड मदद के लिए आता है!

आइए USB होस्ट को CTRL+ALT+DELETE भेजने के लिए press का उपयोग करें:``` P4wnP1_cli hid run -c 'press("CTRL ALT DELETE")'

root@kitploit:~
*नोट: दो कुंजियाँ संशोधक रही हैं (CTRL और ALT) और केवल एक वास्तविक कुंजी रही है (DELETE)*

आइए बिना किसी संशोधक कुंजी के 'A' कुंजी दबाएँ:```
P4wnP1_cli hid run -c 'press("A")'

परिणामी आउटपुट एक लोअरकेस 'a' होना चाहिए, क्योंकि press("A") 'A' को एक कुंजी के रूप में व्याख्या करता है। दूसरी ओर, कमांड type("A") एक कुंजी संयोजन दबाने का प्रयास करता है जिसके परिणामस्वरूप एक अपरकेस 'A' आउटपुट वर्ण होना चाहिए।

आइए एक मॉडिफायर और एक नॉन-मॉडिफायर कुंजी को संयोजित करें, ताकि एक अपरकेस 'A' आउटपुट वर्ण उत्पन्न किया जा सके (type("A") के व्यवहार की नकल करना):``` P4wnP1_cli hid run -c 'press("SHIFT A")'

root@kitploit:~
इससे अपरकेस A आउटपुट उत्पन्न होना चाहिए था।

यह समझना महत्वपूर्ण है, कि `press` अपने दिए गए की-आर्गुमेंट्स को कीज़ के रूप में व्याख्या करता है, जबकि `type` इच्छित आउटपुट वर्ण उत्पन्न करने के लिए उपयुक्त कुंजी संयोजन खोजने का प्रयास करता है।

एक अंतिम उदाहरण में, आइए `press` और `type` को संयोजित करें।```
P4wnP1_cli hid run -c 'type("before caps\n"); press("CAPS"); type("after caps\n"); press("CAPS");'

अंतिम कमांड ने एक स्ट्रिंग टाइप की, CAPSLOCK टॉगल किया, दूसरी स्ट्रिंग टाइप की और CAPS लॉक फिर से टॉगल किया। परिणामस्वरूप, CAPSLOCK अपनी प्रारंभिक स्थिति में होना चाहिए (दो बार टॉगल किया गया), लेकिन एक स्ट्रिंग अपरकेस में टाइप की गई है, दूसरी लोअरकेस में, हालांकि दोनों स्ट्रिंग्स लोअर केस में दी गई थीं।

press के साथ कुंजी दबाने पर अतिरिक्त नोट्स:

मैं USB कीबोर्ड रिपोर्ट के आंतरिक कार्यप्रणाली की गहराई में नहीं जाना चाहता, लेकिन press कमांड की सीमाओं और संभावनाओं को इंगित करने के लिए कुछ बातों का उल्लेख करना उचित है (जो स्वयं रॉ कीबोर्ड रिपोर्ट पर आधारित है):

  • एक कीबोर्ड रिपोर्ट में एक बार में अधिकतम 8 मॉडिफायर कुंजियाँ हो सकती हैं
  • मॉडिफायर कुंजियाँ हैं
    • LEFT_CTRL
    • RIGHT_CTRL
    • LEFT_ALT
    • RIGHT_ALT
    • LEFT_SHIFT
    • RIGHT_SHIFT
    • LEFT_GUI
    • RIGHT_GUI
  • P4wnP1 सामान्य मॉडिफायर के लिए उपनामों का उपयोग करने की अनुमति देता है
    • CTRL == CONTROL == LEFT_CTRL
    • ALT == LEFT_ALT
    • SHIFT == LEFT_SHIFT
    • WIN == GUI == LEFT_GUI
  • मॉडिफायर के अलावा, press अधिकतम छह सामान्य या विशेष कुंजियों का उपभोग करता है
    • सामान्य कुंजियाँ अक्षरों और विशेष कुंजियों का प्रतिनिधित्व करती हैं
    • विशेष कुंजियों का उदाहरण: BACKSPACE, ENTER (== RETURN), F1 .. F12)
    • कुंजियाँ भाषा लेआउट अज्ञेयवादी हैं (press("Z") EN_US कीबोर्ड लेआउट के लिए USB_KEY_Z परिणाम देता है, लेकिन जर्मन लेआउट के लिए USB_KEY_Y उत्पन्न करता है। यह जर्मन कीबोर्ड पर हार्डवेयर कुंजी 'Z' दबाने के अनुरूप है, जो USB_KEY_Y भी उत्पन्न करेगा।)
    • /usr/local/P4wnP1/keymaps/common.json में सभी संभावित कुंजियों के साथ एक स्वरूपित JSON कीमैप है (फ़ाइल को बदलने से सावधान रहें)
  • एकल press कमांड में कई कुंजियाँ जोड़ने से कुंजी अनुक्रम उत्पन्न नहीं होता। सभी दी गई कुंजियाँ एक ही समय दबाई जाती हैं और एक ही समय छोड़ी जाती हैं।
  • press कुंजियाँ स्वचालित रूप से छोड़ता है, इसका मतलब है कि "ALT दबाए रखें, TAB दबाएं, TAB दबाएं, ALT छोड़ें" जैसा अनुक्रम वर्तमान में संभव नहीं है

कीबोर्ड लेआउट

कीबोर्ड लेआउट बदलने के लिए HIDScript कमांड layout(<language map name>) है।

निम्नलिखित उदाहरण कीबोर्ड लेआउट को 'US' पर स्विच करता है, कुछ टाइप करता है और टाइपिंग जारी रखने से पहले लेआउट को 'German' पर स्विच करता है:``` P4wnP1_cli hid run -c 'layout("us"); type("Typing with EN_US layout\n");layout("de"); type("Typing with German layout supporting special chars üäö\n");'

root@kitploit:~
ऊपर दिए गए कमांड का आउटपुट परिणाम, USB होस्ट द्वारा उपयोग किए जाने वाले लक्ष्य लेआउट पर निर्भर करता है।

जर्मन कीबोर्ड लेआउट वाले होस्ट पर परिणाम इस प्रकार दिखता है:```
Tzping with EN?US lazout
Typing with German layout supporting special chars üäö

US कीबोर्ड लेआउट वाले होस्ट पर यह इस प्रकार दिखता है:``` Typing with EN_US layout Tzping with German lazout supporting special chars [';

root@kitploit:~
कृपया ध्यान दें कि वांछित आउटपुट तभी प्राप्त होता है जब P4wnP1 का कीबोर्ड लेआउट USB होस्ट द्वारा वास्तव में उपयोग किए गए कीबोर्ड लेआउट से मेल खाता है।

`layout` कमांड P4wwP1 के आंतरिक लेआउट को लक्ष्य USB होस्ट के लेआउट के साथ संरेखित करने की अनुमति देता है।

चल रहे HIDScript के बीच में लेआउट बदलने में सक्षम होना काम आ सकता है: कौन जानता है, हो सकता है आप लक्ष्य होस्ट के कीबोर्ड लेआउट को बदलते लेआउट के साथ कमांड जारी करके ब्रूट फोर्स करना चाहें जब तक कि टाइप किए गए कमांड में से एक वांछित प्रभाव प्राप्त न कर ले।

**महत्वपूर्ण:** लेआउट का वैश्विक प्रभाव होता है। इसका मतलब है कि यदि एक साथ कई HIDScripts चल रहे हैं और उनमें से एक स्क्रिप्ट एक नया लेआउट सेट करती है, तो अन्य सभी स्क्रिप्ट भी तुरंत प्रभावित होती हैं।

#### टाइपिंग गति

डिफ़ॉल्ट रूप से, P4wnP1 कीस्ट्रोक्स को जितनी जल्दी हो सके इंजेक्ट करता है। आपके लक्ष्य के आधार पर, यह थोड़ा अधिक हो सकता है (टाइपिंग गति के व्यवहार विश्लेषण के आधार पर कीस्ट्रोक इंजेक्शन को रोकने वाले प्रतिउपायों के बारे में सोचें)। HIDScript इस व्यवहार को बदलने के लिए एक कमांड का समर्थन करता है।

`typingSpeed(delayMillis, jitterMillis)`

`typingSpeed` कमांड का पहला तर्क मिलीसेकंड में एक स्थिर विलंब का प्रतिनिधित्व करता है, जो दो कीस्ट्रोक के बीच लागू होता है। दूसरा तर्क मिलीसेकंड में एक अतिरिक्त जिटर है। यह पहले तर्क के साथ प्रदान किए गए स्थिर विलंब में एक अतिरिक्त यादृच्छिक विलंब जोड़ता है, जो 0 और दिए गए जिटर मिलीसेकंड के बीच स्केल होता है।

आइए टाइपिंग को धीमा करने के लिए `typingSpeed` का उपयोग करने का प्रयास करें:```
P4wnP1_cli hid run -c 'typingSpeed(100,0); type("Hello world")'

इसके बाद, एक स्थिर देरी के बजाय, हम एक यादृच्छिक jitter का प्रयास करते हैं:``` P4wnP1_cli hid run -c 'typingSpeed(0,500); type("Writing with random jitter up to 500 milliseconds")'

root@kitploit:~
अंततः, दोनों मानों को संयोजित और समायोजित करके, हम प्राकृतिक टाइपिंग गति का अनुकरण कर सकते हैं:```
P4wnP1_cli hid run -c 'typingSpeed(100,150); type("Writing with more natural speed")'

महत्वपूर्ण: टाइपिंग स्पीड का वैश्विक प्रभाव होता है। इसका मतलब है कि यदि एक साथ कई HIDScripts चल रहे हैं और उनमें से एक स्क्रिप्ट नई टाइपिंग स्पीड सेट करती है, तो अन्य सभी स्क्रिप्ट भी तुरंत प्रभावित होती हैं।

LED रिपोर्ट की प्रतीक्षा करें

LED रिपोर्ट की प्रतीक्षा करना, या सटीक रूप से LED स्थिति परिवर्तनों की प्रतीक्षा करना, HIDScript की अधिक परिष्कृत कीबोर्ड सुविधाओं में से एक है। यह बहुत शक्तिशाली हो सकता है लेकिन इसे थोड़ा समझाने की आवश्यकता है।

आपने देखा होगा कि (USB होस्ट के OS के आधार पर) कीबोर्ड स्थिति संशोधक (NUM LOCK, SCROLL LOCK, CAPS LOCK) कई कनेक्टेड कीबोर्ड पर साझा किए जाते हैं। उदाहरण के लिए, यदि आप एक Windows होस्ट से दो कीबोर्ड कनेक्ट करते हैं, और उनमें से एक पर CAPS LOCK टॉगल करते हैं, तो दोनों कीबोर्ड पर CAPS LOCK LED बदल जाता है।

ठीक इसी परीक्षण का उपयोग यह निर्धारित करने के लिए किया जा सकता है कि किसी दिए गए OS के लिए कीबोर्ड स्थिति संशोधक सभी कीबोर्ड पर साझा किए गए हैं या नहीं।

यदि कोई USB होस्ट इस प्रकार के स्थिति साझाकरण का समर्थन करता है (उदाहरण के लिए Windows करता है), तो P4wnP1 की HIDScript भाषा इसका उपयोग कर सकती है।

निम्नलिखित परिदृश्य की कल्पना करें:

P4wnP1 एक USB होस्ट से कनेक्टेड है और आप कीस्ट्रोक इंजेक्शन लागू करना चाहते हैं, लेकिन आप नहीं चाहते कि HIDScript तुरंत कीस्ट्रोक चलाए। इसके बजाय HIDScript को बैठना चाहिए और तब तक प्रतीक्षा करनी चाहिए जब तक आप होस्ट के वास्तविक कीबोर्ड पर NUMLOCK, CAPSLOCK या SCROLLLOCK नहीं दबाते। क्यों? हो सकता है कि आप किसी कार्य में शामिल हों, कोई अंदर आ गया और आप नहीं चाहते कि यह "कोई" देख सके कि कैसे जादुई रूप से एक कंसोल विंडो में बड़ी मात्रा में अक्षर टाइप होते हैं जो अचानक पॉप अप हुई। तो आप तब तक प्रतीक्षा करते हैं जब तक "कोई" बाहर नहीं चला जाता, NUM LOCK दबाते हैं और अंततः एक कंसोल विंडो पॉप अप होती है और बड़ी मात्रा में अक्षर जादुई रूप से टाइप होते हैं ... मुझे लगता है आप समझ गए।

वर्णित व्यवहार को इस प्रकार प्राप्त किया जा सकता है:``` P4wnP1_cli hid run -c 'waitLED(NUM); type("A huge amount of characters\n")'

root@kitploit:~
यदि आपने उपरोक्त कमांड का परीक्षण किया है, तो टाइपिंग केवल तभी शुरू होनी चाहिए जब USB होस्ट के हार्डवेयर कीबोर्ड पर NUM LOCK दबाया गया हो, लेकिन आप कुछ ऐसे मामलों का सामना कर सकते हैं जहाँ कीस्ट्रोक्स तुरंत जारी हो जाते हैं, भले ही NUM LOCK दबाया न गया हो (और कीबोर्ड LED नहीं बदली हो)।

यह इच्छित व्यवहार है और इसका कारण `waitLED` कमांड का एक और उपयोग मामला है:

शायद आपने पहले अन्य कीबोर्ड स्क्रिप्टिंग भाषाओं और कीस्ट्रोक्स इंजेक्ट करने में सक्षम अन्य USB उपकरणों का उपयोग किया हो। इनमें से अधिकांश उपकरणों में एक सामान्य समस्या होती है: आप नहीं जानते कि टाइप करना कब शुरू करें!

यदि आप USB डिवाइस के पावर ऑन होने के तुरंत बाद टाइप करना शुरू करते हैं, तो संभावना है कि USB होस्ट ने डिवाइस एनुमरेशन पूरा नहीं किया है और इस प्रकार कीबोर्ड ड्राइवरों को लाने में सफल नहीं हुआ है। अंततः आपके कीस्ट्रोक्स खो जाते हैं।

इसे दूर करने के लिए आप कीस्ट्रोक इंजेक्शन शुरू होने से पहले एक विलंब जोड़ सकते हैं। लेकिन यह विलंब कितना लंबा होना चाहिए? पाँच सेकंड, 10 सेकंड, 30 सेकंड?

उत्तर है: यह निर्भर करता है! यह इस बात पर निर्भर करता है कि होस्ट डिवाइस को एनुमरेट करने और कीबोर्ड ड्राइवर को लाने में कितना तेज़ है। वास्तव में आप यह नहीं जान सकते कि इसमें कितना समय लगेगा, बिना वास्तविक लक्ष्य के विरुद्ध परीक्षण किए।

लेकिन जैसा कि हम पहले ही सीख चुके हैं, विंडोज जैसे ऑपरेटिंग सिस्टम कई कीबोर्ड के बीच LED स्थिति साझा करते हैं।
इसका मतलब है कि यदि आप दूसरा कीबोर्ड संलग्न करने से पहले होस्ट कीबोर्ड का NUMLOCK LED ON पर सेट है, तो इस नए कीबोर्ड पर NUMLOCK LED को भी संलग्न होने पर ON पर सेट करना होगा। यदि NUM LOCK LED पहले से OFF पर सेट होता, तो भी, नवसंलग्न कीबोर्ड को LED स्थिति प्राप्त होती है (इस मामले में सभी LEDs बंद)। इसके बारे में दिलचस्प बात यह है कि यह "LED अपडेट" केवल USB होस्ट से संलग्न कीबोर्ड को भेजा जा सकता है, यदि कीबोर्ड ड्राइवर ने लोड करना समाप्त कर दिया है (अन्यथा LED स्थिति भेजना संभव नहीं होगा)।

क्या यह सुंदर नहीं है? USB होस्ट हमें बताता है: "मैं कीस्ट्रोक्स प्राप्त करने के लिए तैयार हूँ"। प्रारंभिक विलंब के साथ खिलवाड़ करने की कोई आवश्यकता नहीं है।

लेकिन यहाँ एक और समस्या है: मान लें कि हम P4wnP1 को USB होस्ट से जोड़ते हैं। हम एक HIDScript चलाते हैं जो हाथ से बनाए गए विलंब के बजाय `waitLED` से शुरू होती है। `waitLED` के बाद टाइपिंग शुरू होती है, लेकिन कुछ नहीं होता - हमारे कीस्ट्रोक्स वैसे भी खो जाते हैं! क्यों? क्योंकि यह संभावना है कि हम LED स्थिति अपडेट से चूक गए, क्योंकि यह हमारे HIDScript शुरू करने से पहले ही आ गया था।

ठीक यही "रेस कंडीशन" इसका कारण है कि P4wnP1 सभी पहचाने गए LED स्थिति परिवर्तनों को संरक्षित करता है, जब तक कि कम से कम एक HIDScript उन्हें `waitLED` (या `waitLEDRepeat`) कॉल करके उपभोग न करे। इसके परिणामस्वरूप पहले वर्णित व्यवहार हो सकता है, जहाँ `waitLED` तुरंत वापस आता है, भले ही कोई LED परिवर्तन न हुआ हो। अब हम जानते हैं: LED परिवर्तन वास्तव में हुआ था, लेकिन यह बहुत पहले हो सकता था (हमारे HIDScript शुरू करने से पहले), क्योंकि स्थिति परिवर्तन संरक्षित किया गया था। हम यह भी जानते हैं कि यह व्यवहार LED स्थिति परिवर्तनों को खोने से बचने के लिए आवश्यक है, यदि `waitLED` का उपयोग "USB होस्ट के कीबोर्ड ड्राइवर की तत्परता" के परीक्षण के लिए किया जाता है।

*नोट: यह उल्लेखनीय है कि `waitLED` केवल तभी वापस आता है यदि प्राप्त LED स्थिति P4wnP1 की आंतरिक स्थिति से भिन्न होती है। इसका मतलब है, भले ही हम `waitLED(ANY)` के साथ किसी LED पर परिवर्तन सुन रहे हों, फिर भी ऐसा हो सकता है कि हमें USB होस्ट से एक प्रारंभिक LED स्थिति प्राप्त हो, जो P4wnP1 की आंतरिक स्थिति से भिन्न न हो। इस मामले में `waitLED(ANY)` हमेशा के लिए ब्लॉक हो जाएगा (या जब तक वास्तविक LED परिवर्तन न हो)।
इस विशेष मामले को `waitLED(ANY_OR_NONE)` कॉल करके संभाला जा सकता है, जो नई LED स्थिति आते ही वापस आ जाता है, भले ही इसके परिणामस्वरूप कोई परिवर्तन न हो।*

**पर्याप्त स्पष्टीकरण, चलिए व्यावहारिक होते हैं ... ऐसा करने से पहले, हमें हार्डवेयर सेटअप को थोड़ा बदलना होगा:**

Raspberry Pi Zero के दूसरे USB पोर्ट (बाहरी वाले) से एक बाहरी बिजली आपूर्ति संलग्न करें। यह सुनिश्चित करता है कि P4wnP1 USB होस्ट से डिस्कनेक्ट होने पर बिजली न खोए, क्योंकि यह अब बस पावर पर निर्भर नहीं है। USB पोर्ट जिसका उपयोग P4wnP1 को लक्ष्य USB होस्ट से कनेक्ट करने के लिए किया जाना चाहिए, वह दो पोर्ट में से सबसे भीतरी है।

अब निम्नलिखित HIDScript प्रारंभ करें``` 
P4wnP1_cli hid run -c 'while (true) {waitLED(ANY);type("Attached\n");}'

P4wnP1 को USB होस्ट से अलग करें (और सुनिश्चित करें कि यह चालू रहे)! इसे USB होस्ट से पुनः कनेक्ट करें... हर बार जब आप P4wnP1 को होस्ट से पुनः कनेक्ट करते हैं, तो होस्ट पर "Attached" टाइप होना चाहिए।

इसने हमें 3 तथ्य सिखाए:

  1. waitLED का उपयोग स्क्रिप्ट्स में आरंभिक कमांड के रूप में किया जा सकता है, ताकि कीबोर्ड ड्राइवर तैयार होते ही टाइप करना शुरू हो जाए
  2. waitLED HID स्क्रिप्ट्स को तब तक रोकने के लिए सही विकल्प नहीं है जब तक USB होस्ट पर LED बदलने वाली कुंजी न दबाई जाए, क्योंकि संरक्षित स्थिति परिवर्तन कमांड को अनपेक्षित तरीके से अनब्लॉक कर सकते हैं
  3. अधिक जटिल HIDScript को CLI के पैरामीटर के रूप में प्रदान करना बहुत सुविधाजनक नहीं है

चूंकि हम अभी भी waitLED कमांड के साथ समाप्त नहीं हुए हैं, इसलिए अब हम तीसरे तथ्य का ध्यान रखते हैं। आइए CLI से बाहर निकलें।

  • P4wnP1 CLI को CTRL+C से समाप्त करें (यदि लूपिंग HIDScript अभी भी चल रही हो)
  • उस होस्ट पर एक ब्राउज़र खोलें जिसका उपयोग आप P4wnP1 से SSH कनेक्शन के लिए कर रहे थे (USB होस्ट नहीं)
  • वेबक्लाइंट को SSH सर्वर के समान IP से एक्सेस किया जा सकता है, पोर्ट 8000 है (WiFi के लिए http://172.24.0.1:8000)
  • अब खुले वेबक्लाइंट में "HIDScript" टैब पर जाएं
  • वहां से आप HIDScripts लोड और स्टोर कर सकते हैं (हम अभी ऐसा नहीं करते, हालांकि ms_snake.js LED आधारित ट्रिगर्स की शक्ति का एक बहुत अच्छा उदाहरण है)

एडिटर विंडो में स्क्रिप्ट को निम्नलिखित से बदलें:``` return waitLED(ANY);

root@kitploit:~
रन बटन दबाने के बाद, विंडो के दाईं ओर एक नया चल रहा HID जॉब दिखना चाहिए। यदि आप HIDScript जॉब के दाईं ओर छोटे "info" बटन को दबाते हैं, तो आप विवरण देख सकते हैं, जैसे इसकी स्थिति (चल रहा होना चाहिए), जॉब ID और VM ID (यह इस जॉब को चलाने वाले JavaScript VM की संख्या है। ऐसे 8 VM हैं, इसलिए 8 HIDScripts समानांतर में चल सकते हैं)।

अब, यदि USB होस्ट से कोई LED परिवर्तन उत्सर्जित होता है (NUM, CAPS या SCROLL को टॉगल करके) तो HIDScript जॉब समाप्त हो जाना चाहिए। यह अभी भी "Succeeded" जॉब्स के अंतर्गत पाया जा सकता है।

यदि आप फिर से छोटे "info" बटन को दबाते हैं, तो परिणाम मान (JSON के रूप में एन्कोडेड) के बारे में जानकारी होनी चाहिए, जो कुछ इस प्रकार दिखती है:```
{"ERROR":false,"ERRORTEXT":"","TIMEOUT":false,"NUM":true,"CAPS":false,"SCROLL":false,"COMPOSE":false,"KANA":false}

तो waitLED कमांड एक JavaScript ऑब्जेक्ट लौटाता है जो इस प्रकार दिखता है:``` { ERROR: false, // gets true if an error occurred (f.e. HIDScript was aborted, before waitLED could return)
ERRORTEXT: "", // corresponding error string TIMEOUT: false, // gets true if waitLED timed out (more on this in a minute) NUM: true, // gets true if NUM LED had changed before waitLED returned CAPS: false, // gets true if CAPS LED had changed before waitLED returned SCROLL: false, // gets true if SCROLL LED had changed before waitLED returned COMPOSE: false, // gets true if COMPOSE LED had changed before waitLED returned (uncommon) KANA: false // gets true if KANA LED had changed before waitLED returned (uncommon) }

root@kitploit:~
मेरे मामले में, `NUM` सही हो गया। आपके मामले में शायद `CAPS` था। इससे कोई फर्क नहीं पड़ता कि यह कौन सा LED था। मायने यह रखता है कि रिटर्न वैल्यू LED परिवर्तन की जांच करने का अवसर देती है, जिसके कारण कमांड रिटर्न होता है और इस प्रकार इसका उपयोग आपके HIDScript में शाखा निर्णय लेने के लिए किया जा सकता है (USB होस्ट के वास्तविक कीबोर्ड से जारी LED स्थिति परिवर्तनों के आधार पर)।

आइए एक उदाहरण देखें:```
while (true) {
 result = waitLED(ANY);
 if (result.NUM) {
   type("NUM has been toggled\n");
 }
 if (result.SCROLL) {
   type("SCROLL has been toggled\n");
 }
 if (result.CAPS) {
   break; //exit loop
 }
}

मान लीजिए कि दिया गया स्क्रिप्ट पहले से चल रहा है, तो USB होस्ट पर NUM दबाने से "NUM has been toggled" टाइप होना चाहिए, जबकि SCROLL LOCK दबाने से "SCROLL has been toggled" टेक्स्ट टाइप होता है। यह व्यवहार तब तक दोहराता है जब तक CAPS LOCK नहीं दबाया जाता और परिणामी LED परिवर्तन लूप को रद्द करके HIDScript को समाप्त कर देता है।

पुफ़्फ़ ... एक एकल HIDScript कमांड के लिए इस आदेश पर बहुत सारा टेक्स्ट है, लेकिन अभी भी कुछ चीज़ें बाकी हैं।

हमने waitLED कमांड में NUM, ANY या ANY_OR_NONE जैसे तर्क प्रदान किए, बिना आगे स्पष्टीकरण के।

waitLED अधिकतम दो तर्क स्वीकार करता है:

पहला तर्क, जैसा कि आपने अनुमान लगाया होगा, देखने के लिए LEDs के लिए एक श्वेतसूची फ़िल्टर है। मान्य तर्क हैं:

  • ANY (किसी भी LED में परिवर्तन पर प्रतिक्रिया दें)
  • ANY_OR_NONE (हर नई LED स्थिति पर प्रतिक्रिया दें, भले ही कोई बदलाव न हुआ हो)
  • NUM (NUM LED को छोड़कर सभी LED परिवर्तनों को अनदेखा करें)
  • CAPS (NUM CAPS को छोड़कर सभी LED परिवर्तनों को अनदेखा करें)
  • SCROLL (NUM SCROLL को छोड़कर सभी LED परिवर्तनों को अनदेखा करें)
  • एकाधिक फ़िल्टर को इस प्रकार जोड़ा जा सकता है CAPS | NUM, NUM | SCROLL

दूसरा तर्क, जिसका हमने अब तक उपयोग नहीं किया, मिलीसेकंड में एक समय-समाप्ति अवधि है। यदि इस समय-समाप्ति अवधि के दौरान कोई LED परिवर्तन नहीं हुआ, तो waitLED वापस आता है और परिणामी ऑब्जेक्ट में TIMEOUT: true सेट करता है (इसके अतिरिक्त ERROR को true पर सेट किया जाता है और ERRORTEXT समय-समाप्ति इंगित करता है)।

निम्नलिखित कमांड NUM LED पर परिवर्तन की प्रतीक्षा करेगा, लेकिन 5 सेकंड के बाद प्रतीक्षा रद्द कर देगा:``` waitLED(NUM,5000)

root@kitploit:~
भले ही `waitLED` एक बहुत शक्तिशाली कमांड है यदि सही ढंग से उपयोग किया जाए, लेकिन इसने हमारे आसान कार्य में मदद नहीं की है कि एक HIDScript को तब तक मजबूती से रोका जाए जब तक कि लक्ष्य USB होस्ट पर एक स्थिति संशोधक कुंजी दबाई न जाए (याद रखें: हम टाइपिंग शुरू होने से पहले यह सुनिश्चित करने के लिए निष्पादन को रोकना चाहते थे कि अवांछित "कोई" बाहर चला गया है, लेकिन `waitLED` कभी-कभी जल्दी लौट आता था, क्योंकि LED स्थिति में परिवर्तन संरक्षित थे)।

यहीं पर `waitLEDRepeat` खेल में आता है और बचाव के लिए आता है।

निम्नलिखित स्क्रिप्ट को संपादक में पेस्ट करें और कमांड को लौटने का प्रयास करें। बाद में HIDScript परिणामों का निरीक्षण करें।```
return waitLEDRepeat(ANY)

आप जल्दी देखेंगे कि waitLEDRepeat कमांड को वापस लौटाने के लिए उसी LED को बार-बार बदलना होता है। waitLEDRepeat कमांड वापस नहीं लौटेगा यदि अलग-अलग LED बदलती हैं या एक ही LED पर परिवर्तन बहुत धीमे हो रहे हैं।

waitLEDRepeat को दिया गया आर्गुमेंट (जो उदाहरण में ANY है) वही उद्देश्य पूरा करता है जो waitLED के लिए होता है। यह एक व्हाइटलिस्ट फ़िल्टर है। उदाहरण के लिए, waitLEDRepeat(NUM) केवल NUM LOCK LED के बदलाव पर वापस लौटेगा - चाहे आप CAPS LOCK कुंजी को कितनी भी तेज़ और बार-बार दबाएँ, यह तब तक वापस नहीं लौटेगा जब तक NUM LOCK को बार-बार न दबाया जाए।

डिफ़ॉल्ट रूप से, व्हाइटलिस्ट की गई LEDs में से एक को 3 बार बदलना होता है और दो लगातार बदलावों के बीच का अंतराल 800 मिलीसेकंड से अधिक नहीं होना चाहिए ताकि waitLEDRepeat वापस लौटे। इस व्यवहार को अतिरिक्त आर्गुमेंट प्रदान करके ट्यून किया जा सकता है, जैसा इस उदाहरण में दिखाया गया है:``` filter = ANY; // same filters as for waitLED num_changes = 5; // how often the SAME LED has to change, in order to return from waitLEDRepeat max_delay = 800; // the maximum duration between two LED changes, which should be taken into acccount (milliseconds) timeout = 10000; // timeout in milliseconds

waitLEDRepeat(filter, num_changes, max_delay); //wait till a LED frequently changed 5 times, no timeout waitLEDRepeat(filter, num_changes, max_delay, timeout); //wait till a LED frequently changed 5 times, abort after 10 seconds

root@kitploit:~
So that's how to interact with LED reports from an USB host in HIDScript.

*ध्यान दें: `waitLEDRepeat`, LED स्थिति में सुरक्षित परिवर्तनों के उपभोग के मामले में `waitLED` से भिन्न नहीं है। फिर भी, इसे अनजाने में ट्रिगर करना अधिक कठिन है।*

इसलिए `waitLEDRepeat` सही विकल्प है, यदि कार्य HIDScripts को मानव अंतःक्रिया होने तक रोकना है। बेशक इसका उपयोग शाखाओं (branching) के लिए भी किया जा सकता है, क्योंकि यह `waitLED` के समान रिटर्न ऑब्जेक्ट प्रदान करता है।

इस बिंदु तक हमने HIDScript के बारे में अच्छी जानकारी प्राप्त कर ली है (बेशक सब कुछ नहीं, हमने इस स्क्रिप्टिंग भाषा की माउस नियंत्रण क्षमताओं को भी नहीं देखा है)। फिर भी, यह ट्यूटोरियल P4wnP1 A.L.O.A. वर्कफ़्लो और मूल अवधारणाओं के बारे में है। इसलिए हम अभी अन्य HIDScript सुविधाओं पर ध्यान नहीं देते और आगे बढ़ते हैं।

आइए संक्षेप में बताएं कि हमने P4wnP1 के वर्कफ़्लो और अवधारणाओं के बारे में अब तक क्या सीखा:
- हम CLI क्लाइंट से कीस्ट्रोक इंजेक्शन जैसी क्रियाएं ऑन-डिमांड शुरू कर सकते हैं।
- हम वेबक्लाइंट का उपयोग करके भी ऐसा कर सकते हैं, जबकि HIDScript जॉब्स पर अतिरिक्त नियंत्रण होता है।
- यदि हम P4wnP1 A.L.O.A. से एक बाहरी बिजली आपूर्ति जोड़ते हैं, तो हम विभिन्न USB होस्टों से जुड़/अलग हो सकते हैं और पहले से शुरू किए गए HIDScripts निर्बाध रूप से काम करते रहते हैं।
- हम USB स्टैक को अपनी आवश्यकताओं के अनुसार कॉन्फ़िगर कर सकते हैं (और P4wnP1 को रिबूट किए बिना रनटाइम पर इसका कॉन्फ़िगरेशन बदल सकते हैं)।
- हम JavaScript (फंक्शन, लूप, शाखाओं आदि के समर्थन के साथ) पर आधारित जटिल लॉजिक के साथ बहुउद्देशीय HIDScripts लिख सकते हैं।

### 3. वर्कफ़्लो भाग 2 - टेम्पलेटिंग और ट्रिगरएक्शन

P4wnP1 A.L.O.A. की अन्य प्रमुख अवधारणाओं पर आगे बढ़ने से पहले, आइए अपने पहले लक्ष्य को परिष्कृत करें, जो था "USB होस्ट के विरुद्ध कीस्ट्रोक इंजेक्शन चलाना":

- नया लक्ष्य विंडोज USB होस्ट के एडिटर (notepad.exe) में "Hello world" टाइप करना है।
- एडिटर को P4wnP1 द्वारा खोला जाना चाहिए (उपयोगकर्ता द्वारा मैन्युअल रूप से नहीं)।
- जब USB होस्ट के किसी भी कीबोर्ड LED को टॉगल किया जाता है, तो एडिटर स्वचालित रूप से बंद हो जाना चाहिए।
- जब भी P4wnP1 USB होस्ट से जुड़ा हो, यह व्यवहार दोहराया जाना चाहिए (बाहरी बिजली आपूर्ति के साथ, P4wnP1 के रिबूट के बिना)।
- प्रक्रिया केवल एक बार चलनी चाहिए, जब तक कि P4wnP1 पुनः USB होस्ट से न जुड़ जाए, भले ही HIDScript शुरू होने के बाद लगातार कीबोर्ड LED परिवर्तन हों।
- भले ही P4wnP1 रिबूट हो, उसी व्यवहार को फिर से स्क्रैच से सेटअप के विवरण को पुनः बनाए बिना पुनर्प्राप्त किया जा सकता है।

Notepad शुरू करना, "Hello world" टाइप करना और LED परिवर्तन के बाद notepad बंद करना अब तक सीखी गई चीजों से किया जा सकता है। एक संबंधित HIDScript कुछ इस प्रकार दिख सकता है:```
// Starting notepad
press("WIN R");         // Windows key + R, to open run dialog
delay(500);             // wait 500ms for the dialog to open
type("notepad.exe\n"); 	// type 'notepad.exe' to the run dialog, append a RETURN press
delay(2000);            // wait 2 seconds for notepad to come up

// Type the message
type("Hello world")     // Type "Hello world" to notepad

// close notepad after LED change
waitLED(ANY);           // wait for a single LED change
press("ALT F4");        // ALT+F4 shortcut to close notepad

//as we changed content, there will be a confirmation dialog before notepad exits
delay(500);             // wait for the confirmation dialog
press("RIGHT");         // move focus to next button (don't save) with RIGHT ARROW
press("SPACEBAR");      // confirm dialog with space

इस स्क्रिप्ट में केवल एक नई चीज़ है delay कमांड, जिसे अधिक समझाने की आवश्यकता नहीं है। यह दिए गए मिलीसेकंड के लिए निष्पादन में देरी करता है।

स्क्रिप्ट को वेबक्लाइंट HIDScript एडिटर में पेस्ट किया जा सकता है और इसका परीक्षण करने के लिए "run" के साथ शुरू किया जा सकता है।

इसे इच्छित तरीके से काम करना चाहिए, इसलिए हम लगभग पूरा कर चुके हैं। स्क्रिप्ट को रीबूट के बाद भी पुन: उपयोग करने में सक्षम होने के लिए, हम इसे स्थायी रूप से संग्रहीत करते हैं। यह वेबक्लाइंट के HIDScript टैब में "store" बटन दबाकर प्राप्त किया जा सकता है। एक नाम दर्ज करने (हम अभी के लिए tutorial1 का उपयोग करते हैं) और डायलॉग की पुष्टि करने के बाद, HIDScript संग्रहीत हो जाना चाहिए। हम वेबक्लाइंट में "Load & Replace" बटन दबाकर इसकी जांच कर सकते हैं। संग्रहीत स्क्रिप्ट tutorial1.js नाम के साथ संग्रहीत स्क्रिप्ट की सूची में दिखाई देनी चाहिए (यदि "store" डायलॉग में पहले से प्रदान नहीं किया गया है, तो .js एक्सटेंशन स्वचालित रूप से जोड़ा जाता है)।

चेतावनी: यदि स्टोर डायलॉग में पहले से मौजूद किसी फ़ाइल का नाम उपयोग किया जाता है, तो आगे कोई पुष्टि मांगे बिना संबंधित फ़ाइल को अधिलेखित कर दिया जाता है।

आइए SSH सत्र से CLI क्लाइंट का उपयोग करके संग्रहीत स्क्रिप्ट को इस प्रकार शुरू करने का प्रयास करें:

root@kitploit:~
P4wnP1_cli hid run tutorial1.js
```
यह काम करना चाहिए था। इसका मतलब है, P4wnP1 A.L.O.A. CLI क्लाइंट का उपयोग करके, उन सभी अनुप्रयोगों से संग्रहीत HIDScripts प्रारंभ करना संभव है जो शेल कमांड का समर्थन करते हैं या एक साधारण bash स्क्रिप्ट से।

Windows के लिए संकलित CLI क्लाइंट से दूरस्थ रूप से स्क्रिप्ट प्रारंभ करना भी संभव होगा। यह मानते हुए कि Windows होस्ट WiFi के माध्यम से P4wnP1 A.L.O.A. तक पहुँचने में सक्षम है और P4wnP1 का IP `172.24.0.1` पर सेट है, उपयुक्त कमांड इस प्रकार दिखेगा
यह:```
P4wnP1_cli.exe --host 172.24.0.1 hid run tutorial1.js
```
*नोट: इस लेखन के समय, मैंने अभी तक यह तय नहीं किया है कि P4wnP1 A.L.O.A. प्रत्येक संभावित प्लेटफ़ॉर्म और आर्किटेक्चर के लिए एक CLI बाइनरी शिप करता है या नहीं। लेकिन यह संभावना है कि प्रमुख प्लेटफ़ॉर्म के लिए प्रीकंपाइल्ड संस्करण प्रदान किए जाएंगे। यदि नहीं - यह कोई बड़ी समस्या नहीं है, क्योंकि CLI क्लाइंट के Go कोड का क्रॉस-कंपाइलेशन एक मिनट से भी कम समय लेता है।*

अगला कदम स्क्रिप्ट को हर बार P4wnP1 को USB होस्ट से दोबारा जोड़े जाने पर फिर से चलने देना है। ऐसा व्यवहार प्राप्त करने के लिए हम पहले से उपयोग किया गया एक तरीका यह था कि सब कुछ एक लूप में लपेट दिया जाए और उसमें `waitLED(ANY_OR_NONE)` जोड़ दिया जाए। `waitLED(ANY_OR_NONE)` ने सुनिश्चित किया कि लूप तभी जारी रहे जब लक्ष्य USB होस्ट वैश्विक कीबोर्ड LED स्थिति का एक अपडेट भेजकर संकेत देता है कि कीबोर्ड ड्राइवर इनपुट प्राप्त करने के लिए तैयार है। इस प्रकार संशोधित स्क्रिप्ट कुछ इस तरह दिख सकती है:```
while (true) {
  waitLED(ANY_OR_NONE);     // wait till keyboard driver sends the initial LED state
  
  // Starting notepad
  press("WIN R");           // Windows key + R, to open run dialog
  delay(500);               // wait 500ms for the dialog to open
  type("notepad.exe\n");    // type 'notepad.exe' to the run dialog, append a RETURN press
  delay(2000);              // wait 2 seconds for notepad to come up

  // Type the message
  type("Hello world")       // Type "Hello world" to notepad

  // close notepad after LED change
  waitLED(ANY);       // wait for a single LED change
  press("ALT F4");          // ALT+F4 shortcut to close notepad

  //as we changed content, there will be a confirmation dialog before notepad exits
  delay(500);               // wait for the confirmation dialog
  press("RIGHT");           // move focus to next button (don't save) with RIGHT ARROW
  press("SPACEBAR");        // confirm dialog with space 
}
```
ऊपर दिया गया स्क्रिप्ट, वास्तव में, हर बार जब P4wnP1 USB होस्ट से जुड़ता है तो चलेगा। लेकिन स्क्रिप्ट बहुत मजबूत नहीं है, क्योंकि इसमें दूसरा `waitLED` शामिल है, जो तब तक इंतजार करता है जब तक notepad.exe फिर से बंद न हो जाए।

इस तरह करने में कई समस्याएँ शामिल हैं। उदाहरण के लिए यदि "Hello world" टाइप होने से पहले P4wnP1 को डिटैच कर दिया जाता है, तो अब ब्लॉक करने वाला `waitLED` वही होगा जो `press("ALT F4")` से पहले है और निष्पादन HIDScript के इसी बिंदु पर जारी रहेगा जब P4wnP1 फिर से (शायद किसी भिन्न) USB होस्ट से जुड़ता है।

चुनी गई दृष्टिकोण के लिए एक निश्चित समाप्ति मानदंड निम्नलिखित समस्या है: यह आवश्यकता कि स्क्रिप्ट को P4wnP1 को USB होस्ट से जोड़ने के बाद केवल एक बार चलना चाहिए, पूरी नहीं की जा सकी, क्योंकि NUM LOCK को कई बार दबाने से स्क्रिप्ट बार-बार पुनः शुरू हो जाएगी।

#### आइए TriggerActions का परिचय दें

समस्या का समाधान तथाकथित "TriggerActions" हैं। जैसा कि नाम से पता चलता है, यह P4wnP1 A.L.O.A. वर्कफ़्लो अवधारणा पूर्वनिर्धारित ट्रिगर्स के आधार पर क्रियाओं को सक्रिय करती है।

मैं किस बारे में बात कर रहा हूँ इसका अंदाजा लगाने के लिए, वेबक्लाइंट पर "TRIGGER ACTIONS" टैब पर जाएँ। वर्तमान सेटअप के आधार पर, पहले से ही TriggerActions मौजूद हो सकते हैं। हमें अब मौजूदा TriggerActions की परवाह नहीं है।

"ADD ONE" बटन दबाएँ और एक नया TriggerActions जोड़ा जाना चाहिए और तुरंत संपादन मोड में खुल जाना चाहिए। नया TriggerAction डिफ़ॉल्ट रूप से अक्षम है और इसे संपादन योग्य बनाने के लिए सक्षम करना होगा। इसलिए हम सक्षम स्विच को टॉगल करते हैं।

अब "Trigger" नामक ड्रॉप-डाउन मेनू से विकल्प "USB gadget connected to host" चयनित होना चाहिए। क्रिया में प्रीसेट "write log entry" चयनित होना चाहिए। हम इसे ऐसे ही छोड़ देते हैं और "Update" बटन दबाते हैं।

नव जोड़ा गया TriggerAction अब TriggerActions ओवरव्यू में दिखाई देना चाहिए (सबसे अधिक ID वाला) और चयनित ट्रिगर और चयनित क्रिया का सारांश पठनीय रूप में दिखाना चाहिए।

यह जाँचने के लिए कि नव परिभाषित TriggerAction काम करता है या नहीं, वेबक्लाइंट के "Event Log" टैब पर जाएँ। सुनिश्चित करें कि आपने वेबक्लाइंट को WiFi (USB ईथरनेट के माध्यम से नहीं) के माध्यम से खोला है। P4wnP1 को बाहरी शक्ति प्रदान करें, इसे USB होस्ट से डिस्कनेक्ट करें और फिर से कनेक्ट करें। हर बार जब P4wnP1 USB होस्ट से जुड़ता है, तुरंत क्लाइंट को एक लॉग संदेश भेजा जाना चाहिए।

यदि आपने इसे कुछ बार दोहराया, तो आपने शायद देखा होगा कि "USB gadget connected to host" ट्रिगर बहुत तेज़ी से सक्रिय होता है (या USB एनुमरेशन चरण के प्रारंभिक चरण में)। अधिक सटीक होने के लिए: जब यह ट्रिगर सक्रिय होता है, तो यह ज्ञात है कि P4wnP1 एक USB होस्ट से जुड़ा था, लेकिन इसकी कोई गारंटी नहीं है कि USB होस्ट सभी आवश्यक USB डिवाइस ड्राइवरों को लोड करने में सफल रहा। **वास्तव में यह बहुत संभावना नहीं है कि ट्रिगर के सक्रिय होने पर USB कीबोर्ड ड्राइवर लोड हो गया हो। हमें इसे ध्यान में रखना होगा।**

अपने कार्य के साथ आगे बढ़ने से पहले, हम एक अतिरिक्त परीक्षण करते हैं। "TriggerAction" टैब पर वापस जाएँ और हम अपने नव निर्मित TriggerAction के लिए पेन जैसा दिखने वाला छोटा नीला बटन दबाते हैं। हम फिर से संपादन मोड में आ जाते हैं।

इस बार, हम `One shot` विकल्प को सक्षम करते हैं। बाद में "Event Log" पर वापस जाएँ, और फिर से, P4wnP1 को USB होस्ट से डिटैच और री-अटैच करें। इस बार TriggerAction केवल एक बार सक्रिय होना चाहिए। इसके बाद P4wnP1 को USB होस्ट से कितनी भी बार री-अटैच किया जाए, कोई नया लॉग संदेश जो USB कनेक्ट का संकेत देता है, नहीं बनना चाहिए।

यह उल्लेख करने योग्य है कि "One shot" TriggerAction ट्रिगर के सक्रिय होने के बाद हटाया नहीं जाता है। इसके बजाय TriggerAction फिर से अक्षम कर दिया जाता है। पुनः सक्षम करने से TriggerAction को पुनर्परिभाषित किए बिना पुन: उपयोग करने की अनुमति मिलती है। जब तक किसी TriggerAction पर लाल "trash" बटन नहीं दबाया जाता, जो संबंधित TriggerAction को हटा देगा, तब तक कुछ भी नहीं खोता है।

**चेतावनी: यदि किसी TriggerAction के लिए डिलीट बटन पर क्लिक किया जाता है, तो TriggerAction बिना किसी और पुष्टि के स्थायी रूप से हटा दिया जाता है।**

इस बिंदु पर आइए स्पष्ट काम करें। हम निर्मित TriggerAction को संपादित करते हैं और निष्पादित करने के लिए क्रिया के रूप में "write log entry" के बजाय "start a HIDScript" का चयन करते हैं। इसके अतिरिक्त हम "one-shot" को फिर से अक्षम करते हैं। "script name" नामक एक नया इनपुट फ़ील्ड दिखाया जाता है। इस इनपुट फ़ील्ड पर क्लिक करने से सभी संग्रहीत HIDScripts के लिए एक चयन संवाद खुलता है, जिसमें हमारा पहले बनाया गया `tutorial1.js` HIDScript भी शामिल है।

*इससे पहले कि हम परीक्षण करें कि यह काम करता है, मैं "write log entry" क्रिया पर एक त्वरित टिप्पणी कर दूं: P4wnP1 A.L.O.A. उन ट्रिगर्स पर नज़र नहीं रखता जो पहले ही सक्रिय हो चुके हैं। इसका मतलब है कि "write log entry" क्रिया द्वारा बनाए गए लॉग प्रविष्टियाँ सभी सुनने वाले क्लाइंट को वितरित की जाती हैं, लेकिन P4wnP1 सेवा द्वारा संग्रहीत नहीं की जाती हैं (विभिन्न कारणों से)। दूसरी ओर वेबक्लाइंट लॉग प्रविष्टि को तब तक संग्रहीत करता है जब तक कि वेबक्लाइंट स्वयं पुनः लोड नहीं हो जाता। यही बात उन घटनाओं पर भी लागू होती है जो HIDScript कार्यों से संबंधित हैं। यदि कोई HIDScript समाप्त होता है (सफलता या त्रुटि के साथ), तो वर्तमान में खुले सभी वेबक्लाइंट को एक घटना भेजी जाती है। संक्षेप में, प्रत्येक वेबक्लाइंट के पास एक रनटाइम स्थिति होती है, जिसमें कोर सेवा की तुलना में अधिक जानकारी होती है। यदि वेबक्लाइंट की रनटाइम स्थिति बहुत बड़ी हो जाती है (बहुत अधिक मेमोरी उपयोग), तो "ऐतिहासिक" स्थिति जानकारी को साफ़ करने के लिए केवल क्लाइंट को पुनः लोड करना होता है। यदि कोर सेवा भी ऐसा ही व्यवहार करे और प्रत्येक ऐतिहासिक जानकारी संग्रहीत करे, तो यह बहुत जल्द संसाधनों से बाहर हो जाएगी। इस प्रकार यह अवधारणा P4wnP1 A.L.O.A. के अधिकांश उप-प्रणालियों पर लागू होती है।*

अब अपने कार्य पर वापस आते हैं। हमारे पास एक TriggerAction तैयार है, जिसे हर बार P4wnP1 के USB होस्ट से जुड़ने पर हमारे HIDScript को सक्रिय करना चाहिए।

लक्ष्य USB होस्ट के आधार पर, यह कमोबेश विश्वसनीय रूप से काम करता है। मेरे परीक्षण सेटअप में यह बिल्कुल भी काम नहीं किया और इसका एक कारण है:

आइए हमारे HIDScript की पहली कुछ पंक्तियों की समीक्षा करें:```
// Starting notepad
press("WIN R");         // Windows key + R, to open run dialog
delay(500);             // wait 500ms for the dialog to open
type("notepad.exe\n"); 	// type 'notepad.exe' to the run dialog, append a RETURN press
... snip ...
```
यह तथ्य याद करते हुए कि "USB गैजेट कनेक्टेड" ट्रिगर प्रारंभिक USB एन्यूमरेशन चरण में फायर होता है और USB होस्ट का 
कीबोर्ड ड्राइवर आवश्यक रूप से लोड नहीं हुआ है, समस्या स्पष्ट हो जाती है। हमें स्क्रिप्ट में किसी प्रकार की देरी जोड़नी होगी 
ताकि यह सुनिश्चित हो सके कि कीबोर्ड ड्राइवर ऊपर है (अन्यथा हमारी कीस्ट्रोक्स कहीं नहीं पहुंचेंगी)।

जैसा कि हम पहले से जानते हैं कि इष्टतम देरी की भविष्यवाणी करना संभव नहीं है, हम पहले बताए गए `waitLED(ANY_OR_NONE)` दृष्टिकोण के साथ चलते हैं। नई स्क्रिप्ट इस प्रकार है:```
waitLED(ANY_OR_NONE);   //assure keyboard driver is ready

// Starting notepad
press("WIN R");	        // Windows key + R, to open run dialog
delay(500);             // wait 500ms for the dialog to open
type("notepad.exe\n"); 	// type 'notepad.exe' to the run dialog, append a RETURN press
delay(2000);            // wait 2 seconds for notepad to come up

// Type the message
type("Hello world")     // Type "Hello world" to notepad

// close notepad after LED change
waitLEDRepeat(ANY);     // wait for a single LED change
press("ALT F4");        // ALT+F4 shortcut to close notepad

//as we changed content, there will be a confirmation dialog before notepad exits
delay(500);             // wait for the confirmation dialog
press("RIGHT");         // move focus to next button (don't save) with RIGHT ARROW
press("SPACEBAR");      // confirm dialog with space
```
संशोधित स्क्रिप्ट को ठीक उसी नाम (`tutorial1`) के तहत स्टोर करने से पूर्व HIDScript बिना किसी और पुष्टि के ओवरराइट हो जाती है, जैसा कि पहले बताया गया था। इस प्रकार हमारे TriggerAction को समायोजित करने की कोई आवश्यकता नहीं है, क्योंकि TriggerAction जिस HIDScript नाम को संदर्भित करता है वह नहीं बदला है।

इस छोटे से बदलाव के साथ सब कुछ इच्छित रूप से काम करना चाहिए और स्क्रिप्ट हर बार जब हम USB होस्ट से अटैच होते हैं तो ट्रिगर होनी चाहिए, लेकिन केवल एक बार चले।

अब, यदि P4wnP1 रीबूट हो जाता है या बिजली खो देता है, तो हमारी HIDScript बच जाएगी, क्योंकि हमने इसे स्थायी रूप से संग्रहीत किया है, लेकिन TriggerAction गायब हो जाएगा। यह कहने की आवश्यकता नहीं है कि TriggerActions को भी स्थायी रूप से संग्रहीत किया जा सकता है।

"TriggerAction" टैब में "store" बटन बिल्कुल HIDScript एडिटर की तरह काम करता है। यह ध्यान दिया जाना चाहिए कि *सभी वर्तमान में सक्रिय TriggerActions* संग्रहीत हो जाएंगे यदि "store" डायलॉग की पुष्टि की जाती है (अक्षम किए गए सहित)।
सबसे अच्छा अभ्यास यह है कि स्टोर करने से पहले उन सभी TriggerActions को हटा दें जो वर्तमान कार्य के दायरे में नहीं आते हैं (यदि आवश्यक हो तो उन्हें पहले संग्रहीत किया जाना चाहिए था) और केवल वर्तमान कार्य से संबंधित TriggerActions के छोटे सेट को उपयुक्त नाम से स्टोर करें। संग्रहीत TriggerActions को सक्रिय में वापस लोड करने के लिए दो विकल्प हैं:
 - "load & replace" सभी सक्रिय ट्रिगर एक्शन को साफ करता है और केवल संग्रहीत को लोड करता है
 - "load & add" पहले से सक्रिय TriggerActions को रखता है और संग्रहीत को जोड़ता है। इस प्रकार "load & add" का उपयोग छोटे सेटों से एक जटिल TriggerAction सेट बनाने के लिए किया जा सकता है। परिणामी सेट को फिर से संग्रहीत किया जा सकता है।

अब हमें केवल अपना एकल TriggerAction स्टोर करना चाहिए, जो हमारी HIDScript शुरू करता है। हम स्टोर करने के लिए फिर से `tutorial1` नाम का उपयोग करते हैं और यह `tutorial1` नामक HIDScript से विरोध नहीं करेगा।

"TriggerAction" टैब में "load&replace" बटन दबाकर सफल स्टोरेज की पुष्टि करें। संग्रहीत TriggerAction सेट सूची में होना चाहिए और इसका नाम `tutorial1` होना चाहिए।

**चेतावनी: TriggerAction "load" डायलॉग प्रत्येक एक्शन के आगे लाल "trash" बटन दबाकर संग्रहीत TriggerActions को हटाने की अनुमति देते हैं। बटन दबाने से बिना किसी और पुष्टि के संबंधित TriggerAction सेट स्थायी रूप से हट जाता है**

इस बिंदु पर हम सुरक्षित रूप से अपने TriggerAction को "TriggerActions" टैब से हटा सकते हैं (!!लोड डायलॉग में से किसी एक के ट्रैश बटन से नहीं!!)।

सक्रिय लोगों से TriggerAction हटाने पर, यदि हम P4wnP1 को USB होस्ट से डिटैच और री-अटैच करते हैं तो कुछ नहीं होता।

वैसे भी, संग्रहीत TriggerAction सेट `tutorial1` रीबूट के बाद भी बना रहेगा और किसी भी समय पुनः लोड किया जा सकता है।

TriggerAction सेट को वेबक्लाइंट से पुनः लोड करने के बजाय, हम इसे CLI क्लाइंट का उपयोग करके पूरा करने का प्रयास करते हैं।

आइए `template deploy` उप-कमांड की सहायता स्क्रीन पर एक त्वरित नज़र डालते हैं:```
root@kali:~# P4wnP1_cli template deploy -h
Deploy given gadget settings

Usage:
  P4wnP1_cli template deploy [flags]

Flags:
  -b, --bluetooth string         Deploy Bluetooth template
  -f, --full string              Deploy full settings template
  -h, --help                     help for deploy
  -n, --network string           Deploy network settings template
  -t, --trigger-actions string   Deploy trigger action template
  -u, --usb string               Deploy USB settings template
  -w, --wifi string              Deploy WiFi settings templates

Global Flags:
      --host string   The host with the listening P4wnP1 RPC server (default "localhost")
      --port string   The port on which the P4wnP1 RPC server is listening (default "50051")

``` 
उपयोग स्क्रीन दिखाती है कि TriggerAction Templates को `-t` फ़्लैग के साथ तैनात किया जा सकता है। हम संग्रहीत TriggerAction सेट को पुनर्स्थापित करने के लिए निम्नलिखित कमांड चलाते हैं:``` 
P4wnP1_cli template deploy -t tutorial1
``` 
The TriggerAction जो USB होस्ट कनेक्शन पर HIDScript चलाता है, अब फिर से लोड हो गया है और इसे वेबक्लाइंट के TriggerActions टैब में दिखना चाहिए। यदि P4wnP1 A.L.O.A. USB होस्ट से जुड़ा है, तो स्क्रिप्ट फिर से चलनी चाहिए।

टेम्प्लेट को स्टोर करना, लोड करना और डिप्लॉय करना P4wnP1 के ऑटोमेशन वर्कफ़्लो के दो मुख्य अवधारणाओं में से एक है, दूसरा पहले से ज्ञात TriggerActions हैं। यह उल्लेखनीय है कि न केवल TriggerAction सेट को टेम्प्लेट के रूप में स्टोर और लोड किया जा सकता है, बल्कि TriggerActions का उपयोग पहले से स्टोर किए गए टेम्प्लेट को डिप्लॉय करने के लिए भी किया जा सकता है, यदि यह समझ में आता है।

अपने कार्यों पर पुनर्विचार करते हुए, ऐसा लगता है कि अब सभी परिभाषित आवश्यकताएं पूरी हो गई हैं:
- हमने विंडोज USB होस्ट के एडिटर में "Hello world" टाइप किया
- एडिटर P4wnP1 द्वारा खोला गया है, उपयोगकर्ता द्वारा मैन्युअल रूप से नहीं
- जब कीबोर्ड LED एक बार टॉगल होती है, तो एडिटर स्वचालित रूप से बंद हो जाता है
- हर बार जब P4wnP1 USB होस्ट से जुड़ता है, यह व्यवहार दोहराया जाता है
- HIDScript केवल एक बार चलती है, जब तक P4wnP1 USB होस्ट से पुनः नहीं जुड़ता, भले ही क्रमिक कीबोर्ड LED परिवर्तन हों
- यदि P4wnP1 रीबूट किया जाता है, तो संग्रहीत TriggerAction सेट (जो फिर से संग्रहीत HIDScript को संदर्भित करता है) को लोड करके समान व्यवहार प्राप्त किया जा सकता है। यह या तो एक CLI कमांड से या वेबक्लाइंट के ट्रिगर एक्शन टैब से एक सरल "load&add" या "load&replace" द्वारा प्राप्त किया जा सकता है।

एक बार फिर आइए अतिरिक्त लक्ष्य जोड़ें:
- यह सुनिश्चित किया जाना चाहिए कि USB कॉन्फ़िगरेशन में कीबोर्ड कार्यक्षमता सक्षम है (वर्तमान सेटअप ऐसा नहीं करता है और यदि USB कीबोर्ड अक्षम है तो TriggerAction HIDScript शुरू नहीं कर सकता)
- बनाया गया सेटअप P4wnP1 A.L.O.A. के बूट पर लागू होना चाहिए, बिना मैन्युअल रूप से TriggerAction सेट लोड करने की आवश्यकता के। सेटअप P4wnP1 के रीबूट पर भी बना रहना चाहिए।

दो अतिरिक्त लक्ष्यों को प्राप्त करने के लिए, हमें एक नए विषय में गोता लगाना होगा और...

#### Master Templates और Startup Master Template का परिचय

Master Templates में जाने से पहले, हम कुछ ऐसा करते हैं जो अभी तक नहीं किया गया है, क्योंकि अब तक सब कुछ इच्छित तरीके से काम कर रहा था: हम अपने कार्य के अनुरूप एक मान्य USB कॉन्फ़िगरेशन परिभाषित करते हैं!

- device serial number: 123456789
- device product name: Auto Writer
- device manufacturer: The Creator
- Product ID: 0x9876
- Vendor ID: 0x1D6B
- enabled USB functions
  - HID keyboard
  - HID mouse

आइए पहले CLI कमांड के उपयोग स्क्रीन पर एक नज़र डालें, जिसका उपयोग इन सेटिंग्स को तैनात करने के लिए किया जा सकता है:``` 
root@kali:~# P4wnP1_cli usb set -h
set USB Gadget settings

Usage:
  P4wnP1_cli usb set [flags]

Flags:
  -e, --cdc-ecm               Use the CDC ECM gadget function
  -n, --disable               If this flag is set, the gadget stays inactive after deployment (not bound to UDC)
  -h, --help                  help for set
  -k, --hid-keyboard          Use the HID KEYBOARD gadget function
  -m, --hid-mouse             Use the HID MOUSE gadget function
  -g, --hid-raw               Use the HID RAW gadget function
  -f, --manufacturer string   Manufacturer string (default "MaMe82")
  -p, --pid string            Product ID (format '0x1347') (default "0x1347")
  -o, --product string        Product name string (default "P4wnP1 by MaMe82")
  -r, --rndis                 Use the RNDIS gadget function
  -s, --serial                Use the SERIAL gadget function
  -x, --sn string             Serial number (alpha numeric) (default "deadbeef1337")
  -u, --ums                   Use the USB Mass Storage gadget function
      --ums-cdrom             If this flag is set, UMS emulates a CD-Rom instead of a flashdrive (ignored, if UMS disabled)
      --ums-file string       Path to the image or block device backing UMS (ignored, if UMS disabled)
  -v, --vid string            Vendor ID (format '0x1d6b') (default "0x1d6b")

Global Flags:
      --host string   The host with the listening P4wnP1 RPC server (default "localhost")
      --json          Output results as JSON if applicable
      --port string   The port on which the P4wnP1 RPC server is listening (default "50051")
``` 
कमांड में बहुत सारे फ़्लैग होते हैं, लेकिन कई बदलने योग्य USB सेटिंग्स भी मौजूद हैं। 
हमारे परिभाषित USB सेटअप को इस प्रकार तैनात किया जा सकता है, CLI का उपयोग करके:```
root@kali:~# P4wnP1_cli usb set \
> --sn 123456789 \
> --product "Auto Writer" \
> --manufacturer "The Creator" \
> --pid "0x9876" \
> --vid "0x1d6b" \
> --hid-keyboard \
> --hid-mouse
Successfully deployed USB gadget settings
Enabled:      true
Product:      Auto Writer
Manufacturer: The Creator
Serialnumber: 123456789
PID:          0x9876
VID:          0x1d6b

Functions:
    RNDIS:        false
    CDC ECM:      false
    Serial:       false
    HID Mouse:    true
    HID Keyboard: true
    HID Generic:  false
    Mass Storage: false
```
(लंबे) कमांड का आउटपुट परिणामी USB सेटिंग्स दिखाता है। आइए यह सुनिश्चित करने के लिए वेबक्लाइंट के "USB सेटिंग्स" टैब की जाँच करें कि वे लागू हो गई हैं। यदि कुछ गलत नहीं हुआ है, तो सभी परिवर्तन प्रतिबिंबित होने चाहिए।

हालाँकि CLI का उपयोग करके USB सेटअप तैनात करना पूरी तरह से संभव है, फिर भी CLI के बजाय वेबक्लाइंट का उपयोग करने के कई लाभ हैं। इस मामले में:
- वेबक्लाइंट से सेटिंग्स बदलना आसान और अधिक सुविधाजनक है
- वेबक्लाइंट एक आंतरिक सेटिंग्स स्थिति रखता है, इसलिए वास्तव में तैनात किए बिना USB सेटिंग्स को परिभाषित किया जा सकता है (दूसरी ओर, CLI केवल उन्हें तैनात करके ही सेटिंग्स में हेरफेर कर सकता है। इससे, फिर से, P4wnP1 का संपूर्ण USB स्टैक और उस पर निर्भर सभी कार्यक्षमताएँ रीसेट हो जाती हैं। जैसे, पहले से चल रही HIDScript बाधित हो सकती है या USB नेटवर्क इंटरफ़ेस पुनः तैनात हो सकते हैं)
- वेबक्लाइंट की वर्तमान सेटिंग्स को पहले तैनात किए बिना एक स्थायी टेम्पलेट में संग्रहित किया जा सकता है
- CLI क्लाइंट (वर्तमान में) USB सेटिंग्स को संग्रहित करने में सक्षम नहीं है

हमारे वर्तमान मामले में, USB सेटिंग्स में आवश्यक बदलावों के लिए वेबक्लाइंट का उपयोग करना स्पष्ट रूप से बेहतर विकल्प है। CLI दृष्टिकोण (जिसका हमने यहाँ पहले उपयोग किया है) के बारे में अच्छी बात यह है: चूँकि CLI ने हमें USB सेटिंग्स तैनात करने के लिए मजबूर किया, हम उन्हें एक स्थायी टेम्पलेट में संग्रहित करने से पहले पुष्टि कर सकते थे कि वे काम कर रही हैं।

आइए USB सेटिंग्स को संग्रहित करने के साथ आगे बढ़ें:

हम फिर से "संग्रहित करें" बटन दबाते हैं, इस बार "USB सेटिंग्स" टैब में। एक बार फिर हम टेम्पलेट को `tutorial1` कहते हैं (उसी नाम के अंतर्गत संग्रहित TriggerAction टेम्पलेट के साथ कोई विरोध नहीं है, क्योंकि USB सेटिंग्स के लिए एक अलग नामस्थान का उपयोग किया जाता है)।


अब हमारे पास दो नए और स्थायी रूप से संग्रहित टेम्पलेट हैं:
1) TriggerAction सेट के लिए एक टेम्पलेट, जिसका नाम `tutorial1` है
2) USB सेटिंग्स के लिए एक टेम्पलेट, जिसका नाम भी `tutorial1` है

यह मानते हुए कि वर्तमान USB सेटिंग्स, TriggerActions या दोनों की स्थिति किसी भी तरह बदल गई है, हम निम्नलिखित CLI कमांड जारी करके एक साथ दोनों संग्रहित सेटिंग्स को पुनः लोड कर सकते हैं:```
P4wnP1_cli template deploy --usb tutorial1 --trigger-actions tutorial1
```
`P4wnP1 template deploy` कमांड एक ही रन में P4wnP1 A.L.O.A. के उप-प्रणालियों में से प्रत्येक के लिए एक टेम्पलेट लोड कर सकता है (नेटवर्क उप-प्रणाली के लिए कई टेम्पलेट लोड किए जा सकते हैं, प्रति एडॉप्टर एक)। विभिन्न उप-प्रणालियों के लिए टेम्पलेट तैनात करना P4wnP1 A.L.O.A. के साथ काम करते समय एक सामान्य कार्य माना जाता है, क्योंकि अधिकांश मामलों में एक ही लक्ष्य प्राप्त करने के लिए कई उप-प्रणालियों को पुन: कॉन्फ़िगर करना आवश्यक होना चाहिए। इसका ध्यान रखने के लिए, तथाकथित *मास्टर टेम्पलेट* पेश किए गए हैं।

एक मास्टर टेम्पलेट में निम्न शामिल हो सकते हैं:
- पहले से संग्रहीत एक TriggerAction सेट टेम्पलेट
- पहले से संग्रहीत एक USB सेटिंग्स टेम्पलेट
- पहले से संग्रहीत एक वाई-फ़ाई सेटिंग्स टेम्पलेट
- पहले से संग्रहीत एक ब्लूटूथ सेटिंग्स टेम्पलेट
- कई संग्रहीत नेटवर्क सेटिंग्स टेम्पलेट (प्रति एडॉप्टर एक)

"जेनेरिक सेटिंग्स" टैब के "मास्टर टेम्पलेट संपादक" का उपयोग करके, वेबक्लाइंट से एक मास्टर टेम्पलेट को परिभाषित, संग्रहीत या लोड किया जा सकता है। मास्टर टेम्पलेट को परिभाषित करने के लिए वेबक्लाइंट का उपयोग करना एक सुविधाजनक तरीका है, क्योंकि यह आपको केवल उन टेम्पलेट का चयन करने की अनुमति देकर समर्थन करता है जो संबंधित उप-प्रणालियों के लिए पहले से संग्रहीत किए गए हैं (और वर्तमान में वेबक्लाइंट मास्टर टेम्पलेट को परिभाषित करने का एकमात्र तरीका है)।

तो आइए अपने वर्तमान कार्य के लिए एक मास्टर टेम्पलेट परिभाषित करें:
1) वेबक्लाइंट के "जेनेरिक सेटिंग्स" टैब पर जाएँ
2) "मास्टर टेम्पलेट संपादक" पर "ट्रिगरएक्शन टेम्पलेट" फ़ील्ड के दाईं ओर छोटे बटन पर क्लिक करें
3) डायलॉग से `tutorial1` टेम्पलेट चुनें और "OK" बटन से पुष्टि करें
4) यदि आपने गलत टेम्पलेट चुना है, तो डायलॉग को फिर से खोलें और एक अलग चुनें या वर्तमान चयन को हटाने के लिए "ट्रिगरएक्शन टेम्पलेट" के दाईं ओर "x" आइकन का उपयोग करें
5) "USB टेम्पलेट" चयन के लिए चरणों को दोहराएं, फिर से `tutorial1` चुनें (यह USB उप-प्रणाली के लिए एक अलग टेम्पलेट है, हालाँकि इसका नाम TriggerActions वाले से मेल खाता है)
6) जाँच करें कि बॉट, USB और TriggerActions दोनों के लिए सही टेम्पलेट चुने गए हैं, और अन्य सभी टेम्पलेट खाली छोड़ दिए गए हैं
7) "स्टोर" बटन दबाकर और `tutorial1` नाम देकर नए मास्टर टेम्पलेट को संग्रहीत करें

यह पुष्टि करने के लिए कि टेम्पलेट संग्रहीत हो गया है, आप "लोड स्टोर्ड" बटन का उपयोग कर सकते हैं - टेम्पलेट चयन में सूचीबद्ध होना चाहिए। "लोड स्टोर्ड" डायलॉग को फिर से रद्द करें।

अब "डिप्लॉय स्टोर्ड" बटन दबाएँ, `startup` नामक टेम्पलेट चुनें और "OK" से पुष्टि करें।

"लोड स्टोर्ड" फ़ंक्शन के विपरीत, जो एक संग्रहीत टेम्पलेट को मास्टर टेम्पलेट संपादक में लोड करता है, "डिप्लॉय स्टोर्ड" फ़ंक्शन एक मास्टर टेम्पलेट की सभी सेटिंग्स को P4wnP1 के संबंधित उप-प्रणालियों पर तुरंत लागू करता है (उन्हें मास्टर टेम्पलेट संपादक में लोड किए बिना भी)।

जैसे ही `startup` मास्टर टेम्पलेट वर्तमान वाई-फ़ाई सेटिंग्स को ओवरराइट करता है, ऐसा हो सकता है कि आपने वेबक्लाइंट से कनेक्शन खो दिया हो और P4wnP1 वाई-फ़ाई नेटवर्क से पुन: कनेक्ट करने की आवश्यकता हो।

एक बार जब आप सफलतापूर्वक पुन: कनेक्ट हो जाते हैं और वर्तमान USB सेटिंग्स और वर्तमान TriggerActions का निरीक्षण करते हैं, तो हमारे द्वारा पहले संग्रहीत की गई सेटिंग्स `startup` मास्टर टेम्पलेट की उप-सेटिंग्स द्वारा ओवरराइट कर दी गई हैं।

`tutorial1` मास्टर टेम्पलेट को फिर से तैनात करने के दो तरीके हैं:
1) "मास्टर टेम्पलेट संपादक" से "डिप्लॉय स्टोर्ड" डायलॉग का उपयोग करके इसे तैनात करना (जैसा कि एक मिनट पहले `startup` मास्टर टेम्पलेट के साथ किया गया था)
2) CLI क्लाइंट के साथ `P4wnP1_cli template deploy --full tutorial1` का उपयोग करके इसे तैनात करना (`--full` फ़्लैग मास्टर टेम्पलेट का उपनाम है)

मास्टर टेम्पलेट `tutorial1` को तैनात करने में सक्षम होने पर, हम पहले ही अपने एक नए लक्ष्य को प्राप्त कर चुके हैं:

यह सुनिश्चित है कि जब हम अपना कीस्ट्रोक इंजेक्शन सेटअप लोड करते हैं तो USB कॉन्फ़िगरेशन में कीबोर्ड कार्यक्षमता सक्षम होती है।

इस पर एक त्वरित सारांश कि यह कैसे काम करता है:

Read more

टूल डाउनलोड करें