The basic of developing iOS Tweak (Part 1/4)

Witsarut L.
INCOGNITO LAB
Published in
4 min readMay 2, 2019

หลาย ๆ คน คงเคย jailbreak iOS กันมาบ้าง และแน่นอนเมื่อ jailbreak แล้วก็ต้องเคยใช้พวก Tweak ทั้งหลายในการปรับแต่ง iOS กันตามใจชอบ หรือบางคนก็ jailbreak เพื่อใช้ application เถื่อน ใช้แล้วเคยสงสัยกันไหมครับว่าจริง ๆ แล้วพวก Tweak ทั้งหลาย ถูกพัฒนาขึ้นมาอย่างไร? ทำงานอย่างไร? ในบทความนี้เราจะมาพูดถึงวิธีการที่จะพัฒนา Tweak สำหรับ application ที่ถูกเขียนด้วย Objective-C ขึ้นมาใช้กันครับ

ก่อนที่จะเข้าเรื่องกันจริง ๆ จัง ๆ ก็อยากจะบอกไว้ก่อนว่าการจะพัฒนา Tweak ขึ้นมาซักอันหนึ่งต้องใช้พื้นฐานความรู้หลายอย่างด้วยกัน โดยในบทความนี้อาจจะไม่ได้ลงรายละเอียดลึกมากทั้งหมด แต่จะลงรายละเอียดในระดับที่ให้พอรู้และทำต่อได้ แล้วจะพยายามหาแทรก reference ไว้ เพื่อให้ไปต่อยอดกันได้นะครับ

เราจะมาปูพื้นฐานสิ่งที่ควรรู้ก่อนที่จะเริ่มลงมือทำกันซักเล็กน้อย โดยจะเริ่มจากภาพใหญ่ และจะค่อย ๆ อธิบายแต่ละหัวข้อลงไปในรายละเอียด และแน่นอนหัวข้อหลักที่ควรจะถูกพูดถึงก่อนก็คือ..

Tweak คืออะไร ทำไมถึงต้องเรียกว่า Tweak?

คำว่า Tweak แปลเป็นภาษาไทย จะมีความหมายว่า บิด, ดึง, ปรับเปลี่ยนเล็กน้อย หากใช้กับ electronic device จะหมายถึงการ tuning หรือการปรับแต่งระบบที่มีความซับซ้อน แต่ในกรณีของ iOS แล้ว Tweak จะหมายถึง dylib (Dynamic Library) ที่สามารถที่จะเพิ่มความสามารถหรือปรับแต่ง process อื่น ให้เป็นไปในแบบที่เราต้องการ

ด้านล่างนี้ก็จะเป็นตัวอย่าง Tweak อันหนึ่งจาก Cydia เอาไว้ปรับสีของ application Notes บน iOS โดยปกติแล้วมันจะไม่สามารถเปลี่ยนสีได้ แต่ Tweak ทำให้มันเป็นไปได้

Tweak ชื่อ NiceNotes จาก Cydia
โครงสร้างของ NiceNotes (ไฟล์ในกรอบสีแดงคือไฟล์ Dynamic Library ที่ใช้ inject ไปที่ process เป้าหมาย)
ซ้ายคือภาพก่อนติดตั้ง NiceNotes ขวาคือภาพหลังติดตั้ง

บางครั้ง feature บน iOS ก็ไม่สามารถตอบสนองความต้องการของเราได้อย่างเพียงพอ Tweak ก็เป็นสิ่งที่เข้ามาช่วย customize ให้เป็นแบบที่เราต้องการได้ เช่น หากต้องการ lock application บาง application ให้จำเป็นต้องใส่ password ก่อนที่จะใช้งานได้ แน่นอนว่า feature ที่มีของ iOS โดยทั่วไปนั้น ไม่สามารถทำได้ แต่ Tweak ชื่อ AppLocker สามารถตอบสนองความต้องการตรงนี้ได้

Calculator ถูก lock โดย AppLocker

