हुकिंग: Difference between revisions

From Vigyanwiki
(Created page with "{{Short description|Techniques to alter an operating system}} {{other uses|Hooking (disambiguation)}} {{distinguish|Hook-up}} कंप्यूटर प्रोग्र...")
 
No edit summary
Line 1: Line 1:
{{Short description|Techniques to alter an operating system}}
{{Short description|Techniques to alter an operating system}}
{{other uses|Hooking (disambiguation)}}
{{other uses|हुकिंग (बहुविकल्पी)}}
{{distinguish|Hook-up}}
{{distinguish|हुकिंग}}


[[कंप्यूटर प्रोग्रामिंग]] में, हुकिंग शब्द [[मॉड्यूलर प्रोग्रामिंग]] के बीच पारित [[फ़ंक्शन कॉल]] या [[संदेश देना]] या [[ घटना (कंप्यूटिंग) ]] को इंटरसेप्ट करके [[ऑपरेटिंग सिस्टम]], [[अनुप्रयोग प्रक्रिया सामग्री]] या अन्य सॉफ़्टवेयर घटकों के व्यवहार को बदलने या बढ़ाने के लिए उपयोग की जाने वाली तकनीकों की एक श्रृंखला को शामिल करता है। कोड जो ऐसे इंटरसेप्टेड फ़ंक्शन कॉल, ईवेंट या संदेशों को संभालता है उसे हुक कहा जाता है।
[[कंप्यूटर प्रोग्रामिंग]] में '''हुकिंग''' शब्द में [[मॉड्यूलर प्रोग्रामिंग]] के बीच [[फ़ंक्शन कॉल]] या [[संदेश देना|संदेशों]] या [[ घटना (कंप्यूटिंग) |घटना (कंप्यूटिंग)]] को इंटरसेप्ट करके [[ऑपरेटिंग सिस्टम]], [[अनुप्रयोग प्रक्रिया सामग्री|एप्लिकेशन]] या अन्य सॉफ़्टवेयर घटकों के व्यवहार को परिवर्तित या बढ़ाने के लिए उपयोग की जाने वाली तकनीकों की एक श्रृंखला सम्मिलित है। कोड जो ऐसे इंटरसेप्टेड फ़ंक्शन कॉल, ईवेंट या संदेशों को संभालता है उसे हुक कहा जाता है।


हुकिंग का उपयोग कई उद्देश्यों के लिए किया जाता है, जिसमें [[डिबगिंग]] और कार्यक्षमता का विस्तार शामिल है।
हुकिंग का उपयोग कई उद्देश्यों के लिए किया जाता है, जिसमें [[डिबगिंग]] और कार्यक्षमता का विस्तार सम्मिलित है। उदाहरणों में किसी एप्लिकेशन तक पहुंचने से पहले कीबोर्ड या माउस ईवेंट संदेशों को इंटरसेप्ट करना या व्यवहार की निगरानी करने या किसी एप्लिकेशन या अन्य घटक के फ़ंक्शन को संशोधित करने के लिए ऑपरेटिंग सिस्टम कॉल को इंटरसेप्ट करना सम्मिलित हो सकता है। इसका व्यापक रूप से बेंचमार्किंग प्रोग्राम में भी उपयोग किया जाता है उदाहरण के लिए 3डी गेम में [[फ्रेम रेट]] मापना जहां आउटपुट और इनपुट हुकिंग के माध्यम से किया जाता है।
उदाहरणों में किसी एप्लिकेशन तक पहुंचने से पहले कीबोर्ड या माउस ईवेंट संदेशों को इंटरसेप्ट करना, या व्यवहार की निगरानी करने या किसी एप्लिकेशन या अन्य घटक के फ़ंक्शन को संशोधित करने के लिए ऑपरेटिंग सिस्टम कॉल को इंटरसेप्ट करना शामिल हो सकता है। इसका व्यापक रूप से बेंचमार्किंग कार्यक्रमों में भी उपयोग किया जाता है, उदाहरण के लिए 3डी गेम में [[फ्रेम रेट]] मापना, जहां आउटपुट और इनपुट हुकिंग के माध्यम से किया जाता है।


हुकिंग का उपयोग दुर्भावनापूर्ण कोड द्वारा भी किया जा सकता है। उदाहरण के लिए, [[रूटकिट]], सॉफ़्टवेयर के टुकड़े जो [[एपीआई]] कॉल के नकली आउटपुट द्वारा खुद को अदृश्य बनाने की कोशिश करते हैं जो अन्यथा उनके अस्तित्व को प्रकट कर सकते हैं, अक्सर हुकिंग तकनीकों का उपयोग करते हैं।
हुकिंग का उपयोग दुर्भावनापूर्ण कोड द्वारा भी किया जा सकता है। उदाहरण के लिए, [[रूटकिट]], सॉफ़्टवेयर के टुकड़े जो [[एपीआई]] कॉल के नकली आउटपुट द्वारा खुद को अदृश्य बनाने की कोशिश करते हैं जो अन्यथा उनके अस्तित्व को प्रकट कर सकते हैं प्रायः हुकिंग तकनीकों का उपयोग करते हैं।


== तरीके ==
== प्रकार ==
आमतौर पर हुक तब डाले जाते हैं जब सॉफ़्टवेयर पहले से ही चल रहा हो, लेकिन हुकिंग एक ऐसी रणनीति है जिसे एप्लिकेशन शुरू होने से पहले भी नियोजित किया जा सकता है। इन दोनों तकनीकों का नीचे विस्तार से वर्णन किया गया है।
सामान्यतः हुक तब डाले जाते हैं जब सॉफ़्टवेयर पहले से ही चल रहा हो, लेकिन हुकिंग एक ऐसा फ़ंक्शन है जिसे एप्लिकेशन शुरू होने से पहले भी नियोजित किया जा सकता है। इन दोनों तकनीकों का नीचे विस्तार से वर्णन किया गया है।


=== स्रोत संशोधन ===
=== सोर्स कोड संशोधन ===
किसी एप्लिकेशन के चलने से पहले, [[रिवर्स इंजीनियरिंग]] की तकनीकों के माध्यम से [[निष्पादन]] योग्य या [[ पुस्तकालय (कंप्यूटिंग) ]] के स्रोत को संशोधित करके हुकिंग प्राप्त की जा सकती है। इसका उपयोग आमतौर पर फ़ंक्शन कॉल को मॉनिटर करने या उन्हें पूरी तरह से बदलने के लिए इंटरसेप्ट करने के लिए किया जाता है।
किसी एप्लिकेशन के चलने से पहले [[रिवर्स इंजीनियरिंग]] की तकनीकों के माध्यम से [[निष्पादन]] योग्य या [[ पुस्तकालय (कंप्यूटिंग) |लाइब्रेरी]] के सोर्स कोड को संशोधित करके हुकिंग प्राप्त की जा सकती है। इसका उपयोग सामान्यतः फ़ंक्शन कॉल को मॉनिटर करने या उन्हें पूरी तरह से परिवर्तित करने के लिए इंटरसेप्ट करने के लिए किया जाता है।


उदाहरण के लिए, एक [[disassembler]] का उपयोग करके, मॉड्यूलर प्रोग्रामिंग के भीतर एक [[फ़ंक्शन (कंप्यूटर विज्ञान)]] का [[प्रवेश बिंदु]] पाया जा सकता है। इसके बाद इसे किसी अन्य लाइब्रेरी मॉड्यूल को गतिशील रूप से लोड करने के लिए बदला जा सकता है और फिर उस लोड की गई लाइब्रेरी के भीतर वांछित तरीकों को निष्पादित किया जा सकता है। यदि लागू हो, तो एक अन्य संबंधित दृष्टिकोण जिसके द्वारा हुकिंग प्राप्त की जा सकती है वह निष्पादन योग्य की पोर्टेबल निष्पादन योग्य#आयात तालिका को बदलकर है। इस तालिका को किसी भी अतिरिक्त लाइब्रेरी मॉड्यूल को लोड करने के लिए संशोधित किया जा सकता है और साथ ही यह भी बदला जा सकता है कि जब एप्लिकेशन द्वारा किसी फ़ंक्शन को कॉल किया जाता है तो कौन सा बाहरी कोड लागू होता है।
उदाहरण के लिए एक डिस्सेबलर का उपयोग करके मॉड्यूल के भीतर किसी फ़ंक्शन का प्रवेश बिंदु पाया जा सकता है। इसके बाद इसे किसी अन्य लाइब्रेरी मॉड्यूल को गतिशील रूप से लोड करने के लिए परिवर्तित किया जा सकता है और फिर उस लोड की गई लाइब्रेरी के भीतर वांछित तरीकों को निष्पादित किया जा सकता है। यदि लागू हो, तो एक अन्य संबंधित दृष्टिकोण जिसके द्वारा हुकिंग प्राप्त की जा सकती है वह निष्पादन योग्य की आयात तालिका को बदलकर है। इस तालिका को किसी भी अतिरिक्त लाइब्रेरी मॉड्यूल को लोड करने के लिए संशोधित किया जा सकता है और साथ ही यह भी परिवर्तित किया जा सकता है कि जब एप्लिकेशन द्वारा किसी फ़ंक्शन को कॉल किया जाता है तो कौन सा बाहरी कोड लागू होता है।


