สิ่งแปลก ๆ ที่ได้เรียนรู้ระหว่างเขียน x86 emulator
- อธิบายเกร็ดความรู้และเรื่องแปลก ๆ หลายอย่างที่ได้เรียนรู้ระหว่างเขียน x86 และ amd64 emulator
- ใน Time Travel Debugging(TTD) มีการใช้ CPU emulator เพื่อบันทึกการทำงานของโปรเซสในระดับคำสั่ง
- TTD เวอร์ชันแรกเรียกว่า iDNA เขียนด้วย assembly code จึงเร็ว แต่ดูแลรักษายาก
- เวอร์ชันที่สองเขียนด้วย C++ ทำให้การบำรุงรักษาดีขึ้น
เกร็ดความรู้ x86 encoding ที่แทบไม่ค่อยมีประโยชน์
- โครงสร้างการเข้ารหัสของ x86 สามารถเข้ารหัสคำสั่งเดียวกันได้หลายวิธี
- คำสั่ง
int 3 สามารถเข้ารหัสได้เป็น CD 03 หรือ CC
- รีจิสเตอร์
EAX ถูกเรียกว่า "accumulator register" และมีความแตกต่างจริงในด้าน encoding
- prefix
REX ช่วยให้เข้าถึงช่วงรีจิสเตอร์ที่กว้างขึ้นได้ในโค้ด 64 บิต
- คำสั่งหนึ่งคำสั่งมีความยาวได้สูงสุด 15 ไบต์ และหากเกินกว่านั้นจะเกิด exception
- address override prefix ช่วยให้อ้างอิงที่อยู่แบบ 32 บิตได้ในโหมด 64 บิต
คุณสมบัติของ flag ที่แปลก ๆ
- คำสั่ง
INC จะไม่อัปเดต carry flag ต่างจากคำสั่ง ADD
- คำสั่ง
CMPXCHG8B/CMPXCHG16B จะเปลี่ยนเฉพาะ zero flag
- คำสั่ง shift และ rotate จะปล่อยให้ overflow flag อยู่ในสถานะไม่กำหนดเมื่อปริมาณการ shift มากกว่า 1
ความน่าประหลาดใจเพิ่มเติมของคำสั่ง shift
shr ax, 10h จะ shift รีจิสเตอร์ ax 16 บิตจนกลายเป็น 0
shr eax, 20h จะ shift รีจิสเตอร์ eax 32 บิต แต่ค่าจะไม่เปลี่ยน
- ปริมาณการ shift จะถูก mask ด้วย
1FH
segment override
- segment ยังคงถูกใช้ในโค้ด 32 บิตและ 64 บิต โดยหลักแล้วใช้กับ thread local storage
- บน Windows จะใช้รีจิสเตอร์
FS หรือ GS เพื่ออ้างอิง TEB(Thread Execution Block)
- โปรเซส 32 บิตใช้
FS และโปรเซส 64 บิตใช้ GS
- ในโหมด 64 บิต ค่าของ segment register ไม่ได้มีความสำคัญ
segment override: เกร็ดเพิ่มเติม
- ในโหมด 32 บิต ค่าจริงของ segment register จะอ้างอิง segment descriptor
- ในโหมด 64 บิต base จะถูกควบคุมโดย MSR
- ใน WinDbg ไม่สามารถอ่านค่า segment ของโปรเซส 64 บิตได้โดยตรง
บทสรุป
- บทความนี้รวบรวมเกร็ด x86 แบบสุ่ม ๆ ไว้หลายข้อ
- การเขียน emulator ช่วยให้เข้าใจอย่างลึกซึ้งว่า CPU ทำงานอย่างไร
- สามารถดูแหล่งข้อมูลดี ๆ เพิ่มเติมได้จากเว็บไซต์ของ Agner Fog
สรุปโดย GN⁺
- อธิบายเกร็ดความรู้และเรื่องแปลก ๆ หลายอย่างที่ได้เรียนรู้ระหว่างเขียน x86 และ amd64 emulator
- การเขียน emulator ช่วยให้เข้าใจการทำงานของ CPU ได้อย่างลึกซึ้ง
- ครอบคลุมเกร็ดหลายเรื่อง เช่น วิธี encoding ที่หลากหลายของคำสั่ง
int 3, prefix REX, และ segment override
- ดูแหล่งข้อมูลเพิ่มเติมได้จากเว็บไซต์ของ Agner Fog
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News