สำหรับ Security researcher หลาย ๆ คนคงจะคุ้นชินกับ Tweak เช่น SSLKillSwitch2, IntroSpy, Liberty หรือ JailProtect ซึ่งเป็นเครื่องมือที่ช่วยให้การทดสอบ application บน iOS ทำได้ง่ายขึ้น นอกจากจะใช้งานเป็นอย่างเดียวแล้ว การเข้าใจวิธีการพัฒนา Tweak จะทำให้สามารถ customize เครื่องมือ ให้เป็นไปตามที่ต้องการได้โดยไม่จำเป็นต้องรอ update จากผู้พัฒนา หรือในกรณีที่ดีที่สุดก็คือการพัฒนา Tweak ขึ้นมาเอง เพื่อให้การทำงานเป็นไปได้อย่างสะดวกรวเร็วและง่ายมากยิ่งขึ้น

ดูแล้วน่าสนใจ อยากทำขึ้นมาบ้าง ต้องทำอย่างไร?

เมื่อพูดจากภาพใหญ่แล้ว Tweak สามารถพัฒนาขึ้นมาได้โดยใช้เครื่องมือ/วิธีการ ได้หลายวิธีด้วยกัน ด้านล่างนี้จะเป็น list ตัวอย่าง (ย้ำว่าตัวอย่าง จริง ๆ แล้วยังมีอีกหลายทาง) ที่สามารถใช้เพื่อช่วยสร้าง Tweak

  • ใช้ Theos คือ platform ที่ช่วยในการพัฒนา Tweak และอยู่คู่กับ Jailbreak Developer มาอย่างช้านาน ในบทความนี้จะอธิบายโดยใช้ framework ตัวนี้เพื่อพัฒนา Tweak
  • ใช้ application ที่ชื่อว่า FLEX เป็น application ที่ช่วยให้พัฒนา Tweak ได้ง่ายขึ้น ผ่านการใช้ GUI โดยที่ไม่จำเป็นต้องพึ่งการเขียนโค้ด
  • ใช้ Frida — น้องใหม่มาแรง เป็นเครื่องมือประเภท Dynamic Instrumentation Toolkit ที่ช่วยในการทำ runtime-patching (แก้ไข logic ของ application ในขณะที่กำลังทำงาน) และ dynamic analysis ได้
  • เขียน dylib ขึ้นมาใหม่ แล้ว inject เข้าไปใน application เองเลย (เพิ่มเติม)

ข้างบนเป็นแค่เครื่องมือ/วิธีการที่ช่วยในการพัฒนา Tweak เท่านั้น แต่ก่อนที่จะใช้เครื่องมือพวกนี้ได้ จะต้องมีพื้นฐานความเข้าใจเกี่ยวกับหัวข้อต่อไปนี้

  • การพัฒนา iOS application โดยใช้ Objective-C
  • การทำ static/dynamic analysis iOS application

เนื่องจาก Tweak คือการปรับแต่งส่วนที่มีอยู่แล้ว ให้เป็นไปตามที่เราต้องการ และการที่จะปรับแต่งส่วนของ appplication ได้นั้น ต้องใช้ static/dynamic analysis เข้ามาช่วยเพื่อหาส่วนที่จะต้องปรับแต่งนั้นเอง

โดยความรู้ที่เกี่ยวข้องกับทั้งสองเรื่อง จะกระจายกันแทรกอยู่ในเนื้อหาที่จะเขียนถึงต่อไปครับ

จริง ๆ แล้ว Tweak ทำงานอย่างไรกัน?

Tweak โดยส่วนใหญ่แล้วจะประกอบไปด้วยการ hook method/function บน Objective-C, C และ C++ ซึ่งคำว่า hook ในที่นี่จะเป็นความหมายรวม ๆ ที่หมายถึงการ intercept method/function call หรือ message หรือ event อะไรก็ตามที่เกิดขึ้นกับ method/function เป้าหมาย หรือสามารถหมายถึง การเปลี่ยนแปลงการทำงานของ method/function นั้น ให้เป็นแบบที่เราต้องการ

