REA หรือ Reverse Engineer Anything เป็นชุดเครื่องมือที่ช่วยให้ AI agent ตรวจสอบซอฟต์แวร์และอธิบายการทำงานโดยมีหลักฐานประกอบ แม้บางกรณีจะไม่มีซอร์สโค้ดต้นฉบับ เราต้องการรู้ว่าเครื่องมือนี้จะช่วยตรวจพฤติกรรมของ Muse Code ที่ได้รับอนุญาตให้ศึกษาได้ลึกเพียงใด จึงเริ่มจากโปรแกรมทดสอบขนาดเล็กก่อนลองวิเคราะห์ทั้งโปรแกรม ผลเล็กผ่าน แต่งานใหญ่หมดเวลาโดยไม่มี snapshot ที่ยืนยันการทำต่อได้ ทำให้เราได้บทเรียนทั้งเรื่องขอบเขตการทดลองและการอ่านหลักฐาน

สรุปสำหรับผู้บริหาร

  • ทีมผู้เขียนตรวจผล Ghidra ผ่าน REA กับโปรแกรมทดสอบทั้งบนเครื่อง ARM64 และ Linux x64; ผลถอดรหัสฟังก์ชันคืนค่า 7
  • การเก็บผล Muse Code --help และ --version ผ่าน REA ทำได้ภายใต้ HOME ชั่วคราวและ environment ว่าง แต่ยังพบไฟล์ล็อกด้านการยืนยันตัวตน
  • งานวิเคราะห์ Muse Code ทั้งโปรแกรมรอบแรกหยุดเพราะตีความ RSS เร็วเกินไป; รอบถัดไปสิ้นสุด FAILED ที่กำหนดสี่ชั่วโมง โดยไม่มี snapshot
  • หลังจบงาน ตรวจยืนยันว่าโปรเซส พื้นที่ชั่วคราว และไฟล์เป้าหมายที่โอนมาหายไปแล้ว; ผลวิเคราะห์ที่ล้มเหลวไม่เท่ากับการเก็บกวาดล้มเหลว
  • รอบหน้าให้กำหนดพฤติกรรมเป้าหมายแคบ ๆ เก็บ stage log และ diagnostics จริง พร้อมเกณฑ์หยุดและหลักฐานสำหรับ resume ก่อนขยายงาน

รู้จัก REA: จากโปรแกรมที่มีอยู่ สู่คำอธิบายที่ตรวจสอบได้

งาน reverse engineering คือการศึกษาซอฟต์แวร์จากสิ่งที่มีอยู่ เช่น ไฟล์โปรแกรม โค้ดที่คอมไพล์แล้ว หรือพฤติกรรมที่สังเกตได้ เพื่อทำความเข้าใจกลไกภายใน แทนการเดาว่าฟีเจอร์หนึ่งน่าจะทำงานอย่างไร REA จากโครงการต้นน้ำ จัดเครื่องมือสำหรับงานนี้ให้ agent เรียกผ่าน CLI หรือ MCP ซึ่งเป็นช่องทางเชื่อม agent กับเครื่องมือภายนอก ผู้ใช้จึงเริ่มจากคำถามเกี่ยวกับโปรแกรม แล้วให้ agent เลือกตรวจหลักฐานที่เกี่ยวข้องภายใต้สิทธิ์ที่ได้รับ

สำหรับงานไบนารี REA เชื่อมกับ provider อย่าง Hopper หรือ Ghidra เพื่อค้นชื่อฟังก์ชัน ข้อความในโปรแกรม คำสั่งเครื่อง และ pseudocode หรือโค้ดจำลองที่อ่านง่ายขึ้น ขณะที่งาน JavaScript และแอปบางประเภทมีเส้นทางตรวจ artifact หรือสังเกต runtime ตามความสามารถที่รองรับ REA จึงไม่ใช่ชื่อใหม่ของตัวถอดรหัสเพียงตัวเดียว แต่เป็นชั้นเชื่อม workflow เครื่องมือวิเคราะห์ และผลลัพธ์ให้ agent ใช้งานร่วมกัน

