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

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

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

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

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

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
Unwinder — रस्ट के लिए कॉल स्टैक स्पूफिंग | Kitploit
उपकरण/GitHubGitHub/kudaes/unwinder
आईडीएस/आईपीएस से बचनापोस्ट-शोषणरेड टीमिंगपेलोड डेवलपमेंटप्रतिकूल हमला
GitHubkudaes/unwinder

Unwinder

रस्ट के लिए कॉल स्टैक स्पूफिंग

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

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

सभी देखें →

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

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

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

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

सामग्री

  • SilentMoonWalk
    • विवरण
    • श्रेय
    • उपयोग
      • call_function!() मैक्रो
      • indirect_syscall!() मैक्रो
      • पैरामीटर पास करना
    • उदाहरण
      • kernel32.dll!Sleep() को कॉल करना
      • kernel32.dll!OpenProcess() को कॉल करना
      • NtDelayExecution() को अप्रत्यक्ष syscall के रूप में कॉल करना
      • मैक्रो कॉल्स को जोड़ना
    • विचारणीय बातें
      • प्रारंभिक फ्रेम
      • PoC
  • स्टैक प्रतिस्थापन
    • विवरण
    • उपयोग
    • व्यावहारिक उदाहरण
    • टिप्पणियाँ

SilentMoonWalk

विवरण

Unwinder, SilentMoonWalk तकनीक का पूर्ण शस्त्रीकरण प्रदान करता है, जो Rust में पूर्ण और स्थिर कॉल स्टैक स्पूफिंग प्राप्त करने की अनुमति देता है।

