
الإخراج من سجل kernel بعد تجميع وتشغيل example/open1_hook.c
Xnuspy هي وحدة Pongoos التي تقوم بتثبيت مكالمة نظام جديدة ، xnuspy_ctl ، والتي تتيح لك ربط وظائف kernel من مساحة المستخدمين. وهو يدعم iOS 13.x ، iOS 14.x ، و iOS 15.x على checkra1n 0.12.2 وما فوق. أجهزة 4K غير مدعومة.
هذه الوحدة تحيي تمامًا KTRR/KPP وتتيح إنشاء ذاكرة RWX داخل EL1. لا تستخدم هذا على سائقك اليومي.
يتطلب libusb : brew install libusb
تشغيل make في دليل المستوى الأعلى. سوف يبني اللودر والوحدة.
أضف هذه قبل make .
XNUSPY_DEBUG=1kprintf ).XNUSPY_SERIAL=1IOLog .XNUSPY_LEAKED_PAGE_LIMIT=n64 . يمكن العثور على مزيد من المعلومات تحت تصحيح الأخطاء kernel الذعر.XNUSPY_TRAMP_PAGES=n لا يعتمد XNUSPY_DEBUG و XNUSPY_SERIAL على بعضهما البعض.
بعد أن قمت ببناء كل شيء ، اطلب من checkra1n قم بتمهيد جهازك إلى قذيفة Pongo: /Applications/checkra1n.app/Contents/MacOS/checkra1n -p
في نفس الدليل ، قمت ببناء المحمل والوحدة النمطية ، قم بعمل loader/loader module/xnuspy . بعد القيام بذلك ، ستقوم Xnuspy بعملها وفي بضع ثوانٍ سيقوم جهازك بالتمهيد. سوف ينتظر loader بضع ثوانٍ بعد إصدار xnuspy-getkernelv في حالة استغلال Seprom.
في بعض الأحيان ، تتعثر اثنان من هاتفي في "التمهيد" بعد تشغيل kpf من checkra1n. لا يزال يتعين عليّ معرفة ما يسبب هذا ، ولكن إذا حدث ذلك ، فحاول مرة أخرى. أيضًا ، إذا كان الجهاز معلقًا بعد bootx ، فحاول مرة أخرى. أخيرًا ، يعد وضع رمز xnuspy_ctl المترجم على أنه قابل للتنفيذ على جهاز iPhone X الذي يعمل على تشغيل iOS 13.3.1 بقليل ، لكنه ينجح 100 ٪ من الوقت على هواتفاتي الأخرى. إذا كنت تشعر بالذعر مع إحباط تعليمات kernel عند تنفيذ برنامج الخطاف الخاص بك ، فحاول مرة أخرى.
سوف Xnuspy تصحيح استدعاء نظام enosys للإشارة إلى xnuspy_ctl_tramp . هذا هو الترامبولين الصغير الذي يمثل رمز xnuspy_ctl المترجم على أنه قابل للتنفيذ وفروعه. يمكنك العثور على تطبيق xnuspy_ctl في module/el1/xnuspy_ctl/xnuspy_ctl.c والأمثلة في دليل example .
Inside include/xnuspy/ Is xnuspy_ctl.h ، وهو رأس يحدد الثوابت لـ xnuspy_ctl . من المفترض أن يتم تضمينه في جميع البرامج التي تربط وظائف kernel.
يمكنك استخدام 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 . يمكن أن تكون النكهة إما 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 معنى الحجج الثلاثة التالية يعتمد على النكهة.
XNUSPY_CHECK_IF_PATCHED هذا موجود حتى تتمكن من التحقق مما إذا كان xnuspy_ctl موجودًا. إن استدعاءها بهذه النكهة سيؤدي إلى إرجاع 999 . يتم تجاهل قيم الحجج الأخرى.
XNUSPY_INSTALL_HOOK لقد صممت هذه النكهة لتتناسب مع واجهة برمجة تطبيقات MSHookFunction . arg1 هو العنوان القلمي لوظيفة kernel التي ترغب في ربطها. إذا قمت بتوفير عنوان انزلاق ، فمن المحتمل أن تكون ذعرًا. arg2 هو مؤشر لوظيفة الاستبدال المتوافقة مع ABI. arg3 هو مؤشر لـ xnuspy_ctl copyout عنوان الترامبولين الذي يمثل وظيفة kernel الأصلية. يمكن أن يكون هذا NULL إذا كنت لا تنوي الاتصال بالأصل.
XNUSPY_REGISTER_DEATH_CALLBACKتتيح لك هذه النكهة تسجيل "رد اتصال الموت" الاختياري ، وهي وظيفة سوف تتصل بها Xnuspy عند خروج برنامج الخطاف. يمنحك فرصة لتنظيف أي شيء قمت بإنشائه من خطافات kernel الخاصة بك. إذا قمت بإنشاء أي مؤشرات ترابط kernel ، فستخبرهم بإنهاء هذه الوظيفة.
لم يتم استدعاء رد الاتصال الخاص بك بشكل غير متزامن ، لذلك إذا قمت بحظر ، فأنت تمنع مؤشر ترابط جمع القمامة من Xnuspy من التنفيذ.
arg1 هو مؤشر لوظيفة رد الاتصال الخاصة بك. يتم تجاهل قيم الحجج الأخرى.
XNUSPY_CALL_HOOKME hookme هو كعب تجميع صغير يصدره Xnuspy من خلال ذاكرة التخزين المؤقت Xnuspy لتتخلق. إن استدعاء xnuspy_ctl مع هذه النكهة سيؤدي إلى استدعاء hookme ، مما يوفر طريقة لك للحصول على تنفيذ رمز kernel بسهولة دون الحاجة إلى ربط وظيفة kernel الفعلية.
arg1 هي حجة سيتم تمريرها إلى hookme عندما يتم استدعاءها. هذا يمكن أن يكون NULL .
XNUSPY_CACHE_READ تمنحك هذه النكهة طريقة للقراءة من ذاكرة التخزين المؤقت Xnuspy. إنه يحتوي على العديد من الأشياء المفيدة مثل kprintf و current_proc و kernel_thread_start وبعض وظائف libc ، وشريحة kernel حتى لا تضطر إلى العثور عليها بنفسك. للحصول على قائمة كاملة بمعرفات ذاكرة التخزين المؤقت ، تحقق من example/xnuspy_ctl.h .
arg1 هو واحد من معرفات ذاكرة التخزين المؤقت المحددة في xnuspy_ctl.h و arg2 هو مؤشر لـ xnuspy_ctl copyout عنوان أو قيمة ما طلبته. يتم تجاهل قيم الحجج الأخرى.
XNUSPY_KREADتمنحك هذه النكهة طريقة سهلة لقراءة ذاكرة kernel من مساحة المستخدمين بدون TFP0.
arg1 هو عنوان kernel الظاهري ، arg2 هو عنوان مخزن مؤقت للمساحة المستخدمين ، و arg3 هو حجم المخزن المؤقت للمساحة المستخدمة. سيتم كتابة Bytes arg3 من arg1 إلى arg2 .
XNUSPY_KWRITEتمنحك هذه النكهة طريقة سهلة للكتابة إلى ذاكرة kernel من مساحة المستخدمين بدون TFP0.
arg1 هو عنوان kernel الظاهري ، arg2 هو عنوان مخزن مؤقت للمساحة المستخدمين ، و arg3 هو حجم المخزن المؤقت للمساحة المستخدمة. سيتم كتابة Bytes arg3 من arg2 إلى arg1 .
XNUSPY_GET_CURRENT_THREADتوفر هذه النكهة مساحة المستخدمين على عنوان kernel لخيط الاتصال.
arg1 هو مؤشر لـ xnuspy_ctl copyout قيمة إرجاع current_thread . يتم تجاهل قيم الحجج الأخرى.
لجميع النكهات باستثناء XNUSPY_CHECK_IF_PATCHED ، يتم إرجاع 0 عند النجاح. عند الخطأ ، يتم إرجاع -1 ويتم تعيين errno . XNUSPY_CHECK_IF_PATCHED لا يعيد أي أخطاء. يتم استخدام mach_to_bsd_errno من Xnu لتحويل kern_return_t إلى errno المناسب.
XNUSPY_INSTALL_HOOK تم تعيين errno على ...
EEXIST إذا:arg1 .ENOMEM إذا:unified_kalloc عاد NULL .ENOSPC إذا:xnuspy_tramp مجانية ، وهيكل بيانات داخلي إلى xnuspy. لا ينبغي أن يحدث هذا إلا إذا كنت تقوم بتثبيط مئات وظائف النواة في نفس الوقت . إذا كنت بحاجة إلى مزيد من السنانير الوظائف ، تحقق من الحدود.ENOTSUP إذا:ENOENT إذا:mh_for_addr من تحديد رأس Mach-O المقابل لـ arg2 داخل مساحة عنوان المتصل.EFAULT if:EIO إذا:mach_make_memory_entry_64 إدخال ذاكرة لكامل شرائح Mach-O's المحددة __TEXT و __DATA . يعتمد errno أيضًا على قيمة إرجاع vm_map_wire_external ، mach_vm_map_external ، mach_make_memory_entry_64 ، copyin ، copyout ، وإذا كان ذلك ممكنًا ، وظيفة التهيئة لمرة واحدة.
إذا أدت هذه النكهة إلى خطأ ، فإن وظيفة kernel الهدف لم تكن مدمن مخدرات. إذا قمت بتمرير مؤشر غير NULL لـ arg3 ، فقد تم أو لم تتم تهيئته. من غير الآمن استخدام إذا كان.
XNUSPY_REGISTER_DEATH_CALLBACK تم تعيين errno على ...
ENOENT إذا:إذا كانت هذه النكهة تُرجع خطأً ، فلن يتم تسجيل رد الاتصال الخاص بك.
XNUSPY_CALL_HOOKME تم تعيين errno على ...
ENOTSUP إذا:hookme بعيد جدًا عن الذاكرة التي تحتوي على هياكل xnuspy_tramp . يتم تحديد هذا داخل Pongoos ، ولا يمكن أن يحدث إلا إذا اضطر Xnuspy إلى العودة إلى الكود غير المستخدمة بالفعل داخل kernelcache. في هذه الحالة ، من المؤكد أن استدعاء hookme سيؤدي إلى ذعر kernel ، وسيتعين عليك اكتشاف وظيفة kernel أخرى لربطها. إذا كانت هذه النكهة تُرجع خطأً ، لم يتم استدعاء hookme .
XNUSPY_CACHE_READ تم تعيين errno على ...
EINVAL إذا:arg1 أي شيء في ذاكرة التخزين المؤقت.arg1 IO_LOCK ، لكن النواة هي iOS 14.4.2 أو أدناه أو iOS 15.x.arg1 IPC_OBJECT_LOCK ، لكن kernel هي iOS 15.x.arg1 IPC_PORT_RELEASE_SEND ، ولكن kernel هو iOS 14.5 أو أعلى.arg1 IPC_PORT_RELEASE_SEND_AND_UNLOCK ، ولكن kernel هو iOS 14.4.2 أو أدناه.arg1 KALLOC_CANBLOCK ، ولكن kernel هو iOS 14.x أو أعلى.arg1 KALLOC_EXTERNAL ، لكن النواة هي iOS 13.x.arg1 KFREE_ADDR ، لكن kernel هو iOS 14.x أو أعلى.arg1 KFREE_EXT ، لكن kernel هو iOS 13.x.arg1 PROC_REF ، ولكن kernel هو iOS 14.8 أو أقل.arg1 PROC_REF_LOCKED ، لكن kernel هي iOS 15.x.arg1 PROC_RELE ، لكن النواة هي iOS 14.8 أو أقل.arg1 PROC_RELE_LOCKED ، لكن kernel هو iOS 15.x.arg1 VM_MAP_UNWIRE ، ولكن kernel هو iOS 15.x.arg1 VM_MAP_UNWIRE_NESTED ، لكن النواة هي iOS 14.8 أو أدناه. يعتمد errno أيضًا على قيمة إرجاع copyout وإذا كان ذلك ممكنًا ، فإن قيمة الإرجاع لوظيفة التهيئة لمرة واحدة.
إذا كانت هذه النكهة تُرجع خطأ ، فلم يتم تهيئة المؤشر الذي مررت به من أجل arg2 .
XNUSPY_KREAD و XNUSPY_KWRITE تم تعيين errno على ...
EFAULT if:arg1 أو arg2 . إذا قمت بتجميعها باستخدام XNUSPY_DEBUG=1 ، يتم طباعة رسالة حولها إلى سجل kernel.إذا كانت هذه النكهة تُرجع خطأً ، لم تتم قراءة/كتابة ذاكرة kernel.
XNUSPY_GET_CURRENT_THREAD إذا فشل copyout ، يتم تعيين errno على قيمة الإرجاع الخاصة به.
أثناء كتابة وظائف الاستبدال ، كان من السهل أن ننسى أنني كنت أكتب رمز kernel. إليك بعض الأشياء التي يجب وضعها في الاعتبار عند كتابة السنانير:
__TEXT لبرنامجك . سوف تشعر بالذعر إذا ، على سبيل المثال ، يمكنك الاتصال عن طريق الخطأ printf بدلاً من kprintf . تحتاج إلى إعادة تنفيذ أي وظيفة LIBC التي تريد الاتصال بها إذا لم تكن هذه الوظيفة متوفرة بالفعل عبر XNUSPY_CACHE_READ . يمكنك إنشاء مؤشرات الوظائف لوظائف kernel الأخرى والاتصال بها.PAGE_SIZE إلى vm_page_size ، وليس ثابتًا. تحتاج إلى تعطيل PAN (على A10+، وهو ما لا أوصي به أيضًا) قبل قراءة هذا المتغير أو ستقوم بالذعر.-fno-stack-protector و -D_FORTIFY_SOURCE=0 في بعض الحالات ، سيتعين على الجهاز قراءة ___stack_chk_guard عن طريق dereferencing مؤشر مساحة مستخدمين أخرى ، والتي ستنوع في A10+.قشط https://developer.apple.com/library/archive/documentation/darwin/conceptual/kernelprogramming/style/style.html يوصى به أيضًا.
الحشرات لا مفر منها عند كتابة الكود ، لذلك في النهاية ستتسبب في ذعر نواة. لا يعني الذعر بالضرورة وجود خطأ مع Xnuspy ، لذلك قبل فتح مشكلة ، يرجى التأكد من أنك لا تزال تشعر بالذعر عندما لا تفعل شيئًا سوى الاتصال بالوظيفة الأصلية وإرجاع قيمتها (إذا لزم الأمر). إذا كنت لا تزال تشعر بالذعر ، فمن المحتمل أن يكون خطأ Xnuspy (ويرجى فتح مشكلة) ، ولكن إذا لم يكن الأمر كذلك ، فهناك خطأ في استبدالك.
نظرًا لأن Xnuspy لا يعيد توجيه التنفيذ إلى صفحات EL0 ، فإن تصحيح الأخطاء للذعر ليس واضحًا. افتح module/el1/xnuspy_ctl/xnuspy_ctl.c مباشرةً قبل المكالمة الوحيدة إلى kwrite_instr في xnuspy_install_hook ، أضف مكالمة إلى IOSleep لبضع ثوانٍ. يتم ذلك للتأكد من أن هناك وقتًا كافيًا قبل ذعر الجهاز لسجلات النشر. إعادة تجميع Xnuspy مع XNUSPY_DEBUG=1 make -B وتحميل الوحدة مرة أخرى. بعد تحميل الوحدة النمطية ، إذا لم تكن قد لم تكن بالفعل ، فقم بتجميع klog من klog/ . قم بتحميله على جهازك وقم بـ stdbuf -o0 ./klog | grep shared_mapping_kva . قم بتشغيل برنامج الخطاف الخاص بك مرة أخرى وشاهد خطًا من klog يشبه هذا:
shared_mapping_kva: dist 0x7af4 uaddr 0x104797af4 umh 0x104790000 kmh 0xfffffff00c90c000
إذا كنت تقوم بتثبيت أكثر من خطاف واحد ، فسيكون هناك أكثر من حدث واحد. في هذه الحالة ، سوف يختلف dist و uaddr ، لكن umh و kmh لن يفعلوا ذلك. يشير kmh إلى بداية رسم خرائط kernel لقطاع __TEXT لبرنامجك. رمي برنامج الخطاف الخاص بك في disassembler المفضل لديك وإعادة صيده بحيث يكون رأس Mach-O على عنوان kmh . بالنسبة إلى IDA Pro ، هذا هو Edit -> Segments -> Rebase program... مع Image base . بعد ذعر جهازك وإعادة تشغيله مرة أخرى ، إذا كانت هناك عناوين تتوافق مع رسم خرائط kernel لاستبدالك في سجل الذعر ، فسيتوافق مع التفكيك. إذا لم يكن هناك أي شيء ، فربما يكون لديك نوع من فساد الذاكرة الدقيق داخل استبدالك.
ليس لدى Xnuspy أيضًا أي طريقة لمعرفة ما إذا كان خيط kernel لا يزال ينفذ (أو سيتم تنفيذه) على رسم خرائط kernel لقطاع __TEXT لبرنامجك بعد إلغاء تثبيت السنانير. أحد الأشياء التي تقوم بها Xnuspy للتعامل مع هذا هو عدم تخصيص هذا التعيين مباشرة بعد وفاة برنامج Hook الخاص بك. بدلاً من ذلك ، تمت إضافتها إلى نهاية قائمة الانتظار. بمجرد إشعارات مؤشر ترابط جمع القمامة من Xnuspy ، تم تجاوز حد محدد فيما يتعلق بعدد الصفحات التي يتم الاحتفاظ بها في قائمة الانتظار ، وسوف تبدأ في التخصيص من مقدمة قائمة الانتظار وستستمر حتى يتم تجاوز هذا الحد. بشكل افتراضي ، هذا الحد هو 1 ميغابايت ، أو 64 صفحة.
على الرغم من أن هذا يساعد بشكل كبير ، فكلما زادت شرائح __TEXT و __DATA من برنامج الخطاف الخاص بك ، كلما كان Xnuspy أقل احتمالًا في هذا السباق. إذا كنت تشعر بالذعر بانتظام ولديك برنامج خطاف كبير إلى حد ما ، فحاول زيادة هذا الحد من خلال إضافة XNUSPY_LEAKED_PAGE_LIMIT=n قبل make . سيؤدي هذا إلى تعيين هذا الحد على صفحات n بدلاً من 64.
تحتفظ Xnuspy صفحة واحدة من ذاكرة kernel ثابتة قبل حذاء XNU لهياكل xnuspy_tramp الخاصة به ، مما يتيح لك في وقت واحد ربط حوالي 225 وظائف kernel. إذا كنت تريد المزيد ، فيمكنك إضافة XNUSPY_TRAMP_PAGES=n قبل make . سيخبر هذا Xnuspy بحجز n ذاكرة ثابتة لهياكل xnuspy_tramp . ومع ذلك ، إذا كان على Xnuspy العودة إلى الكود غير المستخدمة بالفعل داخل kernelcache ، فسيتم تجاهل ذلك. عندما يحدث هذا يتم تفصيله في كيفية عمله.
لسبب ما ، لا تظهر السجلات من os_log_with_args في دفق الإخراج من OSLOG TOOLE oslog . سجلات من kprintf لا تجعلها هناك أيضًا ، ولكن يمكن رؤيتها مع dmesg . ومع ذلك ، فإن dmesg ليست عبارة عن تغذية حية ، لذلك كتبت klog ، وهي أداة تعرض سجلات kprintf في الوقت الفعلي. تجدها في klog/ . أوصي بشدة باستخدام ذلك بدلاً من البريد العشوائي dmesg لرسائل kprintf الخاصة بك.
إذا تم open: Resource busy بعد تشغيل klog ، قم بتشغيل هذا الأمر launchctl unload /System/Library/LaunchDaemons/com.apple.syslogd.plist وحاول مرة أخرى.
لسوء الحظ ، لن تتمكن من رؤية أي NSLog إذا تم تعيين atm_diagnostic_config=0x20000000 في bootargs من XNU. klog يعتمد على حجة التمهيد هذه. إذا كنت تريد العودة إلى NSLog ، فقم بإزالة وسيطة التمهيد هذه من pongo_send_command داخل loader.c .
سوف Xnuspy إدارة هذا من أجلك. بمجرد خروج العملية ، يتم إلغاء تثبيت جميع خطافات kernel التي تم تثبيتها بواسطة هذه العملية خلال ثانية أو نحو ذلك.
تحتوي معظم أطر عمل التثبيت على بعض الحد الأدنى الذي يجعل وظيفة معينة قابلة للتوصيل. لدى Xnuspy هذا الحد فقط إذا كنت تخطط لاستدعاء الوظيفة الأصلية وأن التعليمات الأولى للوظيفة المربطة ليست B . في هذه الحالة ، يكون الحد الأدنى للطول ثمانية بايت. خلاف ذلك ، لا يوجد الحد الأدنى للطول.
يستخدم Xnuspy X16 و X17 لترامبولين ، لذلك لا يمكن توصيل وظائف kernel التي تتوقع أن تستمر تلك المكالمات في الوظائف (لا يوجد الكثير الذي يتوقع ذلك). إذا بدأت الوظيفة التي تريد ربطها بـ BL ، وكنت تنوي الاتصال بالأصل ، فيمكنك القيام بذلك فقط إذا لم يتم تعديل الوظيفة الأصلية X17 .
سيقوم xnuspy_ctl بتنفيذ التهيئة لمرة واحدة في المرة الأولى التي يطلق عليها بعد التمهيد الطازج. هذا هو الجزء الوحيد من Xnuspy الذي يمكن تصويره لأنني لا أستطيع تهيئة قفل القراءة/الكتابة بشكل ثابت الذي أستخدمه. بعد عودة المكالمة الأولى ، تكون أي مكالمات مستقبلية مضغوطة لتكون آمنة للخيط.
هذا مبسط ، لكنه يلتقط الفكرة الرئيسية بشكل جيد. خطاف الوظيفة في Xnuspy هو هيكل موجود على ذاكرة النواة القابلة للكتابة القابلة للتنفيذ. في معظم الحالات ، يتم إرجاع هذه الذاكرة بواسطة alloc_static داخل pongoos. يمكن غليه إلى هذا:
struct {
uint64_t replacement;
uint32_t tramp[2];
uint32_t orig[10];
};
عندما يكون replacement هو العنوان الافتراضي kernel (الموضحة في وقت لاحق) لوظيفة الاستبدال ، فإن tramp هو ترامبولين صغير يعيد توجيه التنفيذ إلى replacement ، orig هي ترامبولين أكبر وأكثر تعقيدًا يمثل الوظيفة الأصلية.
أحد الأشياء الأولى التي تقوم بها Xnuspy هي تحديد مكان وجود استبدال EL0 داخل مساحة عنوان عمليات الاتصال. يتم ذلك حتى يمكن توصيل وظائف kernel من المكتبات الديناميكية. يتم حفظ رأس Mach-O الذي يتوافق مع عنوان هذا البديل.
بعد ذلك ، يتم إنشاء شرائح __TEXT و __DATA الخاصة بالمستخدم المشترك (وكذلك أي شريحة بين هؤلاء ، إن وجدت). تتم مشاركة __TEXT حتى تتمكن من استدعاء وظائف أخرى من السنانير. تتم مشاركة __DATA ، لذا ينظر إلى كل من EL1 و EL0.
نظرًا لأن هذا التعيين عبارة عن نسخة فردية من __TEXT و __DATA ، فمن السهل معرفة عنوان وظيفة استبدال المستخدم عليها. بالنظر إلى عنوان Mach -O header "Mach -O u ، وعنوان بداية التعيين المشترك k ، وعنوان وظيفة استبدال المستخدم r ، نطبق الصيغة التالية: replacement = k + (r - u)
بعد ذلك ، يكون replacement هو العنوان الافتراضي kernel لوظيفة استبدال المستخدم على التعيين المشترك ويتم كتابته إلى بنية خطاف الوظيفة. لا يعيد Xnuspy إعادة التنفيذ إلى عنوان EL0 لوظيفة الاستبدال لأن هذا غير آمن للغاية: لا يضعنا ذلك فقط تحت رحمة الجدولة ، بل إنه لا يعطينا أي سيطرة على السيناريو الذي يموت فيه عملية مع خطاف kernel بينما لا يزال مؤشر ترابط النواة يعانون على البديل.
أخيرًا ، يتم تمييز التعيين المشترك على أنه قابل للتنفيذ ويتم تجميع فرع فوري غير مشروط ( B ). إنه يوجه التنفيذ إلى بداية tramp ، وهو ما يحل محل التعليمات الأولى لوظيفة kernel المحببة الآن. لسوء الحظ ، هذا يحدنا من التفرع إلى ربط الهياكل أكثر من 128 ميجابايت بعيدًا عن وظيفة kernel معينة. يتحقق Xnuspy من هذا السيناريو قبل التمهيد ويعود إلى الكود غير المستخدم بالفعل في kernelcache حتى يقيم هياكل الخطاف بدلاً من ذلك إذا وجد أن هذا قد يحدث.
أبذل قصارى جهدي للتأكد من أن PatchFinders يعمل ، لذلك إذا لم يكن هناك شيء ما ، فيرجى فتح مشكلة.