ฉันสมมติว่ามีประวัติ แต่ทำไมสแต็คถึงลง?
ดูเหมือนว่าฉันชอบบัฟเฟอร์ล้นจะยากมากที่จะใช้ประโยชน์หากกองเติบโตขึ้น ...
ฉันสมมติว่ามีประวัติ แต่ทำไมสแต็คถึงลง?
ดูเหมือนว่าฉันชอบบัฟเฟอร์ล้นจะยากมากที่จะใช้ประโยชน์หากกองเติบโตขึ้น ...
คำตอบ:
ฉันเชื่อว่ามันมาจากยุคแรก ๆ ของการคำนวณเมื่อหน่วยความจำมี จำกัด และไม่ควรจัดสรรหน่วยความจำขนาดใหญ่ไว้ล่วงหน้าเพื่อการใช้งานสแต็กโดยเฉพาะ ดังนั้นโดยการจัดสรรหน่วยความจำฮีปจากที่อยู่ศูนย์ขึ้นไปและสแต็คหน่วยความจำจากจุดสิ้นสุดของหน่วยความจำด้านล่างคุณอาจมีทั้งฮีปและสแต็คแชร์พื้นที่หน่วยความจำเดียวกัน
หากคุณต้องการฮีปเพิ่มอีกเล็กน้อยคุณอาจระมัดระวังในการใช้สแต็ก ถ้าคุณต้องการสแต็คเพิ่มเติมคุณสามารถลองเพิ่มหน่วยความจำฮีปได้บ้าง ผลที่ได้คือแน่นอนว่าส่วนใหญ่เกิดปัญหาล่มเนื่องจากกองซ้อนจะเขียนทับกองและในทางกลับกันเป็นครั้งคราว
ย้อนกลับไปในสมัยนั้นไม่มี interwebz ดังนั้นจึงไม่มีปัญหาเรื่องการบุกรุกช่องโหว่ของบัฟเฟอร์ (หรืออย่างน้อยก็ในกรณีที่ interwebz มีอยู่ทั้งหมดอยู่ในระบบรักษาความปลอดภัยขั้นสูงของกระทรวงกลาโหมสหรัฐดังนั้นความเป็นไปได้ของข้อมูลที่เป็นอันตรายไม่จำเป็นต้องได้รับการพิจารณามาก)
หลังจากนั้นด้วยสถาปัตยกรรมส่วนใหญ่มันเป็นเรื่องของการรักษาความเข้ากันได้กับสถาปัตยกรรมรุ่นก่อนหน้า นั่นเป็นเหตุผลที่วันนี้สแตคดาวน์ยังคงอยู่กับเรา
หน่วยความจำโปรแกรมถูกตั้งค่าตามธรรมเนียมแล้ว
code
constants
heap (growing up)
...
stack (growing down)
สามารถแลกเปลี่ยนฮีปและสแต็กได้
แต่บัฟเฟอร์โอเวอร์โฟลว์ยังสามารถใช้ประโยชน์ได้หากสแต็กไปทางอื่น
strcpy
ยกตัวอย่างคลาสสิก
foo(char* in){
char[100] buff;
strcpy(buff,in);
}
กับหน่วยความจำสแต็คเป็น
ret foo
arg in
buff array
ret strcpy
buf pointer
in
นี่หมายความว่าเมื่อการคัดลอกเสร็จสิ้นที่อยู่ผู้ส่งstrcpy
จะอยู่หลังบัฟเฟอร์ (แทนที่จะfoo
เป็นที่อยู่ผู้ส่ง) และสามารถเขียนทับได้โดยสิ่งใดก็ตามที่อยู่ในin
ฮาร์ดแวร์บางตัวมีฮีปเริ่มต้นที่หน่วยความจำสูงการเติบโตในขณะที่สแต็กเริ่มที่หน่วยความจำต่ำที่เติบโตขึ้น
ฮาร์ดแวร์ PA-RISC ของ HP และอื่น ๆ ทำสิ่งนี้: http://www.embeddedrelated.com/usenet/embedded/show/68749-1.php
ระบบปฏิบัติการ Multics ที่น่าเชื่อถือวิ่งบนฮาร์ดแวร์ที่มี (หนึ่งในหลาย ๆ อาจ) เติบโตขึ้นมา: ดูhttp://www.acsac.org/2002/papers/classic-multics.pdf , ตอนท้ายของส่วน 2.3.2:
ประการที่สามกองการประมวลผล Multics เติบโตในทิศทางบวกมากกว่าทิศทางลบ นี่หมายความว่าหากคุณทำบัฟเฟอร์ล้นอย่างแท้จริงคุณจะเขียนทับสแต็กเฟรมที่ไม่ได้ใช้แทนตัวชี้คืนของคุณเองทำให้การหาประโยชน์ทำได้ยากขึ้น
นั่นเป็นคำที่ค่อนข้างน่าสนใจ การบัฟเฟอร์ล้นนั้นเป็นปัญหาใหญ่เพียงอย่างเดียวเนื่องจากการจัดเรียงแบบ ยิ่งไปกว่านั้นชื่อเสียงของ Multics ในฐานะ Totally Invulnerable นั้นเป็นเพียงแค่การออกแบบฮาร์ดแวร์