1 คะแนน โดย GN⁺ 2025-02-19 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • การทำ reverse engineering แอป iOS จำเป็นต้องสามารถสังเกตและปรับเปลี่ยนแอปขณะกำลังรันได้ แต่แอปวิดเจ็ตนี้ใช้ทั้ง การบล็อกดีบักเกอร์·การบล็อกการฉีดโค้ด·การตรวจจับ jailbreak ร่วมกัน
  • กลไกบล็อกหลักอาจถูกทำด้วย PT_DENY_ATTACH ของ ptrace หรือ system call โดยตรง (svc #0x80) ที่ให้ผลแบบเดียวกัน ทำให้จับไม่ได้ด้วย breakpoint ที่ ptrace แบบง่าย ๆ เท่านั้น
  • การเรียก system call โดยตรงถูกเลี่ยงด้วยการค้นหาแพตเทิร์น mov w16, #26 ในไบนารี ตั้ง breakpoint ที่ตำแหน่ง svc แล้วใช้ lldb jump ข้ามคำสั่งนั้น
  • พฤติกรรมที่ทำให้โทรศัพท์ soft-reboot/respring หลังตรวจจับ jailbreak เชื่อมโยงกับฟังก์ชันที่เรียก snapshotViewAfterScreenUpdates: ใน ลูปไม่สิ้นสุด และถูกข้ามด้วย thread return ที่จุดเริ่มต้นของฟังก์ชัน
  • crash หลังฉีดโค้ดดูใกล้เคียงกับ การสูญเสียสิทธิ์ App Group มากกว่าการตรวจสอบ framework runtime แยกต่างหาก และทำให้รันบนอุปกรณ์ทั่วไปได้ด้วยการ swizzle ให้ containerURLForSecurityApplicationGroupIdentifier: เปลี่ยนไปใช้ไดเรกทอรีชั่วคราว

แอปวิดเจ็ต iOS ที่ซ้อนกลไกป้องกันหลายชั้น

  • เป้าหมายคือแอปวิดเจ็ตบน App Store ซึ่งมี พฤติกรรมป้องกัน ที่แข็งแรงกว่าแอปวิดเจ็ตทั่วไป
    • บล็อกการ attach ดีบักเกอร์
    • ปิดแอปเมื่อมีการฉีดโค้ด
    • หากรันในสภาพแวดล้อม jailbreak โทรศัพท์ทั้งเครื่องจะ soft-reboot/respring
  • การใส่กลไกป้องกันอย่างการตรวจจับ jailbreak หรือการทำ code obfuscation ในแอป iOS ไม่ใช่เรื่องแปลก แต่แอปนี้ใช้หลายวิธีร่วมกัน
  • พฤติกรรมที่น่าสนใจอื่น ๆ ภายในแอปถูกเก็บไว้เป็นหัวข้อของบทความถัดไป

บล็อกการ attach ดีบักเกอร์ด้วย PT_DENY_ATTACH

  • บนอุปกรณ์ jailbreak โดยปกติสามารถเชื่อมต่อด้วย ssh แล้วรัน debugserver จากนั้นเชื่อมต่อจาก lldb บนคอมพิวเตอร์อีกเครื่องเพื่อดีบักแอปได้
  • เมื่อนำ debugserver ไป attach กับแอปนี้ด้วยวิธีเดียวกัน จะเกิด Segmentation fault และ attach ไม่สำเร็จ
  • สาเหตุเกี่ยวข้องกับคำขอ PT_DENY_ATTACH ของ ptrace
    • ptrace เป็น private API บน iOS และเป็น public API บน macOS
    • PT_DENY_ATTACH ตั้งค่า flag ที่ปฏิเสธการ trace จาก parent process หลังจากนั้น
    • หากกำลังถูก trace อยู่แล้ว แอปจะจบการทำงานด้วยสถานะ ENOTSUP
    • หาก parent พยายาม trace process ที่ตั้งค่า flag นี้ไว้ ฝั่ง parent จะเกิด segmentation violation
  • การทำแบบง่ายสามารถเรียก ptrace(PT_DENY_ATTACH, 0, 0, 0) ได้
    • เนื่องจากเป็น private API ของ iOS การเรียกจริงต้องใช้ dlopen, dlsym เพื่อค้นหา symbol ptrace ใน libsystem_kernel.dylib
    • วิธีนี้เลี่ยงได้ค่อนข้างง่ายด้วยการตั้ง breakpoint ที่ ptrace แล้วใช้ thread return เพื่อข้ามการเรียก

ทำไมการเลี่ยงแบบง่ายจึงใช้ไม่ได้

  • PT_DENY_ATTACH จะกันดีบักเกอร์ได้หลังถูกเรียกเท่านั้น ดังนั้นถ้า attach ก่อนที่โค้ดแอปจะทำงาน ก็สามารถสร้างจุดเลี่ยงได้
  • หากไม่ attach debugserver เข้ากับ process โดยตรง แต่รันไว้ก่อน แล้วใช้ process attach --name TopWidget --waitfor ใน lldb เพื่อรอการเปิดแอป ก็จะ attach ได้ก่อนที่โค้ดแอปจะทำงาน
  • แต่ในแอปนี้ breakpoint b ptrace แรก ๆ ไม่ถูก resolve และแม้ภายหลังจะ resolve ได้ ก็ไม่เคย hit จริงก่อนที่แอปจะจบการทำงาน
  • เพราะแอปใช้วิธี เรียก system call โดยตรง ที่ให้ผลแบบเดียวกัน แทนการเรียกฟังก์ชัน ptrace

ค้นหาตำแหน่ง system call โดยตรง

  • ใน disassembly ของฟังก์ชัน ptrace มี system call หลักคือ svc #0x80
    • x0 มีค่า 31 ซึ่งเป็นค่าของ PT_DENY_ATTACH
    • x1, x2, x3 มี argument ที่ไม่ได้ใช้คือ 0
    • x16 มีหมายเลข system call ของ ptrace คือ 26
  • แอปสามารถไม่เรียกฟังก์ชัน ptrace แต่ตั้งค่า register แบบเดียวกันด้วย inline assembly แล้วรัน svc #0x80 โดยตรงได้
    • วิธีนี้หลีกเลี่ยงการ lookup private API ที่ดูน่าสงสัยอย่าง dlopen, dlsym
    • จับได้ยากด้วยวิธีตั้ง breakpoint ที่ ptrace ซึ่งเป็นฟังก์ชันร่วม
  • หากต้องการเลี่ยง ต้องเปิดไบนารีแอปที่ถอดรหัสแล้วด้วย disassembler และหาตำแหน่ง system call ของ ptrace
  • เป้าหมายการค้นหาคือ mov x16, #26 หรือ mov w16, #26 ซึ่งเป็นมุมมอง 32 บิตของ register เดียวกัน
    • ใช้ armconverter.com เพื่อได้ byte ของ mov x16, #26 คือ 50 03 80 D2 แล้วนำไปค้นหาในไบนารีได้
    • mov x16, #26 ไม่พบผลลัพธ์ ส่วนการค้นหา mov w16, #26 พบ 4 ผลลัพธ์
  • ในจำนวนนั้น สองผลลัพธ์มีคำสั่งรอบข้างไม่ตรงกับแพตเทิร์นที่คาดไว้ และที่ผลลัพธ์ที่สามพบโค้ดรูปแบบต่อไปนี้
    • MOV X0, #0x1F
    • MOV X1, #0
    • MOV X2, #0
    • MOV X3, #0
    • MOV W16, #0x1A
    • SVC 0x80
  • ผลลัพธ์ที่สี่เป็น branch อื่นของฟังก์ชันเดียวกัน และยืนยันได้ว่าฟังก์ชันนี้คือตำแหน่งที่บล็อกการ attach ดีบักเกอร์

ข้ามคำสั่ง svc

  • ที่อยู่ svc ที่ยืนยันใน disassembler คือ 0x102A2BB14 และ 0x102A2BB68
  • ใน lldb ตั้ง breakpoint โดยใส่ -s TopWidget เพื่อแปลงที่อยู่ตามไบนารีเป็นที่อยู่โหลดจริง
    • br s -a 0x102A2BB14 -s TopWidget
    • br s -a 0x102A2BB68 -s TopWidget
  • เมื่อรันต่อ breakpoint จะถูก hit ที่ตำแหน่ง svc #0x80
  • วิธีเลี่ยงที่ง่ายที่สุดคือ jump ไปยังที่อยู่ของคำสั่งถัดไป เพื่อไม่ให้ system call นั้นทำงานเลย
    • ในตัวอย่าง รัน jump *0x10327bb18 เพื่อข้ามไปยังที่อยู่ถัดจากคำสั่งปัจจุบันคือ 0x10327bb18
  • หลังผ่านขั้นตอนนี้ จะสามารถเข้าสู่แอปในสภาพที่ดีบักเกอร์ attach อยู่ได้

พฤติกรรมที่ทำให้โทรศัพท์ soft-reboot

  • หลังเลี่ยงการ attach ดีบักเกอร์แล้ว แอปยังคงรันพฤติกรรมป้องกันที่ทำให้โทรศัพท์ soft-reboot/respring
  • คราวนี้ lldb ยัง attach อยู่ จึงตรวจสอบสถานะที่ process ได้รับ SIGKILL และ stacktrace ได้
  • ใน stacktrace ปรากฏ flow ที่จับภาพเนื้อหาหน้าจอ
    • CARenderServerSnapshot ของ QuartzCore
    • _UISnapshotScreenWindowsRectAfterCommit ของ UIKitCore
    • unnamed symbol ใน TopWidget ซึ่งเป็นฟังก์ชันภายในแอป
  • ใช้ lldb image lookup เพื่อแปลง runtime address เป็นที่อยู่ตามไบนารี 0x100041898 แล้วตรวจสอบฟังก์ชันนั้นใน disassembler
  • ผล decompile พบว่าฟังก์ชันทำซ้ำเฉพาะงานต่อไปนี้ใน ลูปไม่สิ้นสุด
    • เรียก +[UIScreen mainScreen]
    • เรียก snapshotViewAfterScreenUpdates: กับออบเจ็กต์หน้าจอที่ได้คืนมา
    • ไม่ใช้ผลลัพธ์ และ release ทิ้ง
  • snapshotViewAfterScreenUpdates: เป็น public API สำหรับสร้าง view snapshot แต่แอปนี้เรียกซ้ำไม่สิ้นสุดซึ่งใช้หน่วยความจำหนัก
  • ในวิดีโอที่เชื่อมโยงกัน พบว่าต้นทางของการเรียกนี้เกี่ยวข้องกับ notification com.apple.tw.twrr และหากไม่ผ่าน risk check ของโทรศัพท์ก็จะ respring
  • สามารถเลี่ยงได้ด้วยการตั้ง breakpoint ที่จุดเริ่มต้นของฟังก์ชันนั้น และเมื่อ hit ให้ใช้ thread return เพื่อข้ามการทำงานของฟังก์ชัน

crash ที่เกิดเมื่อฉีดโค้ด

  • ระหว่างดีบัก สามารถ implement ยูทิลิตีที่ซับซ้อน เช่น การ log ข้อมูล accessibility ของปุ่มบนหน้าจอ ใน framework ที่ฉีดเข้าไปในแอป แล้วเรียกจาก debugger ได้
  • แม้ไม่มีอุปกรณ์ jailbreak ก็สามารถฉีด Frida หรือ Flex เพื่อสำรวจแอปเบื้องต้นได้
  • โดยทั่วไปการฉีดแบบนี้ทำด้วยเครื่องมือที่ resign แอป ตัวอย่างที่ใช้คือ Sideloadly
  • แอปนี้ crash ทันทีเมื่อรันหลัง resign
  • เมื่อตรวจที่อยู่ด้านบนของ crash stack คือ 0x1002027D4 ใน disassembler พบคำสั่ง BRK ซึ่งตรงกับสถานการณ์ crash แบบตั้งใจ เช่น nil force-unwrap
  • ในโค้ดที่ decompile แล้ว การเรียกที่ดูเป็นปัญหาคือ containerURLForSecurityApplicationGroupIdentifier:
    • เมธอดนี้คืน URL ของโฟลเดอร์ที่แอปและ extension ใน group เดียวกันเข้าถึงร่วมกันได้
    • App Group ถูกกำหนดในกระบวนการ code signing
    • เมื่อฉีดโค้ดแล้ว resign ลายเซ็นเดิมของแอปจะถูกทิ้ง และสิทธิ์ App Group ก็หายไปด้วย
    • ดังนั้นมีความเป็นไปได้สูงว่าจะคืน nil แทน URL และแอป crash เมื่อ force-unwrap ค่านี้
  • แอปวิดเจ็ตต้องแชร์ App Group กับ extension ที่รับผิดชอบการแสดงวิดเจ็ตบนหน้าจอ Home ดังนั้นปัญหานี้จึงใกล้เคียงกับปัญหา code signing ที่พบบ่อย มากกว่าจะเป็นพฤติกรรมตั้งใจเพื่อป้องกัน

เลี่ยงปัญหา App Group

  • วิธีแก้ที่ง่ายที่สุดคือไม่ resign แอป
    • บนอุปกรณ์ jailbreak สามารถฉีด framework ด้วย jailbreak tweak ได้โดยไม่ต้อง resign แอป
    • การรันโค้ดที่มีลายเซ็นไม่ถูกต้อง หรือเพิ่มแอปที่ต้องการเข้า group ที่ต้องการก็ทำได้เช่นกัน
  • หากไม่มีอุปกรณ์ jailbreak และจำเป็นต้อง resign ก็ยังเลี่ยงได้ด้วยการ swizzle เมธอดผ่าน framework ขนาดเล็ก
  • โค้ดตัวอย่างแทนที่ containerURLForSecurityApplicationGroupIdentifier: ของ NSFileManager
    • เมื่อเมธอดเดิมถูกเรียก replacement method จะทำงาน
    • replacement method จะคืน temporaryDirectory แทน shared container
  • การแทนที่นี้ไม่เหมือนพฤติกรรมเดิมที่แอปต้องการ
    • แอปเดิมต้องการโฟลเดอร์แชร์ที่แอปและ extension เข้าถึงร่วมกันได้
    • ไดเรกทอรีชั่วคราวไม่ใช่โฟลเดอร์แชร์แบบนั้น
  • แต่ถ้าเป้าหมายคือดูเฉพาะการทำงานของแอปหลัก ก็อาจเพียงพอ
    • patch เล็ก ๆ แบบนี้อาจทำให้ app extension เสียหายได้
    • หากต้องการเพียงฟังก์ชันพื้นฐานของแอปหลัก ก็อาจไม่เป็นปัญหา
  • การเลี่ยงที่ใหญ่กว่านั้นคือสร้าง App Group ใหม่, resign แอปหลักและ extension ทั้งหมดด้วย group นั้น แล้ว swizzle ให้เมธอดที่เกี่ยวข้องใช้ group identifier ใหม่
    • เป็นงานที่ใหญ่กว่ามาก และถ้าไม่จำเป็นจริง ๆ การหา jailbroken device อาจดีกว่า
  • เมื่อฉีด framework นี้ร่วมกับเครื่องมืออย่าง Flex แอปจะรันได้ตามปกติแม้บนอุปกรณ์ทั่วไป
  • บนอุปกรณ์ jailbreak ยังต้องเลี่ยง anti-debugging และการป้องกัน respring ที่กล่าวไปก่อนหน้าอีกครั้ง แต่หลังจากนั้นก็จะเข้าสู่แอปได้ในสภาพที่มี Flex ถูกฉีดอยู่

สถานะสุดท้าย

  • ท้ายที่สุด แอปอยู่ในสถานะที่สามารถ attach ดีบักเกอร์, เลี่ยงการตรวจจับ jailbreak และฉีดโค้ดได้ทั้งหมด
  • สิ่งที่ต้องการดูจริง ๆ ภายในแอปถูกเก็บไว้เป็นหัวข้อของบทความถัดไป

1 ความคิดเห็น

 
GN⁺ 2025-02-19
ความคิดเห็นบน Hacker News
  • Bryce Bostwick ทำงานที่เจ๋งและสร้างแรงบันดาลใจมากในด้านการดีบักแอปและวิศวกรรมย้อนกลับ
    ผมรู้จักเขาจาก YouTube และหลังจากดูวิดีโอที่ดัดแปลง TikTok ให้แสดงเฉพาะวิดีโอแมว (https://youtu.be/YW3jL2gI9IE) ผมก็ลองดัดแปลง Instagram ให้เหลือเฉพาะฟีเจอร์ข้อความที่ผมใช้ แล้วเอาอย่างอื่นออกทั้งหมด
    ผมอยากลงลึกเรื่องวิธีดัดแปลง Windows แบบสไตล์ Windhawk (https://windhawk.net/) มานานแล้ว โดยเฉพาะเรื่อง การดัดแปลงและวิศวกรรมย้อนกลับ และ Bryce ก็แนะนำงานแบบนั้นบน iOS ได้ดีมากผ่านวิดีโอสอนทีละขั้นตอนแบบเรียลไทม์

    • ถ้ามีคนที่คล้ายกันฝั่ง Android ก็อยากเรียนรู้เพิ่มเติม
      เคยเห็นว่า Revanced ทำอะไรน่าทึ่งได้หลายอย่าง แต่ดูเหมือนไม่ค่อยมีไกด์ดี ๆ ที่บอกว่าจะเริ่มงานแบบนั้นอย่างไร
    • ผมตั้งใจจะลองทำตามที่อธิบายไว้
      ถ้ามีใครสรุปขั้นตอนไว้ ผมสนใจ
      ผมไม่ชอบที่ต้องเจอ Reels แม้แค่จะอัปโหลดรูปหรือแชตกับเพื่อน
  • การขัดขวางการดีบัก และแม้แต่เทคนิคที่ขัดขวางการป้องกันการขัดขวางการดีบักนั้นมีมานานแล้วในฝั่ง DOS/Windows
    ถ้าดูเอกสารเก่า ๆ เรื่องการแคร็กหรือการแกะแพ็ก จะเห็นว่ามีการพูดถึงเรื่องนี้ในหลายระดับความลึก
    ความง่ายที่ผู้ใช้จะควบคุมการทำงานของแอปได้นั้นแปรผกผันกับความเป็นปฏิปักษ์ต่อผู้ใช้ของแพลตฟอร์ม
    PT_DENY_ATTACH ดูเหมือนเป็นฟีเจอร์ที่สร้างมาเพื่อความเป็นปฏิปักษ์ต่อผู้ใช้นั้นพอดี
    เท่าที่ผมรู้ Windows ไม่มีฟีเจอร์แบบนั้น แต่ใช้เทคนิคให้แอป attach เข้ากับตัวเองแทน
    https://www.x86matthew.com/view_post?id=selfdebug
    https://anti-debug.checkpoint.com/techniques/interactive.htm...

    • ใช่แล้ว PT_DENY_ATTACH เป็นฟีเจอร์ที่ Apple สร้างขึ้นเองแบบตรงตัวในอดีตเพื่อเป็นส่วนหนึ่งของวิธีแก้ DRM ของ iTunes
  • ค่อนข้างแปลกใจที่การตรวจของ App Store ของ Apple ไม่ปฏิเสธแอปที่ทำ system call โดยตรง
    system call บนแพลตฟอร์มของ Apple ไม่ใช่ ABI ที่เสถียร ดังนั้น system call ทั้งหมดควรต้องผ่าน libSystem และแอปที่ทำ system call โดยตรงโดยไม่ผ่าน libSystem ก็เท่ากับกำลังทำสิ่งที่ไม่ควรทำ
    เช่นเดียวกัน ผมสงสัยว่าทำไมผู้เขียนถึงมองหา mov w16, #26 ในโค้ด แทนที่จะเป็น svc 0x80

    • svc 0x80 เป็นคำสั่งที่รัน system call ใด ๆ ก็ได้ และการเรียกที่แน่นอนว่าจะรันอะไรนั้นขึ้นอยู่กับ รีจิสเตอร์ x16
      แอปคงทำ system call ที่ไม่เกี่ยวข้องเป็นจำนวนมาก ดังนั้นการตั้ง breakpoint ตรงนั้นคงไม่ค่อยมีประโยชน์
      อย่างน้อยในวิดีโอก็อธิบายไว้แบบนั้น
    • คอมไพเลอร์บางครั้งอาจ inline wrapper ของ system call ได้ จึงตรวจแบบ static ได้ไม่ง่ายนัก
      ด้วยเหตุผลเดียวกัน ถ้าค้นหาคำสั่ง SVC ผลลัพธ์จะออกมาเยอะมาก
      ถ้าหา ID ของ system call ที่แน่นอนซึ่งถูกย้ายเข้า X16 ได้ ก็จะเจอทันที
  • ผมเป็นผู้เขียนบทความเอง ถ้ามีคำถามก็ถามได้ ขอบคุณ xmprt ที่แชร์

    • ดูวิดีโอบน YouTube แล้วน่าสนใจมาก
      ดีใจที่มีเวอร์ชันบทความให้อ่านด้วย
    • เป็นบทความที่น่าสนใจมาก และผมอยากเห็นบทความแนว วิศวกรรมย้อนกลับระดับต่ำบนโทรศัพท์มือถือ แบบนี้อยู่เสมอ
      มีบางอย่างอยากถามผู้เขียน: ถ้าเครื่องมือเชิงพาณิชย์ที่มีชื่อเสียงที่สุดคือ Guardsquare จริง ผมสงสัยว่ามันมีอะไรใหม่ ๆ ที่ป้องกันการ disassemble แบบง่าย ๆ อย่างนี้หรือไม่
      และก็สงสัยว่า TopWidgets ใช้การป้องกันแบบคล้าย ๆ กันหรือเปล่า หรือเป็นระดับที่ทำขึ้นเอง
    • วิดีโอน่าสนใจมาก และผมแปลกใจที่ไม่ได้มีคนดูหรืออ่านบทความมากกว่านี้
      ส่วนตัวใช้ Android จึงนำไปใช้ตรง ๆ ในเชิงเทคนิคไม่ได้ แต่ยังได้คุณค่ามากจากการเรียนรู้ว่า การดีบักระดับต่ำ บน iOS ทำงานอย่างไร
    • สงสัยว่า iOS มีฟีเจอร์แบบ PTRACE_SYSCALL ที่ดักตรงจุดเข้า system call เพื่อเปลี่ยนค่าที่คืนกลับ หรือใช้ตรวจจับว่า SVC เกิดขึ้นที่ไหนได้หรือไม่
  • วิดีโอด้านบนสุดเป็นหนึ่งในวิดีโอเกี่ยวกับการเขียนโปรแกรมที่ดีที่สุดเท่าที่เคยดูมา
    ดำเนินเรื่องเร็ว สมมติพื้นความรู้ได้พอดี และมีเดโมที่ยอดเยี่ยมโดยไม่ทำให้จังหวะของวิดีโอสะดุด

  • บทความยอดเยี่ยม
    ผมสงสัยจริง ๆ ว่านี่เป็นแอปปกติที่หวาดระแวงเกินเหตุ หรือเป็นแอปที่ถูกดีบักเพราะถูกสงสัยว่าเป็นมัลแวร์ตั้งแต่แรก
    ถ้าไม่ใช่อย่างหลัง ความพยายามที่ลงไปก็ดูเกินไปพอสมควร

    • จากการตัดสินของผม มันน่าจะเป็นแอปที่ หวาดระแวงเกินเหตุ มากกว่า
      ดูเหมือนพวกเขาทำอะไรค่อนข้างเจ๋งกับวิดเจ็ต เลยพยายามปกป้องสิ่งนั้นไว้ แต่กลยุทธ์พวกนั้นก็เริ่มรั่วไหลออกมาทีละนิดอยู่ดี
      ในไบนารีก็มีสิ่งที่น่าสนใจอยู่ด้วย
      ครั้งหนึ่งผมพยายามหาคำตอบว่าทำไมถึงเห็นโค้ดที่ดูเหมือนกำลังดาวน์โหลดไฟล์ .iso ของ Windows และสุดท้ายมันก็ใช่จริง ๆ โดยถูกใช้ใน วิดเจ็ตทดสอบความเร็วเครือข่าย
    • หรืออาจเป็นการพยายามพิสูจน์ การละเมิดลิขสิทธิ์ ในกรณีที่ตัวแอปถูกคอมไพล์ใหม่พร้อมโลโก้อื่น ๆ เป็นต้น
  • ยังมีโหมดที่ยากกว่า “ข้าม PT_DENY_ATTACH (โหมด Hard)” อีก
    สมัยก่อนผมเคย แพตช์เคอร์เนล บน macOS เพื่อทำให้ PT_DENY_ATTACH ไม่ทำอะไรเลย
    บน Mac การรันเคอร์เนลที่ถูกแพตช์นั้นจริง ๆ แล้วค่อนข้างง่าย แต่บน iOS น่าจะยุ่งยากกว่ามากเพราะมีสิ่งอย่าง KTRR
    แม้ XNU จะเป็นโอเพนซอร์สในเชิงเทคนิค แต่การแพตช์ด้วย hex editor นั้นง่ายกว่าการคอมไพล์ใหม่

    • สามารถใช้ kernel task port เพื่อสลับบิตในโครงสร้าง proc ได้ด้วย
      และยังอนุญาต code page ที่ไม่ได้เซ็นกับ RWX เพื่อให้ทำ JIT ได้ด้วย
  • ถ้า “เปิดเจลเบรกแล้วรัน จากนั้นทั้งเครื่องก็แครช” แบบนี้ แจ้งสโตร์ว่าเป็น มัลแวร์ ไม่ได้หรือ?
    การทำให้โทรศัพท์แครชเป็นพฤติกรรมของมัลแวร์อย่างชัดเจน และควรสงสัยด้วยว่าอาจมีพฤติกรรมมุ่งร้ายอื่น ๆ ที่พยายามซ่อนอยู่
    การกันขยะพวกนี้ไม่ใช่เหตุผลที่ Apple ใช้สนับสนุน ระบบนิเวศแบบปิด หรอกหรือ?

    • “เปิดเจลเบรกแล้ว” หมายความว่าอยู่นอกระบบนิเวศแบบปิด
      Apple คงไม่ค่อยสนใจนักถ้าแอปแครชบนเครื่องที่เจลเบรกแล้ว
  • สงสัยมากเรื่องการแจ้งเตือน com.apple.tw.twrr
    ทำไมถึงขึ้นต้นด้วย com.apple?
    แอปที่เป็นปัญหาตรงนี้ดูเหมือนเป็นแอปชื่อ Top Widgets ไม่ใช่แอปของ Apple

    • ชื่อการแจ้งเตือนเป็นสตริงตามใจตั้ง
      ตามธรรมเนียมจะใช้ “ชื่อเต็ม” แบบนั้นเพื่อเลี่ยงการชนกัน
      ในกรณีนี้ดูเหมือนนักพัฒนาเลือก prefix แบบนั้นโดยบังเอิญ
  • ต่างกันแค่เครื่องมือ แต่นี่ให้ความรู้สึกเหมือนกับการใช้ boot tracing เพื่อแกะระบบป้องกันการคัดลอกของ Apple II ในยุค 1980 เป๊ะ ๆ
    บางอย่างก็ไม่เปลี่ยนไป