ในการสร้าง Tweak โดยใช้ Theos (และ Tweak ส่วนใหญ่ใน Cydia) นั้น จะต้องพึ่งพาสิ่งที่เรียกว่า Cydia Substrate (หรือชื่อเก่า MobileSubstrate) เนื่องจาก Theos มีหน้าที่ compile code ที่เราเขียนให้เป็น dylib และสร้าง package ของ Tweak ขึ้นมาเท่านั้น แต่ส่วนที่จะนำ package ไปใช้งานและทำให้ Tweak สามารถทำ runtime-patching กับ process เป้าหมายได้ คือ Cydia Substrate

Cydia Substrate คืออะไร?

Cydia Substrate

Cydia Substrate คือ platform ที่ช่วย developer ในการทำ runtime-patching ถูกพัฒนาขึ้นโดย Jay Freeman (saurik) บุคคลสำคัญของวงการ jailbreak iOS ซึ่งเป็นคน ๆ เดียวกับที่พัฒนา Cydia package manager ที่ทุกคนคุ้นเคย

Cydia package manager

ทั่วไปแล้วเครื่อง jailbreak ทุกเครื่อง จะต้องติดตั้ง Cydia Substrate อยู่แล้ว ถ้าไม่ได้ติดตั้งก็แทบจะใช้ Tweak อะไรไม่ได้เลย

Cydia Substrate เองจะประกอบไปด้วยส่วนที่สำคัญด้วยกัน 3 ส่วนก็คือ

  1. MobileHooker — คือส่วนที่ใช้ในการ hook method/function
  2. MobileLoader — คือส่วนที่ load code ที่เราเขียนเข้าไปใน process ของ application ที่กำลังทำงานอยู่
  3. Safe mode — ในกรณีที่ Tweak ทำให้ SpringBoard crash ส่วน MobileLoader จะสามารถตรวจจับได้และทำให้อุปกรณ์เข้าสู่ Safe mode โดย Safe mode จะทำการ disable Tweak ทั้งหมดที่ติดตั้งบนอุปกรณ์และทำให้ SpringBoard กลับมาทำงานต่อได้

Note: SpringBoard คือ application หลักใน iOS ที่ใช้ในการจัดการ home screen, การ launch application และการ setting ค่าบางอย่างตอนที่อุปกรณ์กำลังเปิดใช้งาน เพราะฉะนั้นถ้า SpringBoard crash ก็แทบจะไม่สามารถใช้งานอุปกรณ์ได้เลย

มาถึงตรงนี้แล้วก็พอจะรู้ว่าส่วนที่เราต้องยุ่งด้วยมากที่สุดก็คือ MobileHooker นั่นเอง MobileHooker มี API หลัก ๆ ให้เราใช้งานเพื่อ hook method/function อยู่ คือ MSHookMessageEX และ MSHookFunction

API ทั้ง 2 ตัว จะถูกเรียกใช้งานบ่อยมากในการเขียน Tweak เรียกว่าคือหัวใจของ Tweak เลยก็ว่าได้ เพราะฉะนั้นการเข้าใจว่าจริง ๆ แล้ว API ทั้งสองตัวทำงานยังไง จะทำให้เราเข้าใจและพัฒนา Tweak ได้ดียิ่งขึ้น

MSHookMessageEX

ใช้สำหรับ hook Objective-C method เพื่อเปลี่ยนการทำงานของ method นั้น ๆ ให้เป็นการทำงานแบบใหม่ของเราเอง โดยจะทำในระดับ Objective-C runtime

แล้ว MSHookMessageEX ใช้วิธีไหนเข้าไปเปลี่ยนการทำงานของ method?

ก่อนอื่นจะต้องเข้าใจความหมายของคำว่า method, selector และ implementation ใน Objective-C ก่อน

