
आईओएस कर्नेल फंक्शन हुकिंग फ्रेमवर्क checkra1n'able उपकरणों के लिए

कर्नेल लॉग से आउटपुट example/open1_hook.c को संकलित और चलाने के बाद
xnuspy एक pongoOS मॉड्यूल है जो एक नया सिस्टम कॉल xnuspy_ctl स्थापित करता है,
जो आपको यूज़रस्पेस से कर्नेल फ़ंक्शन को हुक करने की अनुमति देता है। यह iOS 13.x,
iOS 14.x, और iOS 15.x को checkra1n 0.12.2 और उससे ऊपर पर सपोर्ट करता है। 4K डिवाइस समर्थित नहीं हैं।
यह मॉड्यूल KTRR/KPP को पूरी तरह से बेअसर कर देता है और EL1 के अंदर RWX मेमोरी बनाना संभव बनाता है। इसे अपने प्राथमिक डिवाइस पर उपयोग न करें।
आवश्यकता है libusb: brew install libusb
शीर्ष स्तर की निर्देशिका में make चलाएँ। यह लोडर और मॉड्यूल बनाएगा।
इन्हें make से पहले जोड़ें।
XNUSPY_DEBUG=1
kprintf) पर भेजें।XNUSPY_SERIAL=1
IOLog पर भेजें।XNUSPY_LEAKED_PAGE_LIMIT=n
64 है। अधिक जानकारी
डीबगिंग कर्नेल पैनिक्स के अंतर्गत पाई जा सकती है।XNUSPY_TRAMP_PAGES=n
XNUSPY_DEBUG और XNUSPY_SERIAL एक-दूसरे पर निर्भर नहीं हैं।
सब कुछ बनाने के बाद, checkra1n को अपने डिवाइस को pongo शेल में बूट करने के लिए कहें:
/Applications/checkra1n.app/Contents/MacOS/checkra1n -p
उसी निर्देशिका में जहाँ आपने लोडर और मॉड्यूल बनाए हैं,
loader/loader module/xnuspy चलाएँ। ऐसा करने के बाद, xnuspy अपना काम करेगा और
कुछ सेकंड में आपका डिवाइस बूट हो जाएगा। loader SEPROM के शोषण की आवश्यकता होने पर
xnuspy-getkernelv जारी करने के बाद कुछ और सेकंड प्रतीक्षा करेगा।
कभी-कभी मेरे कुछ फ़ोन checkra1n के KPF चलने के बाद "Booting" पर अटक जाते हैं।
मुझे अभी तक पता नहीं चला है कि इसका कारण क्या है, लेकिन यदि ऐसा होता है, तो पुनः प्रयास करें।
साथ ही, यदि डिवाइस bootx के बाद हैंग हो जाता है, तो पुनः प्रयास करें। अंत में, मेरे iPhone X पर
iOS 13.3.1 चलाने पर संकलित xnuspy_ctl कोड को निष्पादन योग्य के रूप में चिह्नित करना
थोड़ा अनियमित है, लेकिन मेरे अन्य फ़ोनों पर 100% सफल होता है। यदि आप अपना हुक प्रोग्राम निष्पादित करते समय
कर्नेल निर्देश लाने में विफलता के साथ पैनिक करते हैं, तो पुनः प्रयास करें।
xnuspy एक enosys सिस्टम कॉल को पैच करके xnuspy_ctl_tramp की ओर इंगित करेगा।
यह एक छोटा ट्राम्पोलिन है जो संकलित xnuspy_ctl कोड को निष्पादन योग्य के रूप में चिह्नित करता है
और उस पर शाखा लगाता है। आप xnuspy_ctl का कार्यान्वयन module/el1/xnuspy_ctl/xnuspy_ctl.c पर
और example निर्देशिका में उदाहरण पा सकते हैं।
include/xnuspy/ के अंदर xnuspy_ctl.h है, एक हेडर जो xnuspy_ctl के लिए
स्थिरांक को परिभाषित करता है। इसका उद्देश्य उन सभी प्रोग्रामों में शामिल किया जाना है जो
कर्नेल फ़ंक्शन को हुक करते हैं।
आप यह पता लगाने के लिए sysctlbyname का उपयोग कर सकते हैं कि कौन सा सिस्टम कॉल पैच किया गया था:```
size_t oldlen = sizeof(long);
long SYS_xnuspy_ctl = 0;
sysctlbyname("kern.xnuspy_ctl_callnum", &SYS_xnuspy_ctl, &oldlen, NULL, 0);
यह सिस्टम कॉल चार तर्क लेता है: `flavor`, `arg1`, `arg2`, और `arg3`।
flavor या तो `XNUSPY_CHECK_IF_PATCHED`, `XNUSPY_INSTALL_HOOK`,
`XNUSPY_REGISTER_DEATH_CALLBACK`, `XNUSPY_CALL_HOOKME`, `XNUSPY_CACHE_READ`,
`XNUSPY_KREAD`, `XNUSPY_KWRITE`, या `XNUSPY_GET_CURRENT_THREAD` हो सकता है।
अगले तीन तर्कों का अर्थ flavor पर निर्भर करता है।
## `XNUSPY_CHECK_IF_PATCHED`
यह इसलिए मौजूद है ताकि आप जाँच सकें कि `xnuspy_ctl` मौजूद है या नहीं। इस flavor के साथ इसे कॉल करने पर यह `999` लौटाएगा। अन्य तर्कों के मानों को अनदेखा किया जाता है।
## `XNUSPY_INSTALL_HOOK`
मैंने इस flavor को [`MSHookFunction`](http://www.cydiasubstrate.com/api/c/MSHookFunction/) के API से मेल खाने के लिए डिज़ाइन किया है।
`arg1` उस कर्नेल फ़ंक्शन का *अनस्लाइड* पता है जिसे आप हुक करना चाहते हैं। यदि आप स्लाइड किया हुआ पता देते हैं, तो संभवतः पैनिक होगा। `arg2` आपके ABI-संगत प्रतिस्थापन फ़ंक्शन का सूचक है। `arg3` एक सूचक है जिसमें `xnuspy_ctl` मूल कर्नेल फ़ंक्शन का प्रतिनिधित्व करने वाले ट्रैम्पोलिन के पते को `copyout` करेगा। यदि आप मूल को कॉल करने का इरादा नहीं रखते हैं तो यह `NULL` हो सकता है।
## `XNUSPY_REGISTER_DEATH_CALLBACK`
यह flavor आपको एक वैकल्पिक "डेथ कॉलबैक" पंजीकृत करने की अनुमति देता है, एक फ़ंक्शन जिसे xnuspy आपके हुक प्रोग्राम के बाहर निकलने पर कॉल करेगा। यह आपको अपने कर्नेल हुक से बनाई गई किसी भी चीज़ को साफ करने का मौका देता है। यदि आपने कोई कर्नेल थ्रेड बनाया है, तो आप इस फ़ंक्शन में उन्हें समाप्त करने का निर्देश देंगे।
आपका कॉलबैक अतुल्यकालिक रूप से लागू नहीं होता है, इसलिए यदि आप ब्लॉक करते हैं, तो आप xnuspy के कचरा संग्रह थ्रेड को निष्पादित होने से रोक रहे हैं।
`arg1` आपके कॉलबैक फ़ंक्शन का सूचक है। अन्य तर्कों के मानों को अनदेखा किया जाता है।
## `XNUSPY_CALL_HOOKME`
`hookme` एक छोटा असेंबली स्टब है जिसे xnuspy xnuspy कैश के माध्यम से आपके लिए हुक करने के लिए निर्यात करता है। इस flavor के साथ `xnuspy_ctl` को लागू करने से `hookme` कॉल हो जाएगा, जो आपको वास्तविक कर्नेल फ़ंक्शन को हुक किए बिना आसानी से कर्नेल कोड निष्पादन प्राप्त करने का एक तरीका प्रदान करता है।
`arg1` एक तर्क है जो `hookme` के लागू होने पर उसे दिया जाएगा। यह `NULL` हो सकता है।
## `XNUSPY_CACHE_READ`
यह flavor आपको xnuspy कैश से पढ़ने का एक तरीका देता है। इसमें कई उपयोगी चीज़ें हैं जैसे `kprintf`, `current_proc`, `kernel_thread_start`, कुछ libc फ़ंक्शन, और कर्नेल स्लाइड, ताकि आपको उन्हें स्वयं खोजने की आवश्यकता न पड़े। कैश आईडी की पूरी सूची के लिए `example/xnuspy_ctl.h` देखें।
`arg1` `xnuspy_ctl.h` में परिभाषित कैश आईडी में से एक है और `arg2` एक सूचक है जिसमें `xnuspy_ctl` आपके द्वारा अनुरोधित पते या मान को `copyout` करेगा। अन्य तर्कों के मानों को अनदेखा किया जाता है।
## `XNUSPY_KREAD`
यह flavor आपको tfp0 के बिना यूज़रस्पेस से कर्नेल मेमोरी पढ़ने का एक आसान तरीका देता है।
`arg1` एक कर्नेल वर्चुअल पता है, `arg2` एक यूज़रस्पेस बफ़र का पता है, और `arg3` उस यूज़रस्पेस बफ़र का आकार है। `arg3` बाइट `arg1` से `arg2` पर लिखे जाएंगे।
## `XNUSPY_KWRITE`
यह flavor आपको tfp0 के बिना यूज़रस्पेस से कर्नेल मेमोरी में लिखने का एक आसान तरीका देता है।
`arg1` एक कर्नेल वर्चुअल पता है, `arg2` एक यूज़रस्पेस बफ़र का पता है, और `arg3` उस यूज़रस्पेस बफ़र का आकार है। `arg3` बाइट `arg2` से `arg1` पर लिखे जाएंगे।
## `XNUSPY_GET_CURRENT_THREAD`
यह flavor यूज़रस्पेस को कॉल करने वाले थ्रेड का कर्नेल पता प्रदान करता है।
`arg1` एक सूचक है जिसमें `xnuspy_ctl` `current_thread` के रिटर्न मान को `copyout` करेगा। अन्य तर्कों के मानों को अनदेखा किया जाता है।
### त्रुटियाँ
`XNUSPY_CHECK_IF_PATCHED` को छोड़कर सभी flavors के लिए, सफलता पर `0` लौटाया जाता है।
त्रुटि पर, `-1` लौटाया जाता है और `errno` सेट किया जाता है। `XNUSPY_CHECK_IF_PATCHED` कोई त्रुटि नहीं लौटाता है। `kern_return_t` को उपयुक्त `errno` में बदलने के लिए XNU के `mach_to_bsd_errno` का उपयोग किया जाता है।
#### `XNUSPY_INSTALL_HOOK` से संबंधित त्रुटियाँ
`errno` को इस पर सेट किया जाता है...
- `EEXIST` अगर:
- `arg1` द्वारा निरूपित अनस्लाइड कर्नेल फ़ंक्शन के लिए पहले से ही एक हुक मौजूद है।
- `ENOMEM` अगर:
- `unified_kalloc` ने `NULL` लौटाया।
- `ENOSPC` अगर:
- कोई मुफ्त `xnuspy_tramp` स्ट्रक्ट नहीं है, जो xnuspy के अंदरूनी डेटा स्ट्रक्चर है। यह तब तक नहीं होना चाहिए जब तक आप एक साथ सैकड़ों कर्नेल फ़ंक्शन हुक नहीं कर रहे हों। यदि आपको अधिक फ़ंक्शन हुक की आवश्यकता है, तो [सीमाएँ](#limits) देखें।
- `ENOTSUP` अगर:
- कॉल करने वाला Mach-O निष्पादन योग्य या डायनामिक लाइब्रेरी से नहीं है।
- `ENOENT` अगर:
- `mh_for_addr` कॉल करने वाले के पता स्थान के अंदर `arg2` के अनुरूप Mach-O हेडर निर्धारित करने में असमर्थ था।
- `EFAULT` अगर:
- निर्धारित Mach-O हेडर वास्तव में Mach-O हेडर नहीं है। यह शायद कभी नहीं होगा।
- `EIO` अगर:
- `mach_make_memory_entry_64` ने निर्धारित Mach-O हेडर के `__TEXT` और `__DATA` सेगमेंट के पूरे हिस्से के लिए एक मेमोरी एंट्री नहीं लौटाई।