इस तकनीक में निम्नलिखित विशेषताएँ हैं:

  • किसी भी मनमाने फ़ंक्शन को अधिकतम 11 पैरामीटर के साथ चलाने का समर्थन।
  • अप्रत्यक्ष syscalls (बिना अतिरिक्त heap आवंटन के) को अधिकतम 11 पैरामीटर के साथ चलाने का समर्थन।
  • यह क्रेट इसके माध्यम से बुलाए गए फ़ंक्शनों द्वारा लौटाए गए मान को प्राप्त करने की अनुमति देता है।
  • स्पूफिंग प्रक्रिया को कॉल स्टैक आकार बढ़ाए बिना कितनी भी बार जोड़ा जा सकता है।
  • स्पूफिंग प्रक्रिया के दौरान दक्षता बढ़ाने के लिए TLS का उपयोग किया जाता है।
  • क्रेट के लिए आवश्यक किसी भी Windows API कॉल को करने के लिए dinvoke_rs का उपयोग किया जाता है।
  • श्रेय

    SilentMoonWalk तकनीक के निर्माताओं को धन्यवाद:

    • KlezVirus
    • Waldo-IRC
    • Trickster0

    और निश्चित रूप से namazso को उस Twitter थ्रेड के लिए एक बड़ा धन्यवाद, जिसने इस पूरे प्रोजेक्ट को प्रेरित किया।

    उपयोग

    इस क्रेट को अपने प्रोजेक्ट में आयात करने के लिए अपने cargo.toml में निम्नलिखित पंक्ति जोड़ें और release मोड पर कंपाइल करें:

    root@kitploit:~
    [dependencies]
    unwinder = "=0.1.4"
    

    इस क्रेट की मुख्य कार्यक्षमता को दो मैक्रोज़ में लपेटा गया है:

    • call_function!() मैक्रो एक साफ कॉल स्टैक के साथ किसी भी मनमाने फ़ंक्शन को चलाने की अनुमति देता है।
    • indirect_syscall!() मैक्रो एक साफ कॉल स्टैक के साथ निर्दिष्ट (अप्रत्यक्ष) syscall निष्पादित करता है।

    इनमें से किसी भी मैक्रो का उपयोग करने के लिए std::ffi::c_void डेटा प्रकार को आयात करना आवश्यक है।

    दोनों मैक्रोज़ एक *mut c_void लौटाते हैं जिसका उपयोग निष्पादित फ़ंक्शन द्वारा लौटाए गए मान को प्राप्त करने के लिए किया जा सकता है। अधिक विस्तृत जानकारी उदाहरण अनुभाग में दी गई है।

    call_function मैक्रो

    इस मैक्रो का उपयोग एक साफ कॉल स्टैक के साथ किसी भी वांछित फ़ंक्शन को कॉल करने के लिए किया जाता है। मैक्रो निम्नलिखित पैरामीटर की अपेक्षा करता है:

    • पहला पैरामीटर कॉल स्टैक स्पूफ करने के बाद कॉल करने के लिए मेमोरी एड्रेस है। यह पैरामीटर usize, isize या पॉइंटर के रूप में पास किया जाना चाहिए।
    • दूसरा पैरामीटर एक bool है जो दर्शाता है कि स्टार्ट फ़ंक्शन फ्रेम को रखना है या नहीं। यदि आप इसके बारे में निश्चित नहीं हैं, तो इसे false पर सेट करें, जो हमेशा एक अच्छे कॉल स्टैक की गारंटी देता है।
    • अगले पैरामीटर वे तर्क हैं जो कॉल स्टैक स्पूफ हो जाने के बाद फ़ंक्शन को भेजने हैं।

    indirect_syscall मैक्रो

    इस मैक्रो का उपयोग एक साफ कॉल स्टैक के साथ किसी भी वांछित अप्रत्यक्ष syscall को करने के लिए किया जाता है। मैक्रो निम्नलिखित पैरामीटर की अपेक्षा करता है:

    • पहला पैरामीटर एक स्ट्रिंग है जिसमें NT फ़ंक्शन का नाम होता है जिसका syscall आप निष्पादित करना चाहते हैं।
    • दूसरा पैरामीटर एक bool है जो दर्शाता है कि स्टार्ट फ़ंक्शन फ्रेम को रखना है या नहीं। यदि आप इसके बारे में निश्चित नहीं हैं, तो इसे false पर सेट करें, जो हमेशा एक अच्छे कॉल स्टैक की गारंटी देता है।
    • अगले पैरामीटर वे तर्क हैं जो NT फ़ंक्शन को भेजने हैं।

    पैरामीटर पास करना

    इन दोनों मैक्रोज़ में विभिन्न प्रकार के तर्क पास करने के लिए, निम्नलिखित बातों को ध्यान में रखा जाना चाहिए:

    • कोई भी मूल डेटा प्रकार जिसे usize (u8-u64, i8-i64, bool, आदि) में परिवर्तित किया जा सकता है, सीधे मैक्रोज़ में पास किया जा सकता है।
    • 8, 16, 32 या 64 बिट आकार की संरचनाएँ और यूनियनें ऐसे पास की जाती हैं जैसे कि वे समान आकार के पूर्णांक हों।
    • 64 बिट से बड़े आकार की संरचनाएँ और यूनियनें पॉइंटर के रूप में पास की जानी चाहिए।
    • स्ट्रिंग्स (&str और String) को पॉइंटर के रूप में पास किया जाना चाहिए।
    • नल पॉइंटर्स (ptr::null(), ptr::null_mut(), आदि) को 0 के रूप में पास किया जाता है (चाहे वह u8, u16, i32 या कोई अन्य हो)।
    • फ्लोटिंग-पॉइंट और डबल-प्रिसिजन पैरामीटर वर्तमान में समर्थित नहीं हैं।
    • किसी भी अन्य डेटा प्रकार को पॉइंटर के रूप में पास किया जाना चाहिए।

    उदाहरण

    Sleep को कॉल करना

    root@kitploit:~
    let k32 = dinvoke_rs::dinvoke::get_module_base_address("kernel32.dll");
    let sleep = dinvoke_rs::dinvoke::get_function_address(k32, "Sleep"); // Memory address of kernel32.dll!Sleep() 
    let miliseconds = 1000i32;
    unwinder::call_function!(sleep, false, miliseconds);
    

    OpenProcess को कॉल करना

    root@kitploit:~
    let k32 = dinvoke_rs::dinvoke::get_module_base_address("kernel32.dll"); 
    let open_process: isize = dinvoke_rs::dinvoke::get_function_address(k32, "Openprocess");
    let desired_access: u32 = 0x1000;
    let inherit = 0i32;
    let pid = 20628i32;
    let handle = unwinder::call_function!(open_process, false, desired_access, inherit, pid); // returns *mut c_void
    let handle: HANDLE = std::mem::transmute(handle);
    println!("Handle id: {:x}", handle.0);
    

    ध्यान दें कि मैक्रो एक *mut c_void लौटाता है जिसे सीधे HANDLE में परिवर्तित किया जा सकता है, क्योंकि दोनों डेटा प्रकारों का आकार समान है। यह OpenProcess द्वारा लौटाए गए मान तक पहुँचने की अनुमति देता है, जो टारगेट प्रोसेस के लिए नया हैंडल है।

    NtDelayExecution को अप्रत्यक्ष syscall के रूप में कॉल करना

    root@kitploit:~
    let large = 0x8000000000000000 as u64; // Sleep indefinitely
    let large: *mut i64 = std::mem::transmute(&large);
    let alertable = false;
    let ntstatus = unwinder::indirect_syscall!("NtDelayExecution", false, alertable, large); // returns *mut c_void
    println!("ntstatus: {:x}", ntstatus as i32);
    

    ध्यान दें कि मैक्रो एक *mut c_void लौटाता है जिसका उपयोग NtDelayExecution द्वारा लौटाए गए NTSTATUS को प्राप्त करने के लिए किया जा सकता है।

    मैक्रो कॉल्स को जोड़ना

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

    root@kitploit:~
    fn main()
    {
    	function_a();
    }
    
    fn function_a()
    {
    	unsafe
    	{
    		let func_b = function_b as usize;
    		call_function!(func_b, false);
    		println!("function_a done.");
    	}
    }
    
    fn function_b()
    {
    	unsafe
    	{
    		let func_c = function_c as usize;
    		call_function!(func_c, false);
    		println!("function_b done.")
    	}
    }
    
    fn function_c()
    {
    	unsafe
    	{
    		let large = 0x0000000000000000 as u64; // Don't sleep so we return to function_b, allowing to check the execution flow preservation.
    		let large: *mut i64 = std::mem::transmute(&large);
    		let alertable = false;
    		let ntstatus = unwinder::indirect_syscall!("NtDelayExecution", false, alertable, large);
    		println!("ntstatus: {:x}", (ntstatus as usize) as i32); //NTSTATUS is a i32, although that second casting is not really required in this case.
    	}
    }
    

    विचारणीय बातें

    प्रारंभिक फ्रेम

    यदि आप दूसरे पैरामीटर को true पर सेट करते हैं (दोनों मैक्रोज़ में), तो स्पूफिंग प्रक्रिया वैधता बढ़ाने के लिए कॉल स्टैक में थ्रेड स्टार्ट एड्रेस के फ्रेम को रखने का प्रयास करेगी।

    मुख्य मॉड्यूल को रखते हुए स्पूफ किया गया कॉल स्टैक।

    कभी-कभी, थ्रेड का स्टार्ट फ़ंक्शन बाद के फ़ंक्शन के लिए call नहीं करता है (जैसे कि इसके बजाय jmp निर्देश निष्पादित होता है), जिसका अर्थ है कि स्टैक पर कोई रिटर्न एड्रेस नहीं डाला जाता है। उस परिदृश्य में (और यदि आप उस दूसरे पैरामीटर को false पर सेट करते हैं), तो स्पूफ किया गया कॉल स्टैक BaseThreadInitThunk के फ्रेम से शुरू होगा।

    मुख्य मॉड्यूल के बिना स्पूफ किया गया कॉल स्टैक।

    PoC

    तकनीक के कार्यान्वयन का परीक्षण करने के लिए, PE-sieve का उपयोग /threads फ्लैग के साथ किया गया है। परीक्षण के परिणाम दिखाते हैं कि जब इस क्रेट की कार्यक्षमताओं का उपयोग किया जाता है, तो कॉल स्टैक का निरीक्षण पेलोड की उपस्थिति को प्रकट नहीं करता है। जैसा कि दूसरी छवि में देखा जा सकता है, जब unwinder का उपयोग नहीं किया जाता है तो पेलोड का पता लगाया जाता है।

    PE-sieve परिणाम जब unwinder का उपयोग किया जाता है। PE-sieve परिणाम जब unwinder का उपयोग नहीं किया जाता है।

    स्टैक प्रतिस्थापन

    तकनीक विवरण

    यह SilentMoonWalk का एक कॉल स्टैक स्पूफिंग विकल्प है जो आपके प्रोग्राम के निष्पादन के दौरान एक साफ कॉल स्टैक बनाए रखने की अनुमति देता है। इस तकनीक के पीछे मुख्य विचार यह है कि आपके मॉड्यूल के अंदर प्रत्येक बुलाया गया फ़ंक्शन पहले से पुश किए गए रिटर्न एड्रेस का ध्यान रखता है, और रनटाइम पर एक वैध फ़ंक्शन ढूंढता है जिसका फ्रेम आकार स्पूफ किए जाने वाले रिटर्न एड्रेस के समान होता है। एक बार समान फ्रेम आकार वाला वैध फ़ंक्शन मिल जाने पर, उसके भीतर एक ऑफसेट की गणना की जाती है और अंतिम एड्रेस का उपयोग अंतिम रिटर्न एड्रेस को प्रतिस्थापित करने के लिए किया जाता है, जिससे कॉल स्टैक में किसी भी असामान्य प्रविष्टि को छिपाया जा सके और इसे unwindable रखा जा सके। मूल रिटर्न एड्रेस unwinder द्वारा संग्रहीत किया जाता है और रिटर्न निर्देश निष्पादित होने से पहले इसे स्टैक में सही स्थान पर वापस ले जाया जाता है, जिससे प्रोग्राम के सामान्य प्रवाह को जारी रखा जा सकता है।

    स्टैक प्रतिस्थापन

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

    इसका उपयोग कैसे करें

    स्टैक रिप्लेसमेंट कार्यक्षमता का उपयोग करने के लिए आपको अपने cargo.toml में निम्नलिखित पंक्ति जोड़नी चाहिए और release मोड पर कंपाइल करना चाहिए:

    root@kitploit:~
    [dependencies]
    unwinder = {version = "0.1.4", features = ["Experimental"]}
    

    इस सुविधा की मुख्य कार्यक्षमता निम्नलिखित मैक्रोज़ में लपेटी गई है:

    • start_stack_replacement!()/end_replacement!() मैक्रोज़ की जोड़ी unwinder को स्टैक रिप्लेसमेंट प्रक्रिया शुरू/समाप्त करने का संकेत देती है। ये दो मैक्रोज़ आपके कोड के एंट्री पॉइंट में कॉल किए जाने चाहिए (जैसे आपकी dll के एक्सपोर्टेड फ़ंक्शनों में)।
    • replace_and_continue!()/restore!() मैक्रोज़ की जोड़ी अंतिम रिटर्न एड्रेस का प्रतिस्थापन/पुनर्स्थापन करती है।
    • अंत में, replace_and_call!()/replace_and_syscall!() मैक्रोज़ की जोड़ी का उपयोग स्टैक रिप्लेसमेंट करने के लिए किया जाता है जब हम वर्तमान मॉड्यूल के बाहर के फ़ंक्शनों को कॉल करना चाहते हैं (जैसे Windows API का उपयोग करते समय या किसी अन्य dll के कोड को कॉल करते समय)। ये दोनों मैक्रोज़ एक *mut c_void लौटाएंगे जिसमें इस तरह से बुलाए गए फ़ंक्शन द्वारा लौटाया गया मान होगा (अर्थात ये उसी तरह काम करते हैं जैसा कि SilentMoonWalk को निष्पादित करने के लिए उपयोग किए जाने वाले call_function और indirect_syscall मैक्रोज़ के लिए वर्णित है)।

    इन मैक्रोज़ का उपयोग करने के लिए std::ffi::c_void डेटा प्रकार को आयात करना आवश्यक है। इनमें से किसी भी मैक्रो का उपयोग करने वाले सभी फ़ंक्शनों को #[no_mangle] या #[inline(never)] एट्रिब्यूट से चिह्नित किया जाना चाहिए ताकि ऑप्टिमाइज़ेशन प्रक्रिया के दौरान rust कंपाइलर उन्हें इनलाइन न कर सके।

    यह सब उपयोग करने के तरीके को दर्शाने वाले व्यावहारिक उदाहरण में जाने से पहले, replace_and_call/replace_and_syscall मैक्रोज़ की जोड़ी और उन्हें अपेक्षित तर्क कैसे पास करें, इसका एक संक्षिप्त अवलोकन करते हैं।

    replace_and_call

    इस मैक्रो का उपयोग स्टैक रिप्लेसमेंट का उपयोग करते हुए एक साफ कॉल स्टैक के साथ वर्तमान मॉड्यूल के बाहर किसी भी वांछित फ़ंक्शन को कॉल करने के लिए किया जाता है। मैक्रो निम्नलिखित पैरामीटर की अपेक्षा करता है:

    • पहला पैरामीटर कॉल करने के लिए फ़ंक्शन का मेमोरी एड्रेस है। यह पैरामीटर usize, isize या पॉइंटर के रूप में पास किया जाना चाहिए।
    • अगले पैरामीटर वे तर्क हैं जो निर्दिष्ट फ़ंक्शन को भेजने हैं। वे पैरामीटर पास करना अनुभाग में निर्दिष्ट समान नियमों का पालन करते हैं।

    replace_and_syscall

    इस मैक्रो का उपयोग स्टैक रिप्लेसमेंट का उपयोग करते हुए एक साफ कॉल स्टैक के साथ किसी भी वांछित अप्रत्यक्ष syscall को करने के लिए किया जाता है। मैक्रो निम्नलिखित पैरामीटर की अपेक्षा करता है:

    • पहला पैरामीटर एक स्ट्रिंग है जिसमें NT फ़ंक्शन का नाम होता है जिसका syscall आप निष्पादित करना चाहते हैं।
    • अगले पैरामीटर वे तर्क हैं जो NT फ़ंक्शन को भेजने हैं। वे पैरामीटर पास करना अनुभाग में निर्दिष्ट समान नियमों का पालन करते हैं।

    उदाहरण

    मुझे लगता है कि इन मैक्रोज़ के उपयोग को दिखाने का सबसे अच्छा तरीका एक व्यावहारिक उदाहरण है। मान लीजिए कि हम एक dll बना रहे हैं जिसे मेमोरी में reflectively inject किया जाएगा। यह dll दो फ़ंक्शनों ExportA और ExportB को एक्सपोर्ट करेगी, इसलिए हम इन दोनों फ़ंक्शनों को मॉड्यूल के एंट्री पॉइंट के रूप में मानेंगे। दोनों को शुरुआत में ही start_stack_replacement मैक्रो को कॉल करना होगा और लौटने से पहले उल्टे end_replacement मैक्रो को भी कॉल करना होगा। start_stack_replacement मैक्रो तर्क के रूप में मॉड्यूल के बेस एड्रेस की अपेक्षा करता है, या यदि आपको रनटाइम पर वह एड्रेस नहीं पता है तो आप 0 पास कर सकते हैं, मैक्रो इसे स्वयं पता लगाने की कोशिश करेगा।

    root@kitploit:~
    #[no_mangle]
    fn ExportedA(base_address: usize) -> bool
    {
        unwinder::start_replacement!(base_address);
        ...
        unwinder::end_replacement!();
    
        true
    }
    
    #[no_mangle]
    fn ExportedB() -> bool
    {
        unwinder::start_replacement!(0);
        ...
        unwinder::end_replacement!();
    
        true
    }
    

    स्टैक रिप्लेसमेंट प्रक्रिया शुरू करने में एक नए स्टैक का मैन्युअल निर्माण शामिल होता है जिसका उपयोग तब तक किया जाएगा जब तक end_replacement मैक्रो कॉल नहीं किया जाता। निम्नलिखित चित्र दिखाता है कि अंदर क्या हो रहा है:

    स्टैक प्रतिस्थापन

    हालांकि सैद्धांतिक रूप से खरोंच से एक नया स्टैक शुरू करना आवश्यक नहीं होगा, मैंने स्थिरता सुनिश्चित करने और कुछ भी टूटने से रोकने के लिए प्रक्रिया को इस तरह लागू करने का निर्णय लिया है।

    अब, मान लेते हैं कि हमारा ExportedA फ़ंक्शन दो अन्य आंतरिक फ़ंक्शनों को कई कॉल करता है। ये दो आंतरिक फ़ंक्शन मूल रिटर्न एड्रेस को प्रतिस्थापित/पुनर्स्थापित करने के लिए ज़िम्मेदार हैं जो ExportedA के भीतर किसी स्थान की ओर इंगित करेगा, जब तक कि हम इसका ध्यान नहीं रखते, कॉल स्टैक टूट जाता है। इस प्रतिस्थापन प्रक्रिया में हमारे आंतरिक फ़ंक्शन के कोड को replace_and_continue और restore मैक्रोज़ के बीच लपेटना शामिल है:

    root@kitploit:~
    #[no_mangle]
    fn ExportedA(base_address: usize) -> bool
    {
        unwinder::start_replacement!(base_address);
        let ret_a = internal_a();
        let ret_b = internal_b(ret_a);
        unwinder::end_replacement!();
    
        ret_b
    }
    
    #[inline(never)] // This attribute is mandatory
    fn internal_a() -> bool
    {
        unwinder::replace_and_continue();
        ...
        unwinder::restore();
        
        some_value
    } 
    
    #[inline(never)] // This attribute is mandatory
    fn internal_b(value: bool) -> bool
    {
        unwinder::replace_and_continue();
        ...
        unwinder::restore();
        
        some_value
    } 
    

    अंत में, internal_a और internal_b दोनों फ़ंक्शन कुछ Windows API कार्यक्षमता का उपयोग करते हैं। अनवाइंडेबल कॉल स्टैक को बनाए रखने के लिए, ये कॉल replace_and_call (सामान्य कॉल) या replace_and_syscall (अप्रत्यक्ष syscall) मैक्रोज़ के माध्यम से किए जाने चाहिए।

    root@kitploit:~
    #[no_mangle] // This attribute is mandatory
    fn ExportedA(base_address: usize) -> bool
    {
        unwinder::start_replacement!(base_address);
        let ret_a = internal_a();
        let ret_b = internal_b(ret_a);
        unwinder::end_replacement!();
    
        ret_b
    }
    
    #[inline(never)] // This attribute is mandatory
    fn internal_a() -> bool
    {
        unwinder::replace_and_continue();
        ...
        let module_name = "advapi32.dll";
        let module_name = CString::new(module_name.to_string()).expect("");
        let module_name_ptr: *mut u8 = std::mem::transmute(module_name.as_ptr());
        let k32 = dinvoke_rs::dinvoke::get_module_base_address("kernel32.dll");
        let load_library = dinvoke_rs::dinvoke::get_function_address(k32, "LoadLibraryA");
        let ret = unwinder::replace_and_call!(load_library, module_name_ptr); // Load a dll with an unwindable call stack
        println!("advapi.dll base address: 0x{:x}", ret as usize);
        ...
        unwinder::restore();
        
        some_value
    } 
    
    #[inline(never)] // This attribute is mandatory
    fn internal_b(value: bool) -> bool
    {
        unwinder::replace_and_continue();
        ...
        let large = 0xFFFFFFFFFF676980 as u64; // Sleep one second
        let large: *mut i64 = std::mem::transmute(&large);
        let alertable = false;
        let ntstatus = unwinder::replace_and_syscall!("NtDelayExecution", alertable, large);
        println!("ntstatus: {:x}", ntstatus as usize);
        ...
        unwinder::restore();
        
        some_value
    } 
    

    टिप्पणियाँ

    चूंकि यह एक विकासाधीन सुविधा है, कुछ बातों को ध्यान में रखा जाना चाहिए:

    • यदि आप लोडिंग प्रक्रिया के दौरान अपने PE के हेडर हटा रहे हैं, तो आपको start_stack_replace मैक्रो को मॉड्यूल का बेस एड्रेस पास करना होगा। अभी, यह इसे स्वयं खोजने में सक्षम नहीं होगा (अगले अपडेट में हल किया जाना है)।
    • यदि आप सोच रहे हैं, तो स्टैक रिप्लेसमेंट SilentMoonWalk तकनीक के समान jmp rbx + concealment फ्रेम के संयोजन का उपयोग करता है। यह केवल replace_and_call और replace_and_syscall मैक्रोज़ का उपयोग करते समय होता है और अगले अपडेट में इसे बदलने की योजना है।
    • replace_and_call और replace_and_syscall दोनों मैक्रोज़ एक *mut c_void लौटाते हैं जिसका उपयोग उनके माध्यम से निष्पादित फ़ंक्शन द्वारा लौटाए गए मान को प्राप्त करने के लिए किया जा सकता है। यह call_function और indirect_syscall मैक्रोज़ के लिए वर्णित व्यवहार के समान है।
    • replace_and_call और replace_and_syscall मैक्रोज़ अधिकतम 11 तर्कों की अनुमति देते हैं।

    कृपया इस सुविधा का उपयोग करते समय उत्पन्न होने वाले किसी भी बग की रिपोर्ट करें।

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