ความสัมพันธ์ของ method, selector และ implementation (original from: https://medium.com/rocknnull/ios-to-swizzle-or-not-to-swizzle-f8b0ed4a1ce6)

Method — คือ entry หนึ่งใน dispatch table ของ class ที่ประกอบไปด้วย selector (ทำหน้าที่เป็น key) และ implementation (ทำหน้าที่เป็น value)

Selector — คือ String ที่เป็นชื่อของ method ในขณะ runtime

Implementation — คือ pointer ที่ชี้ไปยังจุดเริ่มต้นการทำงานของ method

เมื่อมีการเรียกใช้ method เกิดขึ้น ก็จะมีการหาค่าของ implementation (value) โดยใช้ selector (key) ซึ่งกระบวนการนี้จะเกิดขึ้นในขณะ runtime นั่นหมายความว่าเรามีโอกาสที่จะเปลี่ยน implementation ของ method ที่เราต้องการได้ และ Objective-C runtime ก็มี function ให้ทำแบบนั้นได้ เช่น function method_setimplementation

โดยวิธีการสับเปลี่ยน implementation ของ method แบบนี้ มีชื่อในวงการว่า “method swizzling” นั่นเอง

MSHookMessageEX ใช้หลักการที่พูดถึงไปข้างต้นในการ interact กับ Objective-C runtime โดยตรงเพื่อทำการสับเปลี่ยน implementation ของ method ทำให้ implementation ชี้ไปยัง function ของเราที่สร้างขึ้นมาใหม่แทน

MSHookFunction

ใช้สำหรับ hook C, C++ function เพื่อเปลี่ยนวิธีการทำงาน โดยจะทำในระดับ assembly ซึ่งแตกต่างจาก Objective-C runtime ที่มี feature สำหรับการเปลี่ยน implementation

แทนที่จะแก้ไข assembly เองเพื่อเปลี่ยนวิธีการทำงานของ function ซึ่งยากกว่าการใช้งาน feature ของ Objective-C runtime มาก MSHookFunction จะเป็นตัวทำหน้าที่นี้แทน เราจะสามารถ hook C, C++ function ได้ โดยที่ไม่จำเป็นต้องไปแก้ไข assembly โดยตรง

วิธีการคร่าว ๆ ในการทำงานของ MSHookFunction นั้น คือการเปลี่ยน assembly ในขั้นก่อนจะเริ่ม execute instruction ของ function เป้าหมาย ให้ jump ไปยัง function ที่เราเขียนขึ้นมาใหม่ จากนั้นจึง jump กลับมายัง flow เดิม ตามรูป

ซ้ายคือรูป flow การทำงานปกติของ program ก่อน hook, ขวาคือ flow ใหม่หลังขณะ hook

เมื่อใช้งาน Theos ในการพัฒนา Tweak ตัว Theos เองจะมีวิธีการ hook ที่ง่ายกว่าการเรียกใช้งาน MSHookMessageEX และ MSHookFunction ตรง ๆ แต่เบื้องหลังก็คือการไปเรียกใช้งาน API ทั้ง 2 ตัวนั่นแหละ หรือใครอยากจะเรียกใช้งาน MSHookMessageEX และ MSHookFunction โดยตรงก็สามารถทำผ่าน Theos ได้เช่นเดียวกัน

API ของ Cydia Substrate ไม่ได้มีแค่ 2 API ที่กล่าวมาเท่านั้น ยังมีให้เลือกใช้งานอีกมากมาย สามารถดูเพิ่มเติมได้จากที่นี่

ทิ้งท้าย..

ใน Part นี้ ได้มีการพูดถึงพื้นฐานที่ควรต้องรู้เกี่ยวกับ Tweak และ Cydia Substrate โดยส่วนใหญ่ไปแล้ว ในส่วนของ Part ต่อไป จะพูดถึงการเริ่มลงมือพัฒนา Tweak ของ application ที่ไม่มีความซับซ้อนมาก ตั้งแต่ต้นจนถึงขั้นตอนที่ได้ Tweak ขึ้นมา และนำไปติดตั้งเพื่อใช้งานในเครื่อง jailbreak ต่อไป

เจอกันใน Part หน้าครับ!!

--

--

Witsarut L.
INCOGNITO LAB

Penetration tester, security researcher at Incognito Lab.