เมื่อใดที่ฉันจะแก้ไขสตริงในไบนารีที่สามารถเรียกทำงานได้


11

ฉันมีไบนารีที่ปฏิบัติการได้; a.outขอเรียกว่า ฉันสามารถดูไบนารีมีสตริง

$ strings a.out
...
/usr/share/foo
....

ฉันจำเป็นต้องเปลี่ยนสายไป/usr/share/foo /usr/share/barฉันสามารถแทนที่สตริงด้วยsedหรือไม่:

sed -i 's@/usr/share/foo@/usr/share/bar@' a.out

นี่เป็นสิ่งที่ควรทำ สิ่งนี้จะใช้งานได้เมื่อสายไม่ยาวเท่ากันหรือไม่

คำตอบ:


17

ฉันไม่ทราบว่าเวอร์ชั่นของคุณsedจะสะอาดแบบไบนารี่หรือไม่หรือจะสำลักกับสิ่งที่คิดว่าเป็นสายยาวจริง ๆ ในอินพุต แต่ไม่รวมถึงปัญหาเหล่านั้นการแก้ไขสตริงควรจะทำงานได้ cmp -lเพื่อดูว่ามันไม่เปรียบเทียบรุ่นเก่าและใหม่ด้วย ควรบอกคุณว่าความแตกต่างเพียงสามประการระหว่างสองไฟล์นั้นคือ 3 ไบต์หรือไม่

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

โดยทั่วไปไม่มีวิธีใดที่คุณสามารถยืดสายอักขระโดยใช้แฮ็คนี้ได้


สิ่งที่เกี่ยวกับการย่อให้สั้นลงด้วยสิ่งที่ชอบsed -i 's@longstring@foo@' a.out? นี่จะทำให้ไบนารีทั้งหมดเล็กลง 7 ไบต์นี่จะไม่ทำให้ไบนารีเสียหายหรือไม่
Martin Vegter

ใช่มันจะทำให้ไบนารีเสียหาย นั่นเป็นเหตุผลที่คุณต้องแปลสตริงให้มีความยาวเท่ากัน แต่ตั้งค่าเทอร์NULมิเนเตอร์ที่ตำแหน่งก่อนหน้าตามที่ฉันอธิบาย (แม้ว่าอาจจะสั้นเกินไป) ปัญหาคือว่าคุณไม่สามารถมีNULไบต์ในบรรทัดคำสั่งเพื่อให้คุณมีที่จะนำคุณโปรแกรมลงในไฟล์และการอ้างอิงถึงมันด้วยsed -fในอีกทางหนึ่งสิ่งที่ปลอดภัยกว่าคือการใช้เครื่องมือที่ออกแบบมาเพื่อทำงานกับข้อมูลไบนารีแทนที่จะเป็นเครื่องมือที่ออกแบบมาเพื่อทำงานกับข้อมูลsedข้อความ
Celada

2
คำตอบที่ดี. sed สามารถทำสิ่งต่าง ๆ ได้มากมาย แต่โดยทั่วไปนั่นเป็นสิ่งที่ผู้ประดิษฐ์ไบนารีแก้ไข พวกเขาสามารถใช้งานได้ยากเมื่อนำทางภายในไฟล์ไบนารีขนาดใหญ่ แต่พวกเขาจะให้คุณเปลี่ยนสิ่งต่าง ๆ ทีละไบต์ ฉันใช้hexeditเมื่อฉันต้องตรวจสอบหรือเปลี่ยนไฟล์ไบนารี คุณสามารถใช้strings -t x file | lessเพื่อค้นหาออฟเซ็ตของสตริง (พิมพ์ได้) ที่คุณต้องการเปลี่ยนก่อนที่จะกระโดดลงในตัวแก้ไข
Joe

สมมติว่าฉันมีสตริงในโปรแกรม C ของฉัน: "ฉันชื่อ Mr Robot" และฉันต้องการแทนที่ 'เป็น' ด้วย 'is' ดังนั้นการขยาย\0จะต้องทำอย่างระมัดระวังเพราะหากการแทนที่ทำสิ่งนี้: "ชื่อของฉัน คือ \ 0 Mr Robot "จากนั้นในขณะที่ดำเนินการกับสตริงอักขระ '\ 0' จะสร้างปัญหาเนื่องจากความยาวจะลดลงโดยไม่ได้ตั้งใจ
Nehal J Wani

@NehalJWani ไม่มีในกรณีที่คุณจะต้องเปลี่ยนส่วนที่เหลือทั้งหมดของสตริงไปข้างหน้าโดยหนึ่งไบต์เพื่อให้คุณใหม่เสริมยกเลิกไปในท้ายที่สุดอยู่ติดกับที่มีอยู่NUL NUL
Celada
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.