แนวทางที่ต้นน้ำอธิบายมีสามช่วง: Decompile เพื่อหาโค้ดและเบาะแส, Understand เพื่อเชื่อมหลักฐานเป็นคำอธิบายของฟีเจอร์ และ Recreate เพื่อนำความเข้าใจไปสร้างฟีเจอร์ของตนให้เหมาะกับความต้องการ ตัวอย่างคำถามคือ “ระบบค้นหาของแอปที่เราได้รับอนุญาตให้ตรวจเชื่อมส่วนใดบ้าง และหลักฐานใดรองรับคำอธิบายนั้น” นี่เป็นตัวอย่างแนวทางใช้งาน ไม่ใช่ผลทดลองของบทความนี้ และเราไม่ได้ทดสอบการสร้างฟีเจอร์ใหม่ในรอบที่เล่าต่อไป

ผลสำคัญไม่ใช่แค่คำตอบของ AI แต่คือ Evidence ที่ระบุเป้าหมาย วิธีตรวจ และข้อจำกัด เพื่อให้ย้อนตรวจข้อสรุปได้ โค้ดที่ decompile ไม่ใช่ซอร์สต้นฉบับที่กู้คืนอย่างแน่นอน และสิ่งที่อนุมานจากไฟล์ไม่เท่ากับพฤติกรรมที่สังเกตขณะรัน REA ไม่ได้รับประกันการโคลนแอปหรือความสำเร็จของการวิเคราะห์ทุกเป้าหมาย ซึ่งเป็นเหตุผลที่เราเริ่มจากการทดลองที่รู้คำตอบก่อนขยายขอบเขต

คำถามที่เราลองตอบ

REA จากโครงการต้นน้ำ ให้ agent ใช้ CLI หรือ MCP ตรวจซอฟต์แวร์และเก็บ Evidence ที่ตรวจย้อนกลับได้ โดยรองรับการวิเคราะห์ไบนารีผ่าน provider อย่าง Ghidra ตามขอบเขตที่เอกสารระบุ ส่วน Ghidra ของผู้พัฒนา มีความสามารถถอดรหัสและวิเคราะห์โค้ดคอมไพล์ การมีเครื่องมือเหล่านี้ไม่ได้แปลว่าทุกเป้าหมายจะวิเคราะห์เสร็จในงบเวลาที่มี

คำถามของเราจึงแยกเป็นสองส่วน: เครื่องมือให้ผลที่ตรวจสอบได้กับเป้าหมายเล็กหรือไม่ และการขยายไปยัง Muse Code ทั้งโปรแกรมจะจบพร้อมหลักฐานที่นำไปตรวจต่อได้หรือไม่ เราอ้างผลทดลองย้อนหลังของทีมผู้เขียนในวันที่ 13–14 ตุลาคม ไม่ได้เริ่มการวิเคราะห์ใหม่เพื่อเขียนบทความนี้ การติดตั้งและปัญหา doctor กับตำแหน่ง provider ในบันทึกตั้งต้นช่วยให้เริ่มงานได้ แต่ไม่ใช่คำตอบของคำถามใหญ่

ด่านตั้งต้น: ตรวจสุขภาพผ่าน แต่ใช้งานจริงยังไม่ผ่าน

บันทึกตั้งต้นของทีมเมื่อวันที่ 12 ตุลาคมพบว่า doctor รายงาน Hopper พร้อมใช้งาน แต่การเปิด provider กลับได้ provider_unavailable พร้อม executable_missing สาเหตุที่บันทึกไว้คือตัวตรวจสุขภาพพบ executable ในตำแหน่งติดตั้งของผู้ใช้ ขณะที่ provider คาดตำแหน่งติดตั้งระดับระบบ ทีมแก้การอ้างตำแหน่งให้ตรงกับ executable ที่มีอยู่ แล้วบันทึกว่า inspect และ search กับไบนารีทดสอบให้ผลสำเร็จ ไม่ได้หมายความว่า doctor หรือ provider ทุกเวอร์ชันมีปัญหานี้

บันทึกเดียวกันระบุว่าการวิเคราะห์โปรเจกต์ JavaScript ได้ผล partial เมื่อขอบเขตรวม dependencies ขนาดใหญ่ ผลนี้ทำให้ทีมเสนอให้เลือกเฉพาะ artifact ที่ต้องการศึกษา แต่ยังไม่ใช่หลักฐานว่าการตัด dependencies ออกจะทำให้การวิเคราะห์ครบแน่นอน บทเรียนตั้งต้นจึงเป็นการแยกสามคำถาม: ตรวจสุขภาพผ่านหรือไม่ เปิดเป้าหมายได้หรือไม่ และหลักฐานครบพอสำหรับคำถามที่ตั้งหรือไม่

ผลที่ผ่านและขอบเขตของมัน

เราใช้เป้าหมายทดสอบที่รู้คำตอบอยู่แล้วเป็นด่านแรก การทดสอบ Ghidra ผ่าน REA กับไบนารี ARM64 ในเครื่องและบน Linux x64 ให้ผลผ่าน; ทีมผู้เขียนตรวจ Evidence ของการเรียก analyze_function ซึ่งมี pseudocode ของฟังก์ชันทางเข้าเป็น return 7 ตรงกับค่าที่คาด การผ่านด่านนี้ยืนยันเส้นทางวิเคราะห์ฟังก์ชันตัวอย่าง ไม่ได้ยืนยันว่าการวิเคราะห์ไบนารีขนาดใหญ่จะจบ

จากนั้นทีมผู้เขียนโอนไฟล์เป้าหมายโดยตรวจ checksum หรือค่าตรวจความตรงกันของไฟล์กับต้นทาง และเก็บผล Muse Code --help กับ --version ผ่าน REA โดยเริ่มโปรเซสด้วยชุดตัวแปรสภาพแวดล้อมว่างและจัดพื้นที่ HOME ชั่วคราวให้การทดลอง การบันทึกผลสองคำสั่งนี้สำเร็จ แต่คำสั่ง help ยังสร้างไฟล์ล็อกด้านการยืนยันตัวตน; การมีไฟล์ล็อกไม่ได้พิสูจน์ว่ามีการเข้าสู่ระบบ เราไม่ได้สังเกตทราฟฟิกเครือข่าย จึงไม่สรุปว่าไม่มีการเชื่อมต่อหรือว่าเป็นการทดสอบที่แยกจากเครือข่าย

จุดตรวจผลที่ทีมผู้เขียนตรวจขอบเขตของข้อสรุป
Smoke กับ Ghidraผ่านบน ARM64 ในเครื่องและ Linux x64; ฟังก์ชันตัวอย่างคืนค่า 7ยืนยันเป้าหมายเล็ก ไม่ใช่งานทั้งโปรแกรม
คำสั่ง Muse Codeเก็บ help/version ได้ใน HOME ชั่วคราวและ environment ว่าง; help สร้าง auth lockไม่ได้วัดทราฟฟิกเครือข่ายหรือทดสอบคำสั่งอื่น
การวิเคราะห์ทั้งโปรแกรมรอบแรกทีมผู้เขียนหยุดเองเมื่อ RSS ดูใกล้ค่า heap ที่ตั้งไม่ใช่หลักฐานว่าเกิด OOM
การวิเคราะห์ทั้งโปรแกรมรอบถัดไปสิ้นสุด FAILED ที่กำหนดสี่ชั่วโมง; ไม่มี snapshotไม่ทราบว่าการวิเคราะห์ไปถึงขั้นใดหรือ resume ได้หรือไม่
การเก็บกวาดรอบสุดท้ายตรวจไม่พบโปรเซส พื้นที่ชั่วคราว และเป้าหมายที่โอนมา; เก็บ tools/results ไว้เป็นผลตรวจหลังงานจบ ไม่ได้เปลี่ยน verdict ของการวิเคราะห์

งานใหญ่ล้มเหลวอย่างไร

ภาพนี้เล่าเส้นทางการทดลอง ไม่ใช่ขั้นตอนที่ผ่านแล้วรับประกันความสำเร็จ จุดแยกหลังการทดสอบเล็กสำคัญกว่าลำดับ setup: หลักฐานที่ผ่านกับฟังก์ชันหนึ่งไม่ข้ามไปเป็นผลสำเร็จของทั้งโปรแกรม

ผังแยกการทดสอบเล็กที่ผ่าน ออกจากการวิเคราะห์ Muse Code ทั้งโปรแกรมที่หยุดรอบแรกและล้มเหลวเมื่อครบกำหนดรอบถัดไป โดยการเก็บกวาดตรวจผ่านแยกต่างหาก

รอบแรกเราหยุดงานจากการเห็น RSS เข้าใกล้ขนาด heap ที่ตั้งไว้ ข้อสรุปนั้นเร็วเกินหลักฐาน: RSS รวมหน่วยความจำนอก Java heap ด้วย และการสังเกตรอบถัดมาพบว่า RSS ลดลงได้ขณะที่งานยังเดินอยู่ เราไม่มีผลวินิจฉัย OOM ของรอบแรก จึงไม่ยกการหยุดนั้นเป็นหลักฐานว่าเครื่องมี RAM ไม่พอ

รอบถัดมาทำตามกำหนดหยุดสี่ชั่วโมงที่ได้รับอนุมัติ งานจบเป็น FAILED ด้วยเหตุ deadline โดยไม่มี snapshot ให้ยืนยันการทำต่อ บันทึก Evidence ใช้คำว่า cleanup_incomplete/cancelled สำหรับผลวิเคราะห์ที่ถูกยกเลิก แต่การตรวจสถานะเครื่องหลังจบแยกต่างหากพบว่าโปรเซส พื้นที่ชั่วคราว และไฟล์เป้าหมายที่โอนมาหายไปแล้ว ส่วนเครื่องมือและระเบียนผลยังอยู่ จึงต้องอ่านผลล้มเหลวของ analysis และผลตรวจ cleanup คนละช่อง ไม่อนุมานจากชื่อ error ว่ายังมีโปรเซสค้าง

สิ่งที่เราอ่านผิดและหลักฐานที่ขาด

ตัวเลข O ของ jstat -gcutil คือสัดส่วนการใช้ old pool ณ ขณะนั้น ไม่ใช่สัดส่วนของ heap ทั้งหมดเทียบกับ Xmx การไม่พบ Full GC ก็ไม่พิสูจน์ว่าไม่มีแรงกดดันด้านหน่วยความจำ ในทำนองเดียวกัน CPU ที่ยังใช้และโปรเซสที่ยังตอบสนองแสดงความมีชีวิต แต่ไม่ได้บอกว่า Ghidra กำลังอยู่ในขั้นวิเคราะห์ใด หรือกำลังคืบหน้าไปสู่ snapshot

เราเคยรายงานตัวเลขการทำงานซ้ำ ๆ ระหว่างรอโดยไม่มีหลักฐานระบุขั้นการวิเคราะห์เพียงพอ คำว่า “เดินตามปกติ” จึงหนักเกินหลักฐาน ตัวเก็บ log ค้นหาชื่อไฟล์ที่ต่างจากชื่อที่ระบุในอาร์กิวเมนต์ JVM ที่รันจริง; การไม่พบข้อความในไฟล์ที่หาไม่เจอไม่ใช่หลักฐานว่าไม่มีข้อผิดพลาด และการลบพื้นที่รันหลังงานจบทำให้เสียโอกาสตรวจข้อมูลวินิจฉัยที่ยังไม่ได้เก็บไว้ก่อน

การทดสอบหกข้อที่ผ่านนั้นตรวจเพียงฟังก์ชันช่วยตัดสินผลลัพธ์ ไม่ได้พิสูจน์วงจรของตัวควบคุมงานจริง ทั้งการยกเลิก การล็อกไม่ให้รันซ้ำ และการเก็บกวาด เราไม่มีรายละเอียดข้อยืนยันทั้งหกในหลักฐานสำหรับบทความนี้ จึงไม่อ้างว่าครอบคลุมกรณีใดบ้าง ความสำเร็จของ smoke test หรือการเพิ่ม RAM ไม่ใช่เหตุผลเพียงพอที่จะรับรองว่างานใหญ่จะเสร็จ และเรายังไม่ทราบสาเหตุเชิงลึกที่ทำให้การวิเคราะห์รอบสุดท้ายไม่จบ

ครั้งหน้าจะตั้งด่านอย่างไร

ก่อนเปิดงานใหญ่ ทีมควรตั้งคำถามถึงพฤติกรรมที่ระบุได้หนึ่งอย่างและกำหนด artifact ที่ได้รับอนุญาตให้ตรวจ เริ่มจากคัดกรองไฟล์และหลักฐาน CLI ที่ควบคุมได้ แล้วใช้ smoke ที่รู้คำตอบเพื่อแยกความพร้อมของ provider ออกจากความยากของเป้าหมายจริง ต้องระบุรายการ log จากอาร์กิวเมนต์ของ provider ที่รันจริง และเก็บ diagnostics หรือข้อมูลวินิจฉัยแบบจำกัดขนาดก่อนลบพื้นที่ชั่วคราว

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

ตัวอย่างงานถัดไปที่ เสนอแต่ยังไม่ได้ทำ คือเลือกฟังก์ชันหนึ่งซึ่งเกี่ยวกับพฤติกรรมที่ทีมต้องการตรวจ ตั้งชื่อคำถามให้ชัด ระบุหลักฐาน static ที่คาดว่าจะพบ แล้วใช้ผลของฟังก์ชันนั้นตรวจทานกับพฤติกรรมที่สังเกตได้ภายใต้สิทธิ์ที่ได้รับ ข้อเสนอนี้ยังไม่ใช่คำตอบว่าฟังก์ชันนั้นอยู่ที่ใดหรือทำงานอย่างไร

ข้อจำกัดของบทความ

ผล smoke การบันทึกผลคำสั่ง และสถานะรอบเครื่องทางไกลเป็นผลที่ทีมผู้เขียนบันทึกและตรวจไว้ในงานย้อนหลัง; บทความนี้ไม่ได้รัน REA หรือวิเคราะห์ Muse Code ใหม่ เราเปิด Evidence ของ smoke ที่มี analyze_function และ pseudocode ที่คืนค่า 7 ส่วนรายละเอียดการหยุดรอบใหญ่ยึดบันทึกสะท้อนงานและผลตรวจสถานะหลังจบของทีม ไม่ได้มี snapshot หรือบันทึกขั้นการวิเคราะห์ครบพอจะระบุสาเหตุ OOM, deadlock หรือขั้นที่ค้าง ไม่มีการสังเกตเครือข่าย และการทดสอบฟังก์ชันช่วยไม่แทนการทดสอบวงจรตัวควบคุมงาน

สรุปชวนใช้

หากจะใช้ REA กับโปรแกรมที่ได้รับอนุญาต เริ่มด้วยคำถามแคบและผลทดสอบเล็กที่รู้คำตอบ แล้วกำหนดว่าหลักฐานแบบใดจึงจะพอเรียกงานใหญ่สำเร็จ เก็บ log จากแหล่งที่รันจริงก่อน cleanup และหยุดตามกำหนดเมื่อยังไม่มี snapshot บทเรียนของรอบนี้ไม่ใช่ว่าเครื่องมือทำงานหรือใช้ไม่ได้ทั้งหมด แต่คือผลผ่านของ smoke ผลล้มเหลวของ analysis และผลผ่านของ cleanup ต้องถูกรายงานแยกกันอย่างตรวจสอบได้