
A DTrace on Windows Reimplementation
Steve का ट्रेसर। विंडोज़ syscall हुक का DTrace पुनः-कार्यान्वयन। इसे पैचगार्ड-संगत SSDT हुक की तरह समझें, लेकिन बिना हैक्स के। यह SSSDT (win32k APIs) का समर्थन नहीं करता, क्योंकि DTrace सिस्टम कॉल APIs स्वयं इस अतिरिक्त तालिका का समर्थन नहीं करते। सभी यूज़रमोड SSDT syscalls के अतिरिक्त Zw* कर्नेल APIs को भी ट्रेस किया जा सकता है।
यदि आप STrace के लिए नए प्लगइन विकसित कर रहे हैं, तो कृपया इस readme को अंत तक पढ़ें!
विंडोज़ पर DTrace कई प्रोब प्रकारों का समर्थन करता है। इनमें syscall, fbt, etw, profile और शायद और भी शामिल हैं। यह पुनः-कार्यान्वयन केवल syscall और etw प्रोब प्रकारों को पुनः लागू करता है। बाकी सभी प्रोब प्रकार इस प्रोजेक्ट के दायरे से पूरी तरह बाहर माने जाते हैं, और उन्हें कभी भी समर्थन नहीं दिया जाएगा। यदि आप अतिरिक्त प्रोब प्रकार जोड़ना चाहते हैं तो प्रोजेक्ट को fork करने के लिए स्वतंत्र महसूस करें। अन्य प्रोब प्रकारों और उनसे जुड़े सिस्टमों की जटिलता के कारण दायरा केवल syscall और etw प्रोब तक सीमित रखा गया था।
यह पुनः-कार्यान्वयन D स्क्रिप्टिंग भाषा को पूरी तरह त्याग देता है (ध्यान दें: DLang नहीं, जो अधिक लोकप्रिय आधुनिक भाषा है)। मूल DTrace कार्यान्वयन की तरह कर्नेल में VM की जटिलता इस प्रोजेक्ट के लिए अनुपयुक्त है। इसके बजाय, यह कार्यान्वयन सीधे उन प्रासंगिक C कॉलबैक को उजागर करता है जो DTrace विंडोज़ कर्नेल इंटरफेस में प्लग करने के लिए आवश्यक हैं। स्क्रिप्ट के 'hot-loading' को सक्षम करने के लिए मूल dtrace के VM + स्क्रिप्टिंग वातावरण के विकल्प के रूप में DLL-आधारित प्लगइन प्रणाली का उपयोग किया गया था। यह प्लगइन प्रणाली बिना किसी सुरक्षा जांच या बाहरी निर्भरता वाली एक 'सामान्य' यूज़रमोड DLL स्वीकार करती है और इसे मैन्युअल रूप से कर्नेल एड्रेस स्पेस में मैप करती है। plugin dll में ऐसे एक्सपोर्ट होते हैं जो कर्नेल syscall कॉलबैक होने पर आमंत्रित किए जाते हैं। कर्नेल APIs को DLL की सामान्य इम्पोर्ट टेबल (IAT) के माध्यम से हल किया जाता है, प्लगइन DLLs ntoskrnl.lib से लिंक होती हैं और फिर ड्राइवर इन APIs को लोड समय पर हल करेगा, जिससे प्लगइन DLLs के भीतर किसी भी सिस्टम API को सामान्य रूप से कॉल किया जा सकता है। इस प्लगइन प्रणाली का प्रदर्शन उत्कृष्ट है क्योंकि syscall ENTRY और RETURN के बीच सीधे नेटिव कोड निष्पादित होता है, न कि कोई स्क्रिप्ट इंटरप्रेटर या JIT। यह डिज़ाइन Microsoft द्वारा प्रदान किए गए dtrace कार्यान्वयन की तुलना में प्रदर्शन में सुधार करता है।
हुक सेट करना बहुत सरल है, आपको API नाम से हुक पंजीकृत/अपंजीकृत करने के लिए एक रूटीन मिलता है, जिसमें syscall से पहले और बाद के कॉलबैक होते हैं। कॉलबैक में तर्क और रिटर्न वैल्यू केवल-पठनीय मानों के रूप में उपलब्ध होते हैं। रिटर्न प्रोब में रिटर्न वैल्यू को स्पूफ किया जा सकता है और एंट्री प्रोब में तर्कों को संशोधित किया जा सकता है, लेकिन मूल syscall सामान्य रूप से किसी syscall को प्रतिस्थापित या 'रद्द' नहीं कर सकता - यह API एक पर्यवेक्षक के रूप में कार्य करता है। हालाँकि, (https://github.com/everdox/InfinityHook और https://github.com/everdox/InfinityHook/raw/master/resources/perf.png) में प्रलेखित समान एक चूक मौजूद है, जो syscall पॉइंटर को स्टैक पर प्रतिस्थापित करने की अनुमति देती है। इस चूक के साथ, किसी syscall को पूरी तरह से आपके नियंत्रण वाले रूटीन के पॉइंटर से बदलना संभव है। जब घटनाएँ घटती हैं और आपका हुक कॉलबैक सक्रिय होता है, तो आप जो चाहें किया जा सकता है। कॉलबैक सिंक्रोनस होते हैं, अर्थात यदि आप एंट्री कॉलबैक में निष्पादन में देरी करते हैं, जैसे while लूप में बैठकर, तो syscall कॉल उतने समय के लिए विलंबित हो जाएगी। सिस्टम कॉल का निष्पादन एंट्री कॉलबैक से वापसी के तुरंत बाद और रिटर्न कॉलबैक के प्रवेश से ठीक पहले होता है। यह प्रणाली पूरी तरह से पैचगार्ड-संगत है, हालाँकि DSE को अक्षम करना होगा, क्योंकि Microsoft दुर्भाग्यवश इस प्रकार के कर्नेल एक्सटेंशन को NT कर्नेल का हिस्सा मानता है और इसलिए सत्यापित करता है कि रूट हस्ताक्षरकर्ता विंडोज़ है। यह कस्टम कर्नेल हस्ताक्षरकर्ताओं को सक्षम करने जैसी तरकीबों के साथ काम नहीं करता, कर्नेल बूट के दौरान DSE वास्तव में बंद होना चाहिए।
ValidationFlags=IMGP_LATEST_MS_ROOT_REQUIRED | IMGP_WINDOWS_ROOT_REQUIRED | IMGP_MS_SIGNATURE_REQUIRED
Scenario=ImgSigningScenarioWindows
Rust ड्राइवर C++ ड्राइवर द्वारा उपयोग की जाने वाली DLL-आधारित प्लगइन प्रणाली को त्याग देता है और इसके बजाय विंडोज़ कर्नेल में wasm स्क्रिप्ट होस्ट करने के लिए वेब असेंबली इंटरप्रेटर का उपयोग करने का प्रयास करता है। यह मूल dtrace कार्यान्वयन के अधिक समान होने के लिए है, जो VM का उपयोग करता है, लेकिन DLang से बेहतर भाषा के साथ। यह सैंडबॉक्सिंग और अन्य अच्छे लाभ प्रदान करता है। POC पूर्ण है और काम करता है, लेकिन दुर्भाग्यवश WASMI के साथ WASM की इंटरप्रेटिंग की प्रदर्शन समस्याओं के कारण यह उपयोग योग्य नहीं है। इस वैकल्पिक डिज़ाइन के काम करने योग्य होने के लिए NT कर्नेल-संगत JIT-आधारित wasm इंजन की आवश्यकता होगी। इसे एक मज़ेदार नवीनता के रूप में शामिल किया गया है, और कुछ काम के साथ शायद किसी और चीज़ के लिए उपयोगी हो सकता है।
यह प्रोजेक्ट मुख्य रूप से अपने C++ और Rust घटकों के बीच विभाजित है। C ड्राइवर सुविधा-पूर्ण है और इसे प्राथमिकता दी जानी चाहिए। उच्च स्तर पर प्रोजेक्ट में निम्नलिखित घटक हैं
Visual Studio w/ DDK सेट करें
ड्राइवर और cli को बिल्ड करें, फ़ाइलों को स्क्रिप्ट वाले फ़ोल्डर में ले जाएँ, फिर install फ़ोल्डर में powershell स्क्रिप्ट को एडमिन के रूप में चलाएँ:
./install_as_admin.ps1
रीबूट करें, फिर STrace बूट एंट्री चुनें, और इस स्क्रीन पर F8 दबाएँ (enter नहीं!):

इससे यह स्क्रीन सामने आनी चाहिए, DSE अक्षम के साथ बूट चुनें:

सफल बूट के बाद, CLI का उपयोग ट्रेसिंग शुरू करने के लिए प्लगइन DLLs को लोड और अनलोड करने हेतु किया जा सकता है। दो उदाहरण प्लगइन प्रदान किए गए हैं। यदि आपको समस्याएँ आती हैं, तो नीचे दिए गए विवरण को ध्यान से पढ़ें। पहली बार आपको फिर से रीबूट करने की आवश्यकता हो सकती है, और संभवतः process hacker जैसे टूल का उपयोग करके STrace सेवा को at boot पर ऑटोस्टार्ट करने के लिए मैन्युअल रूप से सेट करना पड़ सकता है।
मूल DTrace की स्थापना यहाँ है: https://techcommunity.microsoft.com/t5/windows-kernel-internals/dtrace-on-windows-20h1-updates/ba-p/1127929। मूल DTrace के लिए Secure Boot और Virtualized Based Security कॉन्फ़िगर होना आवश्यक है, STrace के मामले में ऐसा नहीं है, क्योंकि यह उन प्रोब प्रकारों (FBT) को लागू नहीं करता जिनके लिए उन सुविधाओं की आवश्यकता होती है।
यह प्रोजेक्ट इंस्टॉलर के समान कार्य करता है, लेकिन MSI के बजाय एक सरल powershell स्क्रिप्ट के माध्यम से। प्रक्रिया सरल है। पहले एक apiset dll को system32 में कॉपी करें ताकि कर्नेल एक्सटेंशन सक्रिय हो जाए। फिर एक ड्राइवर एंट्री इंस्टॉल करें ताकि यूज़रमोड संचार के लिए ड्राइवर main सिस्टम स्टार्टअप पर निष्पादित हो। ApiSet DLLs डिजिटल रूप से हस्ताक्षरित हैं, इसलिए आवश्यकतानुसार मूल microsoft apiset का उपयोग किया गया था। यह फ़ाइल केवल बाइनरी रूप में प्रदान की गई है और एक्सटेंशन इम्पोर्ट को कार्यान्वित ड्राइवर की ओर इंगित करने के अलावा कोई तर्क नहीं रखती: ext-ms-win-ntos-trace-l1-1-0 -> dtrace.sys। इस तंत्र के विवरण के लिए https://www.geoffchappell.com/studies/windows/win32/apisetschema/index.htm (ApiSetSchemaExtensions) देखें।
STrace कर्नेल इनिशियलाइज़ेशन के दौरान बहुत पहले लोड होता है। बूट कॉन्फ़िगरेशन डेटाबेस (BCD) में Test Signing सक्षम करना पर्याप्त नहीं है। STrace को सफलतापूर्वक लोड करने के लिए Driver signature enforcement (DSE) अक्षम होना चाहिए, और यह हर बूट पर मैन्युअल रूप से किया जाना चाहिए। इसे सुविधाजनक बनाने के लिए इंस्टॉल स्क्रिप्ट उपयोगकर्ता के चयन हेतु एक आसान बूट मेनू एंट्री बनाती है। रीबूट के दौरान DSE को स्थायी रूप से अक्षम करने की अनुमति देने वाला कोई BCD फ्लैग नहीं है, कर्नेल विशेष रूप से इसे मना करता है।
बूट पर DSE अक्षम करना भूल जाने पर, पुनः आरंभ करने पर आपको Automatic Repair मेनू देखने को मिलेगा। आप बिना किसी नुकसान के फिर से कोशिश कर सकते हैं; यदि बूट लगातार विफल रहता है, तो STrace ड्राइवर को drivers फ़ोल्डर से मैन्युअल रूप से हटाना होगा। ध्यान रखें कि बूट विफलताओं के कारण windows द्वारा STrace सेवा का autorun फ्लैग अक्षम किया जा सकता है*; यदि कभी भी बूट विफलता होती है, तो आपको इसे वापस autorun पर सेट करने की आवश्यकता हो सकती है।
अपने स्वयं के प्लगइन विकसित करने के लिए किसी मौजूदा प्लगइन को आधार प्रोजेक्ट के रूप में उपयोग करना सबसे अच्छा है। Visual Studio प्रोजेक्ट्स बिना किसी निर्भरता के स्वतंत्र बाइनरी उत्पन्न करने के लिए कई अति-विशिष्ट सेटिंग्स के साथ सेट किए गए हैं। गैर-डिफ़ॉल्ट सेटिंग्स सूचीबद्ध करने के लिए बहुत अधिक हैं, इसलिए बस किसी एक प्रोजेक्ट की प्रतिलिपि बनाएँ और अपना तर्क जोड़ने के लिए कोड संशोधित करें (https://stackoverflow.com/questions/884255/visual-studio-copy-project)। यदि आप एक उपयोगी प्लगइन बनाते हैं, तो कृपया PR सबमिट करें ! जितने अधिक प्लगइन बनाए जाएँगे, यह प्रणाली सभी के लिए उतनी ही अधिक उपयोगी होगी!