ฉันสงสัยว่าตัวดีบักทำงานอย่างไร เป็นส่วนหนึ่งที่สามารถ 'แนบ' เพื่อเรียกใช้ปฏิบัติการได้แล้ว ฉันเข้าใจว่าคอมไพเลอร์แปลรหัสเป็นภาษาเครื่อง แต่แล้วโปรแกรมดีบั๊กจะรู้ได้อย่างไรว่ามันเชื่อมต่อกับอะไร
ฉันสงสัยว่าตัวดีบักทำงานอย่างไร เป็นส่วนหนึ่งที่สามารถ 'แนบ' เพื่อเรียกใช้ปฏิบัติการได้แล้ว ฉันเข้าใจว่าคอมไพเลอร์แปลรหัสเป็นภาษาเครื่อง แต่แล้วโปรแกรมดีบั๊กจะรู้ได้อย่างไรว่ามันเชื่อมต่อกับอะไร
คำตอบ:
รายละเอียดของการทำงานของดีบักเกอร์จะขึ้นอยู่กับว่าคุณกำลังดีบักอะไรและระบบปฏิบัติการคืออะไร สำหรับการแก้จุดบกพร่องพื้นเมืองใน Windows คุณสามารถหารายละเอียดบางอย่างใน MSDN: Win32 API
ผู้ใช้บอกดีบักเกอร์ว่ากระบวนการใดที่จะแนบไม่ว่าจะด้วยชื่อหรือตาม ID กระบวนการ หากเป็นชื่อตัวดีบักจะค้นหา ID กระบวนการและเริ่มต้นเซสชันการดีบักผ่านการเรียกของระบบ ภายใต้ Windows นี้จะDebugActiveProcess
เมื่อเชื่อมต่อแล้วตัวดีบักจะเข้าสู่ลูปเหตุการณ์คล้ายกับ UI ใด ๆ แต่แทนที่จะเป็นเหตุการณ์ที่มาจากระบบหน้าต่างระบบปฏิบัติการจะสร้างเหตุการณ์ตามสิ่งที่เกิดขึ้นในกระบวนการที่กำลังดีบั๊กตัวอย่างเช่นข้อยกเว้นที่เกิดขึ้น ดูWaitForDebugEvent
ดีบักเกอร์สามารถอ่านและเขียนหน่วยความจำเสมือนของกระบวนการเป้าหมายและปรับค่าการลงทะเบียนผ่าน API ที่จัดทำโดยระบบปฏิบัติการ ดูรายการฟังก์ชั่นการแก้ไขข้อบกพร่องสำหรับ Windows
ดีบักเกอร์สามารถใช้ข้อมูลจากไฟล์สัญลักษณ์เพื่อแปลจากที่อยู่เป็นชื่อตัวแปรและตำแหน่งในซอร์สโค้ด ข้อมูลไฟล์สัญลักษณ์เป็นชุด API แยกต่างหากและไม่ใช่ส่วนหลักของระบบปฏิบัติการดังกล่าว บน Windows นี้คือการตรวจแก้จุดบกพร่องการเชื่อมต่อการเข้าถึง SDK
หากคุณกำลังดีบักสภาพแวดล้อมที่มีการจัดการ (.NET, Java, ฯลฯ ) โดยทั่วไปกระบวนการจะมีลักษณะคล้ายกัน แต่รายละเอียดจะแตกต่างกันเนื่องจากสภาพแวดล้อมของเครื่องเสมือนมี API การดีบักแทนที่จะเป็นระบบปฏิบัติการพื้นฐาน
ตามที่ฉันเข้าใจ
สำหรับจุดพักซอฟต์แวร์บน x86 ตัวดีบักจะแทนที่ไบต์แรกของคำสั่งด้วยCC
( int3
) สิ่งนี้ทำกับWriteProcessMemory
Windows เมื่อ CPU เข้าสู่คำสั่งนั้นและดำเนินการint3
สิ่งนี้จะทำให้ CPU สร้างข้อยกเว้นการดีบัก ระบบปฏิบัติการได้รับการขัดจังหวะนี้ตระหนักถึงกระบวนการกำลังดีบั๊กและแจ้งให้ทราบถึงกระบวนการดีบักเกอร์ที่จุดพักถูกตี
หลังจากจุดหยุดถูกโจมตีและกระบวนการหยุดทำงานดีบักเกอร์จะค้นหาในรายการจุดพักและแทนที่CC
ด้วยไบต์ที่มีอยู่เดิม ดีบักเกอร์ตั้งค่าTF
สถานะการดักจับในEFLAGS
(โดยแก้ไขCONTEXT
) และดำเนินการกระบวนการต่อ กับดักธงทำให้ CPU สร้างข้อยกเว้นขั้นตอนเดียวโดยอัตโนมัติ ( INT 1
) ในคำสั่งต่อไป
เมื่อกระบวนการที่กำลังดีบั๊กหยุดในครั้งต่อไปตัวดีบักจะแทนที่ไบต์แรกของคำสั่งเบรกพอยต์ด้วยอีกครั้งCC
และกระบวนการดำเนินต่อไป
ฉันไม่แน่ใจว่านี่เป็นวิธีการที่ debuggers ใช้จริงหรือไม่ แต่ฉันเขียนโปรแกรม Win32 ที่จัดการเพื่อดีบักตัวเองโดยใช้กลไกนี้ ไร้ประโยชน์อย่างสมบูรณ์ แต่การศึกษา
ใน Linux การดีบักกระบวนการเริ่มต้นด้วยการเรียกระบบ ptrace (2) บทความนี้มีบทช่วยสอนที่ยอดเยี่ยมเกี่ยวกับวิธีใช้ptrace
เพื่อสร้างโครงสร้างการดีบักอย่างง่าย
(2)
บอกเรามากกว่าหรือน้อยกว่า "ptrace คือการเรียกระบบ" หรือไม่?
(2)
คือหมายเลขส่วนคู่มือ ดูen.wikipedia.org/wiki/Man_page#Manual_sectionsสำหรับคำอธิบายของส่วนที่ใช้
ptrace
เป็นการเรียกของระบบ
(2)
บอกเราว่าเราสามารถพิมพ์man 2 ptrace
และรับ manpage ที่ถูกต้อง - ไม่สำคัญที่นี่เพราะไม่มีสิ่งอื่นใดที่ptrace
ทำให้เข้าใจผิด แต่เพื่อเปรียบเทียบman printf
กับman 3 printf
Linux
หากคุณใช้ระบบปฏิบัติการ Windows ทรัพยากรที่ยอดเยี่ยมสำหรับสิ่งนี้คือ "การดีบักแอปพลิเคชันสำหรับ Microsoft .NET และ Microsoft Windows" โดย John Robbins:
(หรือแม้แต่รุ่นที่เก่ากว่า: "แอปพลิเคชันดีบั๊ก" )
หนังสือเล่มนี้มีบทหนึ่งเกี่ยวกับวิธีการทำงานของดีบักเกอร์ที่มีรหัสสำหรับการดีบักเกอร์แบบง่าย ๆ แต่ทำงานอยู่
เนื่องจากฉันไม่คุ้นเคยกับรายละเอียดของการดีบัก Unix / Linux สิ่งนี้อาจไม่สามารถใช้กับระบบปฏิบัติการอื่นได้เลย แต่ฉันเดาว่านี่เป็นการแนะนำให้รู้จักกับแนวคิดที่ซับซ้อนมาก - หากไม่ใช่รายละเอียดและ API - ควร "พอร์ต" กับระบบปฏิบัติการส่วนใหญ่
อีกแหล่งข้อมูลที่มีค่าที่จะเข้าใจการแก้ไขข้อบกพร่องคือคู่มือ Intel CPU (คู่มือผู้พัฒนาซอฟต์แวร์สถาปัตยกรรมIntel® 64 และ IA-32) ในเล่ม 3A บทที่ 16 แนะนำการสนับสนุนการดีบักของฮาร์ดแวร์เช่นข้อยกเว้นพิเศษและการลงทะเบียนการดีบักฮาร์ดแวร์ ต่อไปนี้มาจากบทที่:
T (กับดัก) แฟล็ก TSS - สร้างข้อยกเว้นการดีบัก (#DB) เมื่อมีการพยายามเปลี่ยนเป็นงานที่มีการตั้งค่าสถานะ T ใน TSS
ฉันไม่แน่ใจว่า Window หรือ Linux ใช้แฟล็กนี้หรือไม่ แต่มันน่าสนใจมากที่จะอ่านบทนั้น
หวังว่านี่จะช่วยใครซักคน
ฉันคิดว่ามีสองคำถามหลักที่จะตอบที่นี่:
1. ดีบักเกอร์รู้ได้อย่างไรว่ามีข้อยกเว้นเกิดขึ้น
เมื่อมีข้อยกเว้นเกิดขึ้นในกระบวนการที่กำลังดีบั๊กดีบักเกอร์จะได้รับแจ้งจากระบบปฏิบัติการก่อนที่ตัวจัดการข้อยกเว้นผู้ใช้ที่กำหนดไว้ในกระบวนการเป้าหมายจะได้รับโอกาสตอบสนองต่อข้อยกเว้น ถ้าตัวดีบักเลือกที่จะไม่จัดการกับการแจ้งเตือนข้อยกเว้น (โอกาสแรก) นี้ลำดับการส่งข้อยกเว้นจะดำเนินต่อไปและเธรดเป้าหมายจะได้รับโอกาสในการจัดการข้อยกเว้นหากต้องการทำเช่นนั้น หากข้อยกเว้น SEH ไม่ได้รับการจัดการโดยกระบวนการเป้าหมายดีบักเกอร์จะส่งเหตุการณ์การดีบักอื่นที่เรียกว่าการแจ้งเตือนโอกาสครั้งที่สองเพื่อแจ้งให้ทราบว่ามีข้อยกเว้นที่ไม่สามารถจัดการได้เกิดขึ้นในกระบวนการเป้าหมาย แหล่ง
2. ดีบักเกอร์รู้วิธีหยุดเบรกพอยต์ได้อย่างไร
ประยุกต์คำตอบคือเมื่อคุณใส่แบ่งจุดลงในโปรแกรมดีบักแทนที่รหัสของคุณที่จุดที่มีการเรียนการสอน int3 ซึ่งเป็นผู้มีการขัดจังหวะซอฟแวร์ โปรแกรมจะหยุดทำงานชั่วคราวและดีบักเกอร์จะถูกเรียกใช้
ความเข้าใจของฉันคือเมื่อคุณรวบรวมแอปพลิเคชันหรือไฟล์ DLL สิ่งใดก็ตามที่คอมไพล์มีสัญลักษณ์ที่แสดงถึงฟังก์ชั่นและตัวแปร
เมื่อคุณมีการตรวจแก้จุดบกพร่องสัญลักษณ์เหล่านี้มีรายละเอียดมากกว่าเมื่อมันเป็นรุ่นวางจำหน่ายดังนั้นการอนุญาตให้ดีบักเกอร์ให้ข้อมูลเพิ่มเติมแก่คุณ เมื่อคุณแนบดีบักเกอร์ไปยังกระบวนการมันจะดูว่าฟังก์ชันใดที่กำลังเข้าถึงและแก้ไขสัญลักษณ์การดีบักที่มีอยู่ทั้งหมดจากที่นี่ (เนื่องจากมันรู้ว่าภายในของไฟล์ที่รวบรวมดูเหมือนว่ามันสามารถรับสิ่งที่อยู่ในหน่วยความจำ กับเนื้อหาของ ints ลอยสตริง ฯลฯ ) เช่นเดียวกับโปสเตอร์แรกที่กล่าวถึงข้อมูลนี้และวิธีการทำงานของสัญลักษณ์เหล่านี้ขึ้นอยู่กับสภาพแวดล้อมและภาษา