फ़ंक्शन हुकिंग प्राप्त करने का एक वैकल्पिक तरीका [[रैपर लाइब्रेरी]] के माध्यम से फ़ंक्शन कॉल को इंटरसेप्ट करना है। रैपर एक लाइब्रेरी का एक संस्करण है जिसे एक एप्लिकेशन लोड करता है, जिसमें मूल लाइब्रेरी की सभी समान कार्यक्षमता होती है जिसे वह प्रतिस्थापित करेगा। अर्थात्, सभी फ़ंक्शन जो पहुंच योग्य हैं, मूल और प्रतिस्थापन के बीच अनिवार्य रूप से समान हैं। इस रैपर लाइब्रेरी को मूल लाइब्रेरी से किसी भी कार्यक्षमता को कॉल करने के लिए डिज़ाइन किया जा सकता है, या इसे तर्क के एक बिल्कुल नए सेट के साथ प्रतिस्थापित किया जा सकता है।
फ़ंक्शन हुकिंग प्राप्त करने का एक वैकल्पिक तरीका [[रैपर लाइब्रेरी]] के माध्यम से फ़ंक्शन कॉल को इंटरसेप्ट करना है। रैपर एक लाइब्रेरी का एक संस्करण है जिसे एक एप्लिकेशन लोड करता है, जिसमें मूल लाइब्रेरी की सभी समान कार्यक्षमता होती है जिसे वह प्रतिस्थापित करेगा। अर्थात्, सभी फ़ंक्शन जो पहुंच योग्य हैं, मूल और प्रतिस्थापन के बीच अनिवार्य रूप से समान हैं। इस रैपर लाइब्रेरी को मूल लाइब्रेरी से किसी भी कार्यक्षमता को कॉल करने के लिए डिज़ाइन किया जा सकता है, या इसे तर्क के एक बिल्कुल नए सेट के साथ प्रतिस्थापित किया जा सकता है।


=== रनटाइम संशोधन ===
=== रनटाइम संशोधन ===
ऑपरेटिंग सिस्टम और सॉफ़्टवेयर रन टाइम (प्रोग्राम जीवनचक्र चरण) पर आसानी से इवेंट हुक डालने के साधन प्रदान कर सकते हैं। यह उपलब्ध है बशर्ते कि हुक डालने की [[प्रक्रिया (कंप्यूटिंग)]] को ऐसा करने के लिए पर्याप्त अनुमति दी गई हो। उदाहरण के लिए, माइक्रोसॉफ्ट विंडोज़, उपयोगकर्ताओं को हुक डालने की अनुमति देता है जिसका उपयोग सिस्टम इवेंट (कंप्यूटिंग) और [[ संवाद बकस ]], [[ स्क्रॉल बार ]] और [[मेनू (कंप्यूटिंग)]] के साथ-साथ अन्य आइटमों के लिए एप्लिकेशन इवेंट को संसाधित या संशोधित करने के लिए किया जा सकता है। यह हुक को [[कीबोर्ड (कंप्यूटिंग)]] और [[माउस (कंप्यूटिंग)]] इवेंट को सम्मिलित करने, हटाने, संसाधित करने या संशोधित करने की भी अनुमति देता है। लिनक्स एक और उदाहरण प्रदान करता है जहां [[ नेटफ़िल्टर ]] के माध्यम से [[कर्नेल (ऑपरेटिंग सिस्टम)]] के भीतर नेटवर्क घटनाओं को संसाधित करने के लिए हुक का उपयोग समान तरीके से किया जा सकता है।
ऑपरेटिंग सिस्टम और सॉफ़्टवेयर रनटाइम पर आसानी से इवेंट हुक डालने के साधन प्रदान कर सकते हैं। यह उपलब्ध है बशर्ते कि हुक डालने की प्रक्रिया को ऐसा करने के लिए पर्याप्त अनुमति दी गई हो। उदाहरण के लिए, माइक्रोसॉफ्ट विंडोज़, उपयोगकर्ताओं को हुक डालने की अनुमति देता है जिसका उपयोग सिस्टम इवेंट और [[ संवाद बकस |डायलॉग]], [[ स्क्रॉल बार |स्क्रॉल बार]] और [[मेनू (कंप्यूटिंग)|मेनू]] के साथ-साथ अन्य आइटम के लिए एप्लिकेशन इवेंट को संसाधित या संशोधित करने के लिए किया जा सकता है। यह हुक को [[कीबोर्ड (कंप्यूटिंग)|कीबोर्ड]] और [[माउस (कंप्यूटिंग)]] इवेंट को सम्मिलित करने, हटाने, संसाधित करने या संशोधित करने की भी अनुमति देता है। लिनक्स एक और उदाहरण प्रदान करता है जहां [[ नेटफ़िल्टर |नेटफ़िल्टर]] के माध्यम से [[कर्नेल (ऑपरेटिंग सिस्टम)]] के भीतर नेटवर्क घटनाओं को संसाधित करने के लिए हुक का उपयोग समान तरीके से किया जा सकता है।


जब ऐसी कार्यक्षमता प्रदान नहीं की जाती है, तो हुकिंग का एक विशेष रूप एक प्रक्रिया द्वारा किए गए लाइब्रेरी फ़ंक्शन कॉल को इंटरसेप्ट करने का काम करता है। फ़ंक्शन हुकिंग को एक इंजेक्टेड कोड पर जाने के लिए लक्ष्य फ़ंक्शन के पहले कुछ कोड निर्देशों को बदलकर कार्यान्वित किया जाता है। वैकल्पिक रूप से साझा लाइब्रेरी अवधारणा का उपयोग करने वाले सिस्टम पर, [[इंटरप्ट वेक्टर]] तालिका या निष्पादन योग्य#आयात तालिका को मेमोरी में संशोधित किया जा सकता है। अनिवार्य रूप से ये युक्तियाँ स्रोत संशोधन के समान विचारों को नियोजित करती हैं, लेकिन इसके बजाय किसी प्रक्रिया के पहले से चलने के बाद उसकी मेमोरी में स्थित निर्देशों और संरचनाओं को बदल देती हैं।
जब ऐसी कार्यक्षमता प्रदान नहीं की जाती है, तो हुकिंग का एक विशेष रूप एक प्रक्रिया द्वारा किए गए लाइब्रेरी फ़ंक्शन कॉल को इंटरसेप्ट करने का काम करता है। फ़ंक्शन हुकिंग को एक इंजेक्टेड कोड पर जाने के लिए लक्ष्य फ़ंक्शन के पहले कुछ कोड इंस्ट्रक्शन को बदलकर कार्यान्वित किया जाता है। वैकल्पिक रूप से साझा लाइब्रेरी अवधारणा का उपयोग करने वाले सिस्टम पर, [[इंटरप्ट वेक्टर]] तालिका या आयात डिस्क्रिप्टर तालिका को मेमोरी में संशोधित किया जा सकता है। अनिवार्य रूप से ये युक्तियाँ सोर्स कोड संशोधन के समान विचारों को नियोजित करती हैं, लेकिन इसके अतिरिक्त किसी प्रक्रिया के पहले से चलने के बाद उसकी मेमोरी में स्थित इंस्ट्रक्शन और संरचनाओं को बदल देती हैं।


== नमूना कोड ==
== सैंपल कोड ==


=== वर्चुअल विधि टेबल हुकिंग ===
=== वर्चुअल टेबल हुकिंग विधि ===


जब भी कोई क्लास किसी वर्चुअल फ़ंक्शन (या मेथड) को परिभाषित/इनहेरिट करता है, तो कंपाइलर क्लास में एक छिपा हुआ सदस्य वेरिएबल जोड़ते हैं जो [[ आभासी विधि तालिका ]] (वीएमटी या वीटेबल) की ओर इशारा करता है। अधिकांश कंपाइलर कक्षा के प्रत्येक उदाहरण के पहले 4 बाइट्स पर छिपे हुए वीएमटी पॉइंटर को रखते हैं। वीएमटी मूल रूप से सभी [[आभासी कार्य]]ों के लिए [[संदर्भ (कंप्यूटर विज्ञान)]] की एक श्रृंखला है जिसे कक्षा के उदाहरण कॉल कर सकते हैं। रनटाइम पर ये पॉइंटर्स सही फ़ंक्शंस को इंगित करने के लिए सेट किए जाते हैं, क्योंकि [[संकलन समय]] पर, यह अभी तक ज्ञात नहीं है कि क्या बेस फ़ंक्शन को कॉल किया जाना है या यदि किसी व्युत्पन्न वर्ग से फ़ंक्शन का ओवरराइड संस्करण कॉल किया जाना है (जिससे अनुमति मिलती है) [[बहुरूपता (कंप्यूटर विज्ञान)]] के लिए)। इसलिए, वर्चुअल फ़ंक्शंस को किसी भी वीएमटी के भीतर पॉइंटर्स को प्रतिस्थापित करके हुक किया जा सकता है जो वे दिखाई देते हैं। नीचे दिया गया कोड Microsoft Windows में C++ में लिखे गए एक विशिष्ट VMT हुक का एक उदाहरण दिखाता है।<ref>psyfl, [https://github.com/psyfl/Virtual-Method-Table-Hooking/blob/master/ConsoleApplication5/ConsoleApplication5.cpp]</ref>
जब भी कोई क्लास किसी वर्चुअल फ़ंक्शन (या मेथड) को परिभाषित/इनहेरिट करता है, तो कंपाइलर क्लास में एक छिपा हुआ सदस्य वेरिएबल जोड़ते हैं जो [[ आभासी विधि तालिका |वर्चुअल मेथड टेबल]] (वीएमटी या वीटेबल) की ओर इशारा करता है। अधिकांश कंपाइलर कक्षा के प्रत्येक उदाहरण के पहले 4 बाइट्स पर छिपे हुए वीएमटी पॉइंटर को रखते हैं। वीएमटी मूल रूप से सभी [[आभासी कार्य|वर्चुअल फ़ंक्शन]] के लिए [[संदर्भ (कंप्यूटर विज्ञान)|पॉइंटर्स]] की एक सरणी है जिसे क्लास के इंस्टेंस कॉल कर सकते हैं। रनटाइम पर ये पॉइंटर्स सही फ़ंक्शन को इंगित करने के लिए सेट किए जाते हैं, क्योंकि संकलन समय पर, यह अभी तक ज्ञात नहीं है कि क्या बेस फ़ंक्शन को कॉल किया जाना है या यदि किसी व्युत्पन्न वर्ग से फ़ंक्शन का ओवरराइड संस्करण कॉल किया जाना है (जिससे अनुमति मिलती है) बहुरूपता के लिए)। इसलिए, वर्चुअल फ़ंक्शन को किसी भी वीएमटी के भीतर पॉइंटर्स को प्रतिस्थापित करके हुक किया जा सकता है जो वे दिखाई देते हैं। नीचे दिया गया कोड माइक्रोसॉफ़्ट विंडोज़ में एक विशिष्ट वीएमटी हुक का एक उदाहरण दिखाता है, जो C++ में लिखा गया है।<ref>psyfl, [https://github.com/psyfl/Virtual-Method-Table-Hooking/blob/master/ConsoleApplication5/ConsoleApplication5.cpp]</ref>


<syntaxhighlight lang="cpp">
<syntaxhighlight lang="cpp">
Line 92: Line 91:


</syntaxhighlight>
</syntaxhighlight>
यह ध्यान रखना महत्वपूर्ण है कि सभी वर्चुअल फ़ंक्शंस क्लास सदस्य फ़ंक्शंस होने चाहिए, और सभी (गैर स्थैतिक) क्लास सदस्य फ़ंक्शंस को __thiscall [[ सम्मलेन बुलाना ]] के साथ कॉल किया जाता है (जब तक कि सदस्य फ़ंक्शन तर्कों की एक चर संख्या नहीं लेता है, जिस स्थिति में इसे कहा जाता है) __cdecl के साथ)। __thiscall कॉलिंग कन्वेंशन ECX रजिस्टर (x86 आर्किटेक्चर पर) के माध्यम से कॉलिंग क्लास इंस्टेंस (आमतौर पर इस पॉइंटर के रूप में संदर्भित) के लिए एक पॉइंटर पास करता है। इसलिए, एक हुक फ़ंक्शन के लिए पारित किए गए इस पॉइंटर को ठीक से इंटरसेप्ट करने और इसे एक तर्क के रूप में लेने के लिए, इसे ECX रजिस्टर में देखना होगा। उपरोक्त उदाहरण में, यह __fastcall कॉलिंग कन्वेंशन का उपयोग करने के लिए हुक फ़ंक्शन (hkVirtualFn1) को सेट करके किया जाता है, जो हुक फ़ंक्शन को उसके एक तर्क के लिए ECX रजिस्टर में देखने का कारण बनता है।
यह ध्यान रखना महत्वपूर्ण है कि सभी वर्चुअल फ़ंक्शन क्लास सदस्य फ़ंक्शन होने चाहिए, और सभी (गैर स्थैतिक) क्लास सदस्य फ़ंक्शन को <code>_thiscall</code> कॉलिंग कन्वेंशन के साथ कॉल किया जाता है (जब तक कि सदस्य फ़ंक्शन तर्कों की एक चर संख्या नहीं लेता है, जिस स्थिति में इसे कहा जाता है) <code>_cdecl</code> के साथ)<code>_thiscall</code> कॉलिंग कन्वेंशन ईसीएक्स रजिस्टर (x86 आर्किटेक्चर पर) के माध्यम से कॉलिंग क्लास इंस्टेंस (सामान्यतः "इस" पॉइंटर के रूप में संदर्भित) के लिए एक पॉइंटर पास करता है। इसलिए, हुक फ़ंक्शन द्वारा पारित किए गए "इस" पॉइंटर को ठीक से इंटरसेप्ट करने और इसे एक तर्क के रूप में लेने के लिए, इसे ईसीएक्स रजिस्टर में देखना होगा। उपरोक्त उदाहरण में, यह <code>_fastcall</code> कॉलिंग कन्वेंशन का उपयोग करने के लिए हुक फ़ंक्शन (<code>hkVirtualFn1)</code> को सेट करके किया जाता है, जो हुक फ़ंक्शन को उसके एक तर्क के लिए ईसीएक्स रजिस्टर में देखने का कारण बनता है।


यह भी ध्यान दें कि, उपरोक्त उदाहरण में, हुक फ़ंक्शन (hkVirtualFn1) स्वयं एक सदस्य फ़ंक्शन नहीं है, इसलिए यह __thiscall कॉलिंग कन्वेंशन का उपयोग नहीं कर सकता है। इसके बजाय __fastcall का उपयोग करना होगा क्योंकि यह एकमात्र अन्य कॉलिंग कन्वेंशन है जो किसी तर्क के लिए ECX रजिस्टर को देखता है।
यह भी ध्यान दें कि, उपरोक्त उदाहरण में, हुक फ़ंक्शन (<code>hkVirtualFn1)</code> स्वयं एक सदस्य फ़ंक्शन नहीं है, इसलिए यह <code>_thiscall</code> कॉलिंग कन्वेंशन का उपयोग नहीं कर सकता है। इसके अतिरिक्त <code>_fastcall</code> का उपयोग करना होगा क्योंकि यह एकमात्र अन्य कॉलिंग कन्वेंशन है जो किसी तर्क के लिए ईसीएक्स रजिस्टर को देखता है। <code>hkVirtualFn1</code>


=== सी# कीबोर्ड इवेंट हुक ===
=== सी# कीबोर्ड इवेंट हुक ===


निम्नलिखित उदाहरण .NET Framework|Microsoft .NET Framework का उपयोग करके Microsoft Windows में कीबोर्ड ईवेंट से जुड़ जाएगा।
निम्न उदाहरण माइक्रोसॉफ्ट नेट फ्रेमवर्क का उपयोग करके माइक्रोसॉफ़्ट विंडोज़ में कीबोर्ड ईवेंट से जुड़ जाएगा।


<syntaxhighlight lang="csharp">
<syntaxhighlight lang="csharp">
Line 184: Line 183:
}
}
</syntaxhighlight>
</syntaxhighlight>
=== एपीआई/फ़ंक्शन हुकिंग/इंटरसेप्शन जेएमपी अनुदेश उर्फ ​​स्प्लिसिंग का उपयोग करके ===
=== एपीआई/फ़ंक्शन हुकिंग/इंटरसेप्शन जेएमपी अनुदेश उर्फ ​​स्प्लिसिंग का उपयोग करके ===


निम्नलिखित स्रोत कोड एक एपीआई/फ़ंक्शन हुकिंग विधि का एक उदाहरण है जो एक गंतव्य [[सबरूटीन]] के पहले छह बाइट्स को [[जेएमपी (x86 निर्देश)]] निर्देश के साथ एक नए फ़ंक्शन में ओवरराइट करके हुक करता है। कोड को [[डायनामिक-लिंक लाइब्रेरी]] फ़ाइल में संकलित किया जाता है और फिर DLL इंजेक्शन की किसी भी विधि का उपयोग करके लक्ष्य प्रक्रिया में लोड किया जाता है। मूल फ़ंक्शन के बैकअप का उपयोग करके पहले छह बाइट्स को फिर से पुनर्स्थापित किया जा सकता है ताकि कॉल बाधित न हो। इस उदाहरण में Win32 API फ़ंक्शन MessageBoxW जुड़ा हुआ है।<ref>For more information, see http://ntvalk.blogspot.nl/2013/11/hooking-explained-detouring-library.html</ref>
निम्नलिखित सोर्स कोड कोड एक एपीआई/फ़ंक्शन हुकिंग विधि का एक उदाहरण है जो एक गंतव्य फ़ंक्शन के पहले छह बाइट्स को [[जेएमपी (x86 निर्देश)|जेएमपी (x86 इंस्ट्रक्शन)]] के साथ एक नए फ़ंक्शन पर ओवरराइट करके हुक करता है। कोड को एक [[डायनामिक-लिंक लाइब्रेरी]] फ़ाइल में संकलित किया जाता है और फिर डायनामिक-लिंक लाइब्रेरी इंजेक्शन की किसी भी विधि का उपयोग करके लक्ष्य प्रक्रिया में लोड किया जाता है। मूल फ़ंक्शन के बैकअप का उपयोग करके पहले छह बाइट्स को फिर से पुनर्स्थापित किया जा सकता है ताकि कॉल बाधित न हो। इस उदाहरण में Win32 API फ़ंक्शन MessageBoxW जुड़ा हुआ है।<ref>For more information, see http://ntvalk.blogspot.nl/2013/11/hooking-explained-detouring-library.html</ref>


<syntaxhighlight lang="c">
<syntaxhighlight lang="c">
Line 255: Line 252:
  }   
  }   
</syntaxhighlight>
</syntaxhighlight>
=== [[नेटफ़िल्टर]] हुक ===
=== [[नेटफ़िल्टर]] हुक ===


यह उदाहरण दिखाता है कि नेटफिल्टर का उपयोग करके लिनक्स कर्नेल में [[ संगणक संजाल ]] ट्रैफ़िक को बदलने के लिए हुकिंग का उपयोग कैसे करें।
यह उदाहरण दिखाता है कि नेटफिल्टर का उपयोग करके लिनक्स कर्नेल में नेटवर्क ट्रैफ़िक को परिवर्तित के लिए हुकिंग का उपयोग कैसे करें।


<syntaxhighlight lang="c">
<syntaxhighlight lang="c">
Line 316: Line 311:
module_exit(my_exit);
module_exit(my_exit);
</syntaxhighlight>
</syntaxhighlight>
=== आंतरिक आईएटी हुकिंग ===
=== आंतरिक आईएटी हुकिंग ===
निम्नलिखित कोड दर्शाता है कि किसी अन्य मॉड्यूल से आयातित फ़ंक्शंस को कैसे हुक किया जाए।
निम्नलिखित कोड दर्शाता है कि किसी अन्य मॉड्यूल से आयातित फ़ंक्शन को कैसे हुक किया जाए। इसका उपयोग कॉलिंग प्रक्रिया से भिन्न प्रक्रिया में फ़ंक्शन को हुक करने के लिए किया जा सकता है। इसके लिए कोड को एक डायनामिक-लिंक लाइब्रेरी फ़ाइल में संकलित किया जाना चाहिए और फिर डायनामिक-लिंक लाइब्रेरी इंजेक्शन की किसी भी विधि का उपयोग करके लक्ष्य प्रक्रिया में लोड किया जाना चाहिए। इस पद्धति का लाभ यह है कि यह [[एंटीवायरस सॉफ्टवेयर]] या [[धोखा विरोधी सॉफ्टवेयर|एंटी-चीट सॉफ़्टवेयर]] द्वारा कम पता लगाया जा सकता है, कोई इसे बाहरी हुक में बना सकता है जो किसी भी दुर्भावनापूर्ण कॉल का उपयोग नहीं करता है। [[पोर्टेबल निष्पादन योग्य|पोर्टेबल एक्ज़ीक्यूटेबल हेडर]] में आयात पता तालिका (आईएटी) सम्मिलित है, जिसे नीचे सोर्स कोड में दिखाए अनुसार हेरफेर किया जा सकता है। नीचे दिया गया सोर्स कोड माइक्रोसॉफ़्ट विंडोज़ के अंतर्गत चलता है।<syntaxhighlight lang="c">
इसका उपयोग कॉलिंग प्रक्रिया से भिन्न प्रक्रिया में फ़ंक्शन को हुक करने के लिए किया जा सकता है। इसके लिए कोड को डायनामिक-लिंक लाइब्रेरी फ़ाइल में संकलित किया जाना चाहिए और फिर DLL इंजेक्शन की किसी भी विधि का उपयोग करके लक्ष्य प्रक्रिया में लोड किया जाना चाहिए।
इस पद्धति का लाभ यह है कि यह [[एंटीवायरस सॉफ्टवेयर]] और/या [[धोखा विरोधी सॉफ्टवेयर]] द्वारा कम पता लगाया जा सकता है, कोई इसे बाहरी हुक में बना सकता है जो किसी भी दुर्भावनापूर्ण कॉल का उपयोग नहीं करता है।
[[पोर्टेबल निष्पादन योग्य]] हेडर में आयात पता तालिका (आईएटी) शामिल है, जिसे नीचे स्रोत में दिखाए अनुसार हेरफेर किया जा सकता है। नीचे दिया गया स्रोत Microsoft Windows के अंतर्गत चलता है।
 
 
 
<syntaxhighlight lang="c">
#include <windows.h>
#include <windows.h>


Line 387: Line 373:


</syntaxhighlight>
</syntaxhighlight>
==यह भी देखें==
==यह भी देखें==
* [[कॉलबैक (कंप्यूटर विज्ञान)]]
* [[कॉलबैक (कंप्यूटर विज्ञान)]]
* [[प्रतिनिधिमंडल (प्रोग्रामिंग)]]
* [[प्रतिनिधिमंडल (प्रोग्रामिंग)|डेलीगेशन (प्रोग्रामिंग)]]
* [[समाप्ति-और-निवासी कार्यक्रम]]
* [[समाप्ति-और-निवासी कार्यक्रम|टर्मिनेट स्टेरेजिडेंट प्रोग्राम]]
* [[उपयोगकर्ता निकास]]
* [[उपयोगकर्ता निकास|यूसर एग्जिट]] [[समाप्ति-और-निवासी कार्यक्रम|प्रोग्राम]]
* [[WinAPIOverride32]]
* [[WinAPIOverride32|विंडोज़ एपीआई ओवरराइड 32]]


==संदर्भ==
==संदर्भ==
Line 425: Line 409:
}}
}}
{{refend}}
{{refend}}
==बाहरी संबंध==
==बाहरी संबंध==
 
=== विंडोज़ ===
 
 
 
=== खिड़कियाँ ===
* [http://sandsprite.com/CodeStuff/IAT_Hooking.html आयात पता तालिका फ़ंक्शन हुकिंग पर जानकारी।]
* [http://sandsprite.com/CodeStuff/IAT_Hooking.html आयात पता तालिका फ़ंक्शन हुकिंग पर जानकारी।]
* [http://msdn.microsoft.com/en-us/library/ms632589(VS.85).aspx हुकिंग पर माइक्रोसॉफ्ट से जानकारी]
* [http://msdn.microsoft.com/en-us/library/ms632589(VS.85).aspx हुकिंग पर माइक्रोसॉफ्ट से जानकारी]
Line 440: Line 418:
* [http://www.codeproject.com/KB/threads/winspy.aspxwinspy] किसी अन्य प्रक्रिया में कोड डालने के तीन तरीके।
* [http://www.codeproject.com/KB/threads/winspy.aspxwinspy] किसी अन्य प्रक्रिया में कोड डालने के तीन तरीके।
* [http://www.codeproject.com/KB/system/hooksys.aspx HookTool SDK (ACF SDK)] एपीआई हुकिंग और कोड इंजेक्शन पर एक व्यापक अवलोकन प्रदान करता है। एक व्यावसायिक उत्पाद भी उपलब्ध है.
* [http://www.codeproject.com/KB/system/hooksys.aspx HookTool SDK (ACF SDK)] एपीआई हुकिंग और कोड इंजेक्शन पर एक व्यापक अवलोकन प्रदान करता है। एक व्यावसायिक उत्पाद भी उपलब्ध है.
* [http://help.madshi.net/ApiCodeHooking.htmmadCodeHook] C++ और डेल्फ़ी के लिए एक व्यावसायिक x86 और x64 API हुकिंग और DLL इंजेक्शन लाइब्रेरी है।
* [http://help.madshi.net/ApiCodeHooking.htmmadCodeHook] C++ और डेल्फ़ी के लिए एक व्यावसायिक x86 और x64 API हुकिंग और डायनामिक-लिंक लाइब्रेरी इंजेक्शन लाइब्रेरी है।
* [http://www.codeplex.com/easyhook EasyHook] एक ओपन सोर्स हुकिंग इंजन है जो विंडोज़ में उपयोगकर्ता और कर्नेल भूमि दोनों में x86 और x64 का समर्थन करता है।
* [http://www.codeplex.com/easyhook EasyHook] एक ओपन सोर्स हुकिंग इंजन है जो विंडोज़ में उपयोगकर्ता और कर्नेल भूमि दोनों में x86 और x64 का समर्थन करता है।
* [http://www.nektra.com/products/spystudio-api-monitor/ SpyStudio एप्लिकेशन ट्रेस] SpyStudio एक एप्लिकेशन ट्रेसर है जो कॉल को हुक करता है, परिणामों को संरचित तरीके से प्रदर्शित करता है।
* [http://www.nektra.com/products/spystudio-api-monitor/ SpyStudio एप्लिकेशन ट्रेस] SpyStudio एक एप्लिकेशन ट्रेसर है जो कॉल को हुक करता है, परिणामों को संरचित तरीके से प्रदर्शित करता है।
* [http://www.rohitab.com/apimonitor rohitab.com एपीआई मॉनिटर] एक फ्रीवेयर एप्लिकेशन है जो 32-बिट और 64-बिट एप्लिकेशन और सेवाओं में 10,000+ विंडोज एपीआई और COM इंटरफेस को हुक और प्रदर्शित कर सकता है।
* [http://www.rohitab.com/apimonitor rohitab.com एपीआई मॉनिटर] एक फ्रीवेयर एप्लिकेशन है जो 32-बिट और 64-बिट एप्लिकेशन और सेवाओं में 10,000+ विंडोज एपीआई और COM इंटरफेस को हुक और प्रदर्शित कर सकता है।
* [http://www.nektra.com/products/deviare-api-hook-windows/ डेविएरे एपीआई हुक] डेविएरे एक फ्रीवेयर इंटर-प्रोसेस हुक फ्रेमवर्क है जिसका उपयोग अन्य प्रक्रियाओं के एपीआई कॉल को इंटरसेप्ट करने और पूर्ण दिखाने के लिए किया जा सकता है। पैरामीटर जानकारी या एपीआई मॉनिटर बनाएं।
* [http://www.nektra.com/products/deviare-api-hook-windows/ डेविएरे एपीआई हुक] डेविएरे एक फ्रीवेयर इंटर-प्रोसेस हुक फ्रेमवर्क है जिसका उपयोग अन्य प्रक्रियाओं के एपीआई कॉल को इंटरसेप्ट करने और पूर्ण दिखाने के लिए किया जा सकता है। पैरामीटर जानकारी या एपीआई मॉनिटर बनाएं।
* [http://jacquelin.potier.free.fr/winapioverride32/ WinAPIOverride] WinAPIOverride गैर व्यावसायिक उपयोग के लिए एक फ्रीवेयर है। यह Win32 API, COM, OLE, ActiveX, .NET को 32-बिट और 64-बिट प्रक्रियाओं में हुक कर सकता है। इसमें पोस्ट विश्लेषण टूल की निगरानी शामिल है।
* [http://jacquelin.potier.free.fr/winapioverride32/ WinAPIOverride] WinAPIOverride गैर व्यावसायिक उपयोग के लिए एक फ्रीवेयर है। यह Win32 API, COM, OLE, ActiveX, .NET को 32-बिट और 64-बिट प्रक्रियाओं में हुक कर सकता है। इसमें पोस्ट विश्लेषण टूल की निगरानी सम्मिलित है।
* [https://github.com/urShadow/urmem urmem] मेमोरी (हुक, पैच, पॉइंटर रैपर, सिग्नेचर स्कैनर आदि) के साथ काम करने के लिए C++11 क्रॉस-प्लेटफॉर्म लाइब्रेरी (x86)
* [https://github.com/urShadow/urmem urmem] मेमोरी (हुक, पैच, पॉइंटर रैपर, सिग्नेचर स्कैनर आदि) के साथ काम करने के लिए C++11 क्रॉस-प्लेटफॉर्म लाइब्रेरी (x86)


Line 464: Line 442:


श्रेणी:प्रवाह नियंत्रित करें
श्रेणी:प्रवाह नियंत्रित करें
श्रेणी:डीएलएल इंजेक्शन
श्रेणी:डीएलएल इंजेक्शन
श्रेणी:उदाहरण कोड वाले लेख
श्रेणी:उदाहरण कोड वाले लेख


[[Category: Machine Translated Page]]
[[Category: Machine Translated Page]]
[[Category:Created On 15/08/2023]]
[[Category:Created On 15/08/2023]]

Revision as of 19:06, 22 November 2023

कंप्यूटर प्रोग्रामिंग में हुकिंग शब्द में मॉड्यूलर प्रोग्रामिंग के बीच फ़ंक्शन कॉल या संदेशों या घटना (कंप्यूटिंग) को इंटरसेप्ट करके ऑपरेटिंग सिस्टम, एप्लिकेशन या अन्य सॉफ़्टवेयर घटकों के व्यवहार को परिवर्तित या बढ़ाने के लिए उपयोग की जाने वाली तकनीकों की एक श्रृंखला सम्मिलित है। कोड जो ऐसे इंटरसेप्टेड फ़ंक्शन कॉल, ईवेंट या संदेशों को संभालता है उसे हुक कहा जाता है।

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

हुकिंग का उपयोग दुर्भावनापूर्ण कोड द्वारा भी किया जा सकता है। उदाहरण के लिए, रूटकिट, सॉफ़्टवेयर के टुकड़े जो एपीआई कॉल के नकली आउटपुट द्वारा खुद को अदृश्य बनाने की कोशिश करते हैं जो अन्यथा उनके अस्तित्व को प्रकट कर सकते हैं प्रायः हुकिंग तकनीकों का उपयोग करते हैं।

प्रकार

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

सोर्स कोड संशोधन

किसी एप्लिकेशन के चलने से पहले रिवर्स इंजीनियरिंग की तकनीकों के माध्यम से निष्पादन योग्य या लाइब्रेरी के सोर्स कोड को संशोधित करके हुकिंग प्राप्त की जा सकती है। इसका उपयोग सामान्यतः फ़ंक्शन कॉल को मॉनिटर करने या उन्हें पूरी तरह से परिवर्तित करने के लिए इंटरसेप्ट करने के लिए किया जाता है।

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

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

रनटाइम संशोधन

ऑपरेटिंग सिस्टम और सॉफ़्टवेयर रनटाइम पर आसानी से इवेंट हुक डालने के साधन प्रदान कर सकते हैं। यह उपलब्ध है बशर्ते कि हुक डालने की प्रक्रिया को ऐसा करने के लिए पर्याप्त अनुमति दी गई हो। उदाहरण के लिए, माइक्रोसॉफ्ट विंडोज़, उपयोगकर्ताओं को हुक डालने की अनुमति देता है जिसका उपयोग सिस्टम इवेंट और डायलॉग, स्क्रॉल बार और मेनू के साथ-साथ अन्य आइटम के लिए एप्लिकेशन इवेंट को संसाधित या संशोधित करने के लिए किया जा सकता है। यह हुक को कीबोर्ड और माउस (कंप्यूटिंग) इवेंट को सम्मिलित करने, हटाने, संसाधित करने या संशोधित करने की भी अनुमति देता है। लिनक्स एक और उदाहरण प्रदान करता है जहां नेटफ़िल्टर के माध्यम से कर्नेल (ऑपरेटिंग सिस्टम) के भीतर नेटवर्क घटनाओं को संसाधित करने के लिए हुक का उपयोग समान तरीके से किया जा सकता है।

जब ऐसी कार्यक्षमता प्रदान नहीं की जाती है, तो हुकिंग का एक विशेष रूप एक प्रक्रिया द्वारा किए गए लाइब्रेरी फ़ंक्शन कॉल को इंटरसेप्ट करने का काम करता है। फ़ंक्शन हुकिंग को एक इंजेक्टेड कोड पर जाने के लिए लक्ष्य फ़ंक्शन के पहले कुछ कोड इंस्ट्रक्शन को बदलकर कार्यान्वित किया जाता है। वैकल्पिक रूप से साझा लाइब्रेरी अवधारणा का उपयोग करने वाले सिस्टम पर, इंटरप्ट वेक्टर तालिका या आयात डिस्क्रिप्टर तालिका को मेमोरी में संशोधित किया जा सकता है। अनिवार्य रूप से ये युक्तियाँ सोर्स कोड संशोधन के समान विचारों को नियोजित करती हैं, लेकिन इसके अतिरिक्त किसी प्रक्रिया के पहले से चलने के बाद उसकी मेमोरी में स्थित इंस्ट्रक्शन और संरचनाओं को बदल देती हैं।

सैंपल कोड

वर्चुअल टेबल हुकिंग विधि

जब भी कोई क्लास किसी वर्चुअल फ़ंक्शन (या मेथड) को परिभाषित/इनहेरिट करता है, तो कंपाइलर क्लास में एक छिपा हुआ सदस्य वेरिएबल जोड़ते हैं जो वर्चुअल मेथड टेबल (वीएमटी या वीटेबल) की ओर इशारा करता है। अधिकांश कंपाइलर कक्षा के प्रत्येक उदाहरण के पहले 4 बाइट्स पर छिपे हुए वीएमटी पॉइंटर को रखते हैं। वीएमटी मूल रूप से सभी वर्चुअल फ़ंक्शन के लिए पॉइंटर्स की एक सरणी है जिसे क्लास के इंस्टेंस कॉल कर सकते हैं। रनटाइम पर ये पॉइंटर्स सही फ़ंक्शन को इंगित करने के लिए सेट किए जाते हैं, क्योंकि संकलन समय पर, यह अभी तक ज्ञात नहीं है कि क्या बेस फ़ंक्शन को कॉल किया जाना है या यदि किसी व्युत्पन्न वर्ग से फ़ंक्शन का ओवरराइड संस्करण कॉल किया जाना है (जिससे अनुमति मिलती है) बहुरूपता के लिए)। इसलिए, वर्चुअल फ़ंक्शन को किसी भी वीएमटी के भीतर पॉइंटर्स को प्रतिस्थापित करके हुक किया जा सकता है जो वे दिखाई देते हैं। नीचे दिया गया कोड माइक्रोसॉफ़्ट विंडोज़ में एक विशिष्ट वीएमटी हुक का एक उदाहरण दिखाता है, जो C++ में लिखा गया है।[1]

#include <iostream>
#include "windows.h"
 
using namespace std;
 
class VirtualClass
{
public:
 
    int number;
 
    virtual void VirtualFn1() //This is the virtual function that will be hooked.
    {
        cout << "VirtualFn1 called " << number++ << "\n\n";
    }
};
 
 
 
 
using VirtualFn1_t = void(__thiscall*)(void* thisptr); 
VirtualFn1_t orig_VirtualFn1;
 

void __fastcall hkVirtualFn1(void* thisptr, int edx) //This is our hook function which we will cause the program to call instead of the original VirtualFn1 function after hooking is done.
{
    cout << "Hook function called" << "\n";
 
    orig_VirtualFn1(thisptr); //Call the original function.
}
 
 
 
 
int main()
{
    VirtualClass* myClass = new VirtualClass(); //Create a pointer to a dynamically allocated instance of VirtualClass.
 
    void** vTablePtr = *reinterpret_cast<void***>(myClass); //Find the address that points to the base of VirtualClass' VMT (which then points to VirtualFn1) and store it in vTablePtr.
 
    DWORD oldProtection;
    VirtualProtect(vTablePtr, 4, PAGE_EXECUTE_READWRITE, &oldProtection); //Removes page protection at the start of the VMT so we can overwrite its first pointer.
 
    orig_VirtualFn1 = reinterpret_cast<VirtualFn1_t>(*vTablePtr); //Stores the pointer to VirtualFn1 from the VMT in a global variable so that it can be accessed again later after its entry in the VMT has been 
                                                                  //overwritten with our hook function.
 
    *vTablePtr = &hkVirtualFn1; //Overwrite the pointer to VirtualFn1 within the virtual table to a pointer to our hook function (hkVirtualFn1).
 
    VirtualProtect(vTablePtr, 4, oldProtection, 0); //Restore old page protection.
 
    myClass->VirtualFn1(); //Call the virtual function from our class instance. Because it is now hooked, this will actually call our hook function (hkVirtualFn1).
    myClass->VirtualFn1();
    myClass->VirtualFn1();
 
    delete myClass;
 
    return 0;
}

यह ध्यान रखना महत्वपूर्ण है कि सभी वर्चुअल फ़ंक्शन क्लास सदस्य फ़ंक्शन होने चाहिए, और सभी (गैर स्थैतिक) क्लास सदस्य फ़ंक्शन को _thiscall कॉलिंग कन्वेंशन के साथ कॉल किया जाता है (जब तक कि सदस्य फ़ंक्शन तर्कों की एक चर संख्या नहीं लेता है, जिस स्थिति में इसे कहा जाता है) _cdecl के साथ)_thiscall कॉलिंग कन्वेंशन ईसीएक्स रजिस्टर (x86 आर्किटेक्चर पर) के माध्यम से कॉलिंग क्लास इंस्टेंस (सामान्यतः "इस" पॉइंटर के रूप में संदर्भित) के लिए एक पॉइंटर पास करता है। इसलिए, हुक फ़ंक्शन द्वारा पारित किए गए "इस" पॉइंटर को ठीक से इंटरसेप्ट करने और इसे एक तर्क के रूप में लेने के लिए, इसे ईसीएक्स रजिस्टर में देखना होगा। उपरोक्त उदाहरण में, यह _fastcall कॉलिंग कन्वेंशन का उपयोग करने के लिए हुक फ़ंक्शन (hkVirtualFn1) को सेट करके किया जाता है, जो हुक फ़ंक्शन को उसके एक तर्क के लिए ईसीएक्स रजिस्टर में देखने का कारण बनता है।

यह भी ध्यान दें कि, उपरोक्त उदाहरण में, हुक फ़ंक्शन (hkVirtualFn1) स्वयं एक सदस्य फ़ंक्शन नहीं है, इसलिए यह _thiscall कॉलिंग कन्वेंशन का उपयोग नहीं कर सकता है। इसके अतिरिक्त _fastcall का उपयोग करना होगा क्योंकि यह एकमात्र अन्य कॉलिंग कन्वेंशन है जो किसी तर्क के लिए ईसीएक्स रजिस्टर को देखता है। hkVirtualFn1

सी# कीबोर्ड इवेंट हुक

निम्न उदाहरण माइक्रोसॉफ्ट नेट फ्रेमवर्क का उपयोग करके माइक्रोसॉफ़्ट विंडोज़ में कीबोर्ड ईवेंट से जुड़ जाएगा।

using System.Runtime.InteropServices;

namespace Hooks;

public class KeyHook
{
    /* Member variables */
    protected static int Hook;
    protected static LowLevelKeyboardDelegate Delegate;
    protected static readonly object Lock = new object();
    protected static bool IsRegistered = false;

    /* DLL imports */
    [DllImport("user32")]
    private static extern int SetWindowsHookEx(int idHook, LowLevelKeyboardDelegate lpfn,
        int hmod, int dwThreadId);

    [DllImport("user32")]
    private static extern int CallNextHookEx(int hHook, int nCode, int wParam, KBDLLHOOKSTRUCT lParam);

    [DllImport("user32")]
    private static extern int UnhookWindowsHookEx(int hHook);

    /* Types & constants */
    protected delegate int LowLevelKeyboardDelegate(int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam);
    private const int HC_ACTION = 0;
    private const int WM_KEYDOWN = 0x0100;
    private const int WM_KEYUP = 0x0101;
    private const int WH_KEYBOARD_LL = 13;

    [StructLayout(LayoutKind.Sequential)]
    public struct KBDLLHOOKSTRUCT
    {
        public int vkCode;
        public int scanCode;
        public int flags;
        public int time;
        public int dwExtraInfo;
    }

    /* Methods */
    static private int LowLevelKeyboardHandler(int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam)
    {
        if (nCode == HC_ACTION)
        {
            if (wParam == WM_KEYDOWN)
                System.Console.Out.WriteLine("Key Down: " + lParam.vkCode);
            else if (wParam == WM_KEYUP)
                System.Console.Out.WriteLine("Key Up: " + lParam.vkCode);
        }
        return CallNextHookEx(Hook, nCode, wParam, lParam);
    }

    public static bool RegisterHook()
    {
        lock (Lock)
        {
            if (IsRegistered)
                return true;
            Delegate = LowLevelKeyboardHandler;
            Hook = SetWindowsHookEx(
                WH_KEYBOARD_LL, Delegate,
                Marshal.GetHINSTANCE(
                    System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0]
                ).ToInt32(), 0
            );

            if (Hook != 0)
                return IsRegistered = true;
            Delegate = null;
            return false;
        }
    }

    public static bool UnregisterHook()
    {
        lock (Lock)
        {
            return IsRegistered = (UnhookWindowsHookEx(Hook) != 0);
        }
    }
}

एपीआई/फ़ंक्शन हुकिंग/इंटरसेप्शन जेएमपी अनुदेश उर्फ ​​स्प्लिसिंग का उपयोग करके

निम्नलिखित सोर्स कोड कोड एक एपीआई/फ़ंक्शन हुकिंग विधि का एक उदाहरण है जो एक गंतव्य फ़ंक्शन के पहले छह बाइट्स को जेएमपी (x86 इंस्ट्रक्शन) के साथ एक नए फ़ंक्शन पर ओवरराइट करके हुक करता है। कोड को एक डायनामिक-लिंक लाइब्रेरी फ़ाइल में संकलित किया जाता है और फिर डायनामिक-लिंक लाइब्रेरी इंजेक्शन की किसी भी विधि का उपयोग करके लक्ष्य प्रक्रिया में लोड किया जाता है। मूल फ़ंक्शन के बैकअप का उपयोग करके पहले छह बाइट्स को फिर से पुनर्स्थापित किया जा सकता है ताकि कॉल बाधित न हो। इस उदाहरण में Win32 API फ़ंक्शन MessageBoxW जुड़ा हुआ है।[2]

/*
 This idea is based on chrom-lib approach, Distributed under GNU LGPL License.
 Source chrom-lib: https://github.com/linuxexp/chrom-lib
 Copyright (C) 2011  Raja Jamwal
*/
#include <windows.h>  
#define SIZE 6

 typedef int (WINAPI *pMessageBoxW)(HWND, LPCWSTR, LPCWSTR, UINT);  // Messagebox prototype
 int WINAPI MyMessageBoxW(HWND, LPCWSTR, LPCWSTR, UINT);            // Our detour

 void BeginRedirect(LPVOID);                                        
 pMessageBoxW pOrigMBAddress = NULL;                                // address of original
 BYTE oldBytes[SIZE] = {0};                                         // backup
 BYTE JMP[SIZE] = {0};                                              // 6 byte JMP instruction
 DWORD oldProtect, myProtect = PAGE_EXECUTE_READWRITE;

 INT APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved)  
 {  
   switch (Reason)  
   {  
   case DLL_PROCESS_ATTACH:                                        // if attached
     pOrigMBAddress = (pMessageBoxW)                      
       GetProcAddress(GetModuleHandleA("user32.dll"),              // get address of original 
               "MessageBoxW");  
     if (pOrigMBAddress != NULL)  
       BeginRedirect(MyMessageBoxW);                               // start detouring
     break;

   case DLL_PROCESS_DETACH:  
     VirtualProtect((LPVOID)pOrigMBAddress, SIZE, myProtect, &oldProtect);   // assign read write protection
     memcpy(pOrigMBAddress, oldBytes, SIZE);                                 // restore backup
     VirtualProtect((LPVOID)pOrigMBAddress, SIZE, oldProtect, &myProtect);   // reset protection

   case DLL_THREAD_ATTACH:  
   case DLL_THREAD_DETACH:  
     break;  
   }  
   return TRUE;  
 }

 void BeginRedirect(LPVOID newFunction)  
 {  
   BYTE tempJMP[SIZE] = {0xE9, 0x90, 0x90, 0x90, 0x90, 0xC3};              // 0xE9 = JMP 0x90 = NOP 0xC3 = RET
   memcpy(JMP, tempJMP, SIZE);                                             // store jmp instruction to JMP
   DWORD JMPSize = ((DWORD)newFunction - (DWORD)pOrigMBAddress - 5);       // calculate jump distance
   VirtualProtect((LPVOID)pOrigMBAddress, SIZE,                            // assign read write protection
           PAGE_EXECUTE_READWRITE, &oldProtect);  
   memcpy(oldBytes, pOrigMBAddress, SIZE);                                 // make backup
   memcpy(&JMP[1], &JMPSize, 4);                                           // fill the nop's with the jump distance (JMP,distance(4bytes),RET)
   memcpy(pOrigMBAddress, JMP, SIZE);                                      // set jump instruction at the beginning of the original function
   VirtualProtect((LPVOID)pOrigMBAddress, SIZE, oldProtect, &myProtect);   // reset protection
 }

 int WINAPI MyMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uiType)  
 {  
   VirtualProtect((LPVOID)pOrigMBAddress, SIZE, myProtect, &oldProtect);   // assign read write protection
   memcpy(pOrigMBAddress, oldBytes, SIZE);                                 // restore backup
   int retValue = MessageBoxW(hWnd, lpText, lpCaption, uiType);            // get return value of original function
   memcpy(pOrigMBAddress, JMP, SIZE);                                      // set the jump instruction again
   VirtualProtect((LPVOID)pOrigMBAddress, SIZE, oldProtect, &myProtect);   // reset protection
   return retValue;                                                        // return original return value
 }

नेटफ़िल्टर हुक

यह उदाहरण दिखाता है कि नेटफिल्टर का उपयोग करके लिनक्स कर्नेल में नेटवर्क ट्रैफ़िक को परिवर्तित के लिए हुकिंग का उपयोग कैसे करें।

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>

#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/in.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>

/* Port we want to drop packets on */
static const uint16_t port = 25;

/* This is the hook function itself */
static unsigned int hook_func(unsigned int hooknum,
                       struct sk_buff **pskb,
                       const struct net_device *in,
                       const struct net_device *out,
                       int (*okfn)(struct sk_buff *))
{
        struct iphdr *iph = ip_hdr(*pskb);
        struct tcphdr *tcph, tcpbuf;

        if (iph->protocol != IPPROTO_TCP)
                return NF_ACCEPT;

        tcph = skb_header_pointer(*pskb, ip_hdrlen(*pskb), sizeof(*tcph), &tcpbuf);
        if (tcph == NULL)
                return NF_ACCEPT;

        return (tcph->dest == port) ? NF_DROP : NF_ACCEPT;
}

/* Used to register our hook function */
static struct nf_hook_ops nfho = {
        .hook     = hook_func,
        .hooknum  = NF_IP_PRE_ROUTING,
        .pf       = NFPROTO_IPV4,
        .priority = NF_IP_PRI_FIRST,
};

static __init int my_init(void)
{
        return nf_register_hook(&nfho);
}

static __exit void my_exit(void)
{
    nf_unregister_hook(&nfho);
}

module_init(my_init);
module_exit(my_exit);

आंतरिक आईएटी हुकिंग

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

#include <windows.h>

typedef int(__stdcall *pMessageBoxA) (HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType); //This is the 'type' of the MessageBoxA call.
pMessageBoxA RealMessageBoxA; //This will store a pointer to the original function.

void DetourIATptr(const char* function, void* newfunction, HMODULE module);

int __stdcall NewMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType) { //Our fake function
    printf("The String Sent to MessageBoxA Was : %s\n", lpText);
    return RealMessageBoxA(hWnd, lpText, lpCaption, uType); //Call the real function
}

int main(int argc, CHAR *argv[]) {
   DetourIATptr("MessageBoxA",(void*)NewMessageBoxA,0); //Hook the function
   MessageBoxA(NULL, "Just A MessageBox", "Just A MessageBox", 0); //Call the function -- this will invoke our fake hook.
   return 0;
}

void **IATfind(const char *function, HMODULE module) { //Find the IAT (Import Address Table) entry specific to the given function.
	int ip = 0;
	if (module == 0)
		module = GetModuleHandle(0);
	PIMAGE_DOS_HEADER pImgDosHeaders = (PIMAGE_DOS_HEADER)module;
	PIMAGE_NT_HEADERS pImgNTHeaders = (PIMAGE_NT_HEADERS)((LPBYTE)pImgDosHeaders + pImgDosHeaders->e_lfanew);
	PIMAGE_IMPORT_DESCRIPTOR pImgImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)((LPBYTE)pImgDosHeaders + pImgNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);

	if (pImgDosHeaders->e_magic != IMAGE_DOS_SIGNATURE)
		printf("libPE Error : e_magic is no valid DOS signature\n");

	for (IMAGE_IMPORT_DESCRIPTOR *iid = pImgImportDesc; iid->Name != NULL; iid++) {
		for (int funcIdx = 0; *(funcIdx + (LPVOID*)(iid->FirstThunk + (SIZE_T)module)) != NULL; funcIdx++) {
			char *modFuncName = (char*)(*(funcIdx + (SIZE_T*)(iid->OriginalFirstThunk + (SIZE_T)module)) + (SIZE_T)module + 2);
			const uintptr_t nModFuncName = (uintptr_t)modFuncName;
			bool isString = !(nModFuncName & (sizeof(nModFuncName) == 4 ? 0x80000000 : 0x8000000000000000));
			if (isString) {
				if (!_stricmp(function, modFuncName))
					return funcIdx + (LPVOID*)(iid->FirstThunk + (SIZE_T)module);
			}
		}
	}
	return 0;
}

void DetourIATptr(const char *function, void *newfunction, HMODULE module) {
	void **funcptr = IATfind(function, module);
	if (*funcptr == newfunction)
		 return;

	DWORD oldrights, newrights = PAGE_READWRITE;
	//Update the protection to READWRITE
	VirtualProtect(funcptr, sizeof(LPVOID), newrights, &oldrights);

	RealMessageBoxA = (pMessageBoxA)*funcptr; //Some compilers require the cast (like "MinGW"), not sure about MSVC though
	*funcptr = newfunction;

	//Restore the old memory protection flags.
	VirtualProtect(funcptr, sizeof(LPVOID), oldrights, &newrights);
}

यह भी देखें

संदर्भ

  • Jonathan Daniel (2013-11-27). "Hooking explained: detouring library calls and vtable patching in Windows/Linux/MAC-OSX". Retrieved 2014-01-01.
  • Binh Nguyen (2004-08-16). "Hacking-Lexicon / Linux Dictionary V 0.16". Retrieved 2008-02-23. Hook
  • [2012-06-29: Link appears to be dead] Author: Holy Father (2002-06-10). "Hooking Windows API - Technics of hooking API functions on Windows 1.1 english" (PDF). Archived from the original (PDF) on 2009-12-29. Retrieved 2008-02-21. {{cite web}}: |author= has generic name (help)

बाहरी संबंध

विंडोज़

  • आयात पता तालिका फ़ंक्शन हुकिंग पर जानकारी।
  • हुकिंग पर माइक्रोसॉफ्ट से जानकारी
  • x86 हुकिंग के संबंध में जानकारी और विभिन्न तकनीकें।
  • APISpy32 एक एप्लिकेशन है जिसका उपयोग Win32 API को हुक करने के लिए किया जाता है।
  • Detours माइक्रोसॉफ्ट रिसर्च द्वारा बनाई गई एक सामान्य प्रयोजन फ़ंक्शन हुकिंग लाइब्रेरी है जो C/C++ में काम करती है।
  • [2] किसी अन्य प्रक्रिया में कोड डालने के तीन तरीके।
  • HookTool SDK (ACF SDK) एपीआई हुकिंग और कोड इंजेक्शन पर एक व्यापक अवलोकन प्रदान करता है। एक व्यावसायिक उत्पाद भी उपलब्ध है.
  • [3] C++ और डेल्फ़ी के लिए एक व्यावसायिक x86 और x64 API हुकिंग और डायनामिक-लिंक लाइब्रेरी इंजेक्शन लाइब्रेरी है।
  • EasyHook एक ओपन सोर्स हुकिंग इंजन है जो विंडोज़ में उपयोगकर्ता और कर्नेल भूमि दोनों में x86 और x64 का समर्थन करता है।
  • SpyStudio एप्लिकेशन ट्रेस SpyStudio एक एप्लिकेशन ट्रेसर है जो कॉल को हुक करता है, परिणामों को संरचित तरीके से प्रदर्शित करता है।
  • rohitab.com एपीआई मॉनिटर एक फ्रीवेयर एप्लिकेशन है जो 32-बिट और 64-बिट एप्लिकेशन और सेवाओं में 10,000+ विंडोज एपीआई और COM इंटरफेस को हुक और प्रदर्शित कर सकता है।
  • डेविएरे एपीआई हुक डेविएरे एक फ्रीवेयर इंटर-प्रोसेस हुक फ्रेमवर्क है जिसका उपयोग अन्य प्रक्रियाओं के एपीआई कॉल को इंटरसेप्ट करने और पूर्ण दिखाने के लिए किया जा सकता है। पैरामीटर जानकारी या एपीआई मॉनिटर बनाएं।
  • WinAPIOverride WinAPIOverride गैर व्यावसायिक उपयोग के लिए एक फ्रीवेयर है। यह Win32 API, COM, OLE, ActiveX, .NET को 32-बिट और 64-बिट प्रक्रियाओं में हुक कर सकता है। इसमें पोस्ट विश्लेषण टूल की निगरानी सम्मिलित है।
  • urmem मेमोरी (हुक, पैच, पॉइंटर रैपर, सिग्नेचर स्कैनर आदि) के साथ काम करने के लिए C++11 क्रॉस-प्लेटफॉर्म लाइब्रेरी (x86)

लिनक्स

  • [4] एक छात्र अनुसंधान परियोजना जो उपयोग करती है हुकिंग.
  • [5] कार्यक्षमता जो सॉफ़्टवेयर के एक टुकड़े को किसी अन्य प्रक्रिया के निष्पादन को देखने और नियंत्रित करने की अनुमति देती है .
  • [6] साझा लाइब्रेरी कॉल को हुक करने के लिए LD_PRELOAD का उपयोग।

Emacs

  • Emacs Hooks Emacs के अनुकूलन के लिए हुक एक महत्वपूर्ण तंत्र हैं। हुक एक लिस्प वैरिएबल है जिसमें कुछ अच्छी तरह से परिभाषित अवसरों पर बुलाए जाने वाले कार्यों की एक सूची होती है। (इसे हुक चलाना कहते हैं।)

ओएस एक्स और आईओएस

  • Cydia Substrate जेलब्रेक किए गए iOS उपकरणों के लिए एक ढांचा है जो डेवलपर्स को किसी अन्य ढांचे या एप्लिकेशन से जुड़ने की अनुमति देता है।
  • harpoon रनटाइम फ़ंक्शन हुकिंग के लिए एक OS

गहराई में एपीआई हुकिंग

  • x86 API Hooking Demystified x86 आर्किटेक्चर के लिए विभिन्न एपीआई हुकिंग विधियों पर लेख।

श्रेणी:प्रवाह नियंत्रित करें

श्रेणी:डीएलएल इंजेक्शन

श्रेणी:उदाहरण कोड